From eec1fd737c6829a29c18db22e10ddbcf32e81b88 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Thu, 13 Apr 2023 14:23:17 +0100 Subject: [PATCH 001/205] [mod_signalwire] Make this module working with libks and signalwire-c in versions 2.0 * [mod_signalwire] Fix load credentials data from json * [mod_signalwire] Fix parsing of configuration response --- .../applications/mod_signalwire/mod_signalwire.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_signalwire/mod_signalwire.c b/src/mod/applications/mod_signalwire/mod_signalwire.c index 5b0be47a91..9846e7e1d2 100644 --- a/src/mod/applications/mod_signalwire/mod_signalwire.c +++ b/src/mod/applications/mod_signalwire/mod_signalwire.c @@ -228,7 +228,7 @@ static ks_status_t load_credentials_from_json(ks_json_t *json) const char *relay_connector_id = NULL; #if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2 - if ((bootstrap = ks_json_get_string(json, "bootstrap")) == NULL) { + if ((bootstrap = ks_json_get_object_string(json, "bootstrap", NULL)) == NULL) { #else if ((bootstrap = ks_json_get_object_cstr(json, "bootstrap")) == NULL) { #endif @@ -238,7 +238,7 @@ static ks_status_t load_credentials_from_json(ks_json_t *json) } #if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2 - if ((relay_connector_id = ks_json_get_string(json, "relay_connector_id")) == NULL) { + if ((relay_connector_id = ks_json_get_object_string(json, "relay_connector_id", NULL)) == NULL) { #else if ((relay_connector_id = ks_json_get_object_cstr(json, "relay_connector_id")) == NULL) { #endif @@ -797,6 +797,7 @@ static ks_status_t load_credentials(void) status = KS_STATUS_FAIL; goto done; } + fclose(fp); json = ks_json_parse(data); @@ -805,6 +806,7 @@ static ks_status_t load_credentials(void) status = KS_STATUS_FAIL; goto done; } + status = load_credentials_from_json(json); ks_json_delete(&json); @@ -981,7 +983,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_signalwire_load) #ifdef WIN32 sslLoadWindowsCACertificate(); #endif - // Configuration swclt_config_create(&globals.config); load_config(); @@ -1206,6 +1207,7 @@ static void mod_signalwire_state_configure(void) #if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2 if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &reply)) { if (reply->type == SWCLT_CMD_TYPE_RESULT) { + ks_json_t *result; #else if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &cmd)) { SWCLT_CMD_TYPE cmd_type; @@ -1215,7 +1217,8 @@ static void mod_signalwire_state_configure(void) #endif signalwire_provisioning_configure_response_t *configure_res; #if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2 - if (!SIGNALWIRE_PROVISIONING_CONFIGURE_RESPONSE_PARSE(reply->pool, reply->json, &configure_res)) { + result = ks_json_get_object_item(reply->json, "result"); + if (!SIGNALWIRE_PROVISIONING_CONFIGURE_RESPONSE_PARSE(reply->pool, result, &configure_res)) { #else swclt_cmd_result(cmd, &result); result = ks_json_get_object_item(result, "result"); @@ -1223,7 +1226,7 @@ static void mod_signalwire_state_configure(void) #endif ks_json_t *configuration = configure_res->configuration; #if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2 - const char *configuration_profile = ks_json_get_string(configuration, "profile"); + const char *configuration_profile = ks_json_get_object_string(configuration, "profile", NULL); #else const char *configuration_profile = ks_json_get_object_cstr(configuration, "profile"); #endif @@ -1231,6 +1234,7 @@ static void mod_signalwire_state_configure(void) switch_xml_free(globals.signalwire_profile); globals.signalwire_profile = NULL; } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\"\n", configuration_profile); globals.signalwire_profile = switch_xml_parse_str_dynamic((char *)configuration_profile, SWITCH_TRUE); if (!globals.signalwire_profile) { From 7f3a833466a470687dbd9e407c049f7e74704e99 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 14 Apr 2023 14:48:41 +0300 Subject: [PATCH 002/205] [mod_commands] Fix leaking session readlock in uuid_capture_text --- src/mod/applications/mod_commands/mod_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 4394d9b02f..5b9620a781 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3225,6 +3225,7 @@ SWITCH_STANDARD_API(uuid_capture_text) } else { if ((tsession = switch_core_session_locate(uuid))) { switch_ivr_capture_text(tsession, switch_true(onoff)); + switch_core_session_rwunlock(tsession); } else { stream->write_function(stream, "-ERR No such channel %s!\n", uuid); } From 70c144309c16eed5b875214ff28e42d412a2a91b Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Thu, 13 Apr 2023 19:46:51 +0100 Subject: [PATCH 003/205] [mod_v8] Coverity CID 1468570 (Resource leak) --- src/mod/languages/mod_v8/src/fsglobal.cpp | 26 ++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_v8/src/fsglobal.cpp b/src/mod/languages/mod_v8/src/fsglobal.cpp index 99a0626f8f..c360955687 100644 --- a/src/mod/languages/mod_v8/src/fsglobal.cpp +++ b/src/mod/languages/mod_v8/src/fsglobal.cpp @@ -169,6 +169,7 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLHash) } else { /* The var exists, but is wrong type - exit with error */ info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Second argument is the name of an existing var of the wrong type")); + return; } } else if (info.Length() > 1 && info[1]->IsArray()) { @@ -177,6 +178,7 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLHash) } else if (info.Length() > 1) { /* The var exists, but is wrong type - exit with error */ info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Second argument is of the wrong type")); + return; } else { /* Second argument doesn't exist, this is also ok. The hash will be returned as the result */ @@ -185,6 +187,11 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLHash) } curl_handle = switch_curl_easy_init(); + if (!curl_handle) { + info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to initiate curl easy session.")); + + return; + } if (!strncasecmp(js_safe_str(*url), "https", 5)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); @@ -224,14 +231,22 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLFile) const char *url = NULL, *filename = NULL; String::Utf8Value str1(info[0]); String::Utf8Value str2(info[1]); + url = js_safe_str(*str1); filename = js_safe_str(*str2); curl_handle = switch_curl_easy_init(); + if (!curl_handle) { + info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to initiate curl easy session.")); + + return; + } + if (!strncasecmp(url, "https", 5)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0); } + config_data.isolate = info.GetIsolate(); if ((config_data.fileHandle = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { @@ -245,13 +260,14 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLFile) switch_curl_easy_perform(curl_handle); - switch_curl_easy_cleanup(curl_handle); close(config_data.fileHandle); info.GetReturnValue().Set(true); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file [%s]\n", filename); info.GetReturnValue().Set(false); } + + switch_curl_easy_cleanup(curl_handle); } else { info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments")); } @@ -270,12 +286,19 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURL) if (info.Length() >= 1) { const char *url; String::Utf8Value str(info[0]); + url = js_safe_str(*str); if (info.Length() > 1) { buffer_size = info[1]->Int32Value(); } curl_handle = switch_curl_easy_init(); + if (!curl_handle) { + info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to initiate curl easy session.")); + + return; + } + if (!strncasecmp(url, "https", 5)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0); @@ -289,6 +312,7 @@ JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURL) if (config_data.buffer == NULL) { info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to allocate data buffer.")); switch_curl_easy_cleanup(curl_handle); + return; } From 85a109617f769d401d9b35df6beb2cfc0f69d3b6 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Thu, 13 Apr 2023 13:58:08 +0100 Subject: [PATCH 004/205] [mod_java] Coverity CID 1320752 (Resource leak) --- src/mod/languages/mod_java/modjava.c | 179 ++++++++++++++------------- 1 file changed, 90 insertions(+), 89 deletions(-) diff --git a/src/mod/languages/mod_java/modjava.c b/src/mod/languages/mod_java/modjava.c index 899fee2b60..9c38bdb70f 100644 --- a/src/mod/languages/mod_java/modjava.c +++ b/src/mod/languages/mod_java/modjava.c @@ -189,107 +189,108 @@ SWITCH_STANDARD_APP(java_function) static switch_status_t load_config(JavaVMOption **javaOptions, int *optionCount, vm_control_t * vmControl) { - switch_xml_t cfg, xml; - switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_xml_t cfg, xml; + switch_status_t status = SWITCH_STATUS_SUCCESS; char *derr = NULL; - xml = switch_xml_open_cfg("java.conf", &cfg, NULL); - if (xml) - { - switch_xml_t javavm; - switch_xml_t options; - switch_xml_t startup; - switch_xml_t shutdown; + xml = switch_xml_open_cfg("java.conf", &cfg, NULL); + if (xml) { + switch_xml_t javavm; + switch_xml_t options; + switch_xml_t startup; + switch_xml_t shutdown; - javavm = switch_xml_child(cfg, "javavm"); - if (javavm != NULL) - { - const char *path = switch_xml_attr_soft(javavm, "path"); - if (path != NULL) - { + javavm = switch_xml_child(cfg, "javavm"); + if (javavm != NULL) { + const char *path = switch_xml_attr_soft(javavm, "path"); + + if (path != NULL) { javaVMHandle = switch_dso_open(path, 0, &derr); if (derr || !javaVMHandle) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading %s\n", path); + switch_safe_free(derr); } - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Java VM path specified in java.conf.xml\n"); - status = SWITCH_STATUS_FALSE; - } - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Java VM specified in java.conf.xml\n"); - status = SWITCH_STATUS_FALSE; - goto close; - } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Java VM path specified in java.conf.xml\n"); + status = SWITCH_STATUS_FALSE; + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Java VM specified in java.conf.xml\n"); + status = SWITCH_STATUS_FALSE; + goto close; + } + + options = switch_xml_child(cfg, "options"); + if (options != NULL) { + switch_xml_t option; + int i = 0; + + *optionCount = 0; + + for (option = switch_xml_child(options, "option"); option; option = option->next) { + const char *value = switch_xml_attr_soft(option, "value"); + + if (value != NULL) { + ++*optionCount; + } + } + + *optionCount += 1; + *javaOptions = switch_core_alloc(memoryPool, (switch_size_t)(*optionCount * sizeof(JavaVMOption))); + if (*javaOptions == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory!\n"); + status = SWITCH_STATUS_FALSE; + goto close; + } + + for (option = switch_xml_child(options, "option"); option; option = option->next) { + const char *value = switch_xml_attr_soft(option, "value"); + + if (value == NULL) { + continue; + } + + (*javaOptions)[i].optionString = switch_core_strdup(memoryPool, value); + if ((*javaOptions)[i].optionString == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory!\n"); + status = SWITCH_STATUS_FALSE; + goto close; + } + + ++i; + } - options = switch_xml_child(cfg, "options"); - if (options != NULL) - { - switch_xml_t option; - int i = 0; - *optionCount = 0; - for (option = switch_xml_child(options, "option"); option; option = option->next) - { - const char *value = switch_xml_attr_soft(option, "value"); - if (value != NULL) - ++*optionCount; - } - *optionCount += 1; - *javaOptions = switch_core_alloc(memoryPool, (switch_size_t)(*optionCount * sizeof(JavaVMOption))); - if (*javaOptions == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory!\n"); - status = SWITCH_STATUS_FALSE; - goto close; - } - for (option = switch_xml_child(options, "option"); option; option = option->next) - { - const char *value = switch_xml_attr_soft(option, "value"); - if (value == NULL) - continue; - (*javaOptions)[i].optionString = switch_core_strdup(memoryPool, value); - if ((*javaOptions)[i].optionString == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory!\n"); - status = SWITCH_STATUS_FALSE; - goto close; - } - ++i; - } (*javaOptions)[i].optionString = switch_core_sprintf(memoryPool, "-Djava.library.path=%s", SWITCH_GLOBAL_dirs.mod_dir); - } + } - /* - - - */ + /* + + + */ - memset(vmControl, 0, sizeof(struct vm_control)); - startup = switch_xml_child(cfg, "startup"); - if (startup != NULL) { - vmControl->startup.class = switch_xml_attr_soft(startup, "class"); - vmControl->startup.method = switch_xml_attr_soft(startup, "method"); - vmControl->startup.arg = switch_xml_attr_soft(startup, "arg"); - } - shutdown = switch_xml_child(cfg, "shutdown"); - if (shutdown != NULL) { - vmControl->shutdown.class = switch_xml_attr_soft(shutdown, "class"); - vmControl->shutdown.method = switch_xml_attr_soft(shutdown, "method"); - vmControl->shutdown.arg = switch_xml_attr_soft(shutdown, "arg"); - } + memset(vmControl, 0, sizeof(struct vm_control)); + startup = switch_xml_child(cfg, "startup"); + if (startup != NULL) { + vmControl->startup.class = switch_xml_attr_soft(startup, "class"); + vmControl->startup.method = switch_xml_attr_soft(startup, "method"); + vmControl->startup.arg = switch_xml_attr_soft(startup, "arg"); + } - close: - switch_xml_free(xml); - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening java.conf.xml\n"); - status = SWITCH_STATUS_FALSE; - } - return status; + shutdown = switch_xml_child(cfg, "shutdown"); + if (shutdown != NULL) { + vmControl->shutdown.class = switch_xml_attr_soft(shutdown, "class"); + vmControl->shutdown.method = switch_xml_attr_soft(shutdown, "method"); + vmControl->shutdown.arg = switch_xml_attr_soft(shutdown, "arg"); + } + + close: + switch_xml_free(xml); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening java.conf.xml\n"); + status = SWITCH_STATUS_FALSE; + } + + return status; } static switch_status_t create_java_vm(JavaVMOption *options, int optionCount, vm_control_t * vmControl) From 0b05623cef5c3425831a7bbf28580b30a04eda3e Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Thu, 13 Apr 2023 14:54:50 +0100 Subject: [PATCH 005/205] [mod_translate] Coverity CID 1301006 (Resource leak) --- src/mod/applications/mod_translate/mod_translate.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_translate/mod_translate.c b/src/mod/applications/mod_translate/mod_translate.c index efbcd3f14b..34b1ad54fc 100644 --- a/src/mod/applications/mod_translate/mod_translate.c +++ b/src/mod/applications/mod_translate/mod_translate.c @@ -130,6 +130,7 @@ static void translate_number(char *number, char *profile, char **translated, swi hi = switch_core_hash_find_rdlock(globals.translate_profiles, (const char *)profile, globals.profile_hash_rwlock); if (!hi) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "can't find key for profile matching [%s]\n", profile); + return; } @@ -142,6 +143,7 @@ static void translate_number(char *number, char *profile, char **translated, swi switch_regex_safe_free(re); goto end; } + memset(substituted, 0, len); switch_perform_substitution(re, proceed, rule->replace, number, substituted, len, ovector); @@ -153,16 +155,21 @@ static void translate_number(char *number, char *profile, char **translated, swi } else if (event) { subbed = switch_event_expand_headers(event, substituted); } + + if (subbed != substituted) { + switch_safe_free(substituted); + } + if (session) { substituted = switch_core_session_strdup(session, subbed); } else { substituted = switch_core_strdup(pool, subbed); } - if (subbed != substituted) { - switch_safe_free(subbed); - } + + switch_safe_free(subbed); } + switch_regex_safe_free(re); break; } } From bc00add2542b22afd9c86068ad1cdd6684603564 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Mon, 17 Apr 2023 11:53:26 +0100 Subject: [PATCH 006/205] [mod_kazoo] Coverity fixes (#2043) * [mod_kazoo] Coverity CID 1395503 (Resource leak) * [mod_kazoo] Coverity CID 1468146 (Resource leak) * [mod_kazoo] Coverity CID 1468483 (Resource leak) --- .../mod_kazoo/kazoo_ei_config.c | 19 ++++++++++++----- .../event_handlers/mod_kazoo/kazoo_message.c | 21 +++++++++++++++---- src/mod/event_handlers/mod_kazoo/kazoo_node.c | 10 +++++++++ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c index f1726b677b..3c626c15da 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c @@ -564,13 +564,16 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c switch_memory_pool_t *pool = NULL; char *name = (char *) switch_xml_attr_soft(cfg, "name"); + if (zstr(name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n"); + return SWITCH_STATUS_GENERR; } if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name); + return SWITCH_STATUS_GENERR; } @@ -582,6 +585,7 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c fetch_section = switch_xml_parse_section_string(name); if ((params = switch_xml_child(cfg, "params")) != NULL) { + for (param = switch_xml_child(params, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); @@ -605,7 +609,9 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c } if (fetch_section == SWITCH_XML_SECTION_RESULT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, switch_xml_toxml(cfg, SWITCH_FALSE)); + char *tmp = switch_xml_toxml(cfg, SWITCH_FALSE); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, tmp); + free(tmp); goto err; } @@ -622,17 +628,20 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c } } - if(ptr) + if (ptr) { *ptr = profile; + } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetch handler profile %s successfully configured\n", name); + return SWITCH_STATUS_SUCCESS; err: /* Cleanup */ - if(pool) { - switch_core_destroy_memory_pool(&pool); - } + if(pool) { + switch_core_destroy_memory_pool(&pool); + } + return SWITCH_STATUS_GENERR; } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_message.c b/src/mod/event_handlers/mod_kazoo/kazoo_message.c index e43d656b4c..43716a8e02 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_message.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_message.c @@ -233,9 +233,11 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie } else if((header = switch_event_get_header_ptr(src, field->name)) != NULL) { if (header->idx) { item = cJSON_CreateArray(); + for(i = 0; i < header->idx; i++) { cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); } + kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); } else if (field->out_type_as_array) { item = cJSON_CreateArray(); @@ -251,13 +253,16 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie expanded = kz_event_expand_headers(src, field->value); if(expanded != NULL && !zstr(expanded)) { item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, expanded); - if(expanded != field->value) { - free(expanded); - } } + + if (expanded != field->value) { + switch_safe_free(expanded); + } + break; case FIELD_FIRST_OF: + for(n = 0; n < field->list.size; n++) { if(*field->list.value[n] == '#') { item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, ++field->list.value[n]); @@ -267,33 +272,41 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie if(header) { if (header->idx) { item = cJSON_CreateArray(); + for(i = 0; i < header->idx; i++) { cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); } + kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); } else { item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value); } + break; } } } + break; case FIELD_PREFIX: + for (header = src->headers; header; header = header->next) { if(!strncmp(header->name, field->name, strlen(field->name))) { if (header->idx) { cJSON *array = cJSON_CreateArray(); + for(i = 0; i < header->idx; i++) { cJSON_AddItemToArray(array, kazoo_event_json_value(field->out_type, header->array[i])); } + kazoo_cJSON_AddItemToObject(dst, field->exclude_prefix ? header->name+strlen(field->name) : header->name, array); } else { kazoo_event_add_json_value(dst, field, field->exclude_prefix ? header->name+strlen(field->name) : header->name, header->value); } } } + break; case FIELD_STATIC: @@ -308,7 +321,7 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie break; } - return item; + return item; } static switch_status_t kazoo_event_add_fields_to_json(kazoo_logging_ptr logging, cJSON *dst, switch_event_t *src, kazoo_field_ptr field) { diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c index feb8970a86..f75c327023 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_node.c @@ -1097,23 +1097,27 @@ static switch_status_t handle_request_fetch_reply(ei_node_t *ei_node, erlang_pid if (ei_decode_atom_safe(buf->buff, &buf->index, section_str) || !(section = switch_xml_parse_section_string(section_str))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without a configuration section\n"); + return erlang_response_badarg(rbuf); } if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str) || zstr_buf(uuid_str)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without request UUID\n"); + return erlang_response_badarg(rbuf); } if (ei_decode_string_or_binary(buf->buff, &buf->index, &xml_str)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without XML : %s \n", uuid_str); + return erlang_response_badarg(rbuf); } if (zstr(xml_str)) { switch_safe_free(xml_str); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring an empty fetch reply : %s\n", uuid_str); + return erlang_response_badarg(rbuf); } @@ -1138,13 +1142,19 @@ static switch_status_t handle_request_fetch_reply(ei_node_t *ei_node, erlang_pid break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received fetch reply %s for an unknown configuration section: %s : %s\n", uuid_str, section_str, xml_str); + switch_safe_free(xml_str); + return erlang_response_badarg(rbuf); } if (result == SWITCH_STATUS_SUCCESS) { + switch_safe_free(xml_str); + return erlang_response_ok(rbuf); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received fetch reply %s is unknown or has expired : %s\n", uuid_str, xml_str); + switch_safe_free(xml_str); + return erlang_response_baduuid(rbuf); } } From 0c2edc4f56a64ddab1a94a91981517df20d83139 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 14 Apr 2023 11:28:01 +0100 Subject: [PATCH 007/205] [mod_radius_cdr] Coverity CID 1395529 (Resource leak) --- .../mod_radius_cdr/mod_radius_cdr.c | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c index 490a7911f1..153ec6252d 100644 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c +++ b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c @@ -166,8 +166,10 @@ static switch_status_t my_on_routing(switch_core_session_t *session) if (channel) { const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_start"); + if (switch_true(disable_flag)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Start\n"); + return SWITCH_STATUS_SUCCESS; } } @@ -250,6 +252,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->caller_id_number) { if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); @@ -257,6 +260,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->caller_id_name) { if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); @@ -264,6 +268,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->destination_number) { if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); @@ -271,6 +276,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->dialplan) { if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); @@ -278,6 +284,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->network_addr) { inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr); framed_addr = htonl(framed_addr); @@ -287,6 +294,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->rdnis) { if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); @@ -294,6 +302,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->context) { if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); @@ -301,6 +310,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->ani) { if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); @@ -308,6 +318,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->aniii) { if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); @@ -315,6 +326,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (profile->source) { if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); @@ -322,6 +334,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) goto end; } } + if (callstartdate > 0) { switch_time_exp_tz(&tm, callstartdate, requested_tm.tm_gmtoff); switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", @@ -380,25 +393,33 @@ static switch_status_t my_on_routing(switch_core_session_t *session) } if (radius_avpair) { + char *radius_avpair_data_tmp = NULL; + radius_avpair_data = strdup(radius_avpair + (strncmp(radius_avpair, "ARRAY::", 7) ? 0 : 7)); + radius_avpair_data_tmp = radius_avpair_data; + do { - delim = strstr(radius_avpair_data, "|:"); + delim = strstr(radius_avpair_data_tmp, "|:"); if (delim) { *delim = '\0'; } - if (rc_avpair_add(rad_config, &send, PW_FS_AVPAIR, (void *) radius_avpair_data, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-AVPair: %s\n", radius_avpair_data); + if (rc_avpair_add(rad_config, &send, PW_FS_AVPAIR, (void *)radius_avpair_data_tmp, -1, PW_FS_PEC) == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-AVPair: %s\n", radius_avpair_data_tmp); rc_destroy(rad_config); + switch_safe_free(radius_avpair_data); goto end; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "added Freeswitch-AVPair: %s\n", radius_avpair_data); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "added Freeswitch-AVPair: %s\n", radius_avpair_data_tmp); if (delim) { - radius_avpair_data = delim + 2; + radius_avpair_data_tmp = delim + 2; } } while (delim); + + switch_safe_free(radius_avpair_data); } } else { @@ -413,11 +434,13 @@ static switch_status_t my_on_routing(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] RADIUS Accounting Failed\n"); retval = SWITCH_STATUS_TERM; } + rc_avpair_free(send); rc_destroy(rad_config); end: switch_xml_free(cdr); switch_thread_rwlock_unlock(globals.rwlock); + return (retval); } From 98c0482844a51a99197906983c0b7942b7993130 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 10 Apr 2023 15:29:47 +0300 Subject: [PATCH 008/205] [mod_opusfile] coverity CID 1468424 (Missing break in switch) --- src/mod/formats/mod_opusfile/mod_opusfile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/formats/mod_opusfile/mod_opusfile.c b/src/mod/formats/mod_opusfile/mod_opusfile.c index 1560142263..a065108f5c 100644 --- a/src/mod/formats/mod_opusfile/mod_opusfile.c +++ b/src/mod/formats/mod_opusfile/mod_opusfile.c @@ -654,6 +654,7 @@ static switch_status_t switch_opusstream_stream_decode(opus_stream_context_t *co } switch_goto_status(SWITCH_STATUS_SUCCESS, end); } + break; case OP_EREAD: /*An underlying read operation failed. This may signal a truncation attack from an source.*/ case OP_EFAULT: /* An internal memory allocation failed. */ From 01e960cd90c32b59b695421388d2522a0178b28e Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 10 Apr 2023 17:48:33 +0300 Subject: [PATCH 009/205] [mod_erlang_event] coverity CID 1500239 (Uninitialized scalar variable) --- src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index d15f748eb7..bd7bf8e26c 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -1998,7 +1998,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_erlang_event_runtime) struct ei_cnode_s ec; ErlConnect conn; int clientfd; - switch_os_socket_t epmdfd; + switch_os_socket_t epmdfd = SWITCH_SOCK_INVALID; switch_socket_t *epmd_sock = NULL; if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { From aab9839678e506ee50c76421acce5f76f5962d97 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 10 Apr 2023 18:22:45 +0300 Subject: [PATCH 010/205] [mod_sofia] coverity CID 1468496 (Unchecked return value) --- src/mod/endpoints/mod_sofia/sip-dig.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sip-dig.c b/src/mod/endpoints/mod_sofia/sip-dig.c index e89f5aef44..c9a6f5b463 100644 --- a/src/mod/endpoints/mod_sofia/sip-dig.c +++ b/src/mod/endpoints/mod_sofia/sip-dig.c @@ -815,8 +815,12 @@ sres_record_t ** dig_addr_simple(struct dig *dig, uint16_t type) { sres_record_t **answers = NULL; + int error; - sres_blocking_query(dig->sres, type, host, 0, &answers); + error = sres_blocking_query(dig->sres, type, host, 0, &answers); + if (error < 0) { + return NULL; + } return answers; } From 075724845e1c9795ccb6625912b4f81e87401a1e Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 14 Apr 2023 10:25:40 +0100 Subject: [PATCH 011/205] [mod_rayo] Coverity CID 1395579 (Resource leak) --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 6ed46489a7..228e89b323 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -4765,7 +4765,7 @@ static void send_console_command(struct rayo_client *client, const char *to, con iks *command = NULL; iksparser *p = iks_dom_new(&command); - if (iks_parse(p, command_str, 0, 1) == IKS_OK && command) { + if (p && iks_parse(p, command_str, 0, 1) == IKS_OK && command) { char *str; iks *iq = NULL; @@ -4784,9 +4784,11 @@ static void send_console_command(struct rayo_client *client, const char *to, con if (!iks_find_attrib(iq, "type")) { iks_insert_attrib(iq, "type", "set"); } + if (!iks_find_attrib(iq, "id")) { iks_insert_attrib_printf(iq, "id", "console-%i", RAYO_SEQ_NEXT(client)); } + iks_insert_attrib(iq, "from", RAYO_JID(client)); /* send command */ @@ -4794,10 +4796,13 @@ static void send_console_command(struct rayo_client *client, const char *to, con switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nSEND: to %s, %s\n", to, str); rayo_client_command_recv(client, iq); iks_delete(command); + iks_parser_delete(p); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "bad request xml\n"); + if (p) { + iks_parser_delete(p); + } } - iks_parser_delete(p); } /** From 6eefc674fe1bf75122dc511ea4a8fb0367167210 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Mon, 17 Apr 2023 19:49:42 +0100 Subject: [PATCH 012/205] [mod_avmd] Coverity fixes * [mod_avmd] Coverity CID 1395501 (Dereference null return value) * [mod_avmd] Coverity CID 1395478 (Resource leak) --- .../applications/mod_avmd/avmd_fast_acosf.c | 20 +++++++++++-------- src/mod/applications/mod_avmd/mod_avmd.c | 18 +++-------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/mod/applications/mod_avmd/avmd_fast_acosf.c b/src/mod/applications/mod_avmd/avmd_fast_acosf.c index 572c6a84f9..59b581b98d 100644 --- a/src/mod/applications/mod_avmd/avmd_fast_acosf.c +++ b/src/mod/applications/mod_avmd/avmd_fast_acosf.c @@ -86,7 +86,6 @@ typedef union { static uint32_t index_from_float(float f); static float float_from_index(uint32_t d); static float *acos_table = NULL; -static int acos_fd = -1; #ifdef FAST_ACOSF_TESTING @@ -112,6 +111,10 @@ extern int compute_table(void) acos_table_file = fopen(ACOS_TABLE_FILENAME, "w"); + if (!acos_table_file) { + return -3; + } + for (i = 0; i < ACOS_TABLE_LENGTH; i++) { f = acosf(float_from_index(i)); res = fwrite(&f, sizeof(f), 1, acos_table_file); @@ -124,10 +127,12 @@ extern int compute_table(void) if (res != 0) { return -2; } + return 0; fail: fclose(acos_table_file); + return -1; } @@ -144,8 +149,9 @@ extern int init_fast_acosf(void) * or some other error occured */ errsv = errno; strerror_r(errsv, err, 150); - if (errsv != ENOENT) return -1; - else { + if (errsv != ENOENT) { + return -1; + } else { switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, @@ -166,10 +172,10 @@ extern int init_fast_acosf(void) acos_fp = fopen(ACOS_TABLE_FILENAME, "r"); if (acos_fp == NULL) return -3; /* can't fail */ - acos_fd = fileno(acos_fp); acos_table = (float *) mmap( NULL, /* kernel chooses the address at which to create the mapping */ - ACOS_TABLE_LENGTH * sizeof(float), PROT_READ, MAP_SHARED, acos_fd, 0); + ACOS_TABLE_LENGTH * sizeof(float), PROT_READ, MAP_SHARED, fileno(acos_fp), 0); + fclose(acos_fp); if (acos_table == MAP_FAILED) return -4; return 0; @@ -178,9 +184,7 @@ extern int init_fast_acosf(void) extern int destroy_fast_acosf(void) { if (munmap(acos_table, ACOS_TABLE_LENGTH) == -1) return -1; - if (acos_fd != -1) { - if (close(acos_fd) == -1) return -2; - } + /* disable use of fast arc cosine file */ acos_table = NULL; diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index dde3dfbf93..6c59256eda 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -1622,9 +1622,6 @@ SWITCH_STANDARD_APP(avmd_start_function) { SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) { size_t session_n; -#ifndef WIN32 - int res; -#endif switch_mutex_lock(avmd_globals.mutex); @@ -1638,18 +1635,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) { #ifndef WIN32 if (avmd_globals.settings.fast_math == 1) { - res = destroy_fast_acosf(); - if (res != 0) { - switch (res) { - case -1: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed unmap arc cosine table\n"); - break; - case -2: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed closing arc cosine table\n"); - break; - default: - break; - } + if (destroy_fast_acosf()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed unmap arc cosine table\n"); } } #endif @@ -1658,6 +1645,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) { switch_mutex_unlock(avmd_globals.mutex); switch_mutex_destroy(avmd_globals.mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Advanced voicemail detection disabled\n"); + return SWITCH_STATUS_SUCCESS; } From e1d966ed0a362c9c001071c69e8afb8599ad50e6 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 10 Apr 2023 17:05:49 +0300 Subject: [PATCH 013/205] [mod_dptools] coverity CID 1468646 (Unsigned compared against 0) --- src/mod/applications/mod_dptools/mod_dptools.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index f38509016b..e91ec53d47 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4584,7 +4584,7 @@ SWITCH_STANDARD_APP(wait_for_silence_function) timeout_ms = switch_atoui(argv[3]); } - if (thresh > 0 && silence_hits > 0 && listen_hits >= 0) { + if (thresh > 0 && silence_hits > 0) { switch_ivr_wait_for_silence(session, thresh, silence_hits, listen_hits, timeout_ms, argv[4]); return; } From 5597fe30983a580bc009eb9e769e185d3c9035b6 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 10 Apr 2023 18:15:42 +0300 Subject: [PATCH 014/205] [mod_avmd] coverity CID 1395555 (Dereference before null check) --- src/mod/applications/mod_avmd/mod_avmd.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 6c59256eda..e5076c1500 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -1138,6 +1138,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) { switch_application_interface_t *app_interface; switch_api_interface_t *api_interface; + + if (pool == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No memory pool assigned!\n"); + + return SWITCH_STATUS_TERM; + } + /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -1147,10 +1154,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) { } memset(&avmd_globals, 0, sizeof(avmd_globals)); - if (pool == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No memory pool assigned!\n"); - return SWITCH_STATUS_TERM; - } switch_mutex_init(&avmd_globals.mutex, SWITCH_MUTEX_NESTED, pool); avmd_globals.pool = pool; From b5cb26dc479860c62fa9d6e064f893779d27fe21 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Tue, 18 Apr 2023 19:30:22 +0300 Subject: [PATCH 015/205] [Core] Coverity fixes * [core] coverity CID 1024482 (Dereference after null check) * [core] coverity CID 1468368 (Logically dead code) * [core] coverity CID 1468459 (Logically dead code) * [core] coverity CID 1232742 (Dereference before null check) --- src/switch_core.c | 2 +- src/switch_packetizer.c | 2 -- src/switch_rtp.c | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/switch_core.c b/src/switch_core.c index cf2343482a..4e2b70778a 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -147,7 +147,7 @@ static void check_ip(void) } else if (strcmp(hostname, runtime.hostname)) { if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "hostname-change"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "old-hostname", hostname ? hostname : "nil"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "old-hostname", hostname); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "new-hostname", runtime.hostname); switch_event_fire(&event); } diff --git a/src/switch_packetizer.c b/src/switch_packetizer.c index 05688f8a86..626e85ba8e 100644 --- a/src/switch_packetizer.c +++ b/src/switch_packetizer.c @@ -160,8 +160,6 @@ SWITCH_DECLARE(switch_status_t) switch_packetizer_feed_extradata(switch_packetiz p += 5; left -= 5; - if (left < 0) return SWITCH_STATUS_FALSE; - //sps n_sps = *p & 0x1f; p += 1; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index ad9f8eef1c..614d79bf78 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1353,7 +1353,6 @@ SWITCH_DECLARE(void) switch_srtp_err_to_txt(srtp_err_status_t stat, char **msg) else if (stat == srtp_err_status_read_fail) *msg="couldn't read data"; else if (stat == srtp_err_status_write_fail) *msg="couldn't write data"; else if (stat == srtp_err_status_parse_err) *msg="error parsing data"; - else if (stat == srtp_err_status_write_fail) *msg="couldn't read data"; else if (stat == srtp_err_status_encode_err) *msg="error encoding data"; else if (stat == srtp_err_status_semaphore_err) *msg="error while using semaphores"; else if (stat == srtp_err_status_pfkey_err) *msg="error while using pfkey "; @@ -4947,7 +4946,7 @@ SWITCH_DECLARE(void) switch_rtp_kill_socket(switch_rtp_t *rtp_session) } if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { - if (rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_input != rtp_session->sock_input) { + if (rtp_session->sock_input && rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_input != rtp_session->sock_input) { ping_socket(rtp_session); switch_socket_shutdown(rtp_session->rtcp_sock_input, SWITCH_SHUTDOWN_READWRITE); } From 039823848906b11fd6183ba81f037b7211a29497 Mon Sep 17 00:00:00 2001 From: Clarence Date: Fri, 28 Apr 2023 04:43:32 +0800 Subject: [PATCH 016/205] [Core, mod_curl, mod_httapi, mod_http_cache] Compatible with libcurl>=7.87.0 * [core] fix deprecated with libcurl>=7.56.0 * [mod_httpapi] fix deprecated with libcurl>=7.56.0 * [mod_curl] fix deprecated with libcurl>=7.56.0 * [mod_http_cache] fix deprecated with libcurl>=7.12.1 --- src/include/switch_curl.h | 4 +++ src/mod/applications/mod_curl/mod_curl.c | 36 +++++++++++++++++++ src/mod/applications/mod_httapi/mod_httapi.c | 12 +++++++ src/mod/applications/mod_http_cache/azure.c | 4 +++ .../mod_http_cache/mod_http_cache.c | 2 ++ src/switch_curl.c | 31 ++++++++++++++-- 6 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/include/switch_curl.h b/src/include/switch_curl.h index 5872527865..389548791a 100644 --- a/src/include/switch_curl.h +++ b/src/include/switch_curl.h @@ -50,7 +50,11 @@ SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt(CURL *handle, switch_CUR SWITCH_DECLARE(const char *) switch_curl_easy_strerror(switch_CURLcode errornum ); SWITCH_DECLARE(void) switch_curl_init(void); SWITCH_DECLARE(void) switch_curl_destroy(void); +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) +SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, curl_mime **mimep); +#else SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp); +#endif #define switch_curl_easy_setopt curl_easy_setopt SWITCH_END_EXTERN_C diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index 02079d6767..c780e6947e 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -104,8 +104,13 @@ struct http_sendfile_data_obj { char *extrapost_elements; switch_CURL *curl_handle; char *cacert; +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime *mime; + curl_mimepart *part; +#else struct curl_httppost *formpost; struct curl_httppost *lastptr; +#endif uint8_t flags; /* This is for where to send output of the curl_sendfile commands */ switch_stream_handle_t *stream; char *sendfile_response; @@ -456,8 +461,19 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEFUNCTION, http_sendfile_response_callback); curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEDATA, (void *) http_data); + /* Initial http_data->mime */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->mime = curl_mime_init(http_data->curl_handle); +#endif + /* Add the file to upload as a POST form field */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->part = curl_mime_addpart(http_data->mime); + curl_mime_name(http_data->part, http_data->filename_element_name); + curl_mime_filedata(http_data->part, http_data->filename_element); +#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, http_data->filename_element_name, CURLFORM_FILE, http_data->filename_element, CURLFORM_END); +#endif if(!zstr(http_data->extrapost_elements)) { @@ -476,16 +492,32 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) if(argc2 == 2) { switch_url_decode(argv2[0]); switch_url_decode(argv2[1]); +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->part = curl_mime_addpart(http_data->mime); + curl_mime_name(http_data->part, argv2[0]); + curl_mime_data(http_data->part, argv2[1], CURL_ZERO_TERMINATED); +#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, argv2[0], CURLFORM_COPYCONTENTS, argv2[1], CURLFORM_END); +#endif } } } /* Fill in the submit field too, even if this isn't really needed */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->part = curl_mime_addpart(http_data->mime); + curl_mime_name(http_data->part, "submit"); + curl_mime_data(http_data->part, "or_die", CURL_ZERO_TERMINATED); +#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "or_die", CURLFORM_END); +#endif /* what URL that receives this POST */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_easy_setopt(http_data->curl_handle, CURLOPT_MIMEPOST, http_data->mime); +#else curl_easy_setopt(http_data->curl_handle, CURLOPT_HTTPPOST, http_data->formpost); +#endif // This part actually fires off the curl, captures the HTTP response code, and then frees up the handle. curl_easy_perform(http_data->curl_handle); @@ -494,7 +526,11 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) curl_easy_cleanup(http_data->curl_handle); // Clean up the form data from POST +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime_free(http_data->mime); +#else curl_formfree(http_data->formpost); +#endif } static switch_status_t http_sendfile_test_file_open(http_sendfile_data_t *http_data, switch_event_t *event) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 4b32d87c6d..4da0deeb49 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1419,7 +1419,11 @@ static switch_status_t httapi_sync(client_t *client) switch_status_t status = SWITCH_STATUS_FALSE; int get_style_method = 0; char *method = NULL; +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime *formpost = NULL; +#else struct curl_httppost *formpost=NULL; +#endif switch_event_t *save_params = NULL; const char *put_file; FILE *fd = NULL; @@ -1588,7 +1592,11 @@ static switch_status_t httapi_sync(client_t *client) curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, put_file_read); } else if (formpost) { +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_easy_setopt(curl_handle, CURLOPT_MIMEPOST, formpost); +#else curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, formpost); +#endif } else { switch_curl_easy_setopt(curl_handle, CURLOPT_POST, !get_style_method); } @@ -1671,7 +1679,11 @@ static switch_status_t httapi_sync(client_t *client) switch_curl_slist_free_all(headers); if (formpost) { +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime_free(formpost); +#else curl_formfree(formpost); +#endif } if (client->err) { diff --git a/src/mod/applications/mod_http_cache/azure.c b/src/mod/applications/mod_http_cache/azure.c index f1e4cf8925..a16d2e9f94 100644 --- a/src/mod/applications/mod_http_cache/azure.c +++ b/src/mod/applications/mod_http_cache/azure.c @@ -279,7 +279,11 @@ switch_status_t azure_blob_finalise_put(http_profile_t *profile, const char *url goto done; } +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x070c01) + switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); +#else switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); +#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url); diff --git a/src/mod/applications/mod_http_cache/mod_http_cache.c b/src/mod/applications/mod_http_cache/mod_http_cache.c index 9d19099e56..365ba27425 100644 --- a/src/mod/applications/mod_http_cache/mod_http_cache.c +++ b/src/mod/applications/mod_http_cache/mod_http_cache.c @@ -393,7 +393,9 @@ static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, swi goto done; } switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); +#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01) switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); +#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url); diff --git a/src/switch_curl.c b/src/switch_curl.c index c99a5f61de..2612faa0da 100644 --- a/src/switch_curl.c +++ b/src/switch_curl.c @@ -58,11 +58,19 @@ SWITCH_DECLARE(void) switch_curl_destroy(void) curl_global_cleanup(); } +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) +SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, curl_mime **mimep) +#else SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp) +#endif { - +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime *mime = NULL; + curl_mimepart *part = NULL; +#else struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; +#endif switch_event_header_t *hp; int go = 0; @@ -77,6 +85,9 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_even return SWITCH_STATUS_FALSE; } +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + mime = curl_mime_init(curl_handle); +#endif for (hp = event->headers; hp; hp = hp->next) { if (!strncasecmp(hp->name, "attach_file:", 12)) { @@ -87,26 +98,42 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_even if (fname) { *fname++ = '\0'; +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + part = curl_mime_addpart(mime); + curl_mime_name(part, pname); + curl_mime_filename(part, fname); + curl_mime_filedata(part, hp->value); +#else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, pname, CURLFORM_FILENAME, fname, CURLFORM_FILE, hp->value, CURLFORM_END); +#endif } free(pname); } } else { +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + part = curl_mime_addpart(mime); + curl_mime_name(part, hp->name); + curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED); +#else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, hp->name, CURLFORM_COPYCONTENTS, hp->value, CURLFORM_END); - +#endif } } +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + *mimep = mime; +#else *formpostp = formpost; +#endif return SWITCH_STATUS_SUCCESS; From f377a0ff578ba950191b4629eae35f82bcd79388 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 1 May 2023 20:38:51 +0300 Subject: [PATCH 017/205] Revert "[Core, mod_curl, mod_httapi, mod_http_cache] Compatible with libcurl>=7.87.0" (#2070) This reverts commit 039823848906b11fd6183ba81f037b7211a29497. --- src/include/switch_curl.h | 4 --- src/mod/applications/mod_curl/mod_curl.c | 36 ------------------- src/mod/applications/mod_httapi/mod_httapi.c | 12 ------- src/mod/applications/mod_http_cache/azure.c | 4 --- .../mod_http_cache/mod_http_cache.c | 2 -- src/switch_curl.c | 31 ++-------------- 6 files changed, 2 insertions(+), 87 deletions(-) diff --git a/src/include/switch_curl.h b/src/include/switch_curl.h index 389548791a..5872527865 100644 --- a/src/include/switch_curl.h +++ b/src/include/switch_curl.h @@ -50,11 +50,7 @@ SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt(CURL *handle, switch_CUR SWITCH_DECLARE(const char *) switch_curl_easy_strerror(switch_CURLcode errornum ); SWITCH_DECLARE(void) switch_curl_init(void); SWITCH_DECLARE(void) switch_curl_destroy(void); -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) -SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, curl_mime **mimep); -#else SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp); -#endif #define switch_curl_easy_setopt curl_easy_setopt SWITCH_END_EXTERN_C diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index c780e6947e..02079d6767 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -104,13 +104,8 @@ struct http_sendfile_data_obj { char *extrapost_elements; switch_CURL *curl_handle; char *cacert; -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_mime *mime; - curl_mimepart *part; -#else struct curl_httppost *formpost; struct curl_httppost *lastptr; -#endif uint8_t flags; /* This is for where to send output of the curl_sendfile commands */ switch_stream_handle_t *stream; char *sendfile_response; @@ -461,19 +456,8 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEFUNCTION, http_sendfile_response_callback); curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEDATA, (void *) http_data); - /* Initial http_data->mime */ -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - http_data->mime = curl_mime_init(http_data->curl_handle); -#endif - /* Add the file to upload as a POST form field */ -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - http_data->part = curl_mime_addpart(http_data->mime); - curl_mime_name(http_data->part, http_data->filename_element_name); - curl_mime_filedata(http_data->part, http_data->filename_element); -#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, http_data->filename_element_name, CURLFORM_FILE, http_data->filename_element, CURLFORM_END); -#endif if(!zstr(http_data->extrapost_elements)) { @@ -492,32 +476,16 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) if(argc2 == 2) { switch_url_decode(argv2[0]); switch_url_decode(argv2[1]); -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - http_data->part = curl_mime_addpart(http_data->mime); - curl_mime_name(http_data->part, argv2[0]); - curl_mime_data(http_data->part, argv2[1], CURL_ZERO_TERMINATED); -#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, argv2[0], CURLFORM_COPYCONTENTS, argv2[1], CURLFORM_END); -#endif } } } /* Fill in the submit field too, even if this isn't really needed */ -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - http_data->part = curl_mime_addpart(http_data->mime); - curl_mime_name(http_data->part, "submit"); - curl_mime_data(http_data->part, "or_die", CURL_ZERO_TERMINATED); -#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "or_die", CURLFORM_END); -#endif /* what URL that receives this POST */ -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_easy_setopt(http_data->curl_handle, CURLOPT_MIMEPOST, http_data->mime); -#else curl_easy_setopt(http_data->curl_handle, CURLOPT_HTTPPOST, http_data->formpost); -#endif // This part actually fires off the curl, captures the HTTP response code, and then frees up the handle. curl_easy_perform(http_data->curl_handle); @@ -526,11 +494,7 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) curl_easy_cleanup(http_data->curl_handle); // Clean up the form data from POST -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_mime_free(http_data->mime); -#else curl_formfree(http_data->formpost); -#endif } static switch_status_t http_sendfile_test_file_open(http_sendfile_data_t *http_data, switch_event_t *event) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 4da0deeb49..4b32d87c6d 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1419,11 +1419,7 @@ static switch_status_t httapi_sync(client_t *client) switch_status_t status = SWITCH_STATUS_FALSE; int get_style_method = 0; char *method = NULL; -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_mime *formpost = NULL; -#else struct curl_httppost *formpost=NULL; -#endif switch_event_t *save_params = NULL; const char *put_file; FILE *fd = NULL; @@ -1592,11 +1588,7 @@ static switch_status_t httapi_sync(client_t *client) curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, put_file_read); } else if (formpost) { -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_easy_setopt(curl_handle, CURLOPT_MIMEPOST, formpost); -#else curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, formpost); -#endif } else { switch_curl_easy_setopt(curl_handle, CURLOPT_POST, !get_style_method); } @@ -1679,11 +1671,7 @@ static switch_status_t httapi_sync(client_t *client) switch_curl_slist_free_all(headers); if (formpost) { -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_mime_free(formpost); -#else curl_formfree(formpost); -#endif } if (client->err) { diff --git a/src/mod/applications/mod_http_cache/azure.c b/src/mod/applications/mod_http_cache/azure.c index a16d2e9f94..f1e4cf8925 100644 --- a/src/mod/applications/mod_http_cache/azure.c +++ b/src/mod/applications/mod_http_cache/azure.c @@ -279,11 +279,7 @@ switch_status_t azure_blob_finalise_put(http_profile_t *profile, const char *url goto done; } -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x070c01) - switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); -#else switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); -#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url); diff --git a/src/mod/applications/mod_http_cache/mod_http_cache.c b/src/mod/applications/mod_http_cache/mod_http_cache.c index 365ba27425..9d19099e56 100644 --- a/src/mod/applications/mod_http_cache/mod_http_cache.c +++ b/src/mod/applications/mod_http_cache/mod_http_cache.c @@ -393,9 +393,7 @@ static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, swi goto done; } switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); -#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01) switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); -#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url); diff --git a/src/switch_curl.c b/src/switch_curl.c index 2612faa0da..c99a5f61de 100644 --- a/src/switch_curl.c +++ b/src/switch_curl.c @@ -58,19 +58,11 @@ SWITCH_DECLARE(void) switch_curl_destroy(void) curl_global_cleanup(); } -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) -SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, curl_mime **mimep) -#else SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp) -#endif { -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - curl_mime *mime = NULL; - curl_mimepart *part = NULL; -#else + struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; -#endif switch_event_header_t *hp; int go = 0; @@ -85,9 +77,6 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_even return SWITCH_STATUS_FALSE; } -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - mime = curl_mime_init(curl_handle); -#endif for (hp = event->headers; hp; hp = hp->next) { if (!strncasecmp(hp->name, "attach_file:", 12)) { @@ -98,42 +87,26 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_even if (fname) { *fname++ = '\0'; -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - part = curl_mime_addpart(mime); - curl_mime_name(part, pname); - curl_mime_filename(part, fname); - curl_mime_filedata(part, hp->value); -#else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, pname, CURLFORM_FILENAME, fname, CURLFORM_FILE, hp->value, CURLFORM_END); -#endif } free(pname); } } else { -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - part = curl_mime_addpart(mime); - curl_mime_name(part, hp->name); - curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED); -#else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, hp->name, CURLFORM_COPYCONTENTS, hp->value, CURLFORM_END); -#endif + } } -#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) - *mimep = mime; -#else *formpostp = formpost; -#endif return SWITCH_STATUS_SUCCESS; From 21613b6f683843bfa73008fa044827a133b0e7c3 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 13 May 2023 15:25:51 +0300 Subject: [PATCH 018/205] Bump sofia-sip library requirement to version 1.13.15 --- configure.ac | 2 +- debian/bootstrap.sh | 4 ++-- freeswitch.spec | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7ca19e49e8..04738e93c1 100644 --- a/configure.ac +++ b/configure.ac @@ -716,7 +716,7 @@ PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[ AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent]) ]) -PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.14],[ +PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.15],[ AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[ AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent]) ]) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index e3f0b1b9db..c207036757 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -332,7 +332,7 @@ Build-Depends: uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev, # used by many modules libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev, - bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.14), + bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.15), libspandsp3-dev, # used to format the private freeswitch apt-repo key properly gnupg, @@ -371,7 +371,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: libfreeswitch1 Architecture: amd64 armhf -Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.14) +Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.15) Recommends: Suggests: libfreeswitch1-dbg Conflicts: freeswitch-all (<= 1.6.7) diff --git a/freeswitch.spec b/freeswitch.spec index f3904afa2c..1d985cc299 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -140,7 +140,7 @@ BuildRequires: curl-devel >= 7.19 BuildRequires: gcc-c++ BuildRequires: libtool >= 1.5.17 BuildRequires: openssl-devel >= 1.0.1e -BuildRequires: sofia-sip-devel >= 1.13.14 +BuildRequires: sofia-sip-devel >= 1.13.15 BuildRequires: spandsp3-devel >= 3.0 BuildRequires: pcre-devel BuildRequires: speex-devel From a3a4244f21472fd42490575a6a01a1f76d264ca9 Mon Sep 17 00:00:00 2001 From: ping Date: Wed, 17 May 2023 00:29:13 +0800 Subject: [PATCH 019/205] [mod_sofia] fix sofia_glue_get_extra_headers memory leak --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 8c9dfcc57a..0eb0dcf601 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -929,9 +929,9 @@ char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix if ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { const char *hname = name + strlen(prefix); stream.write_function(&stream, "%s: %s\r\n", hname, value); - switch_regex_safe_free(re); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex); + switch_regex_safe_free(re); } } } From a4af2ea7de6e3eaff8aed1fb788a962db81739b4 Mon Sep 17 00:00:00 2001 From: Henrique Date: Tue, 23 May 2023 20:14:22 -0300 Subject: [PATCH 020/205] [mod_png] Fix unexpected png video blocked read --- src/mod/formats/mod_png/mod_png.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/formats/mod_png/mod_png.c b/src/mod/formats/mod_png/mod_png.c index 36e38e9c83..fbbe6aaf20 100644 --- a/src/mod/formats/mod_png/mod_png.c +++ b/src/mod/formats/mod_png/mod_png.c @@ -215,7 +215,7 @@ static switch_status_t png_file_read_video(switch_file_handle_t *handle, switch_ switch_goto_status(SWITCH_STATUS_FALSE, end); } - if ((flags && SVR_BLOCK)) { + if ((flags & SVR_BLOCK)) { switch_yield(33000); have_frame = 1; } else if ((context->reads++ % 20) == 0) { From 35823b650a62e83a21b664b2e802b92215e92ac6 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 30 May 2023 22:45:54 +0300 Subject: [PATCH 021/205] [mod_verto] Include libks/ks.h instead of ks.h --- src/mod/endpoints/mod_verto/mod_verto.c | 2 +- src/mod/endpoints/mod_verto/mod_verto.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index e7defb99aa..38a3bc302a 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -43,7 +43,7 @@ SWITCH_MODULE_DEFINITION(mod_verto, mod_verto_load, mod_verto_shutdown, mod_vert #define HTTP_CHUNK_SIZE 1024 * 32 #define EP_NAME "verto.rtc" //#define WSS_STANDALONE 1 -#include "ks.h" +#include "libks/ks.h" #include #ifndef WIN32 diff --git a/src/mod/endpoints/mod_verto/mod_verto.h b/src/mod/endpoints/mod_verto/mod_verto.h index f3326f605d..f13e8ef2b9 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.h +++ b/src/mod/endpoints/mod_verto/mod_verto.h @@ -62,7 +62,7 @@ #include #include "mcast.h" -#include "ks.h" +#include "libks/ks.h" #define MAX_QUEUE_LEN 100000 #define MAX_MISSED 500 From ef275aec8a31a97faf7ddef1e4e4c009fa2ffcf6 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Wed, 31 May 2023 15:58:19 +0300 Subject: [PATCH 022/205] [mod_portaudio] coverity CID 1024263 (Dereference before null check) --- src/mod/endpoints/mod_portaudio/mod_portaudio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index 62eba524d3..acd578e2e2 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -1296,9 +1296,9 @@ error: } switch_mutex_unlock(endpoint->mutex); } - if (new_session && *new_session) { - switch_core_session_destroy(new_session); - } + + switch_core_session_destroy(new_session); + return retcause; } From d7a4ab7dce65e4b828272bd93719b50faeb27d40 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 1 Jun 2023 17:24:37 +0300 Subject: [PATCH 023/205] [mod_spandsp] Coverity CID 1024263 (Dereference before null check) --- src/mod/applications/mod_spandsp/mod_spandsp_modem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c index 560a78be44..1f8a88cc75 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c @@ -897,9 +897,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi fail: - if (new_session) { - switch_core_session_destroy(new_session); - } + switch_core_session_destroy(new_session); if (modem) { modem_set_state(modem, MODEM_STATE_ONHOOK); From b0a52eb1feaade9f0c0a89813fe4faf9dc5fab5c Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 9 Jun 2023 18:25:25 +0000 Subject: [PATCH 024/205] [core] Add switch_core_media_get_engine() and switch_core_media_get_codec() functions --- src/include/switch_core_media.h | 4 ++++ src/switch_core_media.c | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 8694a0bc88..1c1c321cb3 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -399,6 +399,10 @@ SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session, SWITCH_DECLARE(void) switch_core_media_set_resolveice(switch_bool_t resolve_ice); SWITCH_DECLARE(switch_bool_t) switch_core_media_has_resolveice(void); +typedef struct switch_rtp_engine_s switch_rtp_engine_t; +SWITCH_DECLARE(switch_rtp_engine_t *) switch_core_media_get_engine(switch_core_session_t *session, int media_type); +SWITCH_DECLARE(switch_codec_t*) switch_core_media_get_codec(switch_core_session_t *session, switch_media_type_t type); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 912d5a5012..ae5dbf6d45 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -110,7 +110,7 @@ struct switch_rtp_text_factory_s { }; -typedef struct switch_rtp_engine_s { +struct switch_rtp_engine_s { switch_secure_settings_t ssec[CRYPTO_INVALID+1]; switch_rtp_crypto_key_type_t crypto_type; @@ -204,7 +204,7 @@ typedef struct switch_rtp_engine_s { void *engine_user_data; int8_t engine_function_running; switch_frame_buffer_t *write_fb; -} switch_rtp_engine_t; +}; #define MAX_REJ_STREAMS 10 @@ -16421,7 +16421,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess return status; } +SWITCH_DECLARE(switch_rtp_engine_t *) switch_core_media_get_engine(switch_core_session_t *session, int media_type) +{ + if (!session) return NULL; + return &session->media_handle->engines[media_type]; +} + +SWITCH_DECLARE(switch_codec_t*) switch_core_media_get_codec(switch_core_session_t *session, switch_media_type_t type) +{ + switch_rtp_engine_t *engine = switch_core_media_get_engine(session, type); + + if (!engine) return NULL; + + return &engine->read_codec; +} /* For Emacs: * Local Variables: From 86875d238167c3f54d347c29816f45b727a87fc8 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 12 Jun 2023 17:25:37 +0300 Subject: [PATCH 025/205] [mod_verto] Coverity fixes [mod_verto] coverity CID 1468439 (Dereference after null check) [mod_verto] coverity CID 1294451 (Dereference before null check) [mod_verto] coverity CID 1468443 (Logically dead code) --- src/mod/endpoints/mod_verto/mod_verto.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 38a3bc302a..8920de7e02 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -836,7 +836,7 @@ static void set_perm(const char *str, switch_event_t **event, switch_bool_t add) switch_event_create(event, SWITCH_EVENT_REQUEST_PARAMS); } - if (!zstr(str)) { + if (!zstr(str) && event && *event) { edup = strdup(str); switch_assert(edup); @@ -1059,7 +1059,7 @@ static switch_bool_t check_auth(jsock_t *jsock, cJSON *params, int *code, char * *code = CODE_AUTH_FAILED; switch_snprintf(message, mlen, "Login Incorrect"); login_fire_custom_event(jsock, params, 0, "Login Incorrect"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Login incorrect for user: %s domain: %s\n", id, domain ? domain : "N/A"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Login incorrect for user: %s domain: %s\n", id, domain); } else { switch_xml_t x_param, x_params; const char *use_passwd = NULL, *verto_context = NULL, *verto_dialplan = NULL; @@ -3954,7 +3954,7 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock cJSON *obj = cJSON_CreateObject(), *vobj = NULL, *dedEnc = NULL, *mirrorInput, *bandwidth = NULL, *canvas = NULL; switch_core_session_t *session = NULL; switch_channel_t *channel; - switch_event_t *var_event; + switch_event_t *var_event = NULL; switch_call_cause_t reason = SWITCH_CAUSE_INVALID_MSG_UNSPECIFIED, cancel_cause = 0; switch_caller_profile_t *caller_profile; int err = 0; @@ -4756,14 +4756,12 @@ static int start_jsock(verto_profile_t *profile, ks_socket_t sock, int family) error: - if (jsock) { - if (jsock->client_socket != KS_SOCK_INVALID) { - close_socket(&jsock->client_socket); - } - - switch_core_destroy_memory_pool(&pool); + if (jsock->client_socket != KS_SOCK_INVALID) { + close_socket(&jsock->client_socket); } + switch_core_destroy_memory_pool(&pool); + return -1; } From b4e43214f7c29e658e9a44239a45343d28186779 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 23 Mar 2023 23:01:17 +0300 Subject: [PATCH 026/205] [Core] Fix possible deadlock in switch_core_media_set_codec() --- src/switch_core_media.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ae5dbf6d45..c6ed02cfe1 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3601,11 +3601,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ int resetting = 0; switch_media_handle_t *smh; switch_rtp_engine_t *a_engine; - switch_time_t start = switch_micro_time_now(); switch_assert(session); -retry: + switch_core_session_lock_codec_write(session); + switch_core_session_lock_codec_read(session); + switch_mutex_lock(session->codec_init_mutex); if (!(smh = session->media_handle)) { @@ -3627,17 +3628,7 @@ retry: (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms || a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) { - if (switch_core_session_try_reset(session, 0, 0) != SWITCH_STATUS_SUCCESS) { - switch_time_t elapsed = switch_micro_time_now() - start; - if (elapsed > 1000000) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Could not reset session in %"SWITCH_TIME_T_FMT" us. Give up.\n", elapsed); - switch_goto_status(SWITCH_STATUS_FALSE, end); - } - - switch_mutex_unlock(session->codec_init_mutex); - switch_yield(10000); - goto retry; - } + switch_core_session_reset(session, 0, 0); switch_channel_audio_sync(session->channel); @@ -3651,9 +3642,6 @@ retry: a_engine->cur_payload_map->codec_ms, a_engine->cur_payload_map->rm_rate); - switch_yield(a_engine->read_impl.microseconds_per_packet); - switch_core_session_lock_codec_write(session); - switch_core_session_lock_codec_read(session); resetting = 1; switch_yield(a_engine->read_impl.microseconds_per_packet); switch_core_codec_destroy(&a_engine->read_codec); @@ -3767,12 +3755,13 @@ retry: if (resetting) { switch_channel_execute_on(session->channel, "execute_on_audio_change"); - switch_core_session_unlock_codec_write(session); - switch_core_session_unlock_codec_read(session); } switch_mutex_unlock(session->codec_init_mutex); + switch_core_session_unlock_codec_read(session); + switch_core_session_unlock_codec_write(session); + return status; } static void clear_ice(switch_core_session_t *session, switch_media_type_t type) From 9b20b324f5128d8a455342796674f2a9895976ff Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 12 Jun 2023 18:17:12 +0300 Subject: [PATCH 027/205] [mod_sofia] Coverity fixes [mod_sofia] coverity CID 1024253 (Dereference before null check) [mod_sofia] coverity CID 1024254 (Dereference before null check) [mod_sofia] coverity CID 1257620 (Logically dead code) [mod_sofia] coverity CID 1024750 (Dereference null return value) --- src/mod/endpoints/mod_sofia/mod_sofia.c | 12 ++++-------- src/mod/endpoints/mod_sofia/sofia.c | 5 ++++- src/mod/endpoints/mod_sofia/sofia_glue.c | 21 ++++++++------------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 0b74b89c9d..4ff6f2fcff 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -472,7 +472,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_core_hash_delete_locked(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt->profile->flag_mutex); } - if (session && tech_pvt->profile->pres_type) { + if (tech_pvt->profile->pres_type) { char *sql = switch_mprintf("delete from sip_dialogs where uuid='%q'", switch_core_session_get_uuid(session)); switch_assert(sql); sofia_glue_execute_sql_now(tech_pvt->profile, &sql, SWITCH_TRUE); @@ -2205,11 +2205,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi argv[i], (double)((double)(MAX_REDIR + 1 - i))/1000); } } else { - if (i == argc - 1) { - switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>", argv[i]); - } else { - switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>,", argv[i]); - } + switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>", argv[i]); } } else { if (i == argc - 1) { @@ -4313,6 +4309,8 @@ SWITCH_STANDARD_API(sofia_presence_data_function) user = argv[1]; } + if (!user) goto end; + if ((domain = strchr(user, '@'))) { *domain++ = '\0'; if ((concat = strchr(domain, '/'))) { @@ -4329,8 +4327,6 @@ SWITCH_STANDARD_API(sofia_presence_data_function) domain = dup_domain; } - if (!user) goto end; - if (zstr(profile_name) || strcmp(profile_name, "*") || zstr(domain)) { if (!zstr(profile_name)) { profile = sofia_glue_find_profile(profile_name); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f14b574adf..c5b5bcc190 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2818,7 +2818,10 @@ void event_handler(switch_event_t *event) if ((sptr = strstr(fixed_contact_str, needle))) { char *origsptr = strstr(contact_str, needle); - eptr = strchr(++origsptr, ';'); + + if (origsptr) { + eptr = strchr(++origsptr, ';'); + } } else { sptr = strchr(fixed_contact_str, '\0') - 1; } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0eb0dcf601..eceae218f8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2282,8 +2282,7 @@ int sofia_recover_callback(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); private_object_t *tech_pvt = NULL; sofia_profile_t *profile = NULL; - const char *tmp; - const char *rr; + const char *tmp, *rr, *use_uuid; int r = 0; const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1); int swap = switch_channel_var_true(channel, "dlg_req_swap_direction"); @@ -2374,17 +2373,13 @@ int sofia_recover_callback(switch_core_session_t *session) ); } - if (session) { - const char *use_uuid; - - if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) { - if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel), - use_uuid); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n", - switch_channel_get_name(channel), use_uuid); - } + if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) { + if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel), + use_uuid); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n", + switch_channel_get_name(channel), use_uuid); } } From 24452ff104af3282ba4a4a66522c4008bf91d07a Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Sat, 8 Jan 2022 12:14:16 +0200 Subject: [PATCH 028/205] [mod_opus] fix configuration glitches (switch_true() instead of atoi()). --- src/mod/codecs/mod_opus/mod_opus.c | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 04850a672e..6f061d1ce7 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -145,22 +145,22 @@ struct opus_context { }; struct { - int use_vbr; - int use_dtx; + switch_bool_t use_vbr; + switch_bool_t use_dtx; int complexity; int maxaveragebitrate; int maxplaybackrate; int sprop_maxcapturerate; int plpct; - int asymmetric_samplerates; - int bitrate_negotiation; - int keep_fec; - int fec_decode; - int adjust_bitrate; + switch_bool_t asymmetric_samplerates; + switch_bool_t bitrate_negotiation; + switch_bool_t keep_fec; + switch_bool_t fec_decode; + switch_bool_t adjust_bitrate; int debuginfo; - uint32_t use_jb_lookahead; + switch_bool_t use_jb_lookahead; switch_mutex_t *mutex; - int mono; + switch_bool_t mono; } opus_prefs; static struct { @@ -1052,25 +1052,25 @@ static switch_status_t opus_load_config(switch_bool_t reload) char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(key, "use-vbr") && !zstr(val)) { - opus_prefs.use_vbr = atoi(val); + opus_prefs.use_vbr = switch_true(val); } else if (!strcasecmp(key, "use-dtx")) { - opus_prefs.use_dtx = atoi(val); + opus_prefs.use_dtx = switch_true(val); } else if (!strcasecmp(key, "complexity")) { opus_prefs.complexity = atoi(val); } else if (!strcasecmp(key, "packet-loss-percent")) { opus_prefs.plpct = atoi(val); } else if (!strcasecmp(key, "asymmetric-sample-rates")) { - opus_prefs.asymmetric_samplerates = atoi(val); + opus_prefs.asymmetric_samplerates = switch_true(val); } else if (!strcasecmp(key, "bitrate-negotiation")) { - opus_prefs.bitrate_negotiation = atoi(val); + opus_prefs.bitrate_negotiation = switch_true(val); } else if (!strcasecmp(key, "use-jb-lookahead")) { opus_prefs.use_jb_lookahead = switch_true(val); } else if (!strcasecmp(key, "keep-fec-enabled")) { /* encoder */ - opus_prefs.keep_fec = atoi(val); + opus_prefs.keep_fec = switch_true(val); } else if (!strcasecmp(key, "advertise-useinbandfec")) { /*decoder, has meaning only for FMTP: useinbandfec=1 by default */ - opus_prefs.fec_decode = atoi(val); + opus_prefs.fec_decode = switch_true(val); } else if (!strcasecmp(key, "adjust-bitrate")) { /* encoder, this setting will make the encoder adjust its bitrate based on a feedback loop (RTCP). This is not "VBR".*/ - opus_prefs.adjust_bitrate = atoi(val); + opus_prefs.adjust_bitrate = switch_true(val); } else if (!strcasecmp(key, "maxaveragebitrate")) { opus_prefs.maxaveragebitrate = atoi(val); if (opus_prefs.maxaveragebitrate < SWITCH_OPUS_MIN_BITRATE || opus_prefs.maxaveragebitrate > SWITCH_OPUS_MAX_BITRATE) { @@ -1087,7 +1087,7 @@ static switch_status_t opus_load_config(switch_bool_t reload) opus_prefs.sprop_maxcapturerate = 0; /* value not supported */ } } else if (!strcasecmp(key, "mono")) { - opus_prefs.mono = atoi(val); + opus_prefs.mono = switch_true(val); } } } From a458d704abafb9ad26d431924ece44449cdd7fda Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Thu, 18 Aug 2022 19:48:20 +0300 Subject: [PATCH 029/205] [mod_opus] show uuid in logs. --- src/mod/codecs/mod_opus/mod_opus.c | 82 +++++++++++++++--------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 6f061d1ce7..9f34c193db 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -142,6 +142,7 @@ struct opus_context { dec_stats_t decoder_stats; enc_stats_t encoder_stats; codec_control_state_t control_state; + switch_bool_t recreate_decoder; }; struct { @@ -471,7 +472,7 @@ static int switch_opus_get_fec_bitrate(int fs, int loss) return SWITCH_STATUS_FALSE ; } -static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text) +static switch_status_t switch_opus_info(switch_core_session_t *session, void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text) { int nb_samples, nb_opus_frames, nb_channels; int audiobandwidth; @@ -483,18 +484,18 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3 if (!encoded_data) { /* print stuff, even if encoded_data is NULL. eg: "PLC correction" */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s", print_text); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s", print_text); return SWITCH_STATUS_FALSE; } audiobandwidth = opus_packet_get_bandwidth(encoded_data); if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text); } if ((nb_opus_frames = opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)) <= 0 ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames); return SWITCH_STATUS_FALSE; } @@ -504,7 +505,7 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3 nb_channels = opus_packet_get_nb_channels(payload); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n", print_text, nb_opus_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no", nb_channels); return SWITCH_STATUS_SUCCESS; @@ -518,6 +519,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag switch_codec_fmtp_t codec_fmtp, codec_fmtp_only_remote = { 0 }; opus_codec_settings_t opus_codec_settings = { 0 }; opus_codec_settings_t opus_codec_settings_remote = { 0 }; + switch_core_session_t *session = codec->session; if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; @@ -591,7 +593,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag if (settings && settings->maxplaybackrate < enc_samplerate && settings->maxplaybackrate) { enc_samplerate = settings->maxplaybackrate; /*R1*/ context->enc_frame_size = enc_samplerate * (codec->implementation->microseconds_per_packet / 1000) / 1000; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate); } else { enc_samplerate = codec->implementation->actual_samples_per_second; } @@ -604,19 +606,19 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err); if (err != OPUS_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err)); return SWITCH_STATUS_GENERR; } /* https://tools.ietf.org/html/rfc7587 */ if (opus_codec_settings.maxaveragebitrate) { opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate)); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate); } else { opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_AUTO)); opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); /* OPUS_AUTO */ opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&bitrate_bps)); /* return average bps for this audio bandwidth */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps); } /* Another fmtp setting from https://tools.ietf.org/html/rfc7587 - "RTP Payload Format for the Opus Speech and Audio Codec" */ if (opus_codec_settings.maxplaybackrate) { @@ -627,14 +629,14 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) { snprintf(audiobandwidth_str, sizeof(audiobandwidth_str), "%s", "OPUS_AUTO"); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate); } if (use_vbr) { /* VBR is default*/ opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr)); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n"); opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0)); } @@ -684,7 +686,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag if (settings && dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate) { dec_samplerate = settings->sprop_maxcapturerate; /* R2 */ context->dec_frame_size = dec_samplerate*(codec->implementation->microseconds_per_packet / 1000) / 1000; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate); } else { dec_samplerate = codec->implementation->actual_samples_per_second; } @@ -697,7 +699,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC); if (err != OPUS_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err)); if (context->encoder_object) { opus_encoder_destroy(context->encoder_object); @@ -774,7 +776,7 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec, if (globals.debug || context->debug > 1) { int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); - switch_opus_info(encoded_data, bytes, samplerate, "encode"); + switch_opus_info(codec->session, encoded_data, bytes, samplerate, "encode"); } if (bytes > 0) { @@ -796,7 +798,7 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec, return SWITCH_STATUS_SUCCESS; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n", opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data, (void *) encoded_data,(void *) context->encoder_object); @@ -818,6 +820,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, int32_t frame_size = 0, last_frame_size = 0; uint32_t frame_samples; uint8_t buf[SWITCH_RTP_MAX_BUF_LEN]; + switch_core_session_t *session = codec->session; if (!context) { return SWITCH_STATUS_FALSE; @@ -827,7 +830,6 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); if (*flag & SFF_PLC) { - switch_core_session_t *session = codec->session; switch_jb_t *jb = NULL; plc = 1; @@ -856,12 +858,12 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, frame.buflen = sizeof(buf); if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts); } if (switch_jb_peek_frame(jb, ts, seq, 1, &frame) == SWITCH_STATUS_SUCCESS) { if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n", frame.timestamp, frame.seq); } @@ -873,10 +875,10 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, if (globals.debug || context->debug) { if (fec) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n", frame.seq, frame.datalen); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n", frame.seq, frame.datalen); } } @@ -890,9 +892,9 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, if (globals.debug || context->debug) { if (opus_prefs.use_jb_lookahead || context->use_jb_lookahead) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC"); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n"); } } @@ -901,7 +903,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, if (globals.debug || context->debug > 1) { int samplerate = context->dec_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); - switch_opus_info(encoded_data, encoded_data_len, + switch_opus_info(codec->session, encoded_data, encoded_data_len, samplerate ? samplerate : codec->implementation->actual_samples_per_second, !encoded_data ? "PLC correction" : fec ? "FEC correction" : "decode"); } @@ -918,8 +920,8 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, frame_size, fec); if (samples < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n", - opus_strerror(samples), frame_size, plc ? "true" : "false"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n", + opus_strerror(samples), frame_size, plc ? "true" : "false"); return SWITCH_STATUS_NOOP; } @@ -962,7 +964,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec, } frame_size = (decoded_data_len / 2) / nb_frames; if((frame_size * nb_frames) != context->enc_frame_size) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size); switch_goto_status(SWITCH_STATUS_GENERR, end); } opus_repacketizer_init(rp); @@ -982,7 +984,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec, bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, frame_size, enc_ptr_buf, len); if (bytes < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \ "Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n", opus_strerror(bytes), decoded_data_len, codec->implementation->number_of_channels, len, (void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size); @@ -991,7 +993,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec, /* enc_ptr_buf : Opus API manual: "The application must ensure this pointer remains valid until the next call to opus_repacketizer_init() or opus_repacketizer_destroy()." */ ret = opus_repacketizer_cat(rp, enc_ptr_buf, bytes); if (ret != OPUS_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret)); switch_goto_status(SWITCH_STATUS_GENERR, end); } enc_ptr_buf += bytes; @@ -1000,18 +1002,18 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec, } /* this will never happen, unless there is a huge and unsupported number of frames */ if (total_len + opus_repacketizer_get_nb_frames(rp) > len / 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n"); switch_goto_status(SWITCH_STATUS_GENERR, end); } ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp)); if (globals.debug || context->debug) { int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); - switch_opus_info(encoded_data, ret, samplerate, "encode_repacketize"); + switch_opus_info(codec->session, encoded_data, ret, samplerate, "encode_repacketize"); } if (ret <= 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp)); switch_goto_status(SWITCH_STATUS_GENERR, end); } if (want_fec) { @@ -1132,7 +1134,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); if (!real_target_bitrate || !LBRR_threshold_bitrate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n"); return SWITCH_STATUS_FALSE; } @@ -1141,7 +1143,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) if (real_target_bitrate > LBRR_threshold_bitrate) { /*FEC is already enabled, do nothing*/ if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n"); } return SWITCH_STATUS_SUCCESS; } else { @@ -1153,7 +1155,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate)); if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate); } return SWITCH_STATUS_SUCCESS; @@ -1229,7 +1231,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, } if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n", context->old_plpct, plpct); } } @@ -1243,7 +1245,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, float steps = (float)((float)(range / 100) / base_step); int br_step = (int)(round(steps) * base_step) * plpct; if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: bitrate increase/decrease step now is: %d bps, range:%d\n", br_step, range); } context->control_state.increase_step = context->control_state.decrease_step = br_step; @@ -1269,7 +1271,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, opus_prefs.keep_fec = 1; /* enable back FEC if it was disabled by SCC_AUDIO_ADJUST_BITRATE, we have enough network bandwidth now */ } if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step); } } } else if (!strcasecmp(cmd, "decrease")) { @@ -1283,7 +1285,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, } opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(current_bitrate-br_step)); if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step); } } } else if (!strcasecmp(cmd, "default")) { @@ -1293,7 +1295,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, opus_prefs.keep_fec = 1; /* enable back FEC, we have enough network bandwidth now */ } if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate); } } else { /* set Opus minimum bitrate */ @@ -1302,7 +1304,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, opus_prefs.keep_fec = 0; /* do not enforce FEC anymore, we're low on network bandwidth */ } if (globals.debug || context->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE); } } } From 5065c0b11869007809f4983432f93e068d43ac0e Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Wed, 24 Aug 2022 13:02:35 +0300 Subject: [PATCH 030/205] [mod_opus] fix samples_per_packet for 8khz, 16khz, 24khz. --- src/mod/codecs/mod_opus/mod_opus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 9f34c193db..1ab7d9fba1 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -1342,7 +1342,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) { switch_codec_interface_t *codec_interface; switch_api_interface_t *commands_api_interface; - int samples = 480; + int samples = 480; /* start with 10 ms ptime */ int bytes = 960; int mss = 10000; int x = 0; @@ -1443,7 +1443,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) } /* 16 khz */ - samples = 480; + samples = 160; bytes = 320; mss = 10000; rate = 16000; @@ -1540,7 +1540,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) } /* 8 khz */ - samples = 480; + samples = 80; bytes = 160; mss = 10000; rate = 8000; From f90aeade4fcb5cec6884833442ae1111fcf027e9 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Thu, 26 Jan 2023 20:14:35 +0200 Subject: [PATCH 031/205] [core] Opus RTP timestamp: adding an exception on RTP session creation. https://www.rfc-editor.org/rfc/rfc7587.html "The RTP timestamp is incremented with a 48000 Hz clock rate for all modes of Opus and all sampling rates. The unit for the timestamp is samples per single (mono) channel" Follow up: 50f57f85732b0d5a58a39f3fca7b654f894b0c9d, ccbef9e0c7e31c410ce08b5276c3e2e5a2f69883 . --- src/switch_core_media.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index c6ed02cfe1..8ed496bda7 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -8724,7 +8724,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->pt, - a_engine->read_impl.samples_per_packet, + strcasecmp("opus", a_engine->read_impl.iananame) ? a_engine->read_impl.samples_per_packet : + a_engine->read_impl.samples_per_second * (a_engine->read_impl.microseconds_per_packet / 1000) / 1000, a_engine->cur_payload_map->codec_ms * 1000, flags, timer_name, &err, switch_core_session_get_pool(session), 0, 0); From 5e914efc8c0452647dc33f810dd020f8e93d4f5d Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Thu, 11 May 2023 03:55:11 +0300 Subject: [PATCH 032/205] [core, mod_opus] bring more fmtp params to core (offer/answer). --- src/include/switch_module_interfaces.h | 10 ++++++++-- src/mod/codecs/mod_opus/mod_opus.c | 3 +++ src/switch_core_media.c | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 7c54ed67df..ddaaf120a1 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -676,8 +676,14 @@ struct switch_codec_fmtp { int bits_per_second; /*! number of microseconds of media in one packet (ptime * 1000) */ int microseconds_per_packet; - /*! stereo */ - int stereo; + /*! maximum ptime in ms */ + int max_ptime; + /*! minimum ptime in ms */ + int min_ptime; + /*! stereo, typically bidirectional */ + int stereo; + /* sender properties (stereo) */ + int sprop_stereo; /*! private data for the codec module to store handle specific info */ void *private_info; diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 1ab7d9fba1..ce364cc3ef 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -273,10 +273,12 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!strcasecmp(data, "maxptime")) { codec_settings->maxptime = atoi(arg); + codec_fmtp->max_ptime = codec_settings->maxptime; } if (!strcasecmp(data, "minptime")) { codec_settings->minptime = atoi(arg); + codec_fmtp->min_ptime = codec_settings->minptime; } if (!strcasecmp(data, "ptime")) { @@ -291,6 +293,7 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!strcasecmp(data, "sprop-stereo")) { codec_settings->sprop_stereo = atoi(arg); + codec_fmtp->sprop_stereo = codec_settings->sprop_stereo; } if (!strcasecmp(data, "maxaveragebitrate")) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 8ed496bda7..60cc3d531c 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -5497,6 +5497,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } else if (!strcasecmp(map->rm_encoding, "opus")) { map_channels = 1; } + + if (codec_fmtp.max_ptime) { + maxptime = codec_fmtp.max_ptime; + } } } From 7bc999309cd2b9be2420f30dde9ef20b8c92ed96 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Thu, 15 Jun 2023 16:29:43 +0300 Subject: [PATCH 033/205] [mod_opus] fix remote codec rate to match. --- src/mod/codecs/mod_opus/mod_opus.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index ce364cc3ef..4a47b45df4 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -314,6 +314,10 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!switch_opus_acceptable_rate(codec_settings->sprop_maxcapturerate)) { codec_settings->sprop_maxcapturerate = 0; /* value not supported */ } + + if (codec_settings->sprop_maxcapturerate) { + codec_fmtp->actual_samples_per_second = codec_settings->sprop_maxcapturerate; + } } } } From 9c63f03b453e5b935cefd697e9b987d6f0987dca Mon Sep 17 00:00:00 2001 From: Giacomo Vacca Date: Fri, 16 Jun 2023 17:30:15 +0000 Subject: [PATCH 034/205] [Core] Add new cause REJECT_ALL --- src/include/switch_types.h | 3 ++- src/switch_channel.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 7b519899af..82639c2ca6 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2249,7 +2249,8 @@ typedef enum { SWITCH_CAUSE_BAD_IDENTITY_INFO = 821, SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE = 822, SWITCH_CAUSE_INVALID_IDENTITY = 823, - SWITCH_CAUSE_STALE_DATE = 824 + SWITCH_CAUSE_STALE_DATE = 824, + SWITCH_CAUSE_REJECT_ALL = 825 } switch_call_cause_t; typedef enum { diff --git a/src/switch_channel.c b/src/switch_channel.c index ea3f66c246..6f0ad7a964 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -135,6 +135,7 @@ static struct switch_cause_table CAUSE_CHART[] = { {"UNSUPPORTED_CERTIFICATE", SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE}, {"INVALID_IDENTITY", SWITCH_CAUSE_INVALID_IDENTITY}, {"STALE_DATE", SWITCH_CAUSE_STALE_DATE}, + {"REJECT_ALL", SWITCH_CAUSE_REJECT_ALL}, {NULL, 0} }; From f64314ff485a6fa7ea9eb48156bb84f28544504f Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 22 Jun 2023 18:02:20 +0300 Subject: [PATCH 035/205] [mod_sofia] Map SWITCH_CAUSE_REJECT_ALL cause to 603 --- src/mod/endpoints/mod_sofia/mod_sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 4ff6f2fcff..2fdf0063a9 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -348,6 +348,7 @@ static int hangup_cause_to_sip(switch_call_cause_t cause) case SWITCH_CAUSE_BUSY_EVERYWHERE: return 600; case SWITCH_CAUSE_DECLINE: + case SWITCH_CAUSE_REJECT_ALL: return 603; case SWITCH_CAUSE_DOES_NOT_EXIST_ANYWHERE: return 604; From 67840823c178153cb013014c4fa780fe233612cb Mon Sep 17 00:00:00 2001 From: Julien Chavanton Date: Fri, 23 Jun 2023 09:45:31 -0400 Subject: [PATCH 036/205] [core, mod_opus] more elastic jitterbuffer with Opus codec (#2069) --- scripts/lua/hangup_jitterbuffer_metrics.lua | 53 +++ src/include/switch_jitterbuffer.h | 1 + src/include/switch_types.h | 1 + src/mod/codecs/mod_opus/Makefile.am | 2 +- src/mod/codecs/mod_opus/mod_opus.c | 30 ++ src/mod/codecs/mod_opus/opus_parse.c | 366 ++++++++++++++++++++ src/mod/codecs/mod_opus/opus_parse.h | 66 ++++ src/switch_jitterbuffer.c | 239 ++++++++++++- src/switch_rtp.c | 1 + 9 files changed, 756 insertions(+), 3 deletions(-) create mode 100755 scripts/lua/hangup_jitterbuffer_metrics.lua create mode 100644 src/mod/codecs/mod_opus/opus_parse.c create mode 100644 src/mod/codecs/mod_opus/opus_parse.h diff --git a/scripts/lua/hangup_jitterbuffer_metrics.lua b/scripts/lua/hangup_jitterbuffer_metrics.lua new file mode 100755 index 0000000000..8e3dd37623 --- /dev/null +++ b/scripts/lua/hangup_jitterbuffer_metrics.lua @@ -0,0 +1,53 @@ +local https = require("socket.http") +local ip = os.getenv("LOCAL_IPV4") +local response_body = {} +-- jitter buffer stats +local size_max_ms = session:getVariable("rtp_jb_size_max_ms"); +local size_est_ms = session:getVariable("rtp_jb_size_est_ms"); +local acceleration_ms = session:getVariable("rtp_jb_acceleration_ms"); +local expand_ms = session:getVariable("rtp_jb_expand_ms"); +local jitter_max_ms = session:getVariable("rtp_jb_jitter_max_ms"); +local jitter_est_ms = session:getVariable("rtp_jb_jitter_est_ms"); + +local reset_count = session:getVariable("rtp_jb_reset_count"); +local reset_too_big = session:getVariable("rtp_jb_reset_too_big"); +local reset_missing_frames = session:getVariable("rtp_jb_reset_missing_frames"); +local reset_ts_jump = session:getVariable("rtp_jb_reset_ts_jump"); +local reset_error = session:getVariable("rtp_jb_reset_error"); +local call_id = session:getVariable("sip_call_id"); +local out_call_id = session:getVariable("last_bridge_to"); + +if size_max_ms == nil or size_est_ms == nil or acceleration_ms == nil or expand_ms == nil or jitter_max_ms == nil or jitter_est_ms == nil then + session:consoleLog("info", "[metrics] jitter no data\n"); + return +end +local request_body = '{"in_call_id": "'..call_id..'", "out_call_id": "'..out_call_id..'", "jb":{"size_max_ms":'..size_max_ms.. + ',"size_est_ms":'..size_est_ms..',"acceleration_ms":'..acceleration_ms..',"expand_ms":'..expand_ms.. + ',"jitter_max_ms":'..jitter_max_ms..',"jitter_est_ms":'..jitter_est_ms..',"reset":'..reset_count +-- if reset_too_big ~= "0" then + request_body = request_body .. ',"reset_too_big":'..reset_too_big +-- end +if reset_missing_frames ~= "0" then + request_body = request_body .. ',"reset_missing_frames":'..reset_missing_frames +end +if reset_ts_jump ~= "0" then + request_body = request_body .. ',"reset_ts_jump":'..reset_ts_jump +end +if reset_error ~= "0" then + request_body = request_body .. ',"reset_error":'..reset_error +end + +local v = request_body .. '}}'; + +local r, c, h, s = https.request{ + method = 'POST', + url = "http://"..ip..":80/freeswitch_metrics", + headers = { + ["Content-Type"] = "application/json", + ["Content-Length"] = string.len(v) + }, + source = ltn12.source.string(v), + sink = ltn12.sink.table(response_body) +} +-- print('statusCode ', c) +session:consoleLog("info", "[metrics] jitter:".. v .. "\n"); diff --git a/src/include/switch_jitterbuffer.h b/src/include/switch_jitterbuffer.h index bee0fa02f8..f098ede2db 100644 --- a/src/include/switch_jitterbuffer.h +++ b/src/include/switch_jitterbuffer.h @@ -61,6 +61,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb); SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len); SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session); +SWITCH_DECLARE(void) switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second); SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second); SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag); SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 82639c2ca6..94a4c62cca 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2425,6 +2425,7 @@ typedef enum { SCC_VIDEO_RESET, SCC_AUDIO_PACKET_LOSS, SCC_AUDIO_ADJUST_BITRATE, + SCC_AUDIO_VAD, SCC_DEBUG, SCC_CODEC_SPECIFIC } switch_codec_control_command_t; diff --git a/src/mod/codecs/mod_opus/Makefile.am b/src/mod/codecs/mod_opus/Makefile.am index 690c5fa471..70710898e7 100644 --- a/src/mod/codecs/mod_opus/Makefile.am +++ b/src/mod/codecs/mod_opus/Makefile.am @@ -4,7 +4,7 @@ MODNAME=mod_opus if HAVE_OPUS mod_LTLIBRARIES = mod_opus.la -mod_opus_la_SOURCES = mod_opus.c +mod_opus_la_SOURCES = mod_opus.c opus_parse.c mod_opus_la_CFLAGS = $(AM_CFLAGS) $(OPUS_CFLAGS) mod_opus_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(OPUS_LIBS) mod_opus_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 4a47b45df4..ce9aff52a3 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -33,6 +33,7 @@ #include "switch.h" #include "opus.h" +#include "opus_parse.h" #define SWITCH_OPUS_MIN_BITRATE 6000 #define SWITCH_OPUS_MAX_BITRATE 510000 @@ -1169,6 +1170,27 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) } } +static switch_bool_t switch_opus_vad(struct opus_context *context, void *encoded_data, uint32_t encoded_data_len) { + const uint8_t *payload = (const uint8_t *) encoded_data; + opus_packet_info_t opus_packet_info; + switch_bool_t debug = (globals.debug || context->debug > 1); + if (!switch_opus_packet_parse(payload, encoded_data_len, &opus_packet_info, debug)) { + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS PACKET PARSING ERROR len:%d bytes:%02x %02x\n", + (int)encoded_data_len, payload[0], payload[1]); + } + return SWITCH_TRUE; + } + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS EXTRACT PAYLOAD VAD len:%d vad_ms:%d bytes:%02x %02x\n", + (int)encoded_data_len, opus_packet_info.vad_ms, payload[0], payload[1]); + } + if (opus_packet_info.vad_ms == 0) { + return SWITCH_FALSE; + } + return SWITCH_TRUE; +} + static switch_status_t switch_opus_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, @@ -1260,6 +1282,14 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, context->old_plpct = plpct; } break; + case SCC_AUDIO_VAD: + { + void* encoded_data = (void *)cmd_data; + uint16_t* encoded_data_len = (uint16_t *)cmd_arg; + switch_bool_t *ret = (switch_bool_t *) *ret_data; + *ret = switch_opus_vad(context, encoded_data, *encoded_data_len); + } + break; case SCC_AUDIO_ADJUST_BITRATE: { const char *cmd = (const char *)cmd_data; diff --git a/src/mod/codecs/mod_opus/opus_parse.c b/src/mod/codecs/mod_opus/opus_parse.c new file mode 100644 index 0000000000..41e1ec6490 --- /dev/null +++ b/src/mod/codecs/mod_opus/opus_parse.c @@ -0,0 +1,366 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2023, Anthony Minessale II + * + * 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. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Claude Lamblin + * Julien Chavanton + * + */ + +#include "switch.h" +#include +#include "opus_parse.h" +/* Tables for LBRR_sympbol decoding */ + +static const opus_int16 silk_LBRR_flags_2_PDFCum[3] = {53, 106, 256}; /* 256 - silk_LBRR_flags_2_iCDF[i] ; silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; */ +static const opus_int16 silk_LBRR_flags_3_PDFCum[7] = {41, 61, 90, 131, 146, 174, 256}; /* 256 - silk_LBRR_flags_3_iCDF[i] ; silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; */ + +/* get the number of VAD flags - i.e. number of 20 ms frame - from the config */ +/* in a silk-only or hybrid opus frame mono or stereo*/ +/* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1) */ +/* if 10 ms frame (config=0, 4, 8, 12, 14) : return 1 */ +/* if CELT_only frame no VAD flag =>return 0 */ +static opus_int16 switch_opus_get_nb_flags_in_silk_frame(int16_t config) +{ + opus_int16 silk_frame_nb_flags; + if (config > 15) { + /* CELT_only frame no VAD flag nor LBRR flag */ + silk_frame_nb_flags = 0; + } else { + silk_frame_nb_flags = 1; /*default*/ + if (config < 12) { + /* silk-only NB, MB or WB */ + /* The least two significant bits give the number of VAD flags inside the silk frame 1, 2 or 3 */ + silk_frame_nb_flags = config & 0x3; + if (silk_frame_nb_flags == 0) { /* 0 => 10ms frame : one VAD flag */ + silk_frame_nb_flags++; + } + } + } + return silk_frame_nb_flags; +} + +/* get the time in ms corresponding to one VAD flag from the config */ +/* in a silk-only or hybrid opus frame mono or stereo*/ +/* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1) */ +/* if CELT_only frame (config >15) no VAD flag =>return FALSE */ +/* if 10 ms frame (config=0, 4, 8, 12, 14) : return 10 */ +/* otherwise return 20 */ +static opus_int16 switch_opus_get_silk_frame_ms_per_flag(int16_t config, opus_int16 silk_frame_nb_flags) +{ + opus_int16 silk_size_frame_ms_per_flag; + if (config > 15) { + /* CELT_only frame no VAD flag nor LBRR flag */ + /* switch_opus_get_silk_frame_ms_per_flag: code not written for CELT-only mode */ + return FALSE; + } + silk_size_frame_ms_per_flag = 20; /* default*/ + if (silk_frame_nb_flags == 1) { /* could be 10 or 20 ms */ + if ((config &0x01) == 0) { + silk_size_frame_ms_per_flag = 10; + } + } + return silk_size_frame_ms_per_flag; +} + +/* code written only for mono, silk-only or hybrid mode */ +/* for CELT-only frame no vad flags for LBRR flag the routine must not be called */ +/* for stereo : the mid frame VAD_flags and the LBRR_flag could be obtained */ +/* yet, to get the LBRR_flags of the mid frame the routine should be modified */ +/* to skip the side VAD flags and the side LBRR flag and to get the mid LBRR_symbol */ +static bool_t switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_frame_nb_flags, + opus_int16 *VAD_flags, opus_int16 *LBRR_flags, opus_int16 *nb_VAD1, opus_int16 *nb_FEC) +{ + const opus_int16 *ptr_pdf_cum; + opus_int nb_pdf_symbol; + opus_uint16 LBRR_symbol; + opus_int16 val, nb_bit, compl_nb_bit, mask, mask2; + opus_int16 *ptr_flags; + opus_int16 LBRR_flag; + opus_int16 nb_vad, nb_fec; + int i; + + nb_vad = 0; + nb_fec = 0; + + /* get VAD_FLAGS & LBRR_FLAG */ + /* silk_frame_nb_flags = 1 (10 or 20 ms), the two MSB of the first byte are the VAD flag and the LBRR flag */ + /* silk_frame_nb_flags = 2 (40 ms), the three MSB of the first byte are the two VAD flags and the LBRR flag */ + /* silk_frame_nb_flags = 3 (60 ms), the four MSB of the first byte are the three VAD flags and the LBRR flag */ + /* compute the number of MSB to analyse */ + nb_bit = silk_frame_nb_flags + 1; + /* number of right shifts to appply to the first byte to only have the bits of LBRR flag and of the VAD flags */ + compl_nb_bit = 8 - nb_bit; + mask = (1 << nb_bit) - 1; + + /* the bits of the silk_frame_nb_flags VAD flags and the LBRR flag are the MSB of the first byte */ + /* silk_frame_nb_flags = 1 (10 or 20 ms), VAD_flags(0) | LBRR_flag */ + /* silk_frame_nb_flags = 2 (40 ms), VAD_flags(0) | VAD_flags(1) | LBRR_flag */ + /* silk_frame_nb_flags = 3 (60 ms), VAD_flags(0) | VAD_flags(1) | VAD_flags(2) |LBRR_flag */ + val = (buf[0] >> compl_nb_bit) & mask; + + LBRR_flag = val & 0x1; /* LBRR_FLAG LSB */ + + /* get VAD_flags */ + ptr_flags = VAD_flags + silk_frame_nb_flags; + for (i=0; i < silk_frame_nb_flags; i++) { + LBRR_flags[i] = 0; /* init */ + val >>= 1; + *(--ptr_flags) = val & 0x1; + } + if (LBRR_flag != 0) { /* there is at least one LBRR frame */ + if (silk_frame_nb_flags == 1) { + LBRR_flags[0] = 1; + nb_fec = 1; + } else { /* get LBRR_symbol then LBRR_flags */ + /* LBRR symbol is encoded with range encoder : range on 8 bits */ + /* silk_frame_nb_flags = 2 ; 3 possible values for LBRR_flags(1) | LBRR_flags(0))= 01, 10, 11 */ + /* silk_frame_nb_flags = 3 ; 7 possible values for LBRR_flags(2) | LBRR_flags(1) | LBRR_flags(0))= 001, 010, 011, 100, 101, 110, 111 */ + mask2 = (1 << compl_nb_bit) - 1; + /* get next 8 bits: (8-nb_bit) LSB of the first byte and nb_bit MSB of the second byte */ + val = (((buf[0]) & mask2) << nb_bit) | ((buf[1] >> compl_nb_bit) & mask); + + if (silk_frame_nb_flags == 2) { + nb_pdf_symbol = 3; + ptr_pdf_cum = silk_LBRR_flags_2_PDFCum; + } else { + nb_pdf_symbol = 7; + ptr_pdf_cum = silk_LBRR_flags_3_PDFCum; + } + LBRR_symbol = 0; + for (i = 1; i <= nb_pdf_symbol; i++) { + if (val < *ptr_pdf_cum++) { + LBRR_symbol = i; + break; + } + } + for (i = 0; i < silk_frame_nb_flags; i++) { + LBRR_flags[i] = LBRR_symbol & 0x01; + LBRR_symbol >>= 1; + nb_fec += LBRR_flags[i]; + } + } + } + for (i = 0; i < silk_frame_nb_flags; i++) { + nb_vad += VAD_flags[i]; + } + + *nb_VAD1 = nb_vad; + *nb_FEC = nb_fec; + return TRUE; +} + +/* Parse the packet to retrieve informations about its content + * RFC6716: Definition of the Opus Audio Codec + * return: FALSE if there was a problem found parsing the packet, the info returned should be ignored. + * */ +bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, bool_t debug) +{ + int f; + int32_t samplerate; + int i, shift_silk, silk_frame_packet; + int16_t vad_flags_per_silk_frame, fec_flags_per_silk_frame; + opus_int16 frame_sizes[48]; + const unsigned char *frame_data[48]; + opus_int16 packet_LBBR_FLAGS[3 * 48], packet_VAD_FLAGS[3 * 48]; + opus_int16 *ptr_LBBR_FLAGS, *ptr_VAD_FLAGS; + opus_int16 silk_frame_nb_flags, silk_size_frame_ms_per_flag; + opus_int16 silk_frame_nb_fec, silk_frame_nb_vad1; + opus_int sample_per_frame; + packet_info->config = 0; + packet_info->fec = 0; + packet_info->fec_ms = 0; + packet_info->vad = 0; + packet_info->vad_ms = 0; + packet_info->stereo = FALSE; + packet_info->frames = 0; + packet_info->channels = 1; /* as stereo is set to FALSE */ + packet_info->ms_per_frame = 0; + packet_info->ptime_ts = 0; + if (payload == NULL || payload_length_bytes <= 0) { + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: payload null."); + } + return FALSE; + } + + /* In CELT_ONLY mode, packets should not have FEC. */ + if (payload[0] & 0x80) { + /* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */ + return FALSE; + } else { + int mode = (payload[0] >> 3); + if (mode <= 3) { + samplerate = 8000; + } else if (mode <= 7) { + samplerate = 12000; + } else if (mode <= 11) { + samplerate = 16000; + } else if (mode <= 13) { + samplerate = 24000; + } else if (mode <= 15) { + samplerate = 48000; + } else { + /* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */ + return FALSE; + } + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: mode[%d]s[%d]c[%d] [%d]Hz\n", mode, (payload[0]>>2)&0x1 ,(payload[0])&0x3, samplerate); + } + } + if (payload[0] & 0x04) { + packet_info->stereo = TRUE; + packet_info->channels = 2; + } + packet_info->config = payload[0] >> 3; + sample_per_frame = opus_packet_get_samples_per_frame(payload, samplerate); + packet_info->ms_per_frame = sample_per_frame * 1000 / samplerate; + if (packet_info->ms_per_frame < 10 || packet_info->ms_per_frame > 120) { + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: invalid packet."); + } + return FALSE; + } + + packet_info->frames = opus_packet_parse(payload, payload_length_bytes, NULL, frame_data, frame_sizes, NULL); + if (packet_info->frames < 0) { + packet_info->frames = 0; + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse found no frame.\n"); + } + return FALSE; + } + packet_info->ptime_ts = packet_info->frames * sample_per_frame; + + if (frame_sizes[0] <= 1) { + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse frame size too small.\n"); + } + return FALSE; + } + + /* +---------------+-----------+-----------+-------------------+ */ + /* | Configuration | Mode | Bandwidth | Frame Sizes | */ + /* | Number(s) | | | | */ + /* +---------------+-----------+-----------+-------------------+ */ + /* | 0...3 | SILK-only | NB | 10, 20, 40, 60 ms | */ + /* | 4...7 | SILK-only | MB | 10, 20, 40, 60 ms | */ + /* | 8...11 | SILK-only | WB | 10, 20, 40, 60 ms | */ + /* | 12...13 | Hybrid | SWB | 10, 20 ms | */ + /* | 14...15 | Hybrid | FB | 10, 20 ms | */ + /* | 16...19 | CELT-only | NB | 2.5, 5, 10, 20 ms | */ + /* | 20...23 | CELT-only | WB | 2.5, 5, 10, 20 ms | */ + /* | 24...27 | CELT-only | SWB | 2.5, 5, 10, 20 ms | */ + /* | 28...31 | CELT-only | FB | 2.5, 5, 10, 20 ms | */ + /* +---------------+-----------+-----------+-------------------+ */ + + if (!packet_info->stereo) { + /* the routines opus_get_nb_flags_in_silk_frame and opus_get_silk_frame_ms_per_flag are also valid for stereo frames */ + /* yet the routine opus_get_VAD_LBRR_flags is currently only for mono frame*/ + silk_frame_nb_flags = switch_opus_get_nb_flags_in_silk_frame(packet_info->config); /* =1 for 10 or 20 ms frame; = 2 for 40 ms; = 3 for 60 ms */ + if (!silk_frame_nb_flags) { + /* We should not go there as CELT_ONLY is already tested above */ + return FALSE; + } + + packet_info->frames_silk = silk_frame_nb_flags; + silk_size_frame_ms_per_flag = switch_opus_get_silk_frame_ms_per_flag(packet_info->config, silk_frame_nb_flags); /* 10 or 20 ms frame*/ + if (!silk_size_frame_ms_per_flag) { + /* we should not go there as CELT_ONLY is already tested above */ + return FALSE; + } + + ptr_LBBR_FLAGS = packet_LBBR_FLAGS; + ptr_VAD_FLAGS = packet_VAD_FLAGS; + + for (f = 0; f < packet_info->frames; f++) { + switch_opus_get_VAD_LBRR_flags(frame_data[f], silk_frame_nb_flags, ptr_VAD_FLAGS, ptr_LBBR_FLAGS, + &silk_frame_nb_vad1, &silk_frame_nb_fec); + packet_info->vad += silk_frame_nb_vad1; + packet_info->fec += silk_frame_nb_fec; + packet_info->vad_ms += silk_frame_nb_vad1 * silk_size_frame_ms_per_flag; + packet_info->fec_ms += silk_frame_nb_fec * silk_size_frame_ms_per_flag; + + ptr_VAD_FLAGS += silk_frame_nb_flags; + ptr_LBBR_FLAGS += silk_frame_nb_flags; + } + /* store the VAD & LBRR flags of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */ + vad_flags_per_silk_frame = 0; + fec_flags_per_silk_frame = 0; + silk_frame_packet = packet_info->frames * packet_info->frames_silk; + if (silk_frame_packet > 15) { + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: more than %d 20-ms frames in the packet ; only first 15 silk-frames data will be stored (pb silkFastAccelerate)\n", silk_frame_packet); + } + silk_frame_packet = 15; + } + ptr_LBBR_FLAGS = packet_LBBR_FLAGS; + ptr_VAD_FLAGS = packet_VAD_FLAGS; + shift_silk = 0; + for (i=0; i < silk_frame_packet; i++) { + vad_flags_per_silk_frame += (*ptr_VAD_FLAGS) << shift_silk; + fec_flags_per_silk_frame += (*ptr_LBBR_FLAGS) << shift_silk; + shift_silk++; + ptr_LBBR_FLAGS++; ptr_VAD_FLAGS++; + } + packet_info->vad_flags_per_silk_frame = vad_flags_per_silk_frame; + packet_info->fec_flags_per_silk_frame = fec_flags_per_silk_frame; + return TRUE; + } + + if (packet_info->config != 1 && packet_info->config != 5 && packet_info->config != 9) { + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: the current parser implementation does not support muliple SILK frames for VAD or FEC detection.\n"); + } + return FALSE; + } + /* + * Parse the VAD and LBRR flags in each Opus frame + * */ + for (f = 0; f < packet_info->frames; f++) { + if (frame_data[f][0] & 0x80) { + packet_info->vad++; + } + if (frame_data[f][0] & 0x40) { + packet_info->fec++; + } + if (debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: LP layer opus_frame[%d] VAD[%d] FEC[%d]\n", f+1, (frame_data[f][0]&0x80)>>7, (frame_data[f][0]&0x40)>>6); + } + } + packet_info->vad_ms = packet_info->vad * packet_info->ms_per_frame; + packet_info->fec_ms = packet_info->fec * packet_info->ms_per_frame; + return TRUE; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/src/mod/codecs/mod_opus/opus_parse.h b/src/mod/codecs/mod_opus/opus_parse.h new file mode 100644 index 0000000000..8dd61500cd --- /dev/null +++ b/src/mod/codecs/mod_opus/opus_parse.h @@ -0,0 +1,66 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2023, Anthony Minessale II + * + * 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. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Julien Chavanton + * + */ + +#ifndef SWITCH_OPUS_PARSE_H +#define SWITCH_OPUS_PARSE_H + +typedef enum { false, true } bool_t; + +typedef struct opus_packet_info { + int16_t vad; + int16_t vad_ms; + int16_t fec; + int16_t fec_ms; + bool_t stereo; + int16_t frames; /* number of opus frames in the packet */ + int16_t config; + int16_t channels; + int16_t ms_per_frame; + int32_t ptime_ts; + bool_t valid; + int16_t frames_silk; /* number of silk_frames in an opus frame */ + /* VAD flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */ + int16_t vad_flags_per_silk_frame; + /* LBRR (FEC) flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */ + int16_t fec_flags_per_silk_frame; +} opus_packet_info_t; + +bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, bool_t debug); +#endif + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index d68b269024..d8d9df3a33 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -44,6 +44,8 @@ struct switch_jb_s; +static inline int check_jb_size(switch_jb_t *jb); + typedef struct switch_jb_node_s { struct switch_jb_s *parent; switch_rtp_packet_t packet; @@ -56,6 +58,29 @@ typedef struct switch_jb_node_s { switch_bool_t complete_frame_mark; } switch_jb_node_t; +typedef struct switch_jb_stats_s { + uint32_t reset_too_big; + uint32_t reset_missing_frames; + uint32_t reset_ts_jump; + uint32_t reset_error; + uint32_t reset; + uint32_t size_max; + uint32_t size_est; + uint32_t acceleration; + uint32_t expand; + uint32_t jitter_max_ms; + int estimate_ms; + int buffer_size_ms; +} switch_jb_stats_t; + +typedef struct switch_jb_jitter_s { + double *estimate; + uint32_t samples_per_second; + uint32_t samples_per_frame; + uint32_t drop_gap; + switch_jb_stats_t stats; +} switch_jb_jitter_t; + struct switch_jb_s { struct switch_jb_node_s *node_list; uint32_t last_target_seq; @@ -104,6 +129,7 @@ struct switch_jb_s { switch_jb_flag_t flags; switch_jb_type_t type; switch_core_session_t *session; + switch_jb_jitter_t jitter; switch_channel_t *channel; uint32_t buffer_lag; uint32_t flush; @@ -112,6 +138,8 @@ struct switch_jb_s { uint32_t period_len; uint32_t nack_saved_the_day; uint32_t nack_didnt_save_the_day; + switch_bool_t elastic; + switch_codec_t *codec; }; @@ -233,6 +261,7 @@ static inline switch_jb_node_t *new_node(switch_jb_t *jb) if (jb->allocated_nodes > jb->max_frame_len * mult) { jb_debug(jb, 2, "ALLOCATED FRAMES TOO HIGH! %d\n", jb->allocated_nodes); + jb->jitter.stats.reset_too_big++; switch_jb_reset(jb); switch_mutex_unlock(jb->list_mutex); return NULL; @@ -332,6 +361,29 @@ static inline void hide_nodes(switch_jb_t *jb) switch_mutex_unlock(jb->list_mutex); } +static inline switch_bool_t packet_vad(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) { + void* payload; + uint16_t payload_len = len; + + if (packet->ebody) { + payload = packet->ebody; + } else { + payload = packet->body; + } + if (payload && payload_len > 0) { + switch_bool_t ret; + switch_bool_t *ret_p = &ret; + switch_codec_control_type_t ret_t; + switch_core_media_codec_control(jb->session, SWITCH_MEDIA_TYPE_AUDIO, + SWITCH_IO_WRITE, SCC_AUDIO_VAD, + SCCT_STRING, (void *)payload, + SCCT_INT, (void *)&payload_len, + &ret_t, (void *)&ret_p); + return ret; + } + return SWITCH_TRUE; +} + static inline void drop_ts(switch_jb_t *jb, uint32_t ts) { switch_jb_node_t *np; @@ -667,6 +719,7 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch if (((seq_diff >= 100) || (ts_diff > (900000 * 5)))) { jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq)))); + jb->jitter.stats.reset_ts_jump++; switch_jb_reset(jb); } } @@ -732,6 +785,12 @@ static inline void increment_seq(switch_jb_t *jb) jb->target_seq = htons((ntohs(jb->target_seq) + 1)); } +static inline void decrement_seq(switch_jb_t *jb) +{ + jb->last_target_seq = jb->target_seq; + jb->target_seq = htons((ntohs(jb->target_seq) - 1)); +} + static inline void set_read_seq(switch_jb_t *jb, uint16_t seq) { jb->last_target_seq = seq; @@ -854,12 +913,128 @@ static inline switch_status_t jb_next_packet_by_ts(switch_jb_t *jb, switch_jb_no } +static inline int check_jb_size(switch_jb_t *jb) +{ + switch_jb_node_t *np; + uint16_t seq; + uint16_t l_seq=0; + uint16_t h_seq=0; + uint16_t count=0; + uint16_t old=0; + switch_mutex_lock(jb->list_mutex); + + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) { + continue; + } + + seq = ntohs(np->packet.header.seq); + if (ntohs(jb->target_seq) > seq) { + hide_node(np, SWITCH_FALSE); + old++; + continue; + } + if (count == 0) { + l_seq = h_seq = seq; + } + count++; + if (seq < l_seq) + l_seq = seq; + if (seq > h_seq) + h_seq = seq; + } + if (count > jb->jitter.stats.size_max) { + jb->jitter.stats.size_max = count; + } + if (jb->jitter.stats.size_est == 0) { + jb->jitter.stats.size_est = count; + } else { + jb->jitter.stats.size_est = ((99*jb->jitter.stats.size_est)+(1*count))/100; + } + if (ntohs(jb->target_seq) % 50 == 0) { /* update the stats every x packets */ + int packet_ms = jb->jitter.samples_per_frame / (jb->jitter.samples_per_second / 1000); + jb->jitter.stats.estimate_ms = (*jb->jitter.estimate) / jb->jitter.samples_per_second * 1000; + switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_max_ms", "%u", jb->jitter.stats.size_max*packet_ms); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_est_ms", "%u", jb->jitter.stats.size_est*packet_ms); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", jb->jitter.stats.acceleration*packet_ms); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", jb->jitter.stats.expand*packet_ms); + if (jb->jitter.stats.jitter_max_ms < jb->jitter.stats.estimate_ms) { + jb->jitter.stats.jitter_max_ms = jb->jitter.stats.estimate_ms; + } + switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", jb->jitter.stats.jitter_max_ms); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_est_ms", "%u", jb->jitter.stats.estimate_ms); + } + if (old) { + sort_free_nodes(jb); + } + switch_mutex_unlock(jb->list_mutex); + jb_debug(jb, SWITCH_LOG_INFO, "JITTER buffersize %u == %u old[%u] target[%u] seq[%u|%u]\n", count, h_seq-l_seq+1, old, ntohs(jb->target_seq), l_seq, h_seq); + return count; +} + +static inline switch_status_t jb_next_packet_by_seq_with_acceleration(switch_jb_t *jb, switch_jb_node_t **nodep) +{ + switch_status_t status = jb_next_packet_by_seq(jb, nodep); + switch_rtp_packet_t *packet; + uint32_t len; + uint16_t seq = ntohs(jb->target_seq); + + /* When using a Codec that provides voice activity detection ex. Opus, use it to + select packet to drop/accelerate. */ + + if (jb->elastic && jb->jitter.estimate && (jb->visible_nodes*jb->jitter.samples_per_frame)>0 && jb->jitter.samples_per_second) { + int visible_not_old = check_jb_size(jb); + jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate)/((jb->jitter.samples_per_second))*1000); + jb->jitter.stats.buffer_size_ms = (int)((visible_not_old*jb->jitter.samples_per_frame)/(jb->jitter.samples_per_second/1000)); + + // We try to accelerate in order to remove delay when the jitter buffer is 3x larger than the estimation. + if (jb->jitter.stats.buffer_size_ms > (3*jb->jitter.stats.estimate_ms) && jb->jitter.stats.buffer_size_ms > 60) { + if (status == SWITCH_STATUS_SUCCESS) { + packet = &(*nodep)->packet; + seq = ntohs((*nodep)->packet.header.seq); + len = (*nodep)->len; + } + if (jb->jitter.drop_gap > 0) { + jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-gap][%d]\n", + jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq, jb->jitter.drop_gap); + jb->jitter.drop_gap--; + } else { + if (status != SWITCH_STATUS_SUCCESS || packet_vad(jb, packet, len) == SWITCH_FALSE) { + jb->jitter.drop_gap = 3; + if (status != SWITCH_STATUS_SUCCESS) { + jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation n/a buffersize %d/%d %dms seq:%u [drop-missing/no-plc]\n", + jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq); + } else { + jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u ACCELERATE [drop]\n", + jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq); + } + jb->jitter.stats.acceleration++; + return jb_next_packet_by_seq(jb, nodep); + } else { + jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-skip-vad]\n", + jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq); + } + } + } else { + jb_debug(jb, 2, "JITTER estimation %dms buffersize %d/%d %dms\n", + jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms); + } + } + return status; +} + static inline switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep) { if (jb->samples_per_frame) { return jb_next_packet_by_ts(jb, nodep); } else { - return jb_next_packet_by_seq(jb, nodep); + switch_status_t status; + if (jb->elastic && jb->jitter.estimate) { + status = jb_next_packet_by_seq_with_acceleration(jb, nodep); + } else { + status = jb_next_packet_by_seq(jb, nodep); + } + return status; } } @@ -877,13 +1052,50 @@ SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_fra switch_core_inthash_init(&jb->node_hash_ts); } +SWITCH_DECLARE(void) switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second) +{ + if (jb && jitter) { + memset(&jb->jitter,0,sizeof(switch_jb_jitter_t)); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_max_ms", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_ms", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_ms", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", 0); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", 0); + jb->jitter.estimate = jitter; + jb->jitter.samples_per_frame = samples_per_frame; + jb->jitter.samples_per_second = samples_per_second; + jb->jitter.drop_gap = 5; + } +} + SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session) { const char *var; if (session) { + jb->codec = switch_core_session_get_read_codec(session); jb->session = session; jb->channel = switch_core_session_get_channel(session); + if (!strcmp(jb->codec->implementation->iananame, "opus")) { + if (switch_true(switch_channel_get_variable(jb->channel, "rtp_jitter_buffer_accelerate"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate on\n", jb->codec->implementation->iananame); + jb->elastic = SWITCH_TRUE; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate off\n", jb->codec->implementation->iananame); + jb->elastic = SWITCH_FALSE; + } + + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec not opus: %s\n", jb->codec->implementation->iananame); + jb->elastic = SWITCH_FALSE; + } + if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) && (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) { int tmp = atoi(var); @@ -932,6 +1144,12 @@ SWITCH_DECLARE(void) switch_jb_debug_level(switch_jb_t *jb, uint8_t level) SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb) { + jb->jitter.stats.reset++; + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", jb->jitter.stats.reset); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", jb->jitter.stats.reset_too_big); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", jb->jitter.stats.reset_missing_frames); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", jb->jitter.stats.reset_ts_jump); + switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", jb->jitter.stats.reset_error); if (jb->type == SJB_VIDEO) { switch_mutex_lock(jb->mutex); @@ -1257,6 +1475,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp if (got > want) { if (got - want > jb->max_frame_len && got - want > 17) { jb_debug(jb, 2, "Missing %u frames, Resetting\n", got - want); + jb->jitter.stats.reset_missing_frames++; switch_jb_reset(jb); } else { @@ -1434,6 +1653,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp switch(status) { case SWITCH_STATUS_RESTART: jb_debug(jb, 2, "%s", "Error encountered\n"); + jb->jitter.stats.reset_error++; switch_jb_reset(jb); switch_goto_status(SWITCH_STATUS_RESTART, end); case SWITCH_STATUS_NOTFOUND: @@ -1444,7 +1664,22 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp jb_debug(jb, 2, "%s", "Too many frames not found, RESIZE\n"); switch_goto_status(SWITCH_STATUS_RESTART, end); } else { - jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); + if (jb->elastic) { + int visible_not_old = check_jb_size(jb); + jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate)/((jb->jitter.samples_per_second))*1000); + jb->jitter.stats.buffer_size_ms = (int)((visible_not_old*jb->jitter.samples_per_frame)/(jb->jitter.samples_per_second/1000)); + /* When playing PLC, we take the oportunity to expand the buffer if the jitter buffer is smaller than the 3x the estimated jitter. */ + if (jb->jitter.stats.buffer_size_ms < (3*jb->jitter.stats.estimate_ms)) { + jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc]\n", + jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms); + jb->jitter.stats.expand++; + decrement_seq(jb); + } else { + jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); + } + } else { + jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); + } plc = 1; switch_goto_status(SWITCH_STATUS_NOTFOUND, end); } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 614d79bf78..05b0858313 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4676,6 +4676,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * READ_INC(rtp_session); status = switch_jb_create(&rtp_session->jb, SJB_AUDIO, queue_frames, max_queue_frames, rtp_session->pool); switch_jb_set_session(rtp_session->jb, rtp_session->session); + switch_jb_set_jitter_estimator(rtp_session->jb, &rtp_session->stats.rtcp.inter_jitter, samples_per_packet, samples_per_second); if (switch_true(switch_channel_get_variable_dup(switch_core_session_get_channel(rtp_session->session), "jb_use_timestamps", SWITCH_FALSE, -1))) { switch_jb_ts_mode(rtp_session->jb, samples_per_packet, samples_per_second); } From 25afda9be002a2edd7311d2d10531ce88431b5c3 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 23 Jun 2023 21:25:16 +0300 Subject: [PATCH 037/205] [mod_opus] Fix Windows build regression made by previous commit --- src/mod/codecs/mod_opus/mod_opus.2017.vcxproj | 4 ++++ src/mod/codecs/mod_opus/opus_parse.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj b/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj index 3b73a6c42f..18478701c8 100644 --- a/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj +++ b/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj @@ -130,6 +130,10 @@ + + + + diff --git a/src/mod/codecs/mod_opus/opus_parse.c b/src/mod/codecs/mod_opus/opus_parse.c index 41e1ec6490..b94f491ca0 100644 --- a/src/mod/codecs/mod_opus/opus_parse.c +++ b/src/mod/codecs/mod_opus/opus_parse.c @@ -29,7 +29,7 @@ */ #include "switch.h" -#include +#include "opus.h" #include "opus_parse.h" /* Tables for LBRR_sympbol decoding */ From b355bf21e6685a7f88b67d682a8ec761ba4ee4fc Mon Sep 17 00:00:00 2001 From: David Villasmil Date: Wed, 28 Jun 2023 18:39:22 +0200 Subject: [PATCH 038/205] [mod_conference] Add flag to destroy the conference only when all mandatory members disconnect. And set endconf to end the conference when any member with the flag disconnects (#2079) * feature/mod_conference_mandatory_member_flag: Add flag to destroy the conference only when all mandatory members disconnect. And set endconf to end the conference when any member with the flag disconnects --- src/mod/applications/mod_conference/conference_cdr.c | 3 +++ .../applications/mod_conference/conference_member.c | 12 +++++++++++- .../applications/mod_conference/conference_utils.c | 2 ++ src/mod/applications/mod_conference/mod_conference.c | 4 ++++ src/mod/applications/mod_conference/mod_conference.h | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/conference_cdr.c b/src/mod/applications/mod_conference/conference_cdr.c index b6eb630540..f7ed7ddf27 100644 --- a/src/mod/applications/mod_conference/conference_cdr.c +++ b/src/mod/applications/mod_conference/conference_cdr.c @@ -662,6 +662,9 @@ void conference_cdr_render(conference_obj_t *conference) x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++); switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_ENDCONF) ? "true" : "false"); + x_tag = switch_xml_add_child_d(x_flags, "mandatory_member_end_conference", flag_off++); + switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_MANDATORY_MEMBER_ENDCONF) ? "true" : "false"); + x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++); switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_KICKED) ? "true" : "false"); diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index 6112a2890c..c258e59783 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -766,7 +766,12 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m conference->count++; } + if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) { + conference->endconference_time = 0; + } + + if (conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)) { if (conference->end_count++) { conference->endconference_time = 0; } @@ -1314,9 +1319,14 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m conference_video_check_flush(member, SWITCH_FALSE); + /* End conference when any member with "endconf" flag disconnects */ if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) { + conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT); + } + + /* End conference only if all mandatory members have disconnected */ + if (conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)) { if (!--conference->end_count) { - //conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT); conference->endconference_time = switch_epoch_time_now(NULL); } } diff --git a/src/mod/applications/mod_conference/conference_utils.c b/src/mod/applications/mod_conference/conference_utils.c index c8dd0fd4e9..a441594ddc 100644 --- a/src/mod/applications/mod_conference/conference_utils.c +++ b/src/mod/applications/mod_conference/conference_utils.c @@ -132,6 +132,8 @@ void conference_utils_set_mflags(const char *flags, member_flag_t *f) f[MFLAG_NOMOH] = 1; } else if (!strcasecmp(argv[i], "endconf")) { f[MFLAG_ENDCONF] = 1; + } else if (!strcasecmp(argv[i], "mandatory_member_endconf")) { + f[MFLAG_MANDATORY_MEMBER_ENDCONF] = 1; } else if (!strcasecmp(argv[i], "mintwo")) { f[MFLAG_MINTWO] = 1; } else if (!strcasecmp(argv[i], "talk-data-events")) { diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 619cd8c4a6..bf03d2a5bc 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1347,6 +1347,9 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i x_tag = switch_xml_add_child_d(x_flags, "end_conference", count++); switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_ENDCONF) ? "true" : "false"); + x_tag = switch_xml_add_child_d(x_flags, "mandatory_member_end_conference", count++); + switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF) ? "true" : "false"); + x_tag = switch_xml_add_child_d(x_flags, "is_ghost", count++); switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_GHOST) ? "true" : "false"); @@ -1456,6 +1459,7 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences) ADDBOOL(json_conference_member_flags, "has_floor", member->id == member->conference->floor_holder); ADDBOOL(json_conference_member_flags, "is_moderator", conference_utils_member_test_flag(member, MFLAG_MOD)); ADDBOOL(json_conference_member_flags, "end_conference", conference_utils_member_test_flag(member, MFLAG_ENDCONF)); + ADDBOOL(json_conference_member_flags, "mandatory_member_end_conference", conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)); ADDBOOL(json_conference_member_flags, "pass_digits", conference_utils_member_test_flag(member, MFLAG_DIST_DTMF)); } switch_mutex_unlock(conference->member_mutex); diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 3c28634264..21baaadc82 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -178,6 +178,7 @@ typedef enum { MFLAG_NO_MINIMIZE_ENCODING, MFLAG_FLUSH_BUFFER, MFLAG_ENDCONF, + MFLAG_MANDATORY_MEMBER_ENDCONF, MFLAG_HAS_AUDIO, MFLAG_TALKING, MFLAG_RESTART, From a160eced994d528ac0b461af0a9cb128690465a4 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Tue, 4 Jul 2023 09:51:37 +0100 Subject: [PATCH 039/205] [core,libyuv,modules] Fix function declarations without a prototype --- libs/libyuv/include/libyuv/planar_functions.h | 2 +- libs/libyuv/source/planar_functions.cc | 2 +- src/fs_encode.c | 2 +- src/fs_tts.c | 2 +- src/mod/applications/mod_av/avcodec.c | 2 +- src/mod/applications/mod_av/avformat.c | 2 +- .../applications/mod_conference/conference_loop.c | 2 +- .../applications/mod_conference/mod_conference.h | 2 +- src/mod/applications/mod_db/mod_db.c | 2 +- .../applications/mod_signalwire/mod_signalwire.c | 4 ++-- src/mod/endpoints/mod_skinny/mod_skinny.c | 2 +- src/mod/endpoints/mod_skinny/mod_skinny.h | 2 +- src/mod/endpoints/mod_skinny/skinny_api.c | 2 +- src/mod/endpoints/mod_skinny/skinny_api.h | 2 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++-- .../endpoints/mod_sofia/test/sipp-based-tests.c | 6 +++--- src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c | 4 ++-- src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 2 +- src/switch.c | 2 +- src/switch_core.c | 4 ++-- src/switch_log.c | 2 +- src/switch_msrp.c | 14 +++++++------- src/switch_rtp.c | 10 +++++----- src/switch_speex.c | 2 +- src/switch_vpx.c | 2 +- 25 files changed, 41 insertions(+), 41 deletions(-) diff --git a/libs/libyuv/include/libyuv/planar_functions.h b/libs/libyuv/include/libyuv/planar_functions.h index 5299fe2c0e..50fe5f681d 100644 --- a/libs/libyuv/include/libyuv/planar_functions.h +++ b/libs/libyuv/include/libyuv/planar_functions.h @@ -582,7 +582,7 @@ typedef void (*ARGBBlendRow)(const uint8_t* src_argb0, // Get function to Alpha Blend ARGB pixels and store to destination. LIBYUV_API -ARGBBlendRow GetARGBBlend(); +ARGBBlendRow GetARGBBlend(void); // Alpha Blend ARGB images and store to destination. // Source is pre-multiplied by alpha using ARGBAttenuate. diff --git a/libs/libyuv/source/planar_functions.cc b/libs/libyuv/source/planar_functions.cc index 5a9d56d88a..c07f0943d3 100644 --- a/libs/libyuv/source/planar_functions.cc +++ b/libs/libyuv/source/planar_functions.cc @@ -1185,7 +1185,7 @@ int ARGBMirror(const uint8_t* src_argb, // As there are 6 blenders to choose from, the caller should try to use // the same blend function for all pixels if possible. LIBYUV_API -ARGBBlendRow GetARGBBlend() { +ARGBBlendRow GetARGBBlend(void) { void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1, uint8_t* dst_argb, int width) = ARGBBlendRow_C; #if defined(HAS_ARGBBLENDROW_SSSE3) diff --git a/src/fs_encode.c b/src/fs_encode.c index 235a5d9f11..527dc3eeff 100644 --- a/src/fs_encode.c +++ b/src/fs_encode.c @@ -46,7 +46,7 @@ #pragma warning (disable:167) #endif -static void fs_encode_cleanup() +static void fs_encode_cleanup(void) { switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); diff --git a/src/fs_tts.c b/src/fs_tts.c index 2a963ee68e..6632e86566 100644 --- a/src/fs_tts.c +++ b/src/fs_tts.c @@ -46,7 +46,7 @@ #pragma warning (disable:167) #endif -static void fs_tts_cleanup() +static void fs_tts_cleanup(void) { switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index a9f6d0927e..b4eaeadd2e 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -2208,7 +2208,7 @@ static void parse_codecs(avcodec_profile_t *aprofile, switch_xml_t codecs) } -static void load_config() +static void load_config(void) { switch_xml_t cfg = NULL, xml = NULL; diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 1f767d0bde..d52e141b6b 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -2861,7 +2861,7 @@ static char *supported_formats[SWITCH_MAX_CODECS] = { 0 }; static const char modname[] = "mod_av"; -static switch_status_t load_config() +static switch_status_t load_config(void) { char *cf = "avformat.conf"; switch_xml_t cfg, xml, param, settings; diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index f6c2856892..8f112f5453 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -75,7 +75,7 @@ struct _mapping control_mappings[] = { {"deaf off", conference_loop_deaf_off} }; -int conference_loop_mapping_len() +int conference_loop_mapping_len(void) { return (sizeof(control_mappings)/sizeof(control_mappings[0])); } diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 21baaadc82..e45a921c21 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -1124,7 +1124,7 @@ void conference_video_canvas_del_fnode_layer(conference_obj_t *conference, confe void conference_video_canvas_set_fnode_layer(mcu_canvas_t *canvas, conference_file_node_t *fnode, int idx); void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim); const char *conference_utils_combine_flag_var(switch_core_session_t *session, const char *var_name); -int conference_loop_mapping_len(); +int conference_loop_mapping_len(void); void conference_api_set_agc(conference_member_t *member, const char *data); switch_status_t conference_outcall(conference_obj_t *conference, diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index 0e3e227de7..5f14792f2c 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -280,7 +280,7 @@ static switch_xml_config_item_t config_settings[] = { SWITCH_CONFIG_ITEM_END() }; -static switch_status_t do_config() +static switch_status_t do_config(void) { switch_cache_db_handle_t *dbh = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; diff --git a/src/mod/applications/mod_signalwire/mod_signalwire.c b/src/mod/applications/mod_signalwire/mod_signalwire.c index 9846e7e1d2..108f99b2c5 100644 --- a/src/mod/applications/mod_signalwire/mod_signalwire.c +++ b/src/mod/applications/mod_signalwire/mod_signalwire.c @@ -704,7 +704,7 @@ done: return status; } -static switch_status_t load_config() +static switch_status_t load_config(void) { char *cf = "signalwire.conf"; switch_xml_t cfg, xml; @@ -1390,7 +1390,7 @@ static void mod_signalwire_state_register(void) } } -static void mod_signalwire_state_ready() +static void mod_signalwire_state_ready(void) { if (globals.profile_update) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Signalwire SIP profile update initiated\n"); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index c6cfc716c7..64464e4ef6 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -2136,7 +2136,7 @@ void launch_skinny_profile_thread(skinny_profile_t *profile) { /*****************************************************************************/ /* MODULE FUNCTIONS */ /*****************************************************************************/ -switch_endpoint_interface_t *skinny_get_endpoint_interface() +switch_endpoint_interface_t *skinny_get_endpoint_interface(void) { return skinny_endpoint_interface; } diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index 69096ab64e..aff2ee92c0 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -355,7 +355,7 @@ switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); /*****************************************************************************/ /* MODULE FUNCTIONS */ /*****************************************************************************/ -switch_endpoint_interface_t *skinny_get_endpoint_interface(); +switch_endpoint_interface_t *skinny_get_endpoint_interface(void); /*****************************************************************************/ /* TEXT FUNCTIONS */ diff --git a/src/mod/endpoints/mod_skinny/skinny_api.c b/src/mod/endpoints/mod_skinny/skinny_api.c index f79f36c014..4657a5a9d3 100644 --- a/src/mod/endpoints/mod_skinny/skinny_api.c +++ b/src/mod/endpoints/mod_skinny/skinny_api.c @@ -697,7 +697,7 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_ return SWITCH_STATUS_SUCCESS; } -switch_status_t skinny_api_unregister() +switch_status_t skinny_api_unregister(void) { switch_console_set_complete("del skinny"); diff --git a/src/mod/endpoints/mod_skinny/skinny_api.h b/src/mod/endpoints/mod_skinny/skinny_api.h index e246957f0d..833d0c15da 100644 --- a/src/mod/endpoints/mod_skinny/skinny_api.h +++ b/src/mod/endpoints/mod_skinny/skinny_api.h @@ -34,7 +34,7 @@ #define _SKINNY_API_H switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_interface); -switch_status_t skinny_api_unregister(); +switch_status_t skinny_api_unregister(void); #endif /* _SKINNY_API_H */ diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 2fdf0063a9..9255c02664 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -54,7 +54,7 @@ switch_endpoint_interface_t *sofia_endpoint_interface; #define STRLEN 15 -void mod_sofia_shutdown_cleanup(); +void mod_sofia_shutdown_cleanup(void); static switch_status_t sofia_on_init(switch_core_session_t *session); static switch_status_t sofia_on_exchange_media(switch_core_session_t *session); @@ -6833,7 +6833,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) return status; } -void mod_sofia_shutdown_cleanup() { +void mod_sofia_shutdown_cleanup(void) { int sanity = 0; int i; switch_status_t st; diff --git a/src/mod/endpoints/mod_sofia/test/sipp-based-tests.c b/src/mod/endpoints/mod_sofia/test/sipp-based-tests.c index 60a7b61a3a..7b2d7964c9 100644 --- a/src/mod/endpoints/mod_sofia/test/sipp-based-tests.c +++ b/src/mod/endpoints/mod_sofia/test/sipp-based-tests.c @@ -90,7 +90,7 @@ static const char *test_wait_for_chan_var(switch_channel_t *channel, const char return var; } -static switch_bool_t has_ipv6() +static switch_bool_t has_ipv6(void) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); @@ -110,7 +110,7 @@ static switch_bool_t has_ipv6() return SWITCH_TRUE; } -static void register_gw() +static void register_gw(void) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); @@ -118,7 +118,7 @@ static void register_gw() switch_safe_free(stream.data); } -static void unregister_gw() +static void unregister_gw(void) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); diff --git a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c index 20259251de..3ec8b060df 100644 --- a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c +++ b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c @@ -272,7 +272,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } -static void do_rotate_all() +static void do_rotate_all(void) { switch_hash_index_t *hi; void *val; @@ -294,7 +294,7 @@ static void do_rotate_all() } -static void do_teardown() +static void do_teardown(void) { switch_hash_index_t *hi; void *val; diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 4e3bd81f78..da038ff37f 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -88,7 +88,7 @@ static size_t httpCallBack(char *buffer, size_t size, size_t nitems, void *outst return size * nitems; } -static switch_status_t set_xml_cdr_log_dirs() +static switch_status_t set_xml_cdr_log_dirs(void) { switch_time_exp_t tm; char *path = NULL; diff --git a/src/switch.c b/src/switch.c index 19a3d93fad..5011ff2d46 100644 --- a/src/switch.c +++ b/src/switch.c @@ -101,7 +101,7 @@ static void handle_SIGTERM(int sig) } /* kill a freeswitch process running in background mode */ -static int freeswitch_kill_background() +static int freeswitch_kill_background(void) { FILE *f; /* FILE handle to open the pid file */ char path[PATH_MAX] = ""; /* full path of the PID file */ diff --git a/src/switch_core.c b/src/switch_core.c index 4e2b70778a..7ec10d8885 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -3566,7 +3566,7 @@ SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t } } -SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_start_port() +SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_start_port(void) { uint16_t start_port = 0; @@ -3577,7 +3577,7 @@ SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_start_port() return start_port; } -SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_end_port() +SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_end_port(void) { uint16_t end_port = 0; diff --git a/src/switch_log.c b/src/switch_log.c index 74a5713635..563a554510 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -246,7 +246,7 @@ SWITCH_DECLARE(cJSON *) switch_log_node_to_json(const switch_log_node_t *node, i return json; } -static switch_log_node_t *switch_log_node_alloc() +static switch_log_node_t *switch_log_node_alloc(void) { switch_log_node_t *node = NULL; #ifdef SWITCH_LOG_RECYCLE diff --git a/src/switch_msrp.c b/src/switch_msrp.c index 1f5db7ac20..9fd84d846b 100644 --- a/src/switch_msrp.c +++ b/src/switch_msrp.c @@ -99,7 +99,7 @@ static switch_bool_t msrp_check_success_report(switch_msrp_msg_t *msrp_msg) return (msrp_h_success_report && !strcmp(msrp_h_success_report, "yes")); } -static void msrp_deinit_ssl() +static void msrp_deinit_ssl(void) { globals.ssl_ready = 0; if (globals.ssl_ctx) { @@ -112,7 +112,7 @@ static void msrp_deinit_ssl() } } -static void msrp_init_ssl() +static void msrp_init_ssl(void) { const char *err = ""; @@ -187,7 +187,7 @@ static void msrp_init_ssl() SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ip, globals.ip); -static switch_status_t load_config() +static switch_status_t load_config(void) { char *cf = "msrp.conf"; switch_xml_t cfg, xml = NULL, settings, param; @@ -286,12 +286,12 @@ sock_fail: return rv; } -SWITCH_DECLARE(const char *) switch_msrp_listen_ip() +SWITCH_DECLARE(const char *) switch_msrp_listen_ip(void) { return globals.ip; } -SWITCH_DECLARE(switch_status_t) switch_msrp_init() +SWITCH_DECLARE(switch_status_t) switch_msrp_init(void) { switch_memory_pool_t *pool; switch_thread_t *thread; @@ -346,7 +346,7 @@ SWITCH_DECLARE(switch_status_t) switch_msrp_init() return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_msrp_destroy() +SWITCH_DECLARE(switch_status_t) switch_msrp_destroy(void) { switch_status_t st = SWITCH_STATUS_SUCCESS; switch_socket_t *sock; @@ -1622,7 +1622,7 @@ SWITCH_DECLARE (switch_status_t) switch_msrp_perform_send(switch_msrp_session_t return status; } -SWITCH_DECLARE(switch_msrp_msg_t *) switch_msrp_msg_create() +SWITCH_DECLARE(switch_msrp_msg_t *) switch_msrp_msg_create(void) { switch_msrp_msg_t *msg = malloc(sizeof(switch_msrp_msg_t)); switch_assert(msg); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 05b0858313..ce6f3062df 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -262,8 +262,8 @@ typedef struct { struct switch_rtp; -static void switch_rtp_dtls_init(); -static void switch_rtp_dtls_destroy(); +static void switch_rtp_dtls_init(void); +static void switch_rtp_dtls_destroy(void); #define MAX_DTLS_MTU 4096 @@ -1660,7 +1660,7 @@ static void rtcp_generate_sender_info(switch_rtp_t *rtp_session, struct switch_r ); } -static inline uint32_t calc_local_lsr_now() +static inline uint32_t calc_local_lsr_now(void) { switch_time_t now; uint32_t ntp_sec, ntp_usec, lsr_now, sec; @@ -3493,7 +3493,7 @@ static BIO_METHOD dtls_bio_filter_methods = { static BIO_METHOD *dtls_bio_filter_methods = NULL; #endif -static void switch_rtp_dtls_init() { +static void switch_rtp_dtls_init(void) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L dtls_bio_filter_methods = BIO_meth_new(BIO_TYPE_FILTER | BIO_get_new_index(), "DTLS filter"); BIO_meth_set_write(dtls_bio_filter_methods, dtls_bio_filter_write); @@ -3503,7 +3503,7 @@ static void switch_rtp_dtls_init() { #endif } -static void switch_rtp_dtls_destroy() { +static void switch_rtp_dtls_destroy(void) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (dtls_bio_filter_methods) { BIO_meth_free(dtls_bio_filter_methods); diff --git a/src/switch_speex.c b/src/switch_speex.c index 122ae79a73..5a97b082f2 100644 --- a/src/switch_speex.c +++ b/src/switch_speex.c @@ -470,7 +470,7 @@ static switch_status_t switch_speex_destroy(switch_codec_t *codec) /** * read default settings from speex.conf */ -static void load_configuration() +static void load_configuration(void) { switch_xml_t xml = NULL, cfg = NULL; diff --git a/src/switch_vpx.c b/src/switch_vpx.c index e35d87712f..751f2b8c5b 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -1853,7 +1853,7 @@ static void parse_codecs(my_vpx_cfg_t *my_cfg, switch_xml_t codecs) } } -static void load_config() +static void load_config(void) { switch_xml_t cfg = NULL, xml = NULL; my_vpx_cfg_t *my_cfg = NULL; From 5656972bfe2539158c14b9a44aacfb1da86a29ea Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Tue, 4 Jul 2023 10:12:44 +0100 Subject: [PATCH 040/205] [core,miniupnpc,modules] Fix not used variables --- libs/miniupnpc/miniupnpc.c | 2 -- .../applications/mod_conference/conference_api.c | 4 +--- .../applications/mod_conference/conference_cdr.c | 2 +- src/mod/applications/mod_dptools/mod_dptools.c | 2 -- src/mod/endpoints/mod_sofia/mod_sofia.c | 5 ----- src/mod/endpoints/mod_sofia/sofia_presence.c | 2 -- src/mod/endpoints/mod_verto/mod_verto.c | 7 +------ .../mod_event_socket/mod_event_socket.c | 16 +++++++--------- src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 4 ++-- src/switch_core_media.c | 16 +++------------- src/switch_event.c | 2 -- src/switch_ivr_play_say.c | 5 ----- src/switch_loadable_module.c | 3 +-- src/switch_rtp.c | 3 --- src/switch_time.c | 5 ++--- src/switch_utils.c | 3 --- 16 files changed, 18 insertions(+), 63 deletions(-) diff --git a/libs/miniupnpc/miniupnpc.c b/libs/miniupnpc/miniupnpc.c index 88faea1c37..a72ef892b6 100644 --- a/libs/miniupnpc/miniupnpc.c +++ b/libs/miniupnpc/miniupnpc.c @@ -679,7 +679,6 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, char * descXML; int descXMLsize = 0; struct UPNPDev * dev; - int ndev = 0; int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ if(!devlist) { @@ -698,7 +697,6 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, lanaddr, lanaddrlen); if(descXML) { - ndev++; memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); parserootdesc(descXML, descXMLsize, data); diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 8bcfc5862f..7e566367fb 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -4087,7 +4087,6 @@ switch_status_t conference_api_sub_set(conference_obj_t *conference, switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { - int count = 0; switch_hash_index_t *hi; void *val; switch_xml_t x_conference, x_conferences; @@ -4106,7 +4105,6 @@ switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch x_conference = switch_xml_add_child_d(x_conferences, "conference", off++); switch_assert(conference); - count++; conference_xlist(conference, x_conference, off); } @@ -4114,7 +4112,7 @@ switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch } else { x_conference = switch_xml_add_child_d(x_conferences, "conference", off++); switch_assert(conference); - count++; + conference_xlist(conference, x_conference, off); } diff --git a/src/mod/applications/mod_conference/conference_cdr.c b/src/mod/applications/mod_conference/conference_cdr.c index f7ed7ddf27..9f2ccba63c 100644 --- a/src/mod/applications/mod_conference/conference_cdr.c +++ b/src/mod/applications/mod_conference/conference_cdr.c @@ -740,7 +740,7 @@ void conference_cdr_render(conference_obj_t *conference) #endif int wrote; wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); - wrote++; + (void)wrote; close(fd); } else { char ebuf[512] = { 0 }; diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index e91ec53d47..f52b1184e5 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -161,7 +161,6 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match) char *string = NULL; switch_channel_t *channel; switch_core_session_t *use_session = act->session; - int x = 0; char *flags = ""; if (act->target == DIGIT_TARGET_PEER || act->target == DIGIT_TARGET_BOTH) { @@ -171,7 +170,6 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match) } top: - x++; string = switch_core_session_strdup(use_session, act->string); exec = 0; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 2fdf0063a9..9cd447ef71 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3255,8 +3255,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl switch_hash_index_t *hi; void *val; const void *vvar; - int c = 0; - int ac = 0; const char *header = ""; if (argc > 0) { @@ -3466,7 +3464,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl if (sofia_test_pflag(profile, PFLAG_RUNNING)) { if (strcmp(vvar, profile->name)) { - ac++; stream->write_function(stream, "\n%s\n%s\n%s\n%s\n\n", vvar, "alias", profile->name, "ALIASED"); } else { @@ -3492,8 +3489,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl profile->inuse); } - c++; - for (gp = profile->gateways; gp; gp = gp->next) { switch_assert(gp->state < REG_STATE_LAST); stream->write_function(stream, "\n%s\n%s\n%s\n%s\n\n", diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index b8576ae7f5..579cea83e2 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1621,7 +1621,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Started\n"); while (mod_sofia_globals.running == 1) { - int count = 0; if (switch_queue_pop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) { switch_event_t *event = (switch_event_t *) pop; @@ -1656,7 +1655,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread } switch_event_destroy(&event); - count++; } } diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 8920de7e02..6d49fc022b 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -823,7 +823,6 @@ static void set_perm(const char *str, switch_event_t **event, switch_bool_t add) { char delim = ','; char *cur, *next; - int count = 0; char *edup; if (!zstr(str)) { @@ -844,7 +843,7 @@ static void set_perm(const char *str, switch_event_t **event, switch_bool_t add) delim = ' '; } - for (cur = edup; cur; count++) { + for (cur = edup; cur;) { if ((next = strchr(cur, delim))) { *next++ = '\0'; } @@ -5579,8 +5578,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl { verto_profile_t *profile = NULL; jsock_t *jsock; - int cp = 0; - int cc = 0; const char *header = ""; int i; @@ -5594,14 +5591,12 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, "\n%s\n%s\n%s\n%s\n\n", profile->name, "profile", tmpurl, (profile->running) ? "RUNNING" : "DOWN"); switch_safe_free(tmpurl); } - cp++; switch_mutex_lock(profile->mutex); for(jsock = profile->jsock_head; jsock; jsock = jsock->next) { char *tmpname = switch_mprintf("%s@%s", jsock->id, jsock->domain); stream->write_function(stream, "\n%s\n%s\n%s\n%s\n%s (%s)\n\n", profile->name, tmpname, "client", jsock->name, (!zstr(jsock->uid)) ? "CONN_REG" : "CONN_NO_REG", (jsock->ptype & PTYPE_CLIENT_SSL) ? "WSS": "WS"); - cc++; switch_safe_free(tmpname); } switch_mutex_unlock(profile->mutex); diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 70331a95e2..520bd92ac7 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -866,7 +866,7 @@ SWITCH_STANDARD_API(event_sink_function) char *loglevel = switch_event_get_header(stream->param_event, "loglevel"); switch_memory_pool_t *pool; char *next, *cur; - uint32_t count = 0, key_count = 0; + uint32_t key_count = 0; uint8_t custom = 0; char *edup; @@ -925,7 +925,7 @@ SWITCH_STANDARD_API(event_sink_function) delim = ' '; } - for (cur = edup; cur; count++) { + for (cur = edup; cur;) { switch_event_types_t type; if ((next = strchr(cur, delim))) { @@ -1846,7 +1846,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even if (allowed_events) { char delim = ','; char *cur, *next; - int count = 0, custom = 0, key_count = 0; + int custom = 0; switch_set_flag(listener, LFLAG_AUTH_EVENTS); @@ -1862,7 +1862,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even delim = ' '; } - for (cur = edup; cur; count++) { + for (cur = edup; cur;) { switch_event_types_t type; if ((next = strchr(cur, delim))) { @@ -1872,7 +1872,6 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even if (custom) { switch_core_hash_insert(listener->allowed_event_hash, cur, MARKER); } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) { - key_count++; if (type == SWITCH_EVENT_ALL) { uint32_t x = 0; switch_set_flag(listener, LFLAG_ALL_EVENTS_AUTHED); @@ -1904,7 +1903,6 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even if (allowed_api) { char delim = ','; char *cur, *next; - int count = 0; switch_snprintf(api_reply, sizeof(api_reply), "Allowed-API: %s\n", allowed_api); @@ -1916,7 +1914,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even delim = ' '; } - for (cur = edup; cur; count++) { + for (cur = edup; cur;) { if ((next = strchr(cur, delim))) { *next++ = '\0'; } @@ -2540,14 +2538,14 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even } else if (!strncasecmp(cmd, "nixevent", 8)) { char *next, *cur; - uint32_t count = 0, key_count = 0; + uint32_t key_count = 0; uint8_t custom = 0; strip_cr(cmd); cur = cmd + 8; if ((cur = strchr(cur, ' '))) { - for (cur++; cur; count++) { + for (cur++; cur;) { switch_event_types_t type; if ((next = strchr(cur, ' '))) { diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 4e3bd81f78..f8c98f6392 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -254,7 +254,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) #endif int wrote; wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); - wrote++; + (void)wrote; close(fd); } else { char ebuf[512] = { 0 }; @@ -427,7 +427,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) #endif int wrote; wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); - wrote++; + (void)wrote; close(fd); } else { char ebuf[512] = { 0 }; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 60cc3d531c..e75387581d 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4762,7 +4762,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_t *channel = switch_core_session_get_channel(session); const char *val; const char *crypto = NULL; - int got_crypto = 0, got_video_crypto = 0, got_audio = 0, saw_audio = 0, saw_video = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0, got_text = 0, got_text_crypto = 0, got_msrp = 0; + int got_crypto = 0, got_video_crypto = 0, got_audio = 0, saw_audio = 0, saw_video = 0, got_avp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0, got_text = 0, got_text_crypto = 0, got_msrp = 0; int scrooge = 0; sdp_parser_t *parser = NULL; sdp_session_t *sdp; @@ -4958,14 +4958,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) { if (m->m_type == sdp_media_audio) { got_savp++; - } else { - got_video_savp++; } } else if (m->m_proto == sdp_proto_rtp) { if (m->m_type == sdp_media_audio) { got_avp++; - } else { - got_video_avp++; } } else if (m->m_proto == sdp_proto_udptl) { got_udptl++; @@ -7406,7 +7402,7 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi switch_status_t status; switch_frame_t *read_frame = NULL; switch_media_handle_t *smh; - uint32_t loops = 0, xloops = 0, vloops = 0; + uint32_t loops = 0, xloops = 0; switch_image_t *blank_img = NULL; switch_frame_t fr = { 0 }; unsigned char *buf = NULL; @@ -7531,8 +7527,6 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi continue; } - vloops++; - send_blank = blank_enabled || switch_channel_test_flag(channel, CF_VIDEO_ECHO); if (switch_channel_test_flag(channel, CF_VIDEO_READY) && !switch_test_flag(read_frame, SFF_CNG)) { @@ -14243,7 +14237,7 @@ SWITCH_DECLARE(char *) switch_core_media_filter_sdp(const char *sdp_str, const c switch_size_t len; const char *i; char *o; - int in_m = 0, m_tally = 0, slash = 0; + int in_m = 0, slash = 0; int number = 0, skip = 0; int remove = !strcasecmp(cmd, "remove"); int only = !strcasecmp(cmd, "only"); @@ -14277,7 +14271,6 @@ SWITCH_DECLARE(char *) switch_core_media_filter_sdp(const char *sdp_str, const c if (*i == 'm' && *(i+1) == '=') { in_m = 1; - m_tally++; } if (in_m) { @@ -14981,7 +14974,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core { switch_status_t status = SWITCH_STATUS_FALSE; switch_io_event_hook_video_read_frame_t *ptr; - uint32_t loops = 0; switch_media_handle_t *smh; int is_keyframe = 0; @@ -14993,8 +14985,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core top: - loops++; - if (switch_channel_down_nosig(session->channel)) { return SWITCH_STATUS_FALSE; } diff --git a/src/switch_event.c b/src/switch_event.c index be49f2fc14..272255d31c 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -651,7 +651,6 @@ SWITCH_DECLARE(void) switch_event_launch_dispatch_threads(uint32_t max) { switch_threadattr_t *thd_attr; uint32_t index = 0; - int launched = 0; uint32_t sanity = 200; switch_memory_pool_t *pool = RUNTIME_POOL; @@ -682,7 +681,6 @@ SWITCH_DECLARE(void) switch_event_launch_dispatch_threads(uint32_t max) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Create additional event dispatch thread %d\n", index); } - launched++; } SOFT_MAX_DISPATCH = index; diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 25486eee7f..33f3a4e51a 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1271,7 +1271,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess int sleep_val_i = 250; int eof = 0; switch_size_t bread = 0; - int l16 = 0; switch_codec_implementation_t read_impl = { 0 }; char *file_dup; char *argv[128] = { 0 }; @@ -1334,10 +1333,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess arg_recursion_check_start(args); - if (!zstr(read_impl.iananame) && !strcasecmp(read_impl.iananame, "l16")) { - l16++; - } - if (play_delimiter) { file_dup = switch_core_session_strdup(session, file); argc = switch_separate_string(file_dup, play_delimiter, argv, (sizeof(argv) / sizeof(argv[0]))); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index f782e89f6e..bacd2f012a 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -115,12 +115,11 @@ static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thr switch_status_t status = SWITCH_STATUS_SUCCESS; switch_core_thread_session_t *ts = obj; switch_loadable_module_t *module = ts->objs[0]; - int restarts; switch_assert(thread != NULL); switch_assert(module != NULL); - for (restarts = 0; status != SWITCH_STATUS_TERM && !module->shutting_down; restarts++) { + while (status != SWITCH_STATUS_TERM && !module->shutting_down) { status = module->switch_module_runtime(); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Thread ended for %s\n", module->module_interface->module_name); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 05b0858313..40c913e2b9 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5494,7 +5494,6 @@ static switch_size_t do_flush(switch_rtp_t *rtp_session, int force, switch_size_ { int was_blocking = 0; switch_size_t bytes; - uint32_t flushed = 0; switch_size_t bytes_out = 0; if (!switch_rtp_ready(rtp_session)) { @@ -5576,8 +5575,6 @@ static switch_size_t do_flush(switch_rtp_t *rtp_session, int force, switch_size_ #endif } - flushed++; - rtp_session->stats.inbound.raw_bytes += bytes; rtp_session->stats.inbound.flush_packet_count++; rtp_session->stats.inbound.packet_count++; diff --git a/src/switch_time.c b/src/switch_time.c index 445e698f9b..a56c5e96f1 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -1173,9 +1173,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } else { if (tfd > -1 && globals.RUNNING == 1) { uint64_t exp; - int r; - r = read(tfd, &exp, sizeof(exp)); - r++; + read(tfd, &exp, sizeof(exp)); + (void)exp; } else { switch_time_t timediff = runtime.reference - ts; diff --git a/src/switch_utils.c b/src/switch_utils.c index d8b830943a..332137ebda 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -139,13 +139,10 @@ struct switch_frame_buffer_s { static switch_frame_t *find_free_frame(switch_frame_buffer_t *fb, switch_frame_t *orig) { switch_frame_node_t *np; - int x = 0; switch_mutex_lock(fb->mutex); for (np = fb->head; np; np = np->next) { - x++; - if (!np->inuse && ((orig->packet && np->frame->packet) || (!orig->packet && !np->frame->packet))) { if (np == fb->head) { From 2afad15f480065a3f5f44401b2de4d45f7d327b0 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Tue, 4 Jul 2023 10:37:48 +0100 Subject: [PATCH 041/205] [mod_sofia] Remove non-implemented verbose feature --- src/mod/endpoints/mod_sofia/sip-dig.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sip-dig.c b/src/mod/endpoints/mod_sofia/sip-dig.c index c9a6f5b463..10a0a26763 100644 --- a/src/mod/endpoints/mod_sofia/sip-dig.c +++ b/src/mod/endpoints/mod_sofia/sip-dig.c @@ -82,9 +82,6 @@ *
-6
*
Query IP6 addresses (AAAA records). *
- *
-v
- *
Be verbatim. - *
*
*
*
@@ -201,7 +198,7 @@ switch_bool_t verify_ip(sres_record_t **answers, const char *ip, switch_bool_t i switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) { - int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1; + int o_sctp = 1, o_tls_sctp = 1; int family = 0, multiple = 0; char const *string; url_t *uri = NULL; @@ -247,9 +244,7 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor } while (argv[i] && argv[i][0] == '-') { - if (strcmp(argv[i], "-v") == 0) { - o_verbatim++; - } else if (strcmp(argv[i], "-6") == 0) { + if (strcmp(argv[i], "-6") == 0) { dig->ip6 = ++family; } else if (strcmp(argv[i], "-4") == 0) { dig->ip4 = ++family; From eec311d8d7509f1b748beca6d2c41446bdebe497 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Jun 2023 23:12:00 +0300 Subject: [PATCH 042/205] [Build-System] Update commit hash of SpanDSP on Windows. --- w32/download_spandsp.props | 2 +- w32/spandsp-version.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/w32/download_spandsp.props b/w32/download_spandsp.props index 39b7f2b81b..f02c66a9bd 100644 --- a/w32/download_spandsp.props +++ b/w32/download_spandsp.props @@ -29,7 +29,7 @@ - master + 0d2e6ac65e0e8f53d652665a743015a88bf048d4 true From 921eebdbeac0972d08870c652eab2848aec98dcd Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Tue, 4 Jul 2023 10:42:38 +0100 Subject: [PATCH 043/205] [xmlrpc-c] Fix MacOS build --- libs/xmlrpc-c/include/xmlrpc-c/string_int.h | 5 +++++ libs/xmlrpc-c/lib/abyss/src/server.c | 3 +++ libs/xmlrpc-c/lib/abyss/src/thread_fork.c | 4 ++++ libs/xmlrpc-c/lib/libutil/asprintf.c | 3 +++ 4 files changed, 15 insertions(+) diff --git a/libs/xmlrpc-c/include/xmlrpc-c/string_int.h b/libs/xmlrpc-c/include/xmlrpc-c/string_int.h index 04ac8c782b..a0cc58605f 100644 --- a/libs/xmlrpc-c/include/xmlrpc-c/string_int.h +++ b/libs/xmlrpc-c/include/xmlrpc-c/string_int.h @@ -3,7 +3,12 @@ #include + +#ifdef __APPLE__ +#include +#else #include +#endif #include "xmlrpc_config.h" #include "c_util.h" diff --git a/libs/xmlrpc-c/lib/abyss/src/server.c b/libs/xmlrpc-c/lib/abyss/src/server.c index 6337dcfd78..ca05011b83 100644 --- a/libs/xmlrpc-c/lib/abyss/src/server.c +++ b/libs/xmlrpc-c/lib/abyss/src/server.c @@ -1,6 +1,9 @@ /* Copyright information is at end of file */ #define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif #define _BSD_SOURCE /* Make sure setgroups()is in */ #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE diff --git a/libs/xmlrpc-c/lib/abyss/src/thread_fork.c b/libs/xmlrpc-c/lib/abyss/src/thread_fork.c index d96bf59eb1..7ea382918a 100644 --- a/libs/xmlrpc-c/lib/abyss/src/thread_fork.c +++ b/libs/xmlrpc-c/lib/abyss/src/thread_fork.c @@ -3,7 +3,11 @@ #include #include #include +#ifdef __APPLE__ +#include +#else #include +#endif #include #include "xmlrpc_config.h" diff --git a/libs/xmlrpc-c/lib/libutil/asprintf.c b/libs/xmlrpc-c/lib/libutil/asprintf.c index b52523065a..f078518bb5 100644 --- a/libs/xmlrpc-c/lib/libutil/asprintf.c +++ b/libs/xmlrpc-c/lib/libutil/asprintf.c @@ -1,4 +1,7 @@ #define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif #ifndef _GNU_SOURCE #define _GNU_SOURCE /* But only when HAVE_ASPRINTF */ #endif From c9fb586c34780da6115cd341277d4082ac0c7a1e Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Sat, 8 Jul 2023 06:29:23 -0500 Subject: [PATCH 044/205] [mod_verto] Fix function declarations without a prototype --- src/mod/endpoints/mod_verto/mod_verto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 6d49fc022b..9423d03c28 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -5606,7 +5606,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl return SWITCH_STATUS_SUCCESS; } -static cJSON *json_status() +static cJSON *json_status(void) { cJSON *obj, *profiles, *jprofile, *users, *user; verto_profile_t *profile = NULL; @@ -6735,14 +6735,14 @@ static void mod_verto_ks_logger(const char *file, const char *func, int line, in va_end(ap); } -static void verto_event_free_subclass() +static void verto_event_free_subclass(void) { switch_event_free_subclass(MY_EVENT_LOGIN); switch_event_free_subclass(MY_EVENT_CLIENT_DISCONNECT); switch_event_free_subclass(MY_EVENT_CLIENT_CONNECT); } -static void verto_destroy_globals_hash_tables() +static void verto_destroy_globals_hash_tables(void) { if (verto_globals.method_hash) { switch_core_hash_destroy(&verto_globals.method_hash); From 930341ba86d252f9b1c96333ab546b267119cbb3 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Mon, 10 Jul 2023 10:31:09 +0000 Subject: [PATCH 045/205] [core,mod_av,unit-tests] Make transition to core packetizer --- src/mod/applications/mod_av/avcodec.c | 138 +++++++++---------------- src/mod/applications/mod_av/avformat.c | 10 ++ src/switch_packetizer.c | 6 +- tests/unit/switch_packetizer.c | 4 + 4 files changed, 65 insertions(+), 93 deletions(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index b4eaeadd2e..94cc9b36bf 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -399,6 +399,7 @@ typedef struct h264_codec_context_s { enum AVCodecID av_codec_id; uint16_t last_seq; // last received frame->seq int hw_encoder; + switch_packetizer_t *packetizer; } h264_codec_context_t; #ifndef AV_INPUT_BUFFER_PADDING_SIZE @@ -1088,64 +1089,6 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw return SWITCH_STATUS_MORE_DATA; } -static switch_status_t consume_h264_bitstream(h264_codec_context_t *context, switch_frame_t *frame) -{ - AVPacket *pkt = &context->encoder_avpacket; - our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index]; - uint8_t nalu_hdr = *(uint8_t *)(nalu->start); - uint8_t nalu_type = nalu_hdr & 0x1f; - uint8_t nri = nalu_hdr & 0x60; - int left = nalu->len - (nalu->eat - nalu->start); - uint8_t *p = frame->data; - uint8_t start = nalu->start == nalu->eat ? 0x80 : 0; - int n = nalu->len / SLICE_SIZE; - int slice_size = nalu->len / (n + 1) + 1 + 2; - - if (nalu->len <= SLICE_SIZE) { - memcpy(frame->data, nalu->start, nalu->len); - frame->datalen = nalu->len; - context->nalu_current_index++; - - if (context->nalus[context->nalu_current_index].len) { - frame->m = 0; - return SWITCH_STATUS_MORE_DATA; - } - - if (pkt->size > 0) av_packet_unref(pkt); - - switch_clear_flag(frame, SFF_CNG); - frame->m = 1; - - return SWITCH_STATUS_SUCCESS; - } - - if (left <= (slice_size - 2)) { - p[0] = nri | 28; // FU-A - p[1] = 0x40 | nalu_type; - memcpy(p+2, nalu->eat, left); - nalu->eat += left; - frame->datalen = left + 2; - context->nalu_current_index++; - - if (!context->nalus[context->nalu_current_index].len) { - if (pkt->size > 0) av_packet_unref(pkt); - frame->m = 1; - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_MORE_DATA; - } - - p[0] = nri | 28; // FU-A - p[1] = start | nalu_type; - if (start) nalu->eat++; - memcpy(p+2, nalu->eat, slice_size - 2); - nalu->eat += (slice_size - 2); - frame->datalen = slice_size; - frame->m = 0; - return SWITCH_STATUS_MORE_DATA; -} - static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame) { AVPacket *pkt = &context->encoder_avpacket; @@ -1154,8 +1097,12 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_ if (!nalu->len) { frame->datalen = 0; frame->m = 0; - if (pkt->size > 0) av_packet_unref(pkt); + if (pkt->size > 0) { + av_packet_unref(pkt); + } + context->nalu_current_index = 0; + return SWITCH_STATUS_NOTFOUND; } @@ -1167,7 +1114,9 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_ return consume_h263p_bitstream(context, frame); } - return consume_h264_bitstream(context, frame); + switch_assert(0); + + return SWITCH_STATUS_FALSE; } static void set_h264_private_data(h264_codec_context_t *context, avcodec_profile_t *profile) @@ -1436,6 +1385,14 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag } } + switch (context->av_codec_id) { + case AV_CODEC_ID_H264: + context->packetizer = switch_packetizer_create(SPT_H264_BITSTREAM, SLICE_SIZE); + break; + default: + break; + } + switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0); codec->private_info = context; @@ -1480,6 +1437,16 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t } if (frame->flags & SFF_SAME_IMAGE) { + if (context->packetizer) { + switch_status_t status = switch_packetizer_read(context->packetizer, frame); + + if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) { + av_packet_unref(pkt); + } + + return status; + } + // read from nalu buffer return consume_nalu(context, frame); } @@ -1511,7 +1478,9 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t switch_set_flag(frame, SFF_WAIT_KEY_FRAME); } +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(pkt); +GCC_DIAG_ON(deprecated-declarations) pkt->data = NULL; // packet data will be allocated by the encoder pkt->size = 0; @@ -1596,8 +1565,7 @@ GCC_DIAG_ON(deprecated-declarations) // process: if (*got_output) { - const uint8_t *p = pkt->data; - int i = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; *got_output = 0; @@ -1626,38 +1594,22 @@ GCC_DIAG_ON(deprecated-declarations) "Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) nalu_type=0x%x %d\n", context->pts, pkt->size, *((uint8_t *)pkt->data +4), *got_output); } - /* split into nalus */ - memset(context->nalus, 0, sizeof(context->nalus)); - while ((p = fs_avc_find_startcode(p, pkt->data+pkt->size)) < (pkt->data + pkt->size)) { - if (!context->nalus[i].start) { - while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */ - context->nalus[i].start = p; - context->nalus[i].eat = p; + status = switch_packetizer_feed(context->packetizer, pkt->data, pkt->size); + if (status != SWITCH_STATUS_SUCCESS) { + if (pkt->size > 0) { + av_packet_unref(pkt); + } - if ((*p & 0x1f) == 7) { // Got Keyframe - // prevent to generate key frame too frequently - context->last_keyframe_request = switch_time_now(); - if (mod_av_globals.debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n"); - } - } - } else { - context->nalus[i].len = p - context->nalus[i].start; - while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */ - i++; - context->nalus[i].start = p; - context->nalus[i].eat = p; - } - if (i >= MAX_NALUS - 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TOO MANY SLICES!\n"); - break; - } + return status; } - context->nalus[i].len = p - context->nalus[i].start; - context->nalu_current_index = 0; - return consume_nalu(context, frame); + status = switch_packetizer_read(context->packetizer, frame); + if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) { + av_packet_unref(pkt); + } + + return status; } error: @@ -1708,7 +1660,9 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t int decoded_len; if (size > 0) { +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(&pkt); +GCC_DIAG_ON(deprecated-declarations) switch_buffer_zero_fill(context->nalu_buffer, AV_INPUT_BUFFER_PADDING_SIZE); switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt.data); pkt.size = size; @@ -1825,6 +1779,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec) av_free(context->encoder_ctx); } + if (context->packetizer) { + switch_packetizer_close(&context->packetizer); + } + if (context->encoder_avframe) { av_frame_free(&context->encoder_avframe); } diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index d52e141b6b..d17f4eac39 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -877,7 +877,9 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * context->eh.in_callback = 1; +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(&pkt); +GCC_DIAG_ON(deprecated-declarations) if (context->eh.video_st->frame) { ret = av_frame_make_writable(context->eh.video_st->frame); @@ -971,7 +973,9 @@ GCC_DIAG_ON(deprecated-declarations) int got_packet = 0; int ret = 0; +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(&pkt); +GCC_DIAG_ON(deprecated-declarations) GCC_DIAG_OFF(deprecated-declarations) ret = avcodec_encode_video2(context->eh.video_st->st->codec, &pkt, NULL, &got_packet); @@ -1427,7 +1431,9 @@ GCC_DIAG_ON(deprecated-declarations) +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(&pkt); +GCC_DIAG_ON(deprecated-declarations) pkt.data = NULL; pkt.size = 0; @@ -1464,7 +1470,9 @@ GCC_DIAG_ON(deprecated-declarations) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %u %x %x %x %x %x %x\n", pkt.size, *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5)); } +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(new_pkt); +GCC_DIAG_ON(deprecated-declarations) av_packet_ref(new_pkt, &pkt); status = switch_queue_push(context->video_pkt_queue, new_pkt); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %4u flag=%x pts=%" SWITCH_INT64_T_FMT " dts=%" SWITCH_INT64_T_FMT "\n", pkt.size, pkt.flags, pkt.pts, pkt.dts); @@ -2102,8 +2110,10 @@ GCC_DIAG_ON(deprecated-declarations) int j = 0, ret = -1, audio_stream_count = 1; AVFrame *use_frame = NULL; +GCC_DIAG_OFF(deprecated-declarations) av_init_packet(&pkt[0]); av_init_packet(&pkt[1]); +GCC_DIAG_ON(deprecated-declarations) if (context->audio_st[1].active) { switch_size_t len = 0; diff --git a/src/switch_packetizer.c b/src/switch_packetizer.c index 626e85ba8e..c9cdcbf3e7 100644 --- a/src/switch_packetizer.c +++ b/src/switch_packetizer.c @@ -265,7 +265,7 @@ SWITCH_DECLARE(switch_status_t) switch_packetizer_feed(switch_packetizer_t *pack context->nalus[i].eat = p; } else { context->nalus[i].len = p - context->nalus[i].start; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "#%d %x len=%u\n", i, *context->nalus[i].start, context->nalus[i].len); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "#%d %x len=%u\n", i, *context->nalus[i].start, context->nalus[i].len); while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */ i++; context->nalus[i].start = p; @@ -307,8 +307,8 @@ SWITCH_DECLARE(switch_status_t) switch_packetizer_read(switch_packetizer_t *pack nri = nalu_hdr & 0x60; if (real_slice_size > slice_size) real_slice_size = slice_size; - if (frame->buflen < slice_size) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "frame buffer too small %u < %u\n", frame->buflen, slice_size); + if (frame->datalen < slice_size) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "frame buffer too small %u < %u\n", frame->datalen, slice_size); return SWITCH_STATUS_FALSE; } diff --git a/tests/unit/switch_packetizer.c b/tests/unit/switch_packetizer.c index 242ca6ae33..006af5a74b 100644 --- a/tests/unit/switch_packetizer.c +++ b/tests/unit/switch_packetizer.c @@ -52,6 +52,7 @@ FST_CORE_BEGIN("conf") frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE; switch_set_flag(&frame, SFF_ENCODED); status = switch_packetizer_feed(packetizer, h264data, sizeof(h264data)); @@ -94,6 +95,7 @@ FST_CORE_BEGIN("conf") frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE; switch_set_flag(&frame, SFF_ENCODED); status = switch_packetizer_feed(packetizer, h264data, sizeof(h264data)); @@ -138,6 +140,7 @@ FST_CORE_BEGIN("conf") // 1 fps 3 bytes 1pps 3 bytes frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE; switch_set_flag(&frame, SFF_ENCODED); status = switch_packetizer_feed_extradata(packetizer, extradata, sizeof(extradata)); @@ -210,6 +213,7 @@ FST_CORE_BEGIN("conf") frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE; switch_set_flag(&frame, SFF_ENCODED); status = switch_packetizer_feed(packetizer, h264data, sizeof(h264data)); From 2cf57c41b634ba8821d9e65360c1a25159b9ad4c Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Tue, 4 Jul 2023 15:25:05 +0200 Subject: [PATCH 046/205] [mod_python3] fix build on Python 3.10+ fix #2145 --- src/mod/languages/mod_python3/mod_python3.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_python3/mod_python3.c b/src/mod/languages/mod_python3/mod_python3.c index ca05f18710..263c2de1d4 100644 --- a/src/mod/languages/mod_python3/mod_python3.c +++ b/src/mod/languages/mod_python3/mod_python3.c @@ -86,6 +86,9 @@ static void print_python_error(const char * script) { PyObject *pyType = NULL, *pyValue = NULL, *pyTraceback = NULL, *pyString = NULL; PyObject *pyModule=NULL, *pyFunction = NULL, *pyResult = NULL; +#if PY_VERSION_HEX >= 0x030B0000 + PyCodeObject *pcode = NULL; +#endif char * buffer = (char*) malloc( 20 * 1024 * sizeof(char)); /* Variables for the traceback */ PyTracebackObject * pyTB = NULL/*, *pyTB2 = NULL*/; @@ -153,10 +156,23 @@ static void print_python_error(const char * script) /* Traceback */ do { - sprintf((char*)sTemp, "\n\tFile: \"%s\", line %i, in %s", +#if PY_VERSION_HEX >= 0x030B0000 + if (pyTB->tb_frame != NULL) { + pcode = PyFrame_GetCode(pyTB->tb_frame); + } else { + pcode = NULL; + } + + snprintf((char*)sTemp, sizeof(sTemp), "\n\tFile: \"%s\", line %i, in %s", + (pcode)?PyString_AsString(pcode->co_filename):"", + pyTB->tb_lineno, + (pcode)?PyString_AsString(pcode->co_name):"" ); +#else + snprintf((char*)sTemp, sizeof(sTemp), "\n\tFile: \"%s\", line %i, in %s", PyString_AsString(pyTB->tb_frame->f_code->co_filename), pyTB->tb_lineno, PyString_AsString(pyTB->tb_frame->f_code->co_name) ); +#endif strcat(buffer, (char*)sTemp); pyTB=pyTB->tb_next; From 95457f79226ea68f8ba49051eda7ba661da1e36c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 12 Jul 2023 18:17:52 +0300 Subject: [PATCH 047/205] Revert "[mod_opus] Fix Windows build regression made by previous commit" This reverts commit 25afda9be002a2edd7311d2d10531ce88431b5c3. --- src/mod/codecs/mod_opus/mod_opus.2017.vcxproj | 4 ---- src/mod/codecs/mod_opus/opus_parse.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj b/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj index 18478701c8..3b73a6c42f 100644 --- a/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj +++ b/src/mod/codecs/mod_opus/mod_opus.2017.vcxproj @@ -130,10 +130,6 @@ - - - - diff --git a/src/mod/codecs/mod_opus/opus_parse.c b/src/mod/codecs/mod_opus/opus_parse.c index b94f491ca0..41e1ec6490 100644 --- a/src/mod/codecs/mod_opus/opus_parse.c +++ b/src/mod/codecs/mod_opus/opus_parse.c @@ -29,7 +29,7 @@ */ #include "switch.h" -#include "opus.h" +#include #include "opus_parse.h" /* Tables for LBRR_sympbol decoding */ From 34f1d974f50f1c1f819b102550395b0b240d386e Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 12 Jul 2023 18:18:17 +0300 Subject: [PATCH 048/205] Revert "[core, mod_opus] more elastic jitterbuffer with Opus codec (#2069)" This reverts commit 67840823c178153cb013014c4fa780fe233612cb. --- scripts/lua/hangup_jitterbuffer_metrics.lua | 53 --- src/include/switch_jitterbuffer.h | 1 - src/include/switch_types.h | 1 - src/mod/codecs/mod_opus/Makefile.am | 2 +- src/mod/codecs/mod_opus/mod_opus.c | 30 -- src/mod/codecs/mod_opus/opus_parse.c | 366 -------------------- src/mod/codecs/mod_opus/opus_parse.h | 66 ---- src/switch_jitterbuffer.c | 239 +------------ src/switch_rtp.c | 1 - 9 files changed, 3 insertions(+), 756 deletions(-) delete mode 100755 scripts/lua/hangup_jitterbuffer_metrics.lua delete mode 100644 src/mod/codecs/mod_opus/opus_parse.c delete mode 100644 src/mod/codecs/mod_opus/opus_parse.h diff --git a/scripts/lua/hangup_jitterbuffer_metrics.lua b/scripts/lua/hangup_jitterbuffer_metrics.lua deleted file mode 100755 index 8e3dd37623..0000000000 --- a/scripts/lua/hangup_jitterbuffer_metrics.lua +++ /dev/null @@ -1,53 +0,0 @@ -local https = require("socket.http") -local ip = os.getenv("LOCAL_IPV4") -local response_body = {} --- jitter buffer stats -local size_max_ms = session:getVariable("rtp_jb_size_max_ms"); -local size_est_ms = session:getVariable("rtp_jb_size_est_ms"); -local acceleration_ms = session:getVariable("rtp_jb_acceleration_ms"); -local expand_ms = session:getVariable("rtp_jb_expand_ms"); -local jitter_max_ms = session:getVariable("rtp_jb_jitter_max_ms"); -local jitter_est_ms = session:getVariable("rtp_jb_jitter_est_ms"); - -local reset_count = session:getVariable("rtp_jb_reset_count"); -local reset_too_big = session:getVariable("rtp_jb_reset_too_big"); -local reset_missing_frames = session:getVariable("rtp_jb_reset_missing_frames"); -local reset_ts_jump = session:getVariable("rtp_jb_reset_ts_jump"); -local reset_error = session:getVariable("rtp_jb_reset_error"); -local call_id = session:getVariable("sip_call_id"); -local out_call_id = session:getVariable("last_bridge_to"); - -if size_max_ms == nil or size_est_ms == nil or acceleration_ms == nil or expand_ms == nil or jitter_max_ms == nil or jitter_est_ms == nil then - session:consoleLog("info", "[metrics] jitter no data\n"); - return -end -local request_body = '{"in_call_id": "'..call_id..'", "out_call_id": "'..out_call_id..'", "jb":{"size_max_ms":'..size_max_ms.. - ',"size_est_ms":'..size_est_ms..',"acceleration_ms":'..acceleration_ms..',"expand_ms":'..expand_ms.. - ',"jitter_max_ms":'..jitter_max_ms..',"jitter_est_ms":'..jitter_est_ms..',"reset":'..reset_count --- if reset_too_big ~= "0" then - request_body = request_body .. ',"reset_too_big":'..reset_too_big --- end -if reset_missing_frames ~= "0" then - request_body = request_body .. ',"reset_missing_frames":'..reset_missing_frames -end -if reset_ts_jump ~= "0" then - request_body = request_body .. ',"reset_ts_jump":'..reset_ts_jump -end -if reset_error ~= "0" then - request_body = request_body .. ',"reset_error":'..reset_error -end - -local v = request_body .. '}}'; - -local r, c, h, s = https.request{ - method = 'POST', - url = "http://"..ip..":80/freeswitch_metrics", - headers = { - ["Content-Type"] = "application/json", - ["Content-Length"] = string.len(v) - }, - source = ltn12.source.string(v), - sink = ltn12.sink.table(response_body) -} --- print('statusCode ', c) -session:consoleLog("info", "[metrics] jitter:".. v .. "\n"); diff --git a/src/include/switch_jitterbuffer.h b/src/include/switch_jitterbuffer.h index f098ede2db..bee0fa02f8 100644 --- a/src/include/switch_jitterbuffer.h +++ b/src/include/switch_jitterbuffer.h @@ -61,7 +61,6 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb); SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len); SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session); -SWITCH_DECLARE(void) switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second); SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second); SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag); SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 94a4c62cca..82639c2ca6 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2425,7 +2425,6 @@ typedef enum { SCC_VIDEO_RESET, SCC_AUDIO_PACKET_LOSS, SCC_AUDIO_ADJUST_BITRATE, - SCC_AUDIO_VAD, SCC_DEBUG, SCC_CODEC_SPECIFIC } switch_codec_control_command_t; diff --git a/src/mod/codecs/mod_opus/Makefile.am b/src/mod/codecs/mod_opus/Makefile.am index 70710898e7..690c5fa471 100644 --- a/src/mod/codecs/mod_opus/Makefile.am +++ b/src/mod/codecs/mod_opus/Makefile.am @@ -4,7 +4,7 @@ MODNAME=mod_opus if HAVE_OPUS mod_LTLIBRARIES = mod_opus.la -mod_opus_la_SOURCES = mod_opus.c opus_parse.c +mod_opus_la_SOURCES = mod_opus.c mod_opus_la_CFLAGS = $(AM_CFLAGS) $(OPUS_CFLAGS) mod_opus_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(OPUS_LIBS) mod_opus_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index ce9aff52a3..4a47b45df4 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -33,7 +33,6 @@ #include "switch.h" #include "opus.h" -#include "opus_parse.h" #define SWITCH_OPUS_MIN_BITRATE 6000 #define SWITCH_OPUS_MAX_BITRATE 510000 @@ -1170,27 +1169,6 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) } } -static switch_bool_t switch_opus_vad(struct opus_context *context, void *encoded_data, uint32_t encoded_data_len) { - const uint8_t *payload = (const uint8_t *) encoded_data; - opus_packet_info_t opus_packet_info; - switch_bool_t debug = (globals.debug || context->debug > 1); - if (!switch_opus_packet_parse(payload, encoded_data_len, &opus_packet_info, debug)) { - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS PACKET PARSING ERROR len:%d bytes:%02x %02x\n", - (int)encoded_data_len, payload[0], payload[1]); - } - return SWITCH_TRUE; - } - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS EXTRACT PAYLOAD VAD len:%d vad_ms:%d bytes:%02x %02x\n", - (int)encoded_data_len, opus_packet_info.vad_ms, payload[0], payload[1]); - } - if (opus_packet_info.vad_ms == 0) { - return SWITCH_FALSE; - } - return SWITCH_TRUE; -} - static switch_status_t switch_opus_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, @@ -1282,14 +1260,6 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, context->old_plpct = plpct; } break; - case SCC_AUDIO_VAD: - { - void* encoded_data = (void *)cmd_data; - uint16_t* encoded_data_len = (uint16_t *)cmd_arg; - switch_bool_t *ret = (switch_bool_t *) *ret_data; - *ret = switch_opus_vad(context, encoded_data, *encoded_data_len); - } - break; case SCC_AUDIO_ADJUST_BITRATE: { const char *cmd = (const char *)cmd_data; diff --git a/src/mod/codecs/mod_opus/opus_parse.c b/src/mod/codecs/mod_opus/opus_parse.c deleted file mode 100644 index 41e1ec6490..0000000000 --- a/src/mod/codecs/mod_opus/opus_parse.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2023, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Claude Lamblin - * Julien Chavanton - * - */ - -#include "switch.h" -#include -#include "opus_parse.h" -/* Tables for LBRR_sympbol decoding */ - -static const opus_int16 silk_LBRR_flags_2_PDFCum[3] = {53, 106, 256}; /* 256 - silk_LBRR_flags_2_iCDF[i] ; silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; */ -static const opus_int16 silk_LBRR_flags_3_PDFCum[7] = {41, 61, 90, 131, 146, 174, 256}; /* 256 - silk_LBRR_flags_3_iCDF[i] ; silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; */ - -/* get the number of VAD flags - i.e. number of 20 ms frame - from the config */ -/* in a silk-only or hybrid opus frame mono or stereo*/ -/* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1) */ -/* if 10 ms frame (config=0, 4, 8, 12, 14) : return 1 */ -/* if CELT_only frame no VAD flag =>return 0 */ -static opus_int16 switch_opus_get_nb_flags_in_silk_frame(int16_t config) -{ - opus_int16 silk_frame_nb_flags; - if (config > 15) { - /* CELT_only frame no VAD flag nor LBRR flag */ - silk_frame_nb_flags = 0; - } else { - silk_frame_nb_flags = 1; /*default*/ - if (config < 12) { - /* silk-only NB, MB or WB */ - /* The least two significant bits give the number of VAD flags inside the silk frame 1, 2 or 3 */ - silk_frame_nb_flags = config & 0x3; - if (silk_frame_nb_flags == 0) { /* 0 => 10ms frame : one VAD flag */ - silk_frame_nb_flags++; - } - } - } - return silk_frame_nb_flags; -} - -/* get the time in ms corresponding to one VAD flag from the config */ -/* in a silk-only or hybrid opus frame mono or stereo*/ -/* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1) */ -/* if CELT_only frame (config >15) no VAD flag =>return FALSE */ -/* if 10 ms frame (config=0, 4, 8, 12, 14) : return 10 */ -/* otherwise return 20 */ -static opus_int16 switch_opus_get_silk_frame_ms_per_flag(int16_t config, opus_int16 silk_frame_nb_flags) -{ - opus_int16 silk_size_frame_ms_per_flag; - if (config > 15) { - /* CELT_only frame no VAD flag nor LBRR flag */ - /* switch_opus_get_silk_frame_ms_per_flag: code not written for CELT-only mode */ - return FALSE; - } - silk_size_frame_ms_per_flag = 20; /* default*/ - if (silk_frame_nb_flags == 1) { /* could be 10 or 20 ms */ - if ((config &0x01) == 0) { - silk_size_frame_ms_per_flag = 10; - } - } - return silk_size_frame_ms_per_flag; -} - -/* code written only for mono, silk-only or hybrid mode */ -/* for CELT-only frame no vad flags for LBRR flag the routine must not be called */ -/* for stereo : the mid frame VAD_flags and the LBRR_flag could be obtained */ -/* yet, to get the LBRR_flags of the mid frame the routine should be modified */ -/* to skip the side VAD flags and the side LBRR flag and to get the mid LBRR_symbol */ -static bool_t switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_frame_nb_flags, - opus_int16 *VAD_flags, opus_int16 *LBRR_flags, opus_int16 *nb_VAD1, opus_int16 *nb_FEC) -{ - const opus_int16 *ptr_pdf_cum; - opus_int nb_pdf_symbol; - opus_uint16 LBRR_symbol; - opus_int16 val, nb_bit, compl_nb_bit, mask, mask2; - opus_int16 *ptr_flags; - opus_int16 LBRR_flag; - opus_int16 nb_vad, nb_fec; - int i; - - nb_vad = 0; - nb_fec = 0; - - /* get VAD_FLAGS & LBRR_FLAG */ - /* silk_frame_nb_flags = 1 (10 or 20 ms), the two MSB of the first byte are the VAD flag and the LBRR flag */ - /* silk_frame_nb_flags = 2 (40 ms), the three MSB of the first byte are the two VAD flags and the LBRR flag */ - /* silk_frame_nb_flags = 3 (60 ms), the four MSB of the first byte are the three VAD flags and the LBRR flag */ - /* compute the number of MSB to analyse */ - nb_bit = silk_frame_nb_flags + 1; - /* number of right shifts to appply to the first byte to only have the bits of LBRR flag and of the VAD flags */ - compl_nb_bit = 8 - nb_bit; - mask = (1 << nb_bit) - 1; - - /* the bits of the silk_frame_nb_flags VAD flags and the LBRR flag are the MSB of the first byte */ - /* silk_frame_nb_flags = 1 (10 or 20 ms), VAD_flags(0) | LBRR_flag */ - /* silk_frame_nb_flags = 2 (40 ms), VAD_flags(0) | VAD_flags(1) | LBRR_flag */ - /* silk_frame_nb_flags = 3 (60 ms), VAD_flags(0) | VAD_flags(1) | VAD_flags(2) |LBRR_flag */ - val = (buf[0] >> compl_nb_bit) & mask; - - LBRR_flag = val & 0x1; /* LBRR_FLAG LSB */ - - /* get VAD_flags */ - ptr_flags = VAD_flags + silk_frame_nb_flags; - for (i=0; i < silk_frame_nb_flags; i++) { - LBRR_flags[i] = 0; /* init */ - val >>= 1; - *(--ptr_flags) = val & 0x1; - } - if (LBRR_flag != 0) { /* there is at least one LBRR frame */ - if (silk_frame_nb_flags == 1) { - LBRR_flags[0] = 1; - nb_fec = 1; - } else { /* get LBRR_symbol then LBRR_flags */ - /* LBRR symbol is encoded with range encoder : range on 8 bits */ - /* silk_frame_nb_flags = 2 ; 3 possible values for LBRR_flags(1) | LBRR_flags(0))= 01, 10, 11 */ - /* silk_frame_nb_flags = 3 ; 7 possible values for LBRR_flags(2) | LBRR_flags(1) | LBRR_flags(0))= 001, 010, 011, 100, 101, 110, 111 */ - mask2 = (1 << compl_nb_bit) - 1; - /* get next 8 bits: (8-nb_bit) LSB of the first byte and nb_bit MSB of the second byte */ - val = (((buf[0]) & mask2) << nb_bit) | ((buf[1] >> compl_nb_bit) & mask); - - if (silk_frame_nb_flags == 2) { - nb_pdf_symbol = 3; - ptr_pdf_cum = silk_LBRR_flags_2_PDFCum; - } else { - nb_pdf_symbol = 7; - ptr_pdf_cum = silk_LBRR_flags_3_PDFCum; - } - LBRR_symbol = 0; - for (i = 1; i <= nb_pdf_symbol; i++) { - if (val < *ptr_pdf_cum++) { - LBRR_symbol = i; - break; - } - } - for (i = 0; i < silk_frame_nb_flags; i++) { - LBRR_flags[i] = LBRR_symbol & 0x01; - LBRR_symbol >>= 1; - nb_fec += LBRR_flags[i]; - } - } - } - for (i = 0; i < silk_frame_nb_flags; i++) { - nb_vad += VAD_flags[i]; - } - - *nb_VAD1 = nb_vad; - *nb_FEC = nb_fec; - return TRUE; -} - -/* Parse the packet to retrieve informations about its content - * RFC6716: Definition of the Opus Audio Codec - * return: FALSE if there was a problem found parsing the packet, the info returned should be ignored. - * */ -bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, bool_t debug) -{ - int f; - int32_t samplerate; - int i, shift_silk, silk_frame_packet; - int16_t vad_flags_per_silk_frame, fec_flags_per_silk_frame; - opus_int16 frame_sizes[48]; - const unsigned char *frame_data[48]; - opus_int16 packet_LBBR_FLAGS[3 * 48], packet_VAD_FLAGS[3 * 48]; - opus_int16 *ptr_LBBR_FLAGS, *ptr_VAD_FLAGS; - opus_int16 silk_frame_nb_flags, silk_size_frame_ms_per_flag; - opus_int16 silk_frame_nb_fec, silk_frame_nb_vad1; - opus_int sample_per_frame; - packet_info->config = 0; - packet_info->fec = 0; - packet_info->fec_ms = 0; - packet_info->vad = 0; - packet_info->vad_ms = 0; - packet_info->stereo = FALSE; - packet_info->frames = 0; - packet_info->channels = 1; /* as stereo is set to FALSE */ - packet_info->ms_per_frame = 0; - packet_info->ptime_ts = 0; - if (payload == NULL || payload_length_bytes <= 0) { - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: payload null."); - } - return FALSE; - } - - /* In CELT_ONLY mode, packets should not have FEC. */ - if (payload[0] & 0x80) { - /* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */ - return FALSE; - } else { - int mode = (payload[0] >> 3); - if (mode <= 3) { - samplerate = 8000; - } else if (mode <= 7) { - samplerate = 12000; - } else if (mode <= 11) { - samplerate = 16000; - } else if (mode <= 13) { - samplerate = 24000; - } else if (mode <= 15) { - samplerate = 48000; - } else { - /* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */ - return FALSE; - } - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: mode[%d]s[%d]c[%d] [%d]Hz\n", mode, (payload[0]>>2)&0x1 ,(payload[0])&0x3, samplerate); - } - } - if (payload[0] & 0x04) { - packet_info->stereo = TRUE; - packet_info->channels = 2; - } - packet_info->config = payload[0] >> 3; - sample_per_frame = opus_packet_get_samples_per_frame(payload, samplerate); - packet_info->ms_per_frame = sample_per_frame * 1000 / samplerate; - if (packet_info->ms_per_frame < 10 || packet_info->ms_per_frame > 120) { - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: invalid packet."); - } - return FALSE; - } - - packet_info->frames = opus_packet_parse(payload, payload_length_bytes, NULL, frame_data, frame_sizes, NULL); - if (packet_info->frames < 0) { - packet_info->frames = 0; - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse found no frame.\n"); - } - return FALSE; - } - packet_info->ptime_ts = packet_info->frames * sample_per_frame; - - if (frame_sizes[0] <= 1) { - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse frame size too small.\n"); - } - return FALSE; - } - - /* +---------------+-----------+-----------+-------------------+ */ - /* | Configuration | Mode | Bandwidth | Frame Sizes | */ - /* | Number(s) | | | | */ - /* +---------------+-----------+-----------+-------------------+ */ - /* | 0...3 | SILK-only | NB | 10, 20, 40, 60 ms | */ - /* | 4...7 | SILK-only | MB | 10, 20, 40, 60 ms | */ - /* | 8...11 | SILK-only | WB | 10, 20, 40, 60 ms | */ - /* | 12...13 | Hybrid | SWB | 10, 20 ms | */ - /* | 14...15 | Hybrid | FB | 10, 20 ms | */ - /* | 16...19 | CELT-only | NB | 2.5, 5, 10, 20 ms | */ - /* | 20...23 | CELT-only | WB | 2.5, 5, 10, 20 ms | */ - /* | 24...27 | CELT-only | SWB | 2.5, 5, 10, 20 ms | */ - /* | 28...31 | CELT-only | FB | 2.5, 5, 10, 20 ms | */ - /* +---------------+-----------+-----------+-------------------+ */ - - if (!packet_info->stereo) { - /* the routines opus_get_nb_flags_in_silk_frame and opus_get_silk_frame_ms_per_flag are also valid for stereo frames */ - /* yet the routine opus_get_VAD_LBRR_flags is currently only for mono frame*/ - silk_frame_nb_flags = switch_opus_get_nb_flags_in_silk_frame(packet_info->config); /* =1 for 10 or 20 ms frame; = 2 for 40 ms; = 3 for 60 ms */ - if (!silk_frame_nb_flags) { - /* We should not go there as CELT_ONLY is already tested above */ - return FALSE; - } - - packet_info->frames_silk = silk_frame_nb_flags; - silk_size_frame_ms_per_flag = switch_opus_get_silk_frame_ms_per_flag(packet_info->config, silk_frame_nb_flags); /* 10 or 20 ms frame*/ - if (!silk_size_frame_ms_per_flag) { - /* we should not go there as CELT_ONLY is already tested above */ - return FALSE; - } - - ptr_LBBR_FLAGS = packet_LBBR_FLAGS; - ptr_VAD_FLAGS = packet_VAD_FLAGS; - - for (f = 0; f < packet_info->frames; f++) { - switch_opus_get_VAD_LBRR_flags(frame_data[f], silk_frame_nb_flags, ptr_VAD_FLAGS, ptr_LBBR_FLAGS, - &silk_frame_nb_vad1, &silk_frame_nb_fec); - packet_info->vad += silk_frame_nb_vad1; - packet_info->fec += silk_frame_nb_fec; - packet_info->vad_ms += silk_frame_nb_vad1 * silk_size_frame_ms_per_flag; - packet_info->fec_ms += silk_frame_nb_fec * silk_size_frame_ms_per_flag; - - ptr_VAD_FLAGS += silk_frame_nb_flags; - ptr_LBBR_FLAGS += silk_frame_nb_flags; - } - /* store the VAD & LBRR flags of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */ - vad_flags_per_silk_frame = 0; - fec_flags_per_silk_frame = 0; - silk_frame_packet = packet_info->frames * packet_info->frames_silk; - if (silk_frame_packet > 15) { - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: more than %d 20-ms frames in the packet ; only first 15 silk-frames data will be stored (pb silkFastAccelerate)\n", silk_frame_packet); - } - silk_frame_packet = 15; - } - ptr_LBBR_FLAGS = packet_LBBR_FLAGS; - ptr_VAD_FLAGS = packet_VAD_FLAGS; - shift_silk = 0; - for (i=0; i < silk_frame_packet; i++) { - vad_flags_per_silk_frame += (*ptr_VAD_FLAGS) << shift_silk; - fec_flags_per_silk_frame += (*ptr_LBBR_FLAGS) << shift_silk; - shift_silk++; - ptr_LBBR_FLAGS++; ptr_VAD_FLAGS++; - } - packet_info->vad_flags_per_silk_frame = vad_flags_per_silk_frame; - packet_info->fec_flags_per_silk_frame = fec_flags_per_silk_frame; - return TRUE; - } - - if (packet_info->config != 1 && packet_info->config != 5 && packet_info->config != 9) { - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: the current parser implementation does not support muliple SILK frames for VAD or FEC detection.\n"); - } - return FALSE; - } - /* - * Parse the VAD and LBRR flags in each Opus frame - * */ - for (f = 0; f < packet_info->frames; f++) { - if (frame_data[f][0] & 0x80) { - packet_info->vad++; - } - if (frame_data[f][0] & 0x40) { - packet_info->fec++; - } - if (debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: LP layer opus_frame[%d] VAD[%d] FEC[%d]\n", f+1, (frame_data[f][0]&0x80)>>7, (frame_data[f][0]&0x40)>>6); - } - } - packet_info->vad_ms = packet_info->vad * packet_info->ms_per_frame; - packet_info->fec_ms = packet_info->fec * packet_info->ms_per_frame; - return TRUE; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/codecs/mod_opus/opus_parse.h b/src/mod/codecs/mod_opus/opus_parse.h deleted file mode 100644 index 8dd61500cd..0000000000 --- a/src/mod/codecs/mod_opus/opus_parse.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2023, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Julien Chavanton - * - */ - -#ifndef SWITCH_OPUS_PARSE_H -#define SWITCH_OPUS_PARSE_H - -typedef enum { false, true } bool_t; - -typedef struct opus_packet_info { - int16_t vad; - int16_t vad_ms; - int16_t fec; - int16_t fec_ms; - bool_t stereo; - int16_t frames; /* number of opus frames in the packet */ - int16_t config; - int16_t channels; - int16_t ms_per_frame; - int32_t ptime_ts; - bool_t valid; - int16_t frames_silk; /* number of silk_frames in an opus frame */ - /* VAD flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */ - int16_t vad_flags_per_silk_frame; - /* LBRR (FEC) flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */ - int16_t fec_flags_per_silk_frame; -} opus_packet_info_t; - -bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, bool_t debug); -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index d8d9df3a33..d68b269024 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -44,8 +44,6 @@ struct switch_jb_s; -static inline int check_jb_size(switch_jb_t *jb); - typedef struct switch_jb_node_s { struct switch_jb_s *parent; switch_rtp_packet_t packet; @@ -58,29 +56,6 @@ typedef struct switch_jb_node_s { switch_bool_t complete_frame_mark; } switch_jb_node_t; -typedef struct switch_jb_stats_s { - uint32_t reset_too_big; - uint32_t reset_missing_frames; - uint32_t reset_ts_jump; - uint32_t reset_error; - uint32_t reset; - uint32_t size_max; - uint32_t size_est; - uint32_t acceleration; - uint32_t expand; - uint32_t jitter_max_ms; - int estimate_ms; - int buffer_size_ms; -} switch_jb_stats_t; - -typedef struct switch_jb_jitter_s { - double *estimate; - uint32_t samples_per_second; - uint32_t samples_per_frame; - uint32_t drop_gap; - switch_jb_stats_t stats; -} switch_jb_jitter_t; - struct switch_jb_s { struct switch_jb_node_s *node_list; uint32_t last_target_seq; @@ -129,7 +104,6 @@ struct switch_jb_s { switch_jb_flag_t flags; switch_jb_type_t type; switch_core_session_t *session; - switch_jb_jitter_t jitter; switch_channel_t *channel; uint32_t buffer_lag; uint32_t flush; @@ -138,8 +112,6 @@ struct switch_jb_s { uint32_t period_len; uint32_t nack_saved_the_day; uint32_t nack_didnt_save_the_day; - switch_bool_t elastic; - switch_codec_t *codec; }; @@ -261,7 +233,6 @@ static inline switch_jb_node_t *new_node(switch_jb_t *jb) if (jb->allocated_nodes > jb->max_frame_len * mult) { jb_debug(jb, 2, "ALLOCATED FRAMES TOO HIGH! %d\n", jb->allocated_nodes); - jb->jitter.stats.reset_too_big++; switch_jb_reset(jb); switch_mutex_unlock(jb->list_mutex); return NULL; @@ -361,29 +332,6 @@ static inline void hide_nodes(switch_jb_t *jb) switch_mutex_unlock(jb->list_mutex); } -static inline switch_bool_t packet_vad(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) { - void* payload; - uint16_t payload_len = len; - - if (packet->ebody) { - payload = packet->ebody; - } else { - payload = packet->body; - } - if (payload && payload_len > 0) { - switch_bool_t ret; - switch_bool_t *ret_p = &ret; - switch_codec_control_type_t ret_t; - switch_core_media_codec_control(jb->session, SWITCH_MEDIA_TYPE_AUDIO, - SWITCH_IO_WRITE, SCC_AUDIO_VAD, - SCCT_STRING, (void *)payload, - SCCT_INT, (void *)&payload_len, - &ret_t, (void *)&ret_p); - return ret; - } - return SWITCH_TRUE; -} - static inline void drop_ts(switch_jb_t *jb, uint32_t ts) { switch_jb_node_t *np; @@ -719,7 +667,6 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch if (((seq_diff >= 100) || (ts_diff > (900000 * 5)))) { jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq)))); - jb->jitter.stats.reset_ts_jump++; switch_jb_reset(jb); } } @@ -785,12 +732,6 @@ static inline void increment_seq(switch_jb_t *jb) jb->target_seq = htons((ntohs(jb->target_seq) + 1)); } -static inline void decrement_seq(switch_jb_t *jb) -{ - jb->last_target_seq = jb->target_seq; - jb->target_seq = htons((ntohs(jb->target_seq) - 1)); -} - static inline void set_read_seq(switch_jb_t *jb, uint16_t seq) { jb->last_target_seq = seq; @@ -913,128 +854,12 @@ static inline switch_status_t jb_next_packet_by_ts(switch_jb_t *jb, switch_jb_no } -static inline int check_jb_size(switch_jb_t *jb) -{ - switch_jb_node_t *np; - uint16_t seq; - uint16_t l_seq=0; - uint16_t h_seq=0; - uint16_t count=0; - uint16_t old=0; - switch_mutex_lock(jb->list_mutex); - - for (np = jb->node_list; np; np = np->next) { - if (!np->visible) { - continue; - } - - seq = ntohs(np->packet.header.seq); - if (ntohs(jb->target_seq) > seq) { - hide_node(np, SWITCH_FALSE); - old++; - continue; - } - if (count == 0) { - l_seq = h_seq = seq; - } - count++; - if (seq < l_seq) - l_seq = seq; - if (seq > h_seq) - h_seq = seq; - } - if (count > jb->jitter.stats.size_max) { - jb->jitter.stats.size_max = count; - } - if (jb->jitter.stats.size_est == 0) { - jb->jitter.stats.size_est = count; - } else { - jb->jitter.stats.size_est = ((99*jb->jitter.stats.size_est)+(1*count))/100; - } - if (ntohs(jb->target_seq) % 50 == 0) { /* update the stats every x packets */ - int packet_ms = jb->jitter.samples_per_frame / (jb->jitter.samples_per_second / 1000); - jb->jitter.stats.estimate_ms = (*jb->jitter.estimate) / jb->jitter.samples_per_second * 1000; - switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_max_ms", "%u", jb->jitter.stats.size_max*packet_ms); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_est_ms", "%u", jb->jitter.stats.size_est*packet_ms); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", jb->jitter.stats.acceleration*packet_ms); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", jb->jitter.stats.expand*packet_ms); - if (jb->jitter.stats.jitter_max_ms < jb->jitter.stats.estimate_ms) { - jb->jitter.stats.jitter_max_ms = jb->jitter.stats.estimate_ms; - } - switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", jb->jitter.stats.jitter_max_ms); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_est_ms", "%u", jb->jitter.stats.estimate_ms); - } - if (old) { - sort_free_nodes(jb); - } - switch_mutex_unlock(jb->list_mutex); - jb_debug(jb, SWITCH_LOG_INFO, "JITTER buffersize %u == %u old[%u] target[%u] seq[%u|%u]\n", count, h_seq-l_seq+1, old, ntohs(jb->target_seq), l_seq, h_seq); - return count; -} - -static inline switch_status_t jb_next_packet_by_seq_with_acceleration(switch_jb_t *jb, switch_jb_node_t **nodep) -{ - switch_status_t status = jb_next_packet_by_seq(jb, nodep); - switch_rtp_packet_t *packet; - uint32_t len; - uint16_t seq = ntohs(jb->target_seq); - - /* When using a Codec that provides voice activity detection ex. Opus, use it to - select packet to drop/accelerate. */ - - if (jb->elastic && jb->jitter.estimate && (jb->visible_nodes*jb->jitter.samples_per_frame)>0 && jb->jitter.samples_per_second) { - int visible_not_old = check_jb_size(jb); - jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate)/((jb->jitter.samples_per_second))*1000); - jb->jitter.stats.buffer_size_ms = (int)((visible_not_old*jb->jitter.samples_per_frame)/(jb->jitter.samples_per_second/1000)); - - // We try to accelerate in order to remove delay when the jitter buffer is 3x larger than the estimation. - if (jb->jitter.stats.buffer_size_ms > (3*jb->jitter.stats.estimate_ms) && jb->jitter.stats.buffer_size_ms > 60) { - if (status == SWITCH_STATUS_SUCCESS) { - packet = &(*nodep)->packet; - seq = ntohs((*nodep)->packet.header.seq); - len = (*nodep)->len; - } - if (jb->jitter.drop_gap > 0) { - jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-gap][%d]\n", - jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq, jb->jitter.drop_gap); - jb->jitter.drop_gap--; - } else { - if (status != SWITCH_STATUS_SUCCESS || packet_vad(jb, packet, len) == SWITCH_FALSE) { - jb->jitter.drop_gap = 3; - if (status != SWITCH_STATUS_SUCCESS) { - jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation n/a buffersize %d/%d %dms seq:%u [drop-missing/no-plc]\n", - jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq); - } else { - jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u ACCELERATE [drop]\n", - jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq); - } - jb->jitter.stats.acceleration++; - return jb_next_packet_by_seq(jb, nodep); - } else { - jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-skip-vad]\n", - jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms, seq); - } - } - } else { - jb_debug(jb, 2, "JITTER estimation %dms buffersize %d/%d %dms\n", - jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms); - } - } - return status; -} - static inline switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep) { if (jb->samples_per_frame) { return jb_next_packet_by_ts(jb, nodep); } else { - switch_status_t status; - if (jb->elastic && jb->jitter.estimate) { - status = jb_next_packet_by_seq_with_acceleration(jb, nodep); - } else { - status = jb_next_packet_by_seq(jb, nodep); - } - return status; + return jb_next_packet_by_seq(jb, nodep); } } @@ -1052,50 +877,13 @@ SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_fra switch_core_inthash_init(&jb->node_hash_ts); } -SWITCH_DECLARE(void) switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second) -{ - if (jb && jitter) { - memset(&jb->jitter,0,sizeof(switch_jb_jitter_t)); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_max_ms", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_ms", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_ms", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", 0); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", 0); - jb->jitter.estimate = jitter; - jb->jitter.samples_per_frame = samples_per_frame; - jb->jitter.samples_per_second = samples_per_second; - jb->jitter.drop_gap = 5; - } -} - SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session) { const char *var; if (session) { - jb->codec = switch_core_session_get_read_codec(session); jb->session = session; jb->channel = switch_core_session_get_channel(session); - if (!strcmp(jb->codec->implementation->iananame, "opus")) { - if (switch_true(switch_channel_get_variable(jb->channel, "rtp_jitter_buffer_accelerate"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate on\n", jb->codec->implementation->iananame); - jb->elastic = SWITCH_TRUE; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate off\n", jb->codec->implementation->iananame); - jb->elastic = SWITCH_FALSE; - } - - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec not opus: %s\n", jb->codec->implementation->iananame); - jb->elastic = SWITCH_FALSE; - } - if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) && (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) { int tmp = atoi(var); @@ -1144,12 +932,6 @@ SWITCH_DECLARE(void) switch_jb_debug_level(switch_jb_t *jb, uint8_t level) SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb) { - jb->jitter.stats.reset++; - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", jb->jitter.stats.reset); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", jb->jitter.stats.reset_too_big); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", jb->jitter.stats.reset_missing_frames); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", jb->jitter.stats.reset_ts_jump); - switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", jb->jitter.stats.reset_error); if (jb->type == SJB_VIDEO) { switch_mutex_lock(jb->mutex); @@ -1475,7 +1257,6 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp if (got > want) { if (got - want > jb->max_frame_len && got - want > 17) { jb_debug(jb, 2, "Missing %u frames, Resetting\n", got - want); - jb->jitter.stats.reset_missing_frames++; switch_jb_reset(jb); } else { @@ -1653,7 +1434,6 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp switch(status) { case SWITCH_STATUS_RESTART: jb_debug(jb, 2, "%s", "Error encountered\n"); - jb->jitter.stats.reset_error++; switch_jb_reset(jb); switch_goto_status(SWITCH_STATUS_RESTART, end); case SWITCH_STATUS_NOTFOUND: @@ -1664,22 +1444,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp jb_debug(jb, 2, "%s", "Too many frames not found, RESIZE\n"); switch_goto_status(SWITCH_STATUS_RESTART, end); } else { - if (jb->elastic) { - int visible_not_old = check_jb_size(jb); - jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate)/((jb->jitter.samples_per_second))*1000); - jb->jitter.stats.buffer_size_ms = (int)((visible_not_old*jb->jitter.samples_per_frame)/(jb->jitter.samples_per_second/1000)); - /* When playing PLC, we take the oportunity to expand the buffer if the jitter buffer is smaller than the 3x the estimated jitter. */ - if (jb->jitter.stats.buffer_size_ms < (3*jb->jitter.stats.estimate_ms)) { - jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc]\n", - jb->jitter.stats.estimate_ms, jb->complete_frames , jb->frame_len, jb->jitter.stats.buffer_size_ms); - jb->jitter.stats.expand++; - decrement_seq(jb); - } else { - jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); - } - } else { - jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); - } + jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); plc = 1; switch_goto_status(SWITCH_STATUS_NOTFOUND, end); } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index fe97840cc7..4aa68061ab 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4676,7 +4676,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * READ_INC(rtp_session); status = switch_jb_create(&rtp_session->jb, SJB_AUDIO, queue_frames, max_queue_frames, rtp_session->pool); switch_jb_set_session(rtp_session->jb, rtp_session->session); - switch_jb_set_jitter_estimator(rtp_session->jb, &rtp_session->stats.rtcp.inter_jitter, samples_per_packet, samples_per_second); if (switch_true(switch_channel_get_variable_dup(switch_core_session_get_channel(rtp_session->session), "jb_use_timestamps", SWITCH_FALSE, -1))) { switch_jb_ts_mode(rtp_session->jb, samples_per_packet, samples_per_second); } From 7c1faeff48aef815b4cc5f22eb9ead52726dbd95 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 2 Jun 2023 21:58:41 +0300 Subject: [PATCH 049/205] [Build-System] Update libks and signalwire-c requirements to 2.0 --- configure.ac | 34 ++++++++++++++++----------- debian/control-modules | 2 +- freeswitch.spec | 2 +- w32/libks-version.props | 2 +- w32/libks.props | 12 +++++----- w32/signalwire-client-c-version.props | 2 +- w32/signalwire-client-c.props | 6 ++--- 7 files changed, 33 insertions(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index 04738e93c1..8a8bb102a7 100644 --- a/configure.ac +++ b/configure.ac @@ -1518,26 +1518,32 @@ PKG_CHECK_MODULES([V8FS_STATIC], [v8-6.1_static >= 6.1.298],[ ]) ]) -PKG_CHECK_MODULES([KS], [libks >= 1.8.2],[ +PKG_CHECK_MODULES([KS], [libks2 >= 2.0.0],[ AM_CONDITIONAL([HAVE_KS],[true])],[ - if module_enabled mod_verto; then - AC_MSG_ERROR([You need to either install libks or disable mod_verto in modules.conf]) - else - if module_enabled mod_signalwire; then - AC_MSG_ERROR([You need to either install libks or disable mod_signalwire in modules.conf]) + PKG_CHECK_MODULES([KS], [libks >= 1.8.2],[ + AM_CONDITIONAL([HAVE_KS],[true])],[ + if module_enabled mod_verto; then + AC_MSG_ERROR([You need to either install libks2 or libks or disable mod_verto in modules.conf]) else - AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_KS],[false]) + if module_enabled mod_signalwire; then + AC_MSG_ERROR([You need to either install libks2 or libks or disable mod_signalwire in modules.conf]) + else + AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_KS],[false]) + fi fi - fi + ]) ]) -PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client >= 1.0.0],[ +PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client2 >= 2.0.0],[ AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[ - if module_enabled mod_signalwire; then - AC_MSG_ERROR([You need to either install signalwire-client-c or disable mod_signalwire in modules.conf]) - else - AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[false]) - fi + PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client >= 1.0.0],[ + AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[ + if module_enabled mod_signalwire; then + AC_MSG_ERROR([You need to either install signalwire-client-c2 or signalwire-client-c or disable mod_signalwire in modules.conf]) + else + AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[false]) + fi + ]) ]) PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[ diff --git a/debian/control-modules b/debian/control-modules index b9d7a05933..a578ad3ff3 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -209,7 +209,7 @@ Description: Adds mod_skel Module: applications/mod_signalwire Description: mod_signalwire Adds mod_signalwire. -Build-Depends: libks, signalwire-client-c +Build-Depends: libks2, signalwire-client-c2 Module: applications/mod_sms Description: Astract SMS diff --git a/freeswitch.spec b/freeswitch.spec index 1d985cc299..ecf9dacf13 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -497,7 +497,7 @@ the entries aloud via a TTS engine Summary: FreeSWITCH mod_signalwire Group: System/Libraries Requires: %{name} = %{version}-%{release} -BuildRequires: libks signalwire-client-c +BuildRequires: libks2 signalwire-client-c2 %description application-signalwire Provides FreeSWITCH mod_signalwire diff --git a/w32/libks-version.props b/w32/libks-version.props index 44246b4d90..9e013ef808 100644 --- a/w32/libks-version.props +++ b/w32/libks-version.props @@ -4,7 +4,7 @@ - 1.8.2 + 2.0.0 1 diff --git a/w32/libks.props b/w32/libks.props index fb7a82f200..df0b9721f3 100644 --- a/w32/libks.props +++ b/w32/libks.props @@ -37,7 +37,7 @@ - @@ -67,12 +67,12 @@ - $(libksDir)\src\include;$(libksDir)\src\include\libks;%(AdditionalIncludeDirectories) - __PRETTY_FUNCTION__=__FUNCSIG__;WIN32;_WINDOWS;SWCLT_VERSION_MAJOR=1;SWCLT_VERSION_MINOR=0;SWCLT_VERSION_REVISION=0;_WIN32_WINNT=0x0600;_WINSOCK_DEPRECATED_NO_WARNINGS=1;WIN32_LEAN_AND_MEAN=1;KS_PLAT_WIN=1;NOMAXMIN=1;_CRT_SECURE_NO_WARNINGS=1;SWCLT_EXPORTS;%(PreprocessorDefinitions) + $(libksDir)\libks\src\include;$(libksDir)\libks\src\include\libks;%(AdditionalIncludeDirectories) + __KS_FUNC__=__FUNCSIG__;WIN32;_WINDOWS;SWCLT_VERSION_MAJOR=1;SWCLT_VERSION_MINOR=0;SWCLT_VERSION_REVISION=0;_WIN32_WINNT=0x0600;_WINSOCK_DEPRECATED_NO_WARNINGS=1;WIN32_LEAN_AND_MEAN=1;KS_PLAT_WIN=1;NOMAXMIN=1;_CRT_SECURE_NO_WARNINGS=1;SWCLT_EXPORTS;%(PreprocessorDefinitions) $(libksDir)\binaries\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) - ks.lib;%(AdditionalDependencies) + ks2.lib;%(AdditionalDependencies) diff --git a/w32/signalwire-client-c-version.props b/w32/signalwire-client-c-version.props index 337dc4cc19..db6eb873cb 100644 --- a/w32/signalwire-client-c-version.props +++ b/w32/signalwire-client-c-version.props @@ -4,7 +4,7 @@ - 1.3.2 + 2.0.0 1 diff --git a/w32/signalwire-client-c.props b/w32/signalwire-client-c.props index 4d5f917b7e..df82dff00e 100644 --- a/w32/signalwire-client-c.props +++ b/w32/signalwire-client-c.props @@ -35,7 +35,7 @@
- @@ -70,7 +70,7 @@ $(signalwire-client-cDir)\binaries\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) - signalwire_client.lib;%(AdditionalDependencies) + signalwire_client2.lib;%(AdditionalDependencies) From fdce50e420b9946125f9ddd3a48ad14b684f6ee4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 16 Jul 2023 21:20:56 +0300 Subject: [PATCH 050/205] [Core] Fix missing MEDIA_PARAMS in message_names. --- src/switch_core_session.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index a103a6e964..61aa500070 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -799,6 +799,7 @@ static const char *message_names[] = { "DEFLECT", "VIDEO_REFRESH_REQ", "DISPLAY", + "MEDIA_PARAMS", "TRANSCODING_NECESSARY", "AUDIO_SYNC", "VIDEO_SYNC", From 667783831bdc09d847f31510032901518a5fba9c Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Mon, 17 Jul 2023 15:36:27 +0000 Subject: [PATCH 051/205] [mod_av] Migrate to FFmpeg 5.1 --- src/mod/applications/mod_av/avcodec.c | 168 ++++- src/mod/applications/mod_av/avformat.c | 911 ++++++++++++++++++++----- src/mod/applications/mod_av/mod_av.c | 3 + src/mod/applications/mod_av/mod_av.h | 5 + 4 files changed, 872 insertions(+), 215 deletions(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 94cc9b36bf..d84362eb28 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -26,6 +26,7 @@ * Seven Du * Anthony Minessale * Emmanuel Schmidbauer + * Jakub Karolczyk * * mod_avcodec -- Codec with libav.org and ffmpeg * @@ -373,8 +374,13 @@ typedef struct our_h264_nalu_s { typedef struct h264_codec_context_s { switch_buffer_t *nalu_buffer; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) AVCodec *decoder; AVCodec *encoder; +#else + const AVCodec *decoder; + const AVCodec *encoder; +#endif AVCodecContext *decoder_ctx; int got_pps; /* if pps packet received */ int64_t pts; @@ -393,7 +399,7 @@ typedef struct h264_codec_context_s { switch_codec_settings_t codec_settings; AVCodecContext *encoder_ctx; AVFrame *encoder_avframe; - AVPacket encoder_avpacket; + AVPacket *encoder_avpacket; AVFrame *decoder_avframe; our_h264_nalu_t nalus[MAX_NALUS]; enum AVCodecID av_codec_id; @@ -826,7 +832,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p const uint8_t *p = buf; const uint8_t *buf_base = buf; uint32_t code = (ntohl(*(uint32_t *)buf) & 0xFFFFFC00) >> 10; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) int mb_info_size = 0; +#else + switch_size_t mb_info_size = 0; +#endif int mb_info_pos = 0, mb_info_count = 0; const uint8_t *mb_info; @@ -890,7 +900,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p "Unable to split H263 packet! mb_info_pos=%d mb_info_count=%d pos=%d max=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, pos, (switch_size_t)(end - buf_base)); } } else { +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size); +#else + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%ld\n", mb_info_pos, mb_info_count, mb_info_size); +#endif } } } @@ -1034,7 +1048,7 @@ static switch_status_t consume_h263_bitstream(h264_codec_context_t *context, swi } if (!context->nalus[context->nalu_current_index].len) { - av_packet_unref(&context->encoder_avpacket); + av_packet_unref(context->encoder_avpacket); frame->m = 1; } @@ -1082,7 +1096,7 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw #endif if (frame->m) { - av_packet_unref(&context->encoder_avpacket); + av_packet_unref(context->encoder_avpacket); return SWITCH_STATUS_SUCCESS; } @@ -1091,7 +1105,7 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame) { - AVPacket *pkt = &context->encoder_avpacket; + AVPacket *pkt = context->encoder_avpacket; our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index]; if (!nalu->len) { @@ -1291,9 +1305,7 @@ FF_ENABLE_DEPRECATION_WARNINGS set_h264_private_data(context, aprofile); } -GCC_DIAG_OFF(deprecated-declarations) avcodec_string(codec_string, sizeof(codec_string), context->encoder_ctx, 0); -GCC_DIAG_ON(deprecated-declarations) dump_encoder_ctx(context->encoder_ctx); @@ -1393,6 +1405,8 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag break; } + context->encoder_avpacket = av_packet_alloc(); + switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0); codec->private_info = context; @@ -1417,7 +1431,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t int ret; int *got_output = &context->got_encoded_output; AVFrame *avframe = NULL; - AVPacket *pkt = &context->encoder_avpacket; + AVPacket **pkt = &context->encoder_avpacket; uint32_t width = 0; uint32_t height = 0; switch_image_t *img = frame->img; @@ -1440,8 +1454,8 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t if (context->packetizer) { switch_status_t status = switch_packetizer_read(context->packetizer, frame); - if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) { - av_packet_unref(pkt); + if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) { + av_packet_unref(*pkt); } return status; @@ -1456,6 +1470,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) { goto error; } + avctx = context->encoder_ctx; } @@ -1465,6 +1480,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) { goto error; } + avctx = context->encoder_ctx; } @@ -1474,15 +1490,13 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) { goto error; } + avctx = context->encoder_ctx; switch_set_flag(frame, SFF_WAIT_KEY_FRAME); } -GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(pkt); -GCC_DIAG_ON(deprecated-declarations) - pkt->data = NULL; // packet data will be allocated by the encoder - pkt->size = 0; + av_packet_unref(*pkt); + /* packet data will be allocated by the encoder */ avframe = context->encoder_avframe; @@ -1547,14 +1561,42 @@ GCC_DIAG_ON(deprecated-declarations) /* encode the image */ memset(context->nalus, 0, sizeof(context->nalus)); context->nalu_current_index = 0; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) GCC_DIAG_OFF(deprecated-declarations) - ret = avcodec_encode_video2(avctx, pkt, avframe, got_output); + ret = avcodec_encode_video2(avctx, *pkt, avframe, got_output); GCC_DIAG_ON(deprecated-declarations) if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding Error %d\n", ret); goto error; } +#else + ret = avcodec_send_frame(avctx, avframe); + + if (ret == AVERROR_EOF) { + ret = 0; + } else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each encode call, so this should not ever happen */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder - BUG, should never happen\n"); + ret = AVERROR_BUG; + goto error; + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending frame to encoder\n"); + goto error; + } + + while (ret >= 0) { + ret = avcodec_receive_packet(avctx, *pkt); + if (ret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at the moment\n"); + } else if (ret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at all\n"); + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error\n"); + av_packet_unref(*pkt); + goto error; + } +#endif if (context->need_key_frame && avframe->key_frame == 1) { avframe->pict_type = 0; @@ -1564,7 +1606,11 @@ GCC_DIAG_ON(deprecated-declarations) // process: +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) if (*got_output) { +#else + if (ret >= 0) { +#endif switch_status_t status = SWITCH_STATUS_SUCCESS; *got_output = 0; @@ -1572,56 +1618,66 @@ GCC_DIAG_ON(deprecated-declarations) if (context->av_codec_id == AV_CODEC_ID_H263) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5, "Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n", - context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)), - *((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices); + context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)), + *((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices); #ifdef H263_MODE_B - fs_rtp_parse_h263_rfc2190(context, pkt); + fs_rtp_parse_h263_rfc2190(context, *pkt); #endif context->nalu_current_index = 0; + return consume_nalu(context, frame); } else if (context->av_codec_id == AV_CODEC_ID_H263P){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5, "Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n", - context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)), - *((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices); - fs_rtp_parse_h263_rfc4629(context, pkt); + context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)), + *((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices); + fs_rtp_parse_h263_rfc4629(context, *pkt); context->nalu_current_index = 0; + return consume_nalu(context, frame); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5, "Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) nalu_type=0x%x %d\n", - context->pts, pkt->size, *((uint8_t *)pkt->data +4), *got_output); + context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data +4), *got_output); } - status = switch_packetizer_feed(context->packetizer, pkt->data, pkt->size); + status = switch_packetizer_feed(context->packetizer, (*pkt)->data, (*pkt)->size); if (status != SWITCH_STATUS_SUCCESS) { - if (pkt->size > 0) { - av_packet_unref(pkt); + if ((*pkt)->size > 0) { + av_packet_unref(*pkt); } return status; } status = switch_packetizer_read(context->packetizer, frame); - if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) { - av_packet_unref(pkt); + if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) { + av_packet_unref(*pkt); } return status; } +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + break; + } +#endif + error: frame->datalen = 0; + return SWITCH_STATUS_FALSE; } static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t *frame) { h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info; - AVCodecContext *avctx= context->decoder_ctx; switch_status_t status; +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + int ret = 0; +#endif switch_assert(frame); @@ -1654,29 +1710,57 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t if (frame->m) { uint32_t size = switch_buffer_inuse(context->nalu_buffer); - AVPacket pkt = { 0 }; + AVPacket *pkt = NULL; AVFrame *picture; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) int got_picture = 0; int decoded_len; +#endif if (size > 0) { -GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(&pkt); -GCC_DIAG_ON(deprecated-declarations) + pkt = av_packet_alloc(); switch_buffer_zero_fill(context->nalu_buffer, AV_INPUT_BUFFER_PADDING_SIZE); - switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt.data); - pkt.size = size; + switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt->data); + pkt->size = size; if (!context->decoder_avframe) context->decoder_avframe = av_frame_alloc(); picture = context->decoder_avframe; switch_assert(picture); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) GCC_DIAG_OFF(deprecated-declarations) - decoded_len = avcodec_decode_video2(avctx, picture, &got_picture, &pkt); + decoded_len = avcodec_decode_video2(context->decoder_ctx, picture, &got_picture, pkt); GCC_DIAG_ON(deprecated-declarations) +#else + ret = avcodec_send_packet(context->decoder_ctx, pkt); + + if (ret == AVERROR_EOF) { + ret = 0; + } else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not ever happen */ + ret = AVERROR_BUG; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder BUG, should never happen\n"); + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder\n"); + } + + while (ret >= 0) { + ret = avcodec_receive_frame(context->decoder_ctx, picture); + if (ret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at the moment\n"); + } else if (ret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at all\n"); + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video decoding error\n"); + } +#endif // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer: %d got pic: %d len: %d [%dx%d]\n", size, got_picture, decoded_len, picture->width, picture->height); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) if (got_picture && decoded_len > 0) { +#else + if (ret >= 0) { +#endif int width = picture->width; int height = picture->height; @@ -1698,7 +1782,15 @@ GCC_DIAG_ON(deprecated-declarations) frame->img = context->img; } +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + if (ret < 0) { + break; + } + } +#endif + av_frame_unref(picture); + av_packet_free(&pkt); } switch_buffer_zero(context->nalu_buffer); @@ -1791,6 +1883,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec) av_frame_free(&context->decoder_avframe); } + if (context->encoder_avpacket) { + av_packet_free(&context->encoder_avpacket); + } + return SWITCH_STATUS_SUCCESS; } @@ -1818,8 +1914,10 @@ static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev, #endif if (prev->id == id && (encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev))) + return prev; } + return NULL; } diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index d17f4eac39..624af8f4ea 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -25,6 +25,7 @@ * * Seven Du * Anthony Minessale + * Jakub Karolczyk * * mod_avformat -- File Formats with libav.org * @@ -88,7 +89,9 @@ typedef struct MediaStream { AVStream *st; AVFrame *frame; AVFrame *tmp_frame; - +#if (LIBAVFORMAT_VERSION_MAJOR >= LIBAVFORMAT_V) + AVCodecContext *codec; +#endif // audio int channels; int sample_rate; @@ -137,8 +140,13 @@ struct av_file_context { MediaStream video_st; MediaStream audio_st[2]; AVFormatContext *fc; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) AVCodec *audio_codec; AVCodec *video_codec; +#else + const AVCodec *audio_codec; + const AVCodec *video_codec; +#endif enum AVColorSpace colorspace; int has_audio; @@ -220,9 +228,57 @@ static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb static switch_status_t av_file_close(switch_file_handle_t *handle); SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load); +static inline AVCodecContext *av_get_codec_context(MediaStream *stream) +{ + AVCodecContext *c = NULL; + +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) +GCC_DIAG_OFF(deprecated-declarations) + if (stream->st) { + c = stream->st->codec; + } +GCC_DIAG_ON(deprecated-declarations) +#else + c = stream->codec; +#endif + + return c; +} + +static inline enum AVCodecID av_get_codec_id(AVStream *av_stream) +{ + if (!av_stream) { + return AV_CODEC_ID_NONE; + } + +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) +GCC_DIAG_OFF(deprecated-declarations) + return av_stream->codec->codec_id; +GCC_DIAG_ON(deprecated-declarations) +#else + return av_stream->codecpar->codec_id; +#endif +} + +static inline enum AVMediaType av_get_codec_type(AVStream *av_stream) +{ + if (!av_stream) { + return AVMEDIA_TYPE_UNKNOWN; + } + +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) +GCC_DIAG_OFF(deprecated-declarations) + return av_stream->codec->codec_type; +GCC_DIAG_ON(deprecated-declarations) +#else + return av_stream->codecpar->codec_type; +#endif +} + static char *const get_error_text(const int error, char *error_buffer, switch_size_t error_buflen) { av_strerror(error, error_buffer, error_buflen); + return error_buffer; } @@ -354,18 +410,24 @@ static int interrupt_cb(void *cp) } -static int mod_avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, - const char *format, const char *filename, av_file_context_t *context) +static int mod_avformat_alloc_output_context2(AVFormatContext **avctx, const char *format, const char *filename, av_file_context_t *context) { AVFormatContext *s = avformat_alloc_context(); int ret = 0; +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) + AVOutputFormat *oformat = NULL; +#else + const AVOutputFormat *oformat = NULL; +#endif + s->interrupt_callback.callback = interrupt_cb; s->interrupt_callback.opaque = context; - + *avctx = NULL; - if (!s) + if (!s) { goto nomem; + } if (!oformat) { if (format) { @@ -389,14 +451,17 @@ static int mod_avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputF s->oformat = oformat; if (s->oformat->priv_data_size > 0) { s->priv_data = av_mallocz(s->oformat->priv_data_size); - if (!s->priv_data) + if (!s->priv_data) { goto nomem; + } + if (s->oformat->priv_class) { *(const AVClass**)s->priv_data= s->oformat->priv_class; av_opt_set_defaults(s->priv_data); } - } else + } else { s->priv_data = NULL; + } if (filename) { #if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,7,100)) @@ -408,12 +473,14 @@ static int mod_avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputF } *avctx = s; + return 0; nomem: av_log(s, AV_LOG_ERROR, "Out of memory\n"); ret = AVERROR(ENOMEM); error: avformat_free_context(s); + return ret; } @@ -429,9 +496,13 @@ static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AV } /* Add an output stream. */ +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) static switch_status_t add_stream(av_file_context_t *context, MediaStream *mst, AVFormatContext *fc, AVCodec **codec, enum AVCodecID codec_id, switch_mm_t *mm) +#else +static switch_status_t add_stream(av_file_context_t *context, MediaStream *mst, AVFormatContext *fc, const AVCodec **codec, enum AVCodecID codec_id, switch_mm_t *mm) +#endif { - AVCodecContext *c; + AVCodecContext *c = NULL; switch_status_t status = SWITCH_STATUS_FALSE; //int threads = switch_core_cpu_count(); int buffer_bytes = 2097152; /* 2 mb */ @@ -457,9 +528,19 @@ static switch_status_t add_stream(av_file_context_t *context, MediaStream *mst, return status; } mst->st->id = fc->nb_streams - 1; -GCC_DIAG_OFF(deprecated-declarations) - c = mst->st->codec; -GCC_DIAG_ON(deprecated-declarations) + +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + mst->codec = avcodec_alloc_context3(*codec); + + if (!mst->codec) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate codec context\n"); + + return status; + } +#endif + + c = av_get_codec_context(mst); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "id:%d den:%d num:%d\n", mst->st->id, mst->st->time_base.den, mst->st->time_base.num); //if (threads > 4) { @@ -471,8 +552,12 @@ GCC_DIAG_ON(deprecated-declarations) c->sample_fmt = (*codec)->sample_fmts ? (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP; c->bit_rate = 128000; c->sample_rate = mst->sample_rate = context->handle->samplerate; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) c->channels = mst->channels; c->channel_layout = av_get_default_channel_layout(c->channels); +#else + av_channel_layout_default(&c->ch_layout, mst->channels); +#endif if (mm) { if (mm->ab) { @@ -651,23 +736,28 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height) return picture; } +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) static switch_status_t open_video(AVFormatContext *fc, AVCodec *codec, MediaStream *mst) +#else +static switch_status_t open_video(AVFormatContext *fc, const AVCodec *codec, MediaStream *mst) +#endif { int ret; -GCC_DIAG_OFF(deprecated-declarations) - AVCodecContext *c = mst->st->codec; -GCC_DIAG_ON(deprecated-declarations) + AVCodecContext *c = NULL; switch_status_t status = SWITCH_STATUS_FALSE; //int threads = switch_core_cpu_count(); // if (threads > 4) threads = 4; // c->thread_count = threads; + c = av_get_codec_context(mst); + /* open the codec */ ret = avcodec_open2(c, codec, NULL); if (ret < 0) { char ebuf[255] = ""; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open video codec: %s\n", get_error_text(ret, ebuf, sizeof(ebuf))); + return status; } @@ -679,17 +769,29 @@ GCC_DIAG_ON(deprecated-declarations) // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pix_fmt: %d\n", c->pix_fmt); switch_assert(c->pix_fmt == AV_PIX_FMT_YUV420P); // always I420 for NOW +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + if (((ret = avcodec_parameters_from_context(mst->st->codecpar, mst->codec)) < 0)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not copy to codec params ret=%d\n", ret); + + return SWITCH_STATUS_FALSE; + } +#endif + return SWITCH_STATUS_SUCCESS; } +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) static switch_status_t open_audio(AVFormatContext *fc, AVCodec *codec, MediaStream *mst) +#else +static switch_status_t open_audio(AVFormatContext *fc, const AVCodec *codec, MediaStream *mst) +#endif { - AVCodecContext *c; + AVCodecContext *c = NULL; int ret; switch_status_t status = SWITCH_STATUS_FALSE; -GCC_DIAG_OFF(deprecated-declarations) - c = mst->st->codec; -GCC_DIAG_ON(deprecated-declarations) + + c = av_get_codec_context(mst); + ret = avcodec_open2(c, codec, NULL); if (ret == AVERROR_EXPERIMENTAL) { @@ -711,11 +813,19 @@ GCC_DIAG_ON(deprecated-declarations) mst->frame->sample_rate = c->sample_rate; mst->frame->format = AV_SAMPLE_FMT_S16; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) mst->frame->channel_layout = c->channel_layout; +#else + mst->frame->ch_layout = c->ch_layout; +#endif if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) { //mst->frame->nb_samples = 10000; - mst->frame->nb_samples = (mst->frame->sample_rate / 50) * c->channels; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + mst->frame->nb_samples = (mst->frame->sample_rate / 50) * c->channels; +#else + mst->frame->nb_samples = (mst->frame->sample_rate / 50) * c->ch_layout.nb_channels; +#endif } else { mst->frame->nb_samples = c->frame_size; } @@ -733,19 +843,33 @@ GCC_DIAG_ON(deprecated-declarations) } /* set options */ +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59,27,100)) /* FFmpeg 5.0 */ av_opt_set_int(mst->resample_ctx, "in_channel_count", c->channels, 0); +#else /* FFmpeg 5.1 */ + av_opt_set_chlayout(mst->resample_ctx, "in_chlayout", &c->ch_layout, 0); +#endif av_opt_set_int(mst->resample_ctx, "in_sample_rate", c->sample_rate, 0); +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59,27,100)) av_opt_set_int(mst->resample_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(mst->resample_ctx, "in_channel_layout", c->channel_layout, 0); av_opt_set_int(mst->resample_ctx, "out_channel_count", c->channels, 0); +#else + av_opt_set_sample_fmt(mst->resample_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); + av_opt_set_chlayout(mst->resample_ctx, "out_chlayout", &c->ch_layout, 0); +#endif av_opt_set_int(mst->resample_ctx, "out_sample_rate", c->sample_rate, 0); +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59,27,100)) av_opt_set_int(mst->resample_ctx, "out_sample_fmt", c->sample_fmt, 0); av_opt_set_int(mst->resample_ctx, "out_channel_layout", c->channel_layout, 0); +#else + av_opt_set_sample_fmt(mst->resample_ctx, "out_sample_fmt", c->sample_fmt, 0); +#endif if (swr_init(mst->resample_ctx) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to initialize the resampling context\n"); av_free(mst->resample_ctx); mst->resample_ctx = NULL; + return status; } } @@ -753,6 +877,7 @@ GCC_DIAG_ON(deprecated-declarations) ret = av_frame_get_buffer(mst->frame, 0); if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate audio frame.\n"); + return status; } @@ -762,7 +887,11 @@ GCC_DIAG_ON(deprecated-declarations) mst->tmp_frame->sample_rate = c->sample_rate; mst->tmp_frame->format = c->sample_fmt; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) mst->tmp_frame->channel_layout = c->channel_layout; +#else + mst->tmp_frame->ch_layout = c->ch_layout; +#endif mst->tmp_frame->nb_samples = mst->frame->nb_samples; ret = av_frame_get_buffer(mst->tmp_frame, 0); @@ -772,6 +901,14 @@ GCC_DIAG_ON(deprecated-declarations) } } +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + if (((ret = avcodec_parameters_from_context(mst->st->codecpar, mst->codec)) < 0)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not copy to codec params ret=%d\n", ret); + + return SWITCH_STATUS_FALSE; + } +#endif + return SWITCH_STATUS_SUCCESS; } @@ -797,8 +934,7 @@ static void flush_video_pkt_queue(switch_queue_t *q) AVPacket *pkt; while (switch_queue_trypop(q, (void **)&pkt) == SWITCH_STATUS_SUCCESS) { - av_packet_unref(pkt); - free(pkt); + av_packet_free(&pkt); } } @@ -811,12 +947,16 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * int size = 0, skip = 0, skip_freq = 0, skip_count = 0, skip_total = 0, skip_total_count = 0; uint64_t delta_avg = 0, delta_sum = 0, delta_i = 0, delta = 0; int first = 1; + AVCodecContext *c = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video thread start\n"); - switch_assert(context->eh.video_queue); + switch_assert(context->eh.video_queue); + for(;;) { - AVPacket pkt = { 0 }; + AVPacket *pkt = NULL; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) int got_packet; +#endif int ret = -1; top: @@ -829,7 +969,7 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * switch_img_free(&tmp_img); } if (switch_queue_pop(context->eh.video_queue, &pop) == SWITCH_STATUS_SUCCESS) { - switch_img_free(&img); + switch_img_free(&img); if (!pop) { goto endfor; @@ -877,10 +1017,6 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * context->eh.in_callback = 1; -GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(&pkt); -GCC_DIAG_ON(deprecated-declarations) - if (context->eh.video_st->frame) { ret = av_frame_make_writable(context->eh.video_st->frame); } @@ -892,7 +1028,7 @@ GCC_DIAG_ON(deprecated-declarations) if (context->eh.record_timer_paused) { context->eh.last_ts = 0; continue; - } + } fill_avframe(context->eh.video_st->frame, img); @@ -939,61 +1075,149 @@ GCC_DIAG_ON(deprecated-declarations) } } + pkt = av_packet_alloc(); + context->eh.last_ts = context->eh.video_st->frame->pts; // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pts: %" SWITCH_INT64_T_FMT "\n", context->eh.video_st->frame->pts); /* encode the image */ + c = av_get_codec_context(context->eh.video_st); + +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) GCC_DIAG_OFF(deprecated-declarations) - ret = avcodec_encode_video2(context->eh.video_st->st->codec, &pkt, context->eh.video_st->frame, &got_packet); + ret = avcodec_encode_video2(c, pkt, context->eh.video_st->frame, &got_packet); GCC_DIAG_ON(deprecated-declarations) - + if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding Error %d\n", ret); + c = NULL; + av_packet_free(&pkt); continue; } if (got_packet) { +#else + ret = avcodec_send_frame(c, context->eh.video_st->frame); + + if (ret == AVERROR_EOF) { + ret = 0; + } else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each encode call, so this should not ever happen */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder AVERROR_BUG - should never happen\n"); + ret = AVERROR_BUG; + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder\n"); + } + + while (ret >= 0) { + ret = avcodec_receive_packet(c, pkt); + if (ret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at the moment\n"); + break; + } else if (ret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at all\n"); + break; + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error\n"); + break; + } +#endif + switch_mutex_lock(context->eh.mutex); -GCC_DIAG_OFF(deprecated-declarations) - write_frame(context->eh.fc, &context->eh.video_st->st->codec->time_base, context->eh.video_st->st, &pkt); -GCC_DIAG_ON(deprecated-declarations) + write_frame(context->eh.fc, &c->time_base, context->eh.video_st->st, pkt); switch_mutex_unlock(context->eh.mutex); - av_packet_unref(&pkt); } context->eh.in_callback = 0; + av_packet_free(&pkt); + c = NULL; //switch_mutex_unlock(context->eh.mutex); } endfor: for(;;) { - AVPacket pkt = { 0 }; - int got_packet = 0; + AVPacket *pkt = av_packet_alloc(); int ret = 0; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + int got_packet = 0; +#else + int wret = 0; +#endif + c = av_get_codec_context(context->eh.video_st); + +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(&pkt); -GCC_DIAG_ON(deprecated-declarations) - -GCC_DIAG_OFF(deprecated-declarations) - ret = avcodec_encode_video2(context->eh.video_st->st->codec, &pkt, NULL, &got_packet); + ret = avcodec_encode_video2(c, pkt, NULL, &got_packet); GCC_DIAG_ON(deprecated-declarations) if (ret < 0) { - break; + goto do_break; } else if (got_packet) { - switch_mutex_lock(context->eh.mutex); -GCC_DIAG_OFF(deprecated-declarations) - ret = write_frame(context->eh.fc, &context->eh.video_st->st->codec->time_base, context->eh.video_st->st, &pkt); -GCC_DIAG_ON(deprecated-declarations) - switch_mutex_unlock(context->eh.mutex); - av_packet_unref(&pkt); - if (ret < 0) break; - } else { +#else + ret = avcodec_send_frame(c, NULL); + + if (ret == AVERROR_EOF) { + ret = 0; + } else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each encode call, so this should not ever happen */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder on draining AVERROR_BUG - should never happen\n"); + ret = AVERROR_BUG; + goto do_break; + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder on draining\n"); + c = NULL; + goto do_break; + } + + while (ret >= 0) { + ret = avcodec_receive_packet(c, pkt); + if (ret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at the moment on draining\n"); + break; + } else if (ret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at all on draining \n"); + break; + } else if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error on draining\n"); break; } +#endif + switch_mutex_lock(context->eh.mutex); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + ret = write_frame(context->eh.fc, &c->time_base, context->eh.video_st->st, pkt); +#else + wret = write_frame(context->eh.fc, &c->time_base, context->eh.video_st->st, pkt); +#endif + switch_mutex_unlock(context->eh.mutex); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + if (ret < 0) { + goto do_break; + } + } else { + goto do_break; +#else + if (wret < 0) { + goto do_break; + } +#endif + } + + av_packet_free(&pkt); + c = NULL; + +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + if (ret < 0 && ret != AVERROR(EAGAIN)) { + break; + } +#endif + + continue; + do_break: + av_packet_free(&pkt); + break; } while(switch_queue_trypop(context->eh.video_queue, &pop) == SWITCH_STATUS_SUCCESS) { @@ -1010,6 +1234,8 @@ GCC_DIAG_ON(deprecated-declarations) static void close_stream(AVFormatContext *fc, MediaStream *mst) { + AVCodecContext *c = NULL; + if (!mst->active) return; if (mst->resample_ctx) swr_free(&mst->resample_ctx); @@ -1017,12 +1243,13 @@ static void close_stream(AVFormatContext *fc, MediaStream *mst) if (mst->frame) av_frame_free(&mst->frame); if (mst->tmp_frame) av_frame_free(&mst->tmp_frame); -GCC_DIAG_OFF(deprecated-declarations) - if (mst->st && mst->st->codec) { - avcodec_close(mst->st->codec); - } -GCC_DIAG_ON(deprecated-declarations) - + c = av_get_codec_context(mst); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + avcodec_close(c); +#else + /* avcodec_close() will be called in avcodec_free_context() */ + avcodec_free_context(&c); +#endif mst->active = 0; } @@ -1140,8 +1367,15 @@ static void mod_avformat_destroy_output_context(av_file_context_t *context) static switch_status_t open_input_file(av_file_context_t *context, switch_file_handle_t *handle, const char *filename) { +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) AVCodec *audio_codec = NULL; AVCodec *video_codec = NULL; +#else + const AVCodec *audio_codec = NULL; + const AVCodec *video_codec = NULL; +#endif + enum AVCodecID codec_id; + AVCodecContext *cc = NULL; AVDictionary *opts = NULL; int error; int i, idx = 0; @@ -1151,7 +1385,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h /** Open the input file to read from it. */ - if (!context->fc) { + if (!context->fc) { context->fc = avformat_alloc_context(); } @@ -1170,7 +1404,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h context->fc = NULL; switch_goto_status(SWITCH_STATUS_FALSE, err); } - + handle->seekable = context->fc->iformat->read_seek2 ? 1 : (context->fc->iformat->read_seek ? 1 : 0); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "file %s is %sseekable\n", filename, handle->seekable ? "" : "not "); @@ -1187,15 +1421,16 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h av_dump_format(context->fc, 0, filename, 0); for (i = 0; i< context->fc->nb_streams; i++) { -GCC_DIAG_OFF(deprecated-declarations) - if (context->fc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && context->has_audio < 2 && idx < 2) { + enum AVMediaType codec_type = av_get_codec_type(context->fc->streams[i]); + + if (codec_type == AVMEDIA_TYPE_AUDIO && context->has_audio < 2 && idx < 2) { context->audio_st[idx++].st = context->fc->streams[i]; context->has_audio++; - } else if (context->fc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !context->has_video) { -GCC_DIAG_ON(deprecated-declarations) + } else if (codec_type == AVMEDIA_TYPE_VIDEO && !context->has_video) { context->video_st.st = context->fc->streams[i]; if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { context->has_video = 1; +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) handle->duration = av_rescale_q(context->video_st.st->duration != AV_NOPTS_VALUE ? context->video_st.st->duration : context->fc->duration / AV_TIME_BASE * 1000, context->video_st.st->time_base, AV_TIME_BASE_Q); } @@ -1211,42 +1446,95 @@ GCC_DIAG_ON(deprecated-declarations) } context->read_fps = (int)handle->mm.source_fps; +#else + } +#endif } } /** Find a decoder for the audio stream. */ -GCC_DIAG_OFF(deprecated-declarations) - if (context->has_audio && !(audio_codec = avcodec_find_decoder(context->audio_st[0].st->codec->codec_id))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not find input codec %d\n", context->audio_st[0].st->codec->codec_id); + if (context->has_audio && !(audio_codec = avcodec_find_decoder((codec_id = av_get_codec_id(context->audio_st[0].st))))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not find input codec %d\n", codec_id); context->has_audio = 0; } - if (context->has_video && !(video_codec = avcodec_find_decoder(context->video_st.st->codec->codec_id))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find input codec %d\n", context->video_st.st->codec->codec_id); + if (context->has_video && !(video_codec = avcodec_find_decoder((codec_id = av_get_codec_id(context->video_st.st))))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find input codec %d\n", codec_id); context->has_video = 0; } - if (context->has_audio && (error = avcodec_open2(context->audio_st[0].st->codec, audio_codec, NULL)) < 0) { +#if (LIBAVFORMAT_VERSION_MAJOR >= LIBAVFORMAT_V) + if (context->has_audio == 2) { + context->audio_st[1].codec = avcodec_alloc_context3(audio_codec); + context->audio_st[0].codec = avcodec_alloc_context3(audio_codec); + } else if (context->has_audio) { + context->audio_st[0].codec = avcodec_alloc_context3(audio_codec); + } + + if (context->has_video) { + context->video_st.codec = avcodec_alloc_context3(video_codec); + } +#endif + + cc = av_get_codec_context(&context->audio_st[0]); +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) + if (context->has_audio && ((error = avcodec_open2(cc, audio_codec, NULL)) < 0)) { +#else + if (context->has_audio && (((error = avcodec_parameters_to_context(cc, context->audio_st[0].st->codecpar)) < 0) || ((error = avcodec_open2(cc, audio_codec, NULL)) < 0))) { +#endif char ebuf[255] = ""; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open input audio codec (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); context->has_audio = 0; } - if (context->has_audio == 2 && (error = avcodec_open2(context->audio_st[1].st->codec, audio_codec, NULL)) < 0) { + cc = av_get_codec_context(&context->audio_st[1]); +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) + if (context->has_audio == 2 && ((error = avcodec_open2(cc, audio_codec, NULL)) < 0)) { +#else + if (context->has_audio == 2 && (((error = avcodec_parameters_to_context(cc, context->audio_st[1].st->codecpar)) < 0) || ((error = avcodec_open2(cc, audio_codec, NULL)) < 0))) { +#endif char ebuf[255] = ""; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open input audio codec channel 2 (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); - if (context->audio_st[0].st->codec) { - avcodec_close(context->audio_st[0].st->codec); + if ((cc = av_get_codec_context(&context->audio_st[0]))) { + avcodec_close(cc); } + context->has_audio = 0; } - if (context->has_video && (error = avcodec_open2(context->video_st.st->codec, video_codec, NULL)) < 0) { + cc = av_get_codec_context(&context->video_st); + +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) + if (context->has_video && (error = avcodec_open2(cc, video_codec, NULL)) < 0) { +#else + if (context->has_video) { + if (((error = avcodec_parameters_to_context(cc, context->video_st.st->codecpar)) < 0) || ((error = avcodec_open2(cc, video_codec, NULL)) < 0)) { +#endif char ebuf[255] = ""; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open input codec (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); context->has_video = 0; } -GCC_DIAG_ON(deprecated-declarations) + +#if (LIBAVFORMAT_VERSION_MAJOR >= LIBAVFORMAT_V) + handle->duration = av_rescale_q(context->video_st.st->duration != AV_NOPTS_VALUE ? context->video_st.st->duration : context->fc->duration / AV_TIME_BASE * 1000, + context->video_st.st->time_base, AV_TIME_BASE_Q); + + if (context->fc->bit_rate) { + handle->mm.source_kps = context->fc->bit_rate / 1024; + } + + if (context->video_st.st->avg_frame_rate.num) { + handle->mm.source_fps = ceil(av_q2d(context->video_st.st->avg_frame_rate)); + } else { + handle->mm.source_fps = 25; + } + + context->read_fps = (int)handle->mm.source_fps; + + } +#endif context->video_st.active = 1; @@ -1258,16 +1546,14 @@ GCC_DIAG_ON(deprecated-declarations) } if (context->has_audio) { -GCC_DIAG_OFF(deprecated-declarations) AVCodecContext *c[2] = { NULL }; - c[0] = context->audio_st[0].st->codec; + c[0] = av_get_codec_context(&context->audio_st[0]); - if (context->audio_st[1].st && context->audio_st[1].st->codec) { - c[1] = context->audio_st[1].st->codec; + if ((cc = av_get_codec_context(&context->audio_st[1]))) { + c[1] = cc; } -GCC_DIAG_ON(deprecated-declarations) - + context->audio_st[0].frame = av_frame_alloc(); switch_assert(context->audio_st[0].frame); @@ -1282,33 +1568,49 @@ GCC_DIAG_ON(deprecated-declarations) context->audio_st[0].channels = 1; context->audio_st[1].channels = 1; } else { +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVFORMAT_V) handle->channels = c[0]->channels > 2 ? 2 : c[0]->channels; +#else + handle->channels = c[0]->ch_layout.nb_channels > 2 ? 2 : c[0]->ch_layout.nb_channels; +#endif context->audio_st[0].channels = handle->channels; } context->audio_st[0].sample_rate = handle->samplerate; context->audio_st[1].sample_rate = handle->samplerate; -GCC_DIAG_OFF(deprecated-declarations) - if (context->audio_st[0].st->codec->sample_fmt != AV_SAMPLE_FMT_S16 || context->audio_st[0].st->codec->sample_rate != handle->samplerate) { -GCC_DIAG_ON(deprecated-declarations) + if (c[0]->sample_fmt != AV_SAMPLE_FMT_S16 || c[0]->sample_rate != handle->samplerate) { int x; + for (x = 0; x < context->has_audio && x < 2 && c[x]; x++) { struct SwrContext *resample_ctx = swr_alloc(); if (resample_ctx) { int ret; - + +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59,27,100)) /* FFmpeg 5.0 */ av_opt_set_int(resample_ctx, "in_channel_count", c[x]->channels, 0); +#else /* FFmpeg 5.1 */ + av_opt_set_chlayout(resample_ctx, "in_chlayout", &c[x]->ch_layout, 0); +#endif av_opt_set_int(resample_ctx, "in_sample_rate", c[x]->sample_rate, 0); +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59,27,100)) av_opt_set_int(resample_ctx, "in_sample_fmt", c[x]->sample_fmt, 0); av_opt_set_int(resample_ctx, "in_channel_layout", (c[x]->channel_layout == 0 && c[x]->channels == 2) ? AV_CH_LAYOUT_STEREO : c[x]->channel_layout, 0); av_opt_set_int(resample_ctx, "out_channel_count", handle->channels, 0); +#else + av_opt_set_sample_fmt(resample_ctx, "in_sample_fmt", c[x]->sample_fmt, 0); + av_opt_set_chlayout(resample_ctx, "out_chlayout", &c[x]->ch_layout, 0); +#endif av_opt_set_int(resample_ctx, "out_sample_rate", handle->samplerate,0); +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59,27,100)) av_opt_set_int(resample_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(resample_ctx, "out_channel_layout", handle->channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO, 0); - +#else + av_opt_set_sample_fmt(resample_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); +#endif + if ((ret = swr_init(resample_ctx)) < 0) { char errbuf[1024]; av_strerror(ret, errbuf, 1024); @@ -1327,8 +1629,11 @@ GCC_DIAG_ON(deprecated-declarations) if (!context->has_video) { switch_clear_flag(handle, SWITCH_FILE_FLAG_VIDEO); } else { -GCC_DIAG_OFF(deprecated-declarations) - switch (context->video_st.st->codec->pix_fmt) { + if (!(cc = av_get_codec_context(&context->video_st))) { + goto err; + } + + switch (cc->pix_fmt) { case AV_PIX_FMT_YUVA420P: case AV_PIX_FMT_RGBA: case AV_PIX_FMT_ARGB: @@ -1339,8 +1644,7 @@ GCC_DIAG_OFF(deprecated-declarations) context->handle->mm.fmt = SWITCH_IMG_FMT_I420; break; } -GCC_DIAG_ON(deprecated-declarations) - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening file in mode: %s\n", context->handle->mm.fmt == SWITCH_IMG_FMT_ARGB ? "ARGB" : "I420"); } @@ -1372,12 +1676,20 @@ err: static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, void *obj) { av_file_context_t *context = (av_file_context_t *) obj; - AVPacket pkt = { 0 }; + AVPacket *pkt = NULL; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) int got_data = 0; +#else + int dret = -1; +#endif int error; int sync = 0; int eof = 0; - + AVCodecContext *c = NULL; +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + AVFrame *vframe = NULL; +#endif + switch_mutex_lock(context->mutex); context->file_read_thread_started = 1; context->file_read_thread_running = 1; @@ -1394,8 +1706,6 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo switch_buffer_zero(context->audio_buffer); switch_mutex_unlock(context->mutex); - - // if (context->has_audio) stream_id = context->audio_st.st->index; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "seeking to %" SWITCH_INT64_T_FMT "\n", context->seek_ts); avformat_seek_file(context->fc, stream_id, 0, context->seek_ts, INT64_MAX, 0); @@ -1406,10 +1716,12 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo context->video_st.next_pts = 0; context->video_start_time = 0; -GCC_DIAG_OFF(deprecated-declarations) - avcodec_flush_buffers(context->video_st.st->codec); -GCC_DIAG_ON(deprecated-declarations) - + if (!(c = av_get_codec_context(&context->video_st))) { + break; + } + + avcodec_flush_buffers(c); + while(switch_queue_trypop(context->eh.video_queue, &pop) == SWITCH_STATUS_SUCCESS) { switch_image_t *img; if (!pop) break; @@ -1429,23 +1741,18 @@ GCC_DIAG_ON(deprecated-declarations) continue; } + if (pkt) av_packet_free(&pkt); + pkt = av_packet_alloc(); - -GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(&pkt); -GCC_DIAG_ON(deprecated-declarations) - pkt.data = NULL; - pkt.size = 0; - - if ((error = av_read_frame(context->fc, &pkt)) < 0) { + if ((error = av_read_frame(context->fc, pkt)) < 0) { if (error == AVERROR_EOF) { if (!context->has_video) break; eof = 1; /* just make sure*/ - pkt.data = NULL; - pkt.size = 0; - pkt.stream_index = context->video_st.st->index; + pkt->data = NULL; + pkt->size = 0; + pkt->stream_index = context->video_st.st->index; } else { char ebuf[255] = ""; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not read frame (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); @@ -1454,8 +1761,11 @@ GCC_DIAG_ON(deprecated-declarations) } // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "stream: %d, pkt size %d\n", pkt.stream_index, pkt.size); - if (context->has_video && pkt.stream_index == context->video_st.st->index) { - AVFrame *vframe; + + if (context->has_video && pkt->stream_index == context->video_st.st->index) { +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + AVFrame *vframe = NULL; +#endif switch_image_t *img; if (context->no_video_decode) { @@ -1463,26 +1773,22 @@ GCC_DIAG_ON(deprecated-declarations) break; } else { switch_status_t status; - AVPacket *new_pkt = malloc(sizeof(AVPacket)); + AVPacket *new_pkt = av_packet_alloc(); if (0) { // debug - uint8_t *p = pkt.data; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %u %x %x %x %x %x %x\n", pkt.size, *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5)); + uint8_t *p = pkt->data; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %u %x %x %x %x %x %x\n", pkt->size, *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5)); } -GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(new_pkt); -GCC_DIAG_ON(deprecated-declarations) - av_packet_ref(new_pkt, &pkt); + av_packet_ref(new_pkt, pkt); status = switch_queue_push(context->video_pkt_queue, new_pkt); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %4u flag=%x pts=%" SWITCH_INT64_T_FMT " dts=%" SWITCH_INT64_T_FMT "\n", pkt.size, pkt.flags, pkt.pts, pkt.dts); context->vid_ready = 1; if (status != SWITCH_STATUS_SUCCESS) { - av_packet_unref(new_pkt); - free(new_pkt); + av_packet_free(&new_pkt); } - av_packet_unref(&pkt); + continue; } } @@ -1496,18 +1802,57 @@ again: vframe = av_frame_alloc(); switch_assert(vframe); + if (!(c = av_get_codec_context(&context->video_st))) { + break; + } + +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) GCC_DIAG_OFF(deprecated-declarations) - if ((error = avcodec_decode_video2(context->video_st.st->codec, vframe, &got_data, &pkt)) < 0) { + error = avcodec_decode_video2(c, vframe, &got_data, pkt); GCC_DIAG_ON(deprecated-declarations) +#else + if (eof) { + dret = avcodec_send_packet(c, NULL); + } else { + dret = avcodec_send_packet(c, pkt); + } + + if (dret == AVERROR_EOF) { + dret = 0; + } else if (dret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not ever happen */ + dret = AVERROR_BUG; + goto check_errors; + } else if (dret < 0) { + goto check_errors; + } + + while (dret >= 0) { + dret = avcodec_receive_frame(c, vframe); + if (dret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at the moment\n"); + } else if (dret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at all\n"); + } else if (dret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Video decoding error\n"); + } +#endif + +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + check_errors: + if (dret < 0 && dret != AVERROR(EAGAIN) && dret != AVERROR_EOF) { +#else + if (error < 0) { +#endif char ebuf[255] = ""; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not decode frame (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); - av_packet_unref(&pkt); av_frame_free(&vframe); continue; } // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pkt: %d, pts: %lld dts: %lld\n", pkt.size, pkt.pts, pkt.dts); - av_packet_unref(&pkt); + av_packet_unref(pkt); //if (switch_queue_size(context->eh.video_queue) > 300) { // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Dropping frames\n"); @@ -1516,7 +1861,11 @@ GCC_DIAG_ON(deprecated-declarations) //} // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got_data=%d, error=%d\n", got_data, error); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) if (got_data && error >= 0) { +#else + if (dret >= 0) { +#endif switch_img_fmt_t fmt = SWITCH_IMG_FMT_I420; if (( vframe->format == AV_PIX_FMT_YUVA420P || @@ -1538,7 +1887,7 @@ GCC_DIAG_ON(deprecated-declarations) if (!context->video_st.sws_ctx) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot init sws context\n"); av_frame_free(&frm); - continue; + goto do_continue; } } @@ -1549,9 +1898,11 @@ GCC_DIAG_ON(deprecated-declarations) vframe->width = frm->width; vframe->height = frm->height; vframe->pts = frm->pts; +#if (LIBAVUTIL_VERSION_MAJOR < LIBAVUTIL_V) GCC_DIAG_OFF(deprecated-declarations) vframe->pkt_pts = frm->pkt_pts; GCC_DIAG_ON(deprecated-declarations) +#endif vframe->pkt_dts = frm->pkt_dts; ret = av_frame_get_buffer(vframe, 32); @@ -1564,7 +1915,7 @@ GCC_DIAG_ON(deprecated-declarations) if (ret <= 0 ) { av_frame_free(&vframe); - continue; + goto do_continue; } } @@ -1580,9 +1931,13 @@ GCC_DIAG_ON(deprecated-declarations) int diff; int sleep = 66000; #endif +#if (LIBAVUTIL_VERSION_MAJOR < LIBAVUTIL_V) GCC_DIAG_OFF(deprecated-declarations) *pts = vframe->pkt_pts; GCC_DIAG_ON(deprecated-declarations) +#else + *pts = vframe->pts; +#endif avframe2img(vframe, img); img->user_priv = pts; @@ -1605,32 +1960,83 @@ GCC_DIAG_ON(deprecated-declarations) } } +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) av_frame_free(&vframe); +#endif if (eof) { +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) if (got_data) { +#else + if (dret != AVERROR_EOF) { +#endif +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) goto again; // to get all delayed video frames in decoder +#else + av_frame_free(&vframe); + goto again; // to get all delayed video frames in decoder +#endif } else { - break; + goto do_break; } } - continue; - } else if (context->has_audio && pkt.stream_index == context->audio_st[0].st->index) { + +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + } + + av_frame_free(&vframe); +#endif + goto do_continue; + } else if (context->has_audio && pkt->stream_index == context->audio_st[0].st->index) { AVFrame in_frame = { { 0 } }; -GCC_DIAG_OFF(deprecated-declarations) - if ((error = avcodec_decode_audio4(context->audio_st[0].st->codec, &in_frame, &got_data, &pkt)) < 0) { -GCC_DIAG_ON(deprecated-declarations) - char ebuf[255] = ""; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not decode frame (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); - av_packet_unref(&pkt); + if (!(c = av_get_codec_context(&context->audio_st[0]))) { continue; } - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pkt: %d, decodedddd: %d pts: %lld dts: %lld\n", pkt.size, error, pkt.pts, pkt.dts); - av_packet_unref(&pkt); +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) +GCC_DIAG_OFF(deprecated-declarations) + if ((error = avcodec_decode_audio4(c, &in_frame, &got_data, pkt)) < 0) { +GCC_DIAG_ON(deprecated-declarations) + char ebuf[255] = ""; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not decode frame (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); + continue; + } +#else + dret = avcodec_send_packet(c, pkt); + if (dret == AVERROR_EOF) { + dret = 0; + } else if (dret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not ever happen */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending audio packet to decoder - BUG, should never happen\n"); + dret = AVERROR_BUG; + goto do_continue; + } else if (dret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending audio packet to decoder\n"); + goto do_continue; + } + + while (dret >= 0) { + dret = avcodec_receive_frame(c, &in_frame); + if (dret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more audio frames at the moment\n"); + } else if (dret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more audio frames at all\n"); + } else if (dret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Video decoding error\n"); + goto do_continue; + } +#endif + + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pkt: %d, decodedddd: %d pts: %lld dts: %lld\n", pkt.size, error, pkt.pts, pkt.dts); + av_packet_unref(pkt); + +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) if (got_data) { +#else + if (dret >= 0) { +#endif // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got data frm->format: %d samples: %d\n", in_frame.format, in_frame.nb_samples); if (context->audio_st[0].resample_ctx) { @@ -1669,12 +2075,26 @@ GCC_DIAG_ON(deprecated-declarations) } } - - } else { - av_packet_unref(&pkt); +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + } } +#else + } else { + av_packet_unref(pkt); + } +#endif + + do_continue: + continue; + do_break: + break; } + av_packet_free(&pkt); +#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V) + av_frame_free(&vframe); +#endif + if (context->has_video) switch_queue_push(context->eh.video_queue, NULL); context->file_read_thread_running = 0; @@ -1687,7 +2107,13 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa av_file_context_t *context = NULL; char *ext; const char *tmp = NULL; +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) AVOutputFormat *fmt; +#else + const AVOutputFormat *fmt; + enum AVCodecID video_codec = AV_CODEC_ID_NONE; + enum AVCodecID audio_codec = AV_CODEC_ID_NONE; +#endif const char *format = NULL; int ret; char file[1024]; @@ -1805,18 +2231,28 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa return SWITCH_STATUS_SUCCESS; } - mod_avformat_alloc_output_context2(&context->fc, NULL, format, (char *)file, context); + mod_avformat_alloc_output_context2(&context->fc, format, (char *)file, context); if (!context->fc) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not deduce output format from file extension\n"); switch_goto_status(SWITCH_STATUS_GENERR, end); } +#if (LIBAVFORMAT_VERSION_MAJOR >= LIBAVFORMAT_V) + fmt = context->fc->oformat; + video_codec = fmt->video_codec; + audio_codec = fmt->audio_codec; +#endif + fmt = context->fc->oformat; if (handle->params && (tmp = switch_event_get_header(handle->params, "av_audio_codec"))) { if ((context->audio_codec = avcodec_find_encoder_by_name(tmp))) { +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) fmt->audio_codec = context->audio_codec->id; +#else + audio_codec = context->audio_codec->id; +#endif switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "specified audio codec %s %s [%s]\n", tmp, context->audio_codec->name, context->audio_codec->long_name); @@ -1837,7 +2273,11 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa if (handle->params && (tmp = switch_event_get_header(handle->params, "av_video_codec"))) { if ((context->video_codec = avcodec_find_encoder_by_name(tmp))) { +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) fmt->video_codec = context->video_codec->id; +#else + video_codec = context->video_codec->id; +#endif switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "specified video codec %s %s [%s]\n", tmp, context->video_codec->name, context->video_codec->long_name); } @@ -1874,16 +2314,28 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa handle->mm.vb = switch_calc_bitrate(handle->mm.vw, handle->mm.vh, 1, handle->mm.fps); } +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && fmt->video_codec != AV_CODEC_ID_NONE) { +#else + if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && video_codec != AV_CODEC_ID_NONE) { +#endif const AVCodecDescriptor *desc; if ((handle->stream_name && (!strcasecmp(handle->stream_name, "rtmp") || !strcasecmp(handle->stream_name, "rtmps") || !strcasecmp(handle->stream_name, "youtube")))) { - +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) if (fmt->video_codec != AV_CODEC_ID_H264 ) { fmt->video_codec = AV_CODEC_ID_H264; // force H264 +#else + if (video_codec != AV_CODEC_ID_H264 ) { + video_codec = AV_CODEC_ID_H264; // force H264 +#endif } +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) fmt->audio_codec = AV_CODEC_ID_AAC; +#else + audio_codec = AV_CODEC_ID_AAC; +#endif handle->samplerate = 44100; handle->mm.samplerate = 44100; handle->mm.ab = 128; @@ -1919,12 +2371,21 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa } } +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) desc = avcodec_descriptor_get(fmt->video_codec); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "use video codec: [%d] %s (%s)\n", fmt->video_codec, desc->name, desc->long_name); +#else + desc = avcodec_descriptor_get(video_codec); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "use video codec: [%d] %s (%s)\n", video_codec, desc->name, desc->long_name); +#endif } +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) if (fmt->audio_codec != AV_CODEC_ID_NONE) { +#else + if (audio_codec != AV_CODEC_ID_NONE) { +#endif const char *issplit = 0; context->audio_st[0].channels = handle->channels; @@ -1937,8 +2398,13 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa if (lr || rl) { context->audio_st[0].channels = 1; context->audio_st[1].channels = 1; +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) add_stream(context, &context->audio_st[0], context->fc, &context->audio_codec, fmt->audio_codec, &handle->mm); add_stream(context, &context->audio_st[1], context->fc, &context->audio_codec, fmt->audio_codec, &handle->mm); +#else + add_stream(context, &context->audio_st[0], context->fc, &context->audio_codec, audio_codec, &handle->mm); + add_stream(context, &context->audio_st[1], context->fc, &context->audio_codec, audio_codec, &handle->mm); +#endif } if (lr) { @@ -1949,7 +2415,11 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa } if (!context->audio_st[0].active) { +#if (LIBAVFORMAT_VERSION_MAJOR < LIBAVFORMAT_V) add_stream(context, &context->audio_st[0], context->fc, &context->audio_codec, fmt->audio_codec, &handle->mm); +#else + add_stream(context, &context->audio_st[0], context->fc, &context->audio_codec, audio_codec, &handle->mm); +#endif } if (open_audio(context->fc, context->audio_codec, &context->audio_st[0]) != SWITCH_STATUS_SUCCESS) { @@ -2022,11 +2492,16 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s uint32_t bytes; int inuse; int sample_start = 0; + AVCodecContext *c = NULL; if (!switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { return SWITCH_STATUS_FALSE; } + if (!context->has_audio) { + return SWITCH_STATUS_SUCCESS; + } + if (!context->vid_ready) { if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { switch_buffer_zero(context->audio_buffer); @@ -2059,9 +2534,7 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s switch_buffer_write(context->audio_buffer, data, datalen); } -GCC_DIAG_OFF(deprecated-declarations) bytes = context->audio_st[0].frame->nb_samples * 2 * context->handle->channels; //context->audio_st[0].st->codec->channels; -GCC_DIAG_ON(deprecated-declarations) //{ // int inuse = switch_buffer_inuse(context->audio_buffer); @@ -2105,15 +2578,18 @@ GCC_DIAG_ON(deprecated-declarations) } while (switch_buffer_inuse(context->audio_buffer) >= bytes) { - AVPacket pkt[2] = { {0} }; + AVPacket *pkt[2]; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) int got_packet[2] = {0}; + int result[2] = {0}; +#else + int dret = -1; +#endif int j = 0, ret = -1, audio_stream_count = 1; AVFrame *use_frame = NULL; -GCC_DIAG_OFF(deprecated-declarations) - av_init_packet(&pkt[0]); - av_init_packet(&pkt[1]); -GCC_DIAG_ON(deprecated-declarations) + pkt[0] = av_packet_alloc(); + pkt[1] = av_packet_alloc(); if (context->audio_st[1].active) { switch_size_t len = 0; @@ -2149,17 +2625,17 @@ GCC_DIAG_ON(deprecated-declarations) if (context->audio_st[j].resample_ctx) { int out_samples = swr_get_out_samples(context->audio_st[j].resample_ctx, context->audio_st[j].frame->nb_samples); - av_frame_make_writable(context->audio_st[j].tmp_frame); + av_frame_make_writable(context->audio_st[j].tmp_frame); /* convert to destination format */ ret = swr_convert(context->audio_st[j].resample_ctx, - context->audio_st[j].tmp_frame->data, out_samples, - (const uint8_t **)context->audio_st[j].frame->data, context->audio_st[j].frame->nb_samples); + context->audio_st[j].tmp_frame->data, out_samples, + (const uint8_t **)context->audio_st[j].frame->data, context->audio_st[j].frame->nb_samples); if (ret < 0) { char ebuf[255] = ""; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while converting %d samples, error text: %s\n", - context->audio_st[j].frame->nb_samples, get_error_text(ret, ebuf, sizeof(ebuf))); + context->audio_st[j].frame->nb_samples, get_error_text(ret, ebuf, sizeof(ebuf))); continue; } @@ -2170,24 +2646,90 @@ GCC_DIAG_ON(deprecated-declarations) // context->audio_st[j].next_pts = use_frame->pts + use_frame->nb_samples; -GCC_DIAG_OFF(deprecated-declarations) - ret = avcodec_encode_audio2(context->audio_st[j].st->codec, &pkt[j], use_frame, &got_packet[j]); -GCC_DIAG_ON(deprecated-declarations) + if (!(c = av_get_codec_context(&context->audio_st[j]))) { + continue; + } +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) +GCC_DIAG_OFF(deprecated-declarations) + result[j] = avcodec_encode_audio2(c, pkt[j], use_frame, &got_packet[j]); +GCC_DIAG_ON(deprecated-declarations) +#else + dret = avcodec_send_frame(c, use_frame); + + if (dret == AVERROR_EOF) { + dret = 0; + } else if (dret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not ever happen */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Encoding error for channel %d on sending frame to encode - BUG, should never happen\n", j); + dret = AVERROR_BUG; + } else if (dret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error for channel %d on sending frame to encode\n", j); + } + + while (dret >= 0) { + dret = avcodec_receive_packet(c, pkt[j]); + if (dret == AVERROR(EAGAIN)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more audio packets at the moment for channel %d\n", j); + break; + } else if (dret == AVERROR_EOF) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more audio packets at all for channel %d\n", j); + break; + } else if (dret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error for channel %d\n", j); + break; + } + + if (context->mutex) switch_mutex_lock(context->mutex); + + ret = write_frame(context->fc, &c->time_base, context->audio_st[j].st, pkt[j]); + + if (context->mutex) switch_mutex_unlock(context->mutex); + + if (ret < 0) { + context->errs++; + if ((context->errs % 10) == 0) { + char ebuf[255] = ""; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while writing audio frame: %d %s\n", ret, get_error_text(ret, ebuf, sizeof(ebuf))); + if ((ret == -5 || ret == -104) && handle->stream_name) { + context->errs = 1001; + } + } + //switch_goto_status(SWITCH_STATUS_FALSE, end); + } else { + context->errs = 0; + } + + if (context->errs > 1000) { + av_packet_free(&pkt[0]); + av_packet_free(&pkt[1]); + switch_goto_status(SWITCH_STATUS_FALSE, end); + } + } +#endif context->audio_st[j].next_pts += use_frame->nb_samples; - } - - if (ret < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error encoding audio frame: %d\n", ret); + } + +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) + if (result[0] < 0 || result[1] < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error encoding audio frame: %d %d \n", result[0], result[1]); + av_packet_free(&pkt[0]); + av_packet_free(&pkt[1]); continue; } - + for (j = 0; j < audio_stream_count; j++) { if (got_packet[j]) { if (context->mutex) switch_mutex_lock(context->mutex); -GCC_DIAG_OFF(deprecated-declarations) - ret = write_frame(context->fc, &context->audio_st[j].st->codec->time_base, context->audio_st[j].st, &pkt[j]); -GCC_DIAG_ON(deprecated-declarations) + + if (!(c = av_get_codec_context(&context->audio_st[j]))) { + if (context->mutex) switch_mutex_unlock(context->mutex); + continue; + } + + ret = write_frame(context->fc, &c->time_base, context->audio_st[j].st, pkt[j]); + if (context->mutex) switch_mutex_unlock(context->mutex); if (ret < 0) { @@ -2207,6 +2749,10 @@ GCC_DIAG_ON(deprecated-declarations) } } } +#endif + + av_packet_free(&pkt[0]); + av_packet_free(&pkt[1]); } end: @@ -2479,10 +3025,10 @@ static switch_status_t no_video_decode_packets(switch_file_handle_t *handle, swi if (context->last_read_pkt) { status = switch_packetizer_read(context->packetizer, frame); if (status == SWITCH_STATUS_SUCCESS) { - av_packet_unref(context->last_read_pkt); - free(context->last_read_pkt); + av_packet_free(&context->last_read_pkt); context->last_read_pkt = NULL; } + return status; } @@ -2490,6 +3036,7 @@ static switch_status_t no_video_decode_packets(switch_file_handle_t *handle, swi if (status != SWITCH_STATUS_SUCCESS || !pkt) { switch_cond_next(); + return SWITCH_STATUS_BREAK; } @@ -2501,12 +3048,10 @@ static switch_status_t no_video_decode_packets(switch_file_handle_t *handle, swi // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "pts=%" SWITCH_INT64_T_FMT " status = %d\n", pts, status); if (status == SWITCH_STATUS_SUCCESS) { - av_packet_unref(context->last_read_pkt); - free(context->last_read_pkt); + av_packet_free(&context->last_read_pkt); context->last_read_pkt = NULL; } - if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_MORE_DATA) { if (!context->video_start_time) { context->video_start_time = switch_time_now() - pts; @@ -2541,6 +3086,8 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f double fl_to = 0.02; int do_fl = 0; int smaller_ts = context->read_fps; + AVCodecContext *c = NULL; + AVCodecParserContext *cp = NULL; if (!context->has_video) return SWITCH_STATUS_FALSE; @@ -2648,18 +3195,17 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f } #endif -GCC_DIAG_OFF(deprecated-declarations) - if (st->codec->time_base.num) { - ticks = st->parser ? st->parser->repeat_pict + 1 : st->codec->ticks_per_frame; + if ((c = av_get_codec_context(mst)) && c->time_base.num) { + cp = av_stream_get_parser(st); + ticks = cp ? cp->repeat_pict + 1 : c->ticks_per_frame; // mst->next_pts += ((int64_t)AV_TIME_BASE * st->codec->time_base.num * ticks) / st->codec->time_base.den; } if (!context->video_start_time) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "start: %" SWITCH_INT64_T_FMT " ticks: %d ticks_per_frame: %d st num:%d st den:%d codec num:%d codec den:%d start: %" SWITCH_TIME_T_FMT ", duration:%" SWITCH_INT64_T_FMT " nb_frames:%" SWITCH_INT64_T_FMT " q2d:%f\n", - context->video_start_time, ticks, st->codec->ticks_per_frame, st->time_base.num, st->time_base.den, st->codec->time_base.num, st->codec->time_base.den, + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "start: %" SWITCH_INT64_T_FMT " ticks: %d ticks_per_frame: %d st num:%d st den:%d codec num:%d codec den:%d start: %" SWITCH_TIME_T_FMT ", duration:%" SWITCH_INT64_T_FMT " nb_frames:%" SWITCH_INT64_T_FMT " q2d:%f\n", + context->video_start_time, ticks, c ? c->ticks_per_frame : -1, st->time_base.num, st->time_base.den, c ? c->time_base.num : -1, c ? c->time_base.den : -1, st->start_time, st->duration == AV_NOPTS_VALUE ? context->fc->duration / AV_TIME_BASE * 1000 : st->duration, st->nb_frames, av_q2d(st->time_base)); } -GCC_DIAG_ON(deprecated-declarations) again: @@ -2760,6 +3306,7 @@ static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_ switch_status_t status = SWITCH_STATUS_SUCCESS; av_file_context_t *context = (av_file_context_t *)handle->private_info; switch_image_t *img = NULL; + AVCodecContext *c = NULL; if (!switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { return SWITCH_STATUS_FALSE; @@ -2776,12 +3323,13 @@ static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_ if (add_stream(context, &context->video_st, context->fc, &context->video_codec, context->fc->oformat->video_codec, &handle->mm) == SWITCH_STATUS_SUCCESS && open_video(context->fc, context->video_codec, &context->video_st) == SWITCH_STATUS_SUCCESS) { - char codec_str[256]; + char codec_str[256] = ""; int ret; -GCC_DIAG_OFF(deprecated-declarations) - avcodec_string(codec_str, sizeof(codec_str), context->video_st.st->codec, 1); -GCC_DIAG_ON(deprecated-declarations) + if ((c = av_get_codec_context(&context->video_st))) { + avcodec_string(codec_str, sizeof(codec_str), c, 1); + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "use video codec implementation %s\n", codec_str); context->has_video = 1; @@ -2814,8 +3362,11 @@ GCC_DIAG_ON(deprecated-declarations) switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_core_timer_init(&context->video_timer, "soft", 1, 1, context->pool); context->eh.video_timer = &context->video_timer; - context->audio_st[0].frame->pts = 0; - context->audio_st[0].next_pts = 0; + if (context->has_audio) { + context->audio_st[0].frame->pts = 0; + context->audio_st[0].next_pts = 0; + } + switch_thread_create(&context->eh.video_thread, thd_attr, video_thread_run, context, handle->memory_pool); } diff --git a/src/mod/applications/mod_av/mod_av.c b/src/mod/applications/mod_av/mod_av.c index 5d93d9adc7..97b2c8f3d7 100644 --- a/src/mod/applications/mod_av/mod_av.c +++ b/src/mod/applications/mod_av/mod_av.c @@ -25,6 +25,7 @@ * * Seven Du * Anthony Minessale + * Jakub Karolczyk * * mod_av -- FS Video Codec / File Format using libav.org * @@ -49,6 +50,7 @@ typedef struct av_mutex_helper_s { switch_memory_pool_t *pool; } av_mutex_helper_t; +#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) int mod_av_lockmgr_cb(void **m, enum AVLockOp op) { av_mutex_helper_t *context = NULL; @@ -93,6 +95,7 @@ int mod_av_lockmgr_cb(void **m, enum AVLockOp op) } return 0; } +#endif #ifndef AV_LOG_TRACE #define AV_LOG_TRACE 96 diff --git a/src/mod/applications/mod_av/mod_av.h b/src/mod/applications/mod_av/mod_av.h index b240f98aa7..a89e6cb8f7 100644 --- a/src/mod/applications/mod_av/mod_av.h +++ b/src/mod/applications/mod_av/mod_av.h @@ -30,6 +30,7 @@ * Marcel Barbulescu * Raymond Chandler * Emmanuel Schmidbauer + * Jakub Karolczyk * * * mod_av.h -- LibAV mod @@ -39,6 +40,10 @@ #ifndef MOD_AV_H #define MOD_AV_H +#define LIBAVCODEC_V 59 +#define LIBAVFORMAT_V 59 +#define LIBAVUTIL_V 57 + struct mod_av_globals { int debug; }; From 9f8de014a15fdee20a2a1bca84bd316d5d0e62d3 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 15 Jul 2023 22:15:22 +0300 Subject: [PATCH 052/205] [mod_av] Add FFmpeg 5.1.3 support on Windows. --- libs/win32/ffmpeg/ffmpeg.2017.vcxproj | 1127 ++++++++++++++++++++---- src/mod/applications/mod_av/avcodec.c | 3 + src/mod/applications/mod_av/avformat.c | 6 + src/mod/applications/mod_av/mod_av.c | 6 + w32/ffmpeg-version.props | 2 +- w32/ffmpeg.props | 2 +- 6 files changed, 952 insertions(+), 194 deletions(-) diff --git a/libs/win32/ffmpeg/ffmpeg.2017.vcxproj b/libs/win32/ffmpeg/ffmpeg.2017.vcxproj index 7eb6ef65ed..b985670dbe 100644 --- a/libs/win32/ffmpeg/ffmpeg.2017.vcxproj +++ b/libs/win32/ffmpeg/ffmpeg.2017.vcxproj @@ -24,7 +24,6 @@ 10.0.17134.0 {BC1FD72E-1CD5-4525-A7F5-17C5740BFDED} - @@ -78,7 +77,7 @@ - BUILDING_avdevice;BUILDING_avfilter;BUILDING_avformat;BUILDING_avcodec;BUILDING_avresample;BUILDING_swresample;BUILDING_swscale;BUILDING_avutil;%(PreprocessorDefinitions) + WC_ERR_INVALID_CHARS=0x00000080;BUILDING_avdevice;BUILDING_avfilter;BUILDING_avformat;BUILDING_avcodec;BUILDING_swresample;BUILDING_swscale;BUILDING_avutil;%(PreprocessorDefinitions) @@ -209,6 +208,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -242,6 +244,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -305,6 +310,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -332,6 +340,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -350,6 +361,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -392,6 +415,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -401,6 +427,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -410,6 +442,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -419,18 +457,21 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -458,15 +499,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -533,12 +574,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -548,6 +595,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -563,6 +613,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -596,7 +655,7 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -608,10 +667,13 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -638,6 +700,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -680,6 +745,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -719,6 +790,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -755,6 +835,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -764,15 +847,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -782,6 +865,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -815,6 +901,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -875,15 +967,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -908,9 +1000,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -980,6 +1069,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1001,9 +1093,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1049,6 +1150,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1097,9 +1201,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1124,6 +1225,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1133,6 +1240,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1241,6 +1354,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1271,6 +1390,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1301,6 +1423,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1406,7 +1531,7 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1415,9 +1540,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1433,9 +1555,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1454,6 +1585,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1466,6 +1600,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1484,6 +1621,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1538,6 +1678,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1559,6 +1702,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1586,6 +1732,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1595,6 +1744,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1640,6 +1792,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1673,6 +1828,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1691,48 +1849,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1748,6 +1873,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1763,6 +1891,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1793,18 +1924,36 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1832,6 +1981,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1880,6 +2032,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -1964,6 +2125,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2039,6 +2203,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2060,9 +2230,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2072,13 +2239,16 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2105,6 +2275,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2126,9 +2302,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2168,6 +2341,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2177,21 +2353,24 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2222,6 +2401,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2237,9 +2419,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2282,6 +2461,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2318,12 +2503,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2444,12 +2635,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2528,6 +2725,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2636,7 +2842,7 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2726,6 +2932,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2816,9 +3025,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2828,6 +3034,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2849,18 +3058,33 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2876,6 +3100,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2897,6 +3127,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2906,12 +3142,21 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2921,12 +3166,30 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2954,6 +3217,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -2996,9 +3265,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3008,6 +3274,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3026,6 +3295,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3038,6 +3310,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3077,6 +3352,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3095,7 +3373,7 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3110,10 +3388,52 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3122,6 +3442,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3140,6 +3463,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3155,6 +3481,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3203,7 +3532,13 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3215,6 +3550,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3227,6 +3565,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3245,6 +3589,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3257,6 +3604,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3266,12 +3619,21 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3284,18 +3646,33 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3320,6 +3697,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3332,6 +3712,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3341,6 +3724,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3353,6 +3739,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3365,15 +3760,27 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3416,18 +3823,30 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3443,9 +3862,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3455,10 +3880,10 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3470,9 +3895,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3494,7 +3925,16 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3512,9 +3952,21 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3554,9 +4006,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3608,10 +4066,10 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3623,6 +4081,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3632,6 +4093,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3641,6 +4105,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3677,33 +4144,39 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3716,6 +4189,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3734,13 +4210,16 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3755,6 +4234,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3764,12 +4246,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3779,19 +4267,31 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3800,7 +4300,7 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3809,40 +4309,55 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3869,9 +4384,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3896,6 +4417,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3908,9 +4432,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3923,6 +4453,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3935,9 +4468,21 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -3971,15 +4516,18 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4001,6 +4549,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4010,6 +4564,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4067,9 +4624,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4085,21 +4639,36 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4157,9 +4726,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4211,6 +4777,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4259,6 +4828,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4271,6 +4846,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4319,6 +4897,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4337,15 +4918,24 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4358,6 +4948,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4376,9 +4969,15 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4397,6 +4996,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4415,6 +5017,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4457,6 +5065,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4469,6 +5083,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4520,6 +5137,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4532,6 +5152,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4589,9 +5212,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4652,6 +5272,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4871,6 +5494,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4922,6 +5548,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4934,6 +5563,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -4946,6 +5578,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5027,6 +5662,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5075,6 +5713,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5099,9 +5740,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5114,6 +5752,12 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5174,6 +5818,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5234,6 +5881,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5267,15 +5917,24 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5297,6 +5956,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5309,21 +5971,27 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5426,9 +6094,30 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5447,13 +6136,19 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5480,6 +6175,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5525,6 +6223,9 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ @@ -5543,54 +6244,6 @@ $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - Assembling %(Filename)%(Extension) - $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - Assembling %(Filename)%(Extension) - $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - - - Assembling %(Filename)%(Extension) - $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - - - $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_'))\ - Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" @@ -5636,6 +6289,21 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" @@ -5666,7 +6334,7 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -5856,7 +6524,7 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -6041,6 +6709,11 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" @@ -6056,6 +6729,16 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" @@ -6066,12 +6749,27 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -6086,7 +6784,7 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -6106,17 +6804,32 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -6126,12 +6839,12 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -6141,7 +6854,12 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj - + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj @@ -6151,6 +6869,11 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" @@ -6206,6 +6929,11 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + Assembling %(Filename)%(Extension) $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" @@ -6241,6 +6969,21 @@ $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + + + Assembling %(Filename)%(Extension) + $(YasmCommand) -I %(RelativeDir) -o $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj "%(FullPath)" + $(IntDir)$([System.String]::Copy(%(RelativeDir)).Replace('\','_')).%(FileName).obj + @@ -6256,4 +6999,4 @@ - + \ No newline at end of file diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index d84362eb28..16d268273b 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -35,6 +35,9 @@ #include #include "mod_av.h" #include +#ifdef _MSC_VER +#include /* LIBAVCODEC_VERSION_INT */ +#endif #include #include #include diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 624af8f4ea..69475c169f 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -35,7 +35,13 @@ #include "mod_av.h" GCC_DIAG_OFF(deprecated-declarations) #include +#ifdef _MSC_VER +#include /* LIBAVCODEC_VERSION_INT */ +#endif #include +#ifdef _MSC_VER +#include /* LIBAVFORMAT_VERSION_INT */ +#endif #include #include #include diff --git a/src/mod/applications/mod_av/mod_av.c b/src/mod/applications/mod_av/mod_av.c index 97b2c8f3d7..02a481fd2e 100644 --- a/src/mod/applications/mod_av/mod_av.c +++ b/src/mod/applications/mod_av/mod_av.c @@ -34,7 +34,13 @@ #include #include "mod_av.h" #include +#ifdef _MSC_VER +#include /* LIBAVCODEC_VERSION_INT */ +#endif #include +#ifdef _MSC_VER +#include /* LIBAVFORMAT_VERSION_INT */ +#endif SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load); SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load); diff --git a/w32/ffmpeg-version.props b/w32/ffmpeg-version.props index 012af42ccb..5e4a400557 100644 --- a/w32/ffmpeg-version.props +++ b/w32/ffmpeg-version.props @@ -4,7 +4,7 @@ - 4.1 + 5.1.3 true diff --git a/w32/ffmpeg.props b/w32/ffmpeg.props index fe039de408..775b588e4c 100644 --- a/w32/ffmpeg.props +++ b/w32/ffmpeg.props @@ -21,7 +21,7 @@ $(ffmpegDir);%(AdditionalLibraryDirectories) - Bcrypt.lib;Secur32.lib;%(AdditionalDependencies) + Bcrypt.lib;Secur32.lib;Mfuuid.lib;strmiids.lib;%(AdditionalDependencies) openh264.lib;%(AdditionalDependencies) From 55f2dc475932fd825bab1f2de1fe6565852f2e03 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 21 Jul 2023 11:49:40 +0100 Subject: [PATCH 053/205] [core] Coverity fixes * [core] Coverity CID 1024233 (Dereference before null check) * [core] Coverity CID 1024239 (Dereference before null check) * [core] Coverity CID 1024242 (Dereference before null check) * [core] Coverity CID 1024243 (Dereference before null check) * [core] Coverity CID 1024453 (Dereference before null check) * [core] Coverity CID 1024554 (Logically dead code) * [core] Coverity CID 1024868 (unchecked return value from library) * [core] Coverity CID 1024869 (unchecked return value from library) * [core] Coverity CID 1468281 (Dereference before null check) * [core] Coverity CID 1024238 (Dereference before null check) * [core] Coverity CID 1468621 (Copy into fixed size buffer) * [core] Coverity CID 1024871 (Unchecked return value) --- src/switch_core_codec.c | 10 ++++++++-- src/switch_event.c | 20 +++++++++++++++----- src/switch_ivr_originate.c | 15 +++++++++------ src/switch_rtp.c | 18 ------------------ src/switch_xml.c | 36 ++++++++++++++++++++++++++---------- 5 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index 69883f8122..e5c22cd610 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -120,8 +120,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_c } } else { /* replace real_read_codec */ switch_codec_t *cur_codec; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Original read codec replaced with %s:%d\n", - switch_channel_get_name(session->channel), codec->implementation->iananame, codec->implementation->ianacode); + switch_channel_get_name(session->channel), codec->implementation ? codec->implementation->iananame : "undefined", codec->implementation ? codec->implementation->ianacode : -1); /* Set real_read_codec to front of the list of read_codecs */ cur_codec = session->read_codec; while (cur_codec != NULL) { @@ -129,8 +130,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_c cur_codec->next = codec; break; } + cur_codec = cur_codec->next; } + session->real_read_codec = codec; session->real_read_impl = *codec->implementation; @@ -154,6 +157,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_c session->bug_codec.implementation->iananame, session->bug_codec.implementation->ianacode); switch_core_codec_destroy(&session->bug_codec); } + switch_thread_rwlock_unlock(session->bug_rwlock); } else { status = SWITCH_STATUS_FALSE; @@ -169,6 +173,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_c if (session->read_impl.actual_samples_per_second != session->read_impl.samples_per_second) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-reported-read-codec-rate", "%d", session->read_impl.samples_per_second); } + switch_event_fire(&event); } @@ -191,6 +196,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_c } switch_mutex_unlock(session->codec_read_mutex); + return status; } @@ -221,7 +227,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s goto end; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Push codec %s:%d\n", - switch_channel_get_name(session->channel), codec->implementation->iananame, codec->implementation->ianacode); + switch_channel_get_name(session->channel), codec->implementation ? codec->implementation->iananame : "undefined", codec->implementation ? codec->implementation->ianacode : -1); codec->next = session->read_codec; session->read_codec = codec; if (codec->implementation) { diff --git a/src/switch_event.c b/src/switch_event.c index 272255d31c..02a6f81505 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -2071,15 +2071,18 @@ SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, swit switch_mutex_lock(CUSTOM_HASH_MUTEX); if (!(subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name))) { - switch_event_reserve_subclass_detailed(id, subclass_name); - subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name); - subclass->bind = 1; + if (switch_event_reserve_subclass_detailed(id, subclass_name) == SWITCH_STATUS_SUCCESS) { + if ((subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name))) { + subclass->bind = 1; + } + } } switch_mutex_unlock(CUSTOM_HASH_MUTEX); if (!subclass) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not reserve subclass. '%s'\n", subclass_name); + return SWITCH_STATUS_FALSE; } } @@ -2094,6 +2097,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, swit if (subclass_name) { event_node->subclass_name = DUP(subclass_name); } + event_node->callback = callback; event_node->user_data = user_data; @@ -2952,14 +2956,17 @@ static void ecd_deliver(event_channel_data_t **ecdP) int x_argc = switch_separate_string_string(key, (char*) sep, x_argv, SWITCH_CHANNEL_DISPATCH_MAX_KEY_PARTS); char buf[1024]; int i, r; + for(i=x_argc - 1; i > 0; i--) { int z; + memset(buf, 0, 1024); - sprintf(buf, "%s", x_argv[0]); + switch_snprintf(buf, sizeof(buf), "%s", x_argv[0]); for(z=1; z < i; z++) { strcat(buf, sep); - strcat(buf, x_argv[z]); + strncat(buf, x_argv[z], sizeof(buf) - strlen(buf) - 1); } + r = _switch_event_channel_broadcast(buf, ecd->event_channel, ecd->json, ecd->key, ecd->id); t += r; if (r && switch_core_test_flag(SCF_EVENT_CHANNEL_HIERARCHY_DELIVERY_ONCE)) { @@ -2968,11 +2975,13 @@ static void ecd_deliver(event_channel_data_t **ecdP) } } else { char *p = NULL; + if ((p = strchr(key, '.'))) { *p = '\0'; t += _switch_event_channel_broadcast(key, ecd->event_channel, ecd->json, ecd->key, ecd->id); } } + switch_safe_free(key); t += _switch_event_channel_broadcast(SWITCH_EVENT_CHANNEL_GLOBAL, ecd->event_channel, ecd->json, ecd->key, ecd->id); @@ -2980,6 +2989,7 @@ static void ecd_deliver(event_channel_data_t **ecdP) if(t == 0) { if (switch_core_test_flag(SCF_EVENT_CHANNEL_LOG_UNDELIVERABLE_JSON)) { char *json = cJSON_Print(ecd->json); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no subscribers for %s , %s => %s\n", ecd->event_channel, ecd->key, json); switch_safe_free(json); } else { diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index f23549713b..a39553e2f9 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -186,15 +186,16 @@ struct key_collect { static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void *obj) { struct key_collect *collect = (struct key_collect *) obj; - switch_channel_t *channel = switch_core_session_get_channel(collect->session); + switch_channel_t *channel = NULL; char buf[10] = SWITCH_BLANK_STRING; switch_application_interface_t *application_interface = NULL; - if (collect->session) { - if (switch_core_session_read_lock(collect->session) != SWITCH_STATUS_SUCCESS) { - return NULL; - } - } else { + if (!collect->session) { + return NULL; + } + + channel = switch_core_session_get_channel(collect->session); + if (switch_core_session_read_lock(collect->session) != SWITCH_STATUS_SUCCESS) { return NULL; } @@ -232,6 +233,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void switch_channel_set_flag(channel, CF_WINNER); switch_channel_set_variable(channel, "group_dial_status", "winner"); } + goto wbreak; } @@ -271,6 +273,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void switch_ivr_play_file(collect->session, NULL, collect->error_file, NULL); } } + wbreak: switch_core_session_rwunlock(collect->session); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4aa68061ab..db6f63e2dd 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3934,12 +3934,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess case SWITCH_RTP_CRYPTO_RECV: switch_channel_set_variable(channel, "srtp_remote_crypto_key", (const char *)b64_key); break; - case SWITCH_RTP_CRYPTO_SEND_RTCP: - switch_channel_set_variable(channel, "srtcp_local_crypto_key", (const char *)b64_key); - break; - case SWITCH_RTP_CRYPTO_RECV_RTCP: - switch_channel_set_variable(channel, "srtcp_remote_crypto_key", (const char *)b64_key); - break; default: break; } @@ -3952,12 +3946,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess case SWITCH_RTP_CRYPTO_RECV: switch_channel_set_variable(channel, "srtp_remote_video_crypto_key", (const char *)b64_key); break; - case SWITCH_RTP_CRYPTO_SEND_RTCP: - switch_channel_set_variable(channel, "srtcp_local_video_crypto_key", (const char *)b64_key); - break; - case SWITCH_RTP_CRYPTO_RECV_RTCP: - switch_channel_set_variable(channel, "srtcp_remote_video_crypto_key", (const char *)b64_key); - break; default: break; } @@ -3970,12 +3958,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess case SWITCH_RTP_CRYPTO_RECV: switch_channel_set_variable(channel, "srtp_remote_audio_crypto_key", (const char *)b64_key); break; - case SWITCH_RTP_CRYPTO_SEND_RTCP: - switch_channel_set_variable(channel, "srtcp_local_audio_crypto_key", (const char *)b64_key); - break; - case SWITCH_RTP_CRYPTO_RECV_RTCP: - switch_channel_set_variable(channel, "srtcp_remote_audio_crypto_key", (const char *)b64_key); - break; default: break; } diff --git a/src/switch_xml.c b/src/switch_xml.c index 80b7553907..8ed7c27658 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -550,15 +550,22 @@ SWITCH_DECLARE(const char **) switch_xml_pi(switch_xml_t xml, const char *target switch_xml_root_t root = (switch_xml_root_t) xml; int i = 0; - if (!root) + if (!root) { return (const char **) SWITCH_XML_NIL; - while (root->xml.parent) + } + + while (root && root->xml.parent) { root = (switch_xml_root_t) root->xml.parent; /* root tag */ + } + if (!root || !root->pi) { return (const char **) SWITCH_XML_NIL; } - while (root->pi[i] && strcmp(target, root->pi[i][0])) + + while (root->pi[i] && strcmp(target, root->pi[i][0])) { i++; /* find target */ + } + return (const char **) ((root->pi[i]) ? root->pi[i] + 1 : SWITCH_XML_NIL); } @@ -1146,7 +1153,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_str(char *s, switch_size_t len) return switch_xml_err(root, d, "unclosed From eb918fe1807fa8465a68c10088cdd81a9be1b229 Mon Sep 17 00:00:00 2001 From: Sergei Rozhkov <119299827+ghzserg@users.noreply.github.com> Date: Sat, 12 Aug 2023 01:13:00 +0500 Subject: [PATCH 072/205] [Core] Fix switch_console.c for Galera Mariadb cluster Fix in switch_console.c file. Adds column names when inserting data. Calls to use the complete table in Galera Multi-Master Cluster --- src/switch_console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_console.c b/src/switch_console.c index 8e26fec749..2157fda8a2 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -1849,7 +1849,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) SWITCH_STANDARD_STREAM(mystream); if (!strcasecmp(argv[0], "stickyadd")) { - mystream.write_function(&mystream, "insert into complete values (1,"); + mystream.write_function(&mystream, "insert into complete (sticky, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, hostname) values (1,"); for (x = 0; x < 10; x++) { if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) { mystream.write_function(&mystream, "%s", "'', "); @@ -1865,7 +1865,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) switch_core_sql_exec(mystream.data); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add")) { - mystream.write_function(&mystream, "insert into complete values (0,"); + mystream.write_function(&mystream, "insert into complete (sticky, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, hostname) values (0,"); for (x = 0; x < 10; x++) { if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) { mystream.write_function(&mystream, "%s", "'', "); From 9347c967125bfa36ca1b049f29841e4d452815ca Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 1 Aug 2023 19:33:17 +0300 Subject: [PATCH 073/205] [Core] check_ice: sanitize second field of the candidates. Add new switch_is_uint_in_range() API. --- src/include/switch_rtp.h | 9 +++++---- src/include/switch_utils.h | 8 ++++++++ src/switch_core_media.c | 11 ++++++++--- src/switch_utils.c | 24 ++++++++++++++++++++++++ tests/unit/switch_core.c | 15 +++++++++++++++ 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index ca915cf77a..dfcad5453c 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -106,12 +106,13 @@ typedef struct icand_s { } icand_t; #define MAX_CAND 50 +#define MAX_CAND_IDX_COUNT 2 typedef struct ice_s { - icand_t cands[MAX_CAND][2]; - int cand_idx[2]; - int chosen[2]; - int is_chosen[2]; + icand_t cands[MAX_CAND][MAX_CAND_IDX_COUNT]; + int cand_idx[MAX_CAND_IDX_COUNT]; + int chosen[MAX_CAND_IDX_COUNT]; + int is_chosen[MAX_CAND_IDX_COUNT]; char *ufrag; char *pwd; char *options; diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 62f3fcd97e..1d33939f4c 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -498,6 +498,14 @@ SWITCH_DECLARE(switch_size_t) switch_fp_read_dline(FILE *fd, char **buf, switch_ SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size); SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone); SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame); + +/*! \brief Check if a 32 bit unsigned number is in a range. + * \param str string to check. Should not contain non-digit characters. + * \param from start of range including this number + * \param to end of range including this number + * \return true or false + */ +SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to); SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str); SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str); SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 4d11dc8b4e..252d947035 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4167,10 +4167,15 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t argc = switch_split(data, ' ', fields); + if (argc < 6 || !switch_is_uint_in_range(fields[1], 1, MAX_CAND_IDX_COUNT)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n"); + continue; + } + cid = fields[1] ? atoi(fields[1]) - 1 : 0; - if (argc < 6 || engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n"); + if (engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Too many candidates\n"); continue; } @@ -4250,7 +4255,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t relay: - for (cid = 0; cid < 2; cid++) { + for (cid = 0; cid < MAX_CAND_IDX_COUNT; cid++) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Searching for %s candidate.\n", cid ? "rtcp" : "rtp"); for (ai = 0; ai < engine->cand_acl_count; ai++) { diff --git a/src/switch_utils.c b/src/switch_utils.c index 7561835e69..c51953f0cf 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1607,6 +1607,30 @@ SWITCH_DECLARE(char *) switch_separate_paren_args(char *str) return args; } +SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to) +{ + unsigned int number; + const char *original_str = str; + + if (str == NULL || *str == '\0' || from > to) { + return SWITCH_FALSE; + } + + for (; *str != '\0'; str++) { + if (!isdigit(*str)) { + return SWITCH_FALSE; + } + } + + number = atoi(original_str); + + if (number < from || number > to) { + return SWITCH_FALSE; + } + + return SWITCH_TRUE; +} + SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str) { const char *p; diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index 2aa0f10231..da93fbdef4 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -95,6 +95,21 @@ FST_CORE_BEGIN("./conf") FST_TEST_END() #endif + FST_TEST_BEGIN(test_switch_is_number_in_range) + { + fst_check_int_equals(switch_is_uint_in_range("x5", 0, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("0", 1, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("-11", -10, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("-10", -10, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("-5", -10, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("-5", -10, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("5", -10, 10), SWITCH_FALSE); + fst_check_int_equals(switch_is_uint_in_range("0", 0, 10), SWITCH_TRUE); + fst_check_int_equals(switch_is_uint_in_range("10", 0, 10), SWITCH_TRUE); + fst_check_int_equals(switch_is_uint_in_range("11", 0, 10), SWITCH_FALSE); + } + FST_TEST_END() + FST_TEST_BEGIN(test_md5) { char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 }; From 5c289cc063c21cc7814470f92e701b6e7606dc6e Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 13 Aug 2023 16:00:05 +0000 Subject: [PATCH 074/205] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 130 ++++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 81 ++++++++++- 2 files changed, 210 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 89614987b5..742e4f979e 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -21077,6 +21077,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_frame_free___(void * } +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_is_uint_in_range___(char * jarg1, unsigned int jarg2, unsigned int jarg3) { + int jresult ; + char *arg1 = (char *) 0 ; + unsigned int arg2 ; + unsigned int arg3 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + arg2 = (unsigned int)jarg2; + arg3 = (unsigned int)jarg3; + result = (switch_bool_t)switch_is_uint_in_range((char const *)arg1,arg2,arg3); + jresult = (int)result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_is_number___(char * jarg1) { int jresult ; char *arg1 = (char *) 0 ; @@ -33245,6 +33261,50 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_microsecon } +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_max_ptime_set___(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->max_ptime = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_max_ptime_get___(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->max_ptime); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_min_ptime_set___(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->min_ptime = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_min_ptime_get___(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->min_ptime); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_stereo_set___(void * jarg1, int jarg2) { switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; int arg2 ; @@ -33267,6 +33327,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_stereo_get } +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_sprop_stereo_set___(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->sprop_stereo = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_sprop_stereo_get___(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->sprop_stereo); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_codec_fmtp_private_info_set___(void * jarg1, void * jarg2) { switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; void *arg2 = (void *) 0 ; @@ -36802,6 +36884,44 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_channel_get_variab } +SWIGEXPORT char * SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_channel_get_variable_strdup___(void * jarg1, char * jarg2) { + char * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *arg2 = (char *) 0 ; + char *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (char *)jarg2; + result = (char *)switch_channel_get_variable_strdup(arg1,(char const *)arg2); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_channel_get_variable_buf___(void * jarg1, char * jarg2, char * jarg3, void * jarg4) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + switch_size_t arg4 ; + switch_size_t *argp4 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + argp4 = (switch_size_t *)jarg4; + if (!argp4) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0); + return 0; + } + arg4 = *argp4; + result = (switch_status_t)switch_channel_get_variable_buf(arg1,(char const *)arg2,arg3,arg4); + jresult = (int)result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_channel_get_variables___(void * jarg1, void * jarg2) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -45145,6 +45265,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_MAX_CAND_get___() { } +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_MAX_CAND_IDX_COUNT_get___() { + int jresult ; + int result; + + result = (int)(2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_ice_t_cands_set___(void * jarg1, void * jarg2) { ice_s *arg1 = (ice_s *) 0 ; icand_t (*arg2)[2] ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 6483ed103b..02848257bf 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -10932,6 +10932,11 @@ else return ret; } + public static switch_bool_t switch_is_uint_in_range(string str, uint from, uint to) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_is_uint_in_range(str, from, to); + return ret; + } + public static switch_bool_t switch_is_number(string str) { switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_is_number(str); return ret; @@ -11884,6 +11889,17 @@ else return ret; } + public static string switch_channel_get_variable_strdup(SWIGTYPE_p_switch_channel channel, string varname) { + string ret = freeswitchPINVOKE.switch_channel_get_variable_strdup(SWIGTYPE_p_switch_channel.getCPtr(channel), varname); + return ret; + } + + public static switch_status_t switch_channel_get_variable_buf(SWIGTYPE_p_switch_channel channel, string varname, string buf, SWIGTYPE_p_switch_size_t buflen) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_get_variable_buf(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, buf, SWIGTYPE_p_switch_size_t.getCPtr(buflen)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + public static switch_status_t switch_channel_get_variables(SWIGTYPE_p_switch_channel channel, SWIGTYPE_p_p_switch_event arg1) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_get_variables(SWIGTYPE_p_switch_channel.getCPtr(channel), SWIGTYPE_p_p_switch_event.getCPtr(arg1)); return ret; @@ -15223,6 +15239,7 @@ else public static readonly string SWITCH_RTP_CRYPTO_KEY_80 = freeswitchPINVOKE.SWITCH_RTP_CRYPTO_KEY_80_get(); public static readonly int SWITCH_RTP_BUNDLE_INTERNAL_PT = freeswitchPINVOKE.SWITCH_RTP_BUNDLE_INTERNAL_PT_get(); public static readonly int MAX_CAND = freeswitchPINVOKE.MAX_CAND_get(); + public static readonly int MAX_CAND_IDX_COUNT = freeswitchPINVOKE.MAX_CAND_IDX_COUNT_get(); public static readonly int SWITCH_XML_BUFSIZE = freeswitchPINVOKE.SWITCH_XML_BUFSIZE_get(); } @@ -20575,6 +20592,9 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_frame_free___")] public static extern int switch_frame_free(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_is_uint_in_range___")] + public static extern int switch_is_uint_in_range(string jarg1, uint jarg2, uint jarg3); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_is_number___")] public static extern int switch_is_number(string jarg1); @@ -23614,12 +23634,30 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_microseconds_per_packet_get___")] public static extern int switch_codec_fmtp_microseconds_per_packet_get(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_max_ptime_set___")] + public static extern void switch_codec_fmtp_max_ptime_set(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_max_ptime_get___")] + public static extern int switch_codec_fmtp_max_ptime_get(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_min_ptime_set___")] + public static extern void switch_codec_fmtp_min_ptime_set(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_min_ptime_get___")] + public static extern int switch_codec_fmtp_min_ptime_get(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_stereo_set___")] public static extern void switch_codec_fmtp_stereo_set(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2); [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_stereo_get___")] public static extern int switch_codec_fmtp_stereo_get(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_sprop_stereo_set___")] + public static extern void switch_codec_fmtp_sprop_stereo_set(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_sprop_stereo_get___")] + public static extern int switch_codec_fmtp_sprop_stereo_get(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_codec_fmtp_private_info_set___")] public static extern void switch_codec_fmtp_private_info_set(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); @@ -24487,6 +24525,12 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_channel_get_variable_dup___")] public static extern string switch_channel_get_variable_dup(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, int jarg3, int jarg4); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_channel_get_variable_strdup___")] + public static extern string switch_channel_get_variable_strdup(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_channel_get_variable_buf___")] + public static extern int switch_channel_get_variable_buf(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, string jarg3, global::System.Runtime.InteropServices.HandleRef jarg4); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_channel_get_variables___")] public static extern int switch_channel_get_variables(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); @@ -26281,6 +26325,9 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_MAX_CAND_get___")] public static extern int MAX_CAND_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_MAX_CAND_IDX_COUNT_get___")] + public static extern int MAX_CAND_IDX_COUNT_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_ice_t_cands_set___")] public static extern void ice_t_cands_set(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); @@ -31066,7 +31113,8 @@ public enum switch_call_cause_t { SWITCH_CAUSE_BAD_IDENTITY_INFO = 821, SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE = 822, SWITCH_CAUSE_INVALID_IDENTITY = 823, - SWITCH_CAUSE_STALE_DATE = 824 + SWITCH_CAUSE_STALE_DATE = 824, + SWITCH_CAUSE_REJECT_ALL = 825 } } @@ -32781,6 +32829,7 @@ public enum switch_codec_control_command_t { SCC_VIDEO_RESET, SCC_AUDIO_PACKET_LOSS, SCC_AUDIO_ADJUST_BITRATE, + SCC_AUDIO_VAD, SCC_DEBUG, SCC_CODEC_SPECIFIC } @@ -32905,6 +32954,26 @@ public class switch_codec_fmtp : global::System.IDisposable { } } + public int max_ptime { + set { + freeswitchPINVOKE.switch_codec_fmtp_max_ptime_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_max_ptime_get(swigCPtr); + return ret; + } + } + + public int min_ptime { + set { + freeswitchPINVOKE.switch_codec_fmtp_min_ptime_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_min_ptime_get(swigCPtr); + return ret; + } + } + public int stereo { set { freeswitchPINVOKE.switch_codec_fmtp_stereo_set(swigCPtr, value); @@ -32915,6 +32984,16 @@ public class switch_codec_fmtp : global::System.IDisposable { } } + public int sprop_stereo { + set { + freeswitchPINVOKE.switch_codec_fmtp_sprop_stereo_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_sprop_stereo_get(swigCPtr); + return ret; + } + } + public SWIGTYPE_p_void private_info { set { freeswitchPINVOKE.switch_codec_fmtp_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); From b74245d48a1f65a05e853f24e973f9b9ff35f8f5 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 13 Aug 2023 23:20:20 +0300 Subject: [PATCH 075/205] version bump --- build/next-release.txt | 2 +- configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/next-release.txt b/build/next-release.txt index b61c58c7d4..63fd3adc74 100644 --- a/build/next-release.txt +++ b/build/next-release.txt @@ -1 +1 @@ -1.10.10-dev +1.10.11-dev diff --git a/configure.ac b/configure.ac index c0d792d51e..9f852e531a 100644 --- a/configure.ac +++ b/configure.ac @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.10.10-dev], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.10.11-dev], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [10]) -AC_SUBST(SWITCH_VERSION_MICRO, [10-dev]) +AC_SUBST(SWITCH_VERSION_MICRO, [11-dev]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 7d52ceb69df24188dbe44ee347e0a8fc1c6cfc92 Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Tue, 5 Sep 2023 12:46:13 -0400 Subject: [PATCH 076/205] [timezones] Update timezones to version 2023c. --- conf/curl/autoload_configs/timezones.conf.xml | 1170 ++++---- .../autoload_configs/timezones.conf.xml | 1170 ++++---- .../autoload_configs/timezones.conf.xml | 2493 +++++------------ conf/rayo/autoload_configs/timezones.conf.xml | 1170 ++++---- conf/sbc/autoload_configs/timezones.conf.xml | 1170 ++++---- .../autoload_configs/timezones.conf.xml | 2493 +++++------------ .../autoload_configs/timezones.conf.xml | 2349 ++++------------ 7 files changed, 4461 insertions(+), 7554 deletions(-) diff --git a/conf/curl/autoload_configs/timezones.conf.xml b/conf/curl/autoload_configs/timezones.conf.xml index 14f87f8c67..9ddded792c 100644 --- a/conf/curl/autoload_configs/timezones.conf.xml +++ b/conf/curl/autoload_configs/timezones.conf.xml @@ -1,551 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/insideout/autoload_configs/timezones.conf.xml b/conf/insideout/autoload_configs/timezones.conf.xml index 14f87f8c67..9ddded792c 100644 --- a/conf/insideout/autoload_configs/timezones.conf.xml +++ b/conf/insideout/autoload_configs/timezones.conf.xml @@ -1,551 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/minimal/autoload_configs/timezones.conf.xml b/conf/minimal/autoload_configs/timezones.conf.xml index 0af4c77d7f..9ddded792c 100644 --- a/conf/minimal/autoload_configs/timezones.conf.xml +++ b/conf/minimal/autoload_configs/timezones.conf.xml @@ -1,1850 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/conf/rayo/autoload_configs/timezones.conf.xml b/conf/rayo/autoload_configs/timezones.conf.xml index 14f87f8c67..9ddded792c 100644 --- a/conf/rayo/autoload_configs/timezones.conf.xml +++ b/conf/rayo/autoload_configs/timezones.conf.xml @@ -1,551 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/sbc/autoload_configs/timezones.conf.xml b/conf/sbc/autoload_configs/timezones.conf.xml index 14f87f8c67..9ddded792c 100644 --- a/conf/sbc/autoload_configs/timezones.conf.xml +++ b/conf/sbc/autoload_configs/timezones.conf.xml @@ -1,551 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/testing/autoload_configs/timezones.conf.xml b/conf/testing/autoload_configs/timezones.conf.xml index 0af4c77d7f..9ddded792c 100644 --- a/conf/testing/autoload_configs/timezones.conf.xml +++ b/conf/testing/autoload_configs/timezones.conf.xml @@ -1,1850 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/conf/vanilla/autoload_configs/timezones.conf.xml b/conf/vanilla/autoload_configs/timezones.conf.xml index 48206d1ce4..9ddded792c 100644 --- a/conf/vanilla/autoload_configs/timezones.conf.xml +++ b/conf/vanilla/autoload_configs/timezones.conf.xml @@ -1,1816 +1,661 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + - + - - - - - - - - - + + + + + + + + - - + + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - + - + + + + + + + + + + + - + - + - + - + - + - + - + - + - - - + - + + + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - - - - - - - - - - - - - + - + + + + + + + + + + + + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + From 07f192ca03b609ab6b498490e29d849c2bf4946a Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Tue, 5 Sep 2023 16:11:01 -0400 Subject: [PATCH 077/205] [contrib/timezone-gen] Fix timezone gen (#2215) * [contrib/timezone-gen] Move timezone-gen.pl to own folder * [contrib/timezone-gen] Add fixTzstr * [contrib/timezone-gen] Add tests and zone data getter - tests.pl can be used to verify that the generated timezone conf will produce the correct datetimes by testing them against what the system's `date` says - build-zonedata.pl will download the latest tzdb data and build the posix timezone data files. It only builds what is needed rather than adding extraneous "right/" and "posix/" timezones. FreeSWITCH doesn't seem to be able to use the "right/" timezone files. - data/ is where the various files needed to generate the timezones gets stored --- scripts/perl/timezones/build-zonedata.pl | 28 +++++++++ scripts/perl/timezones/data/.gitignore | 4 ++ scripts/perl/timezones/fix-tzstr.pl | 61 ++++++++++++++++++ scripts/perl/timezones/tests.pl | 65 ++++++++++++++++++++ scripts/perl/{ => timezones}/timezone-gen.pl | 10 ++- 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100755 scripts/perl/timezones/build-zonedata.pl create mode 100644 scripts/perl/timezones/data/.gitignore create mode 100644 scripts/perl/timezones/fix-tzstr.pl create mode 100644 scripts/perl/timezones/tests.pl rename scripts/perl/{ => timezones}/timezone-gen.pl (90%) diff --git a/scripts/perl/timezones/build-zonedata.pl b/scripts/perl/timezones/build-zonedata.pl new file mode 100755 index 0000000000..347a743dae --- /dev/null +++ b/scripts/perl/timezones/build-zonedata.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $remote_version = `wget --quiet https://data.iana.org/time-zones/tzdb/version --output-document -` =~ s/\n//r; +my $local_version; + +if ( open my $in, " }; + close $in; +} + +my $up_to_date = defined($local_version) && $local_version eq $remote_version; + +if ( ! $up_to_date ) { + open my $out, ">data/version"; + print $out $remote_version; + close $out; +} + +$local_version = $remote_version; + +`wget --quiet --timestamping --directory-prefix=data https://data.iana.org/time-zones/tzdb-latest.tar.lz`; +`tar --extract --file=data/tzdb-latest.tar.lz --directory=data`; +`make DESTDIR=../ TZDIR=zones-$local_version --directory=data/tzdb-$local_version posix_only`; + +print("Yay. Now you can run\n ./timezone-gen.pl --base=data/zones-$local_version --output=timezones-$local_version.conf.xml") \ No newline at end of file diff --git a/scripts/perl/timezones/data/.gitignore b/scripts/perl/timezones/data/.gitignore new file mode 100644 index 0000000000..144983b728 --- /dev/null +++ b/scripts/perl/timezones/data/.gitignore @@ -0,0 +1,4 @@ +tzdb-* +zones-* +version +tzdb-latest.tar.lz \ No newline at end of file diff --git a/scripts/perl/timezones/fix-tzstr.pl b/scripts/perl/timezones/fix-tzstr.pl new file mode 100644 index 0000000000..224c9a550e --- /dev/null +++ b/scripts/perl/timezones/fix-tzstr.pl @@ -0,0 +1,61 @@ +#!/usr/bin/perl + +sub fixTzstr { + # switch_time.c expects POSIX-style TZ rule, but it won't process quoted TZ + # rules that look like this: <-04>4 or <-04>4<-03> + # See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 + + # Instead it defaults to UTC for these values. Here we process the quoted + # values and convert them into letters. If the zone name has "GMT", we use + # that as the replacement prefix, otherwise a default "STD" is used. Zones + # that have a quoted suffix have their suffix replaced with "DST". + + my ($tzstr, $name) = @_; + + if ( $tzstr =~ /(<(?[^>]+)>)([^<]+)(?<.+>)?(?.+)?/ ) { + my ($tzprefix, $tzsuffix, $tzrest, $offset, $offsetprefix) = ("") x 5; + + if ( defined($+{std}) ) { + my $std = $+{std}; + + if ( lc($name) =~ m/gmt/) { + $tzprefix = "GMT"; + } else { + $tzprefix = "STD"; + } + + if ( $std =~ m/\+/ ) { + $offset = sprintf "%d", $std =~ s/\+//r; + $offsetprefix = "-"; + } else { + $offset = sprintf "%d", $std =~ s/\-//r; + } + + my @chars = split(//, $offset); + if ( @chars > 2 ) { + my $hours = $chars[-3]; + if ( defined( $chars[-4] ) ) { + $hours = $chars[-4].$hours; + } + + $offset = $hours.":".$chars[-2].$chars[-1]; + } + + $offset = $offsetprefix.$offset; + } + + if ( defined($+{dst}) ) { + $tzsuffix = "DST"; + } + + if ( defined($+{rest}) ) { + $tzrest = $+{rest}; + } + + return $tzprefix.$offset.$tzsuffix.$tzrest; + } + + return $tzstr; +} + +1; \ No newline at end of file diff --git a/scripts/perl/timezones/tests.pl b/scripts/perl/timezones/tests.pl new file mode 100644 index 0000000000..3aec76ff68 --- /dev/null +++ b/scripts/perl/timezones/tests.pl @@ -0,0 +1,65 @@ +#!/usr/bin/perl +=pod +Tests to verify that the provided modifications to timezone formats produce +the correct results. The first set of tests verify the fixTzstr subroutine +converts the quoted values to something that won't make FreeSWITCH default to +UTC. + +The second set of tests confirms that those timezone changes actually produce +the correct timestamps. + +Make sure FreeSWITCH already has already loaded the timezones.conf.xml that you +want to test. + +To run tests: + +TIMEZONES_XML_PATH=path/to/timezones.conf.xml prove tests.pl +=cut + +use strict; +use warnings; +use Test::More; +use ESL; +use XML::LibXML::Reader; + +require "./fix-tzstr.pl"; + +use Env qw(TIMEZONES_XML_PATH); +die "The TIMEZONES_XML_PATH environment variable must be set to test timezones." unless ( defined($TIMEZONES_XML_PATH) ); + +ok( fixTzstr("<-02>2", "doesntmatterhere") eq "STD2" ); +ok( fixTzstr("EST5EDT,M3.2.0,M11.1.0", "US/Eastern") eq "EST5EDT,M3.2.0,M11.1.0" ); +ok( fixTzstr("<+11>-11", "GMT-11") eq "GMT-11" ); +ok( fixTzstr("<-02>2<-01>,M3.5.0/-1,M10.5.0/0", "America/Godthab") eq "STD2DST,M3.5.0/-1,M10.5.0/0" ); + +my $test_count = 4; + +my $tz_fmt = "%Y-%m-%d %H:%M:%S"; +my $c = new ESL::ESLconnection("127.0.0.1", "8021", "ClueCon"); +$c->api("reloadxml")->getBody(); +my $epoch = $c->api("strepoch")->getBody(); +run_tests($epoch); +run_tests("1699613236"); # testing DST, add more epochs as needed + +sub run_tests { + my $epoch = shift; + my $reader = XML::LibXML::Reader->new(location => $TIMEZONES_XML_PATH); + while ($reader->read) { + my $tag = $reader; + if ( $tag->name eq "zone" && $tag->hasAttributes() ) { + my $zn = $tag->getAttribute("name"); + + my $cmd = `TZ='$zn' date +'$tz_fmt' --date='\@$epoch'`; + my $sys_time = $cmd =~ s/\n//r; + my $fs_time = $c->api("strftime_tz $zn $epoch|$tz_fmt")->getBody(); + + ok ( $sys_time eq $fs_time, $zn ) or diag( + " (sys) $sys_time\t(fs) $fs_time" + ); + + $test_count++; + } + } +} + +done_testing($test_count); \ No newline at end of file diff --git a/scripts/perl/timezone-gen.pl b/scripts/perl/timezones/timezone-gen.pl similarity index 90% rename from scripts/perl/timezone-gen.pl rename to scripts/perl/timezones/timezone-gen.pl index e812023ef0..86822cc553 100755 --- a/scripts/perl/timezone-gen.pl +++ b/scripts/perl/timezones/timezone-gen.pl @@ -1,10 +1,12 @@ #!/usr/bin/perl use strict; +use warnings; use Getopt::Long; use XML::Entities; use HTML::Entities; +require "./fix-tzstr.pl"; my $base = "/usr/share/zoneinfo"; my $output = "timezones.conf.xml"; @@ -18,7 +20,7 @@ my $res = GetOptions( "base=s" => \$base, "debug+" => \$debug, "help" => \$help, - "output" => \$output + "output=s" => \$output ); if ( !$res || $help ) { print "$0 [--base=/usr/share/zoneinfo] [--output=timezones.conf.xml] [--debug] [--help]\n"; @@ -64,7 +66,9 @@ foreach my $name ( sort( keys(%name_to_file) ) ) { next; } - $zones{$name} = pop(@strings); + my $tzstr = fixTzstr( pop(@strings), $name ); + + $zones{$name} = $tzstr; } open( my $out, ">$output" ); @@ -83,7 +87,7 @@ foreach my $zone ( sort( keys(%zones) ) ) { } $lastprefix = $newprefix; - print $out "\t\n"; + print $out " " x 8, "\n"; } print $out " " x 4, "\n"; print $out "\n"; From b6ccc27e6fc8b74aacc8476c2c43f520ea03cc5d Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 4 Sep 2023 13:10:26 +0300 Subject: [PATCH 078/205] [core] JB audio: check for jb type and silence some debug. (#1191) --- src/switch_jitterbuffer.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 6aa872c439..6f142aec6d 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -1109,17 +1109,19 @@ SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_ jb->codec = switch_core_session_get_read_codec(session); jb->session = session; jb->channel = switch_core_session_get_channel(session); - if (!strcmp(jb->codec->implementation->iananame, "opus")) { - if (switch_channel_var_true(jb->channel, "rtp_jitter_buffer_accelerate")) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate on\n", jb->codec->implementation->iananame); - jb->elastic = SWITCH_TRUE; + if (jb->type == SJB_AUDIO) { + if (!strcmp(jb->codec->implementation->iananame, "opus")) { + if (switch_channel_var_true(jb->channel, "rtp_jitter_buffer_accelerate")) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "audio codec is %s, accelerate on\n", jb->codec->implementation->iananame); + jb->elastic = SWITCH_TRUE; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "audio codec is %s, accelerate off\n", jb->codec->implementation->iananame); + jb->elastic = SWITCH_FALSE; + } } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate off\n", jb->codec->implementation->iananame); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "audio codec is not Opus: %s\n", jb->codec->implementation->iananame); jb->elastic = SWITCH_FALSE; } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec not opus: %s\n", jb->codec->implementation->iananame); - jb->elastic = SWITCH_FALSE; } if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) && From ebcb099a0191740832d4e0763e22bdcc3b634c37 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 1 Sep 2023 11:23:28 +0100 Subject: [PATCH 079/205] [core] Coverity 1325269 Dereference before null check --- src/switch_jitterbuffer.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 6f142aec6d..655fa022c2 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -1719,20 +1719,13 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp } } - if (node) { - status = SWITCH_STATUS_SUCCESS; + *packet = node->packet; + *len = node->len; + jb->last_len = *len; + packet->header.version = 2; + hide_node(node, SWITCH_TRUE); - *packet = node->packet; - *len = node->len; - jb->last_len = *len; - packet->header.version = 2; - hide_node(node, SWITCH_TRUE); - - jb_debug(jb, 2, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " " : ""); - - } else { - status = SWITCH_STATUS_MORE_DATA; - } + jb_debug(jb, 2, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " " : ""); end: From 4c51ba9064292c363d6dc85ca1ec2290c2918821 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 1 Sep 2023 11:27:01 +0100 Subject: [PATCH 080/205] [core] Coverity 1364946 Unchecked return value --- src/switch_core_media.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 252d947035..d61b39e710 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6732,6 +6732,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void float fps = 15.0f; switch_image_t *last_frame = NULL; int last_w = 0, last_h = 0, kps = 0; + switch_status_t res; if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { return NULL; @@ -6739,10 +6740,12 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void if (!(smh = session->media_handle)) { switch_core_session_rwunlock(session); + return NULL; } - switch_core_session_get_partner(session, &b_session); + res = switch_core_session_get_partner(session, &b_session); + (void)res; switch_channel_set_flag(session->channel, CF_VIDEO_WRITING); @@ -6763,7 +6766,6 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void fr.buflen = buflen - 12; switch_core_media_gen_key_frame(session); - if (smh->video_write_fh) { if (smh->video_write_fh->mm.fps) { fps = smh->video_write_fh->mm.fps; @@ -6803,8 +6805,6 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) { switch_status_t wstatus = SWITCH_STATUS_FALSE; - - switch_core_timer_next(&timer); switch_mutex_lock(v_engine->mh.file_write_mutex); @@ -6847,12 +6847,14 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF); } } + switch_mutex_unlock(v_engine->mh.file_write_mutex); } if (last_frame) { int x = 0; switch_rgb_color_t bgcolor; + switch_color_set_rgb(&bgcolor, "#000000"); switch_img_fill(last_frame, 0, 0, last_frame->d_w, last_frame->d_h, &bgcolor); fr.img = last_frame; @@ -6863,12 +6865,12 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME; switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0); } + switch_core_media_gen_key_frame(session); switch_core_session_request_video_refresh(session); switch_img_free(&last_frame); } - switch_core_timer_destroy(&timer); switch_core_session_rwunlock(session); @@ -6878,7 +6880,6 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_core_session_rwunlock(b_session); } - v_engine->thread_write_lock = 0; switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]); From bb9afcb3880c37acff83fadf0c93ce248128f592 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 8 Sep 2023 18:17:57 +0100 Subject: [PATCH 081/205] [core] Coverity fixes * [core] Coverity 1518099, 1518097, 1518098 (Unchecked return value from library) * [core] Coverity 1468551 Unchecked return value * [core] Coverity 1468293 Unchecked return value * [core] Coverity 1468274 Explicit null dereferenced * [core] Coverity 1395588 Unchecked return value * [core] Coverity 1395515 Logically dead code * [core] Coverity 1364984 Result is not floating-point * [core] Coverity 1395554, 1468440 Dereference before null check * [core] Coverity 1024487 Dereference after null check * [core] Coverity 1024872 Unchecked return value * [core] Coverity 1025822 Unchecked return value * [core] Coverity 1025823 Unchecked return value * [core] Coverity 1087637, 1346467, 1087638 Unchecked return value * [core] Coverity 1107607 Unchecked return value * [core] Coverity 1210777 Unchecked return value * [core] Coverity 1227670 Dereference before null check * [core] Coverity 1024551 Logically dead code * [core] Coverity 1024560 Logically dead code * [core] Coverity 1024664 Operands don't affect result * [core] Coverity 1364957 Dereference after null check * [core] Coverity 1395572 Logically dead code * [core] Coverity 1412459 Unchecked return value * [core] Coverity 1412490 Unchecked return value * [core] Coverity 1395515/2 Logically dead code * [core] Coverity cleanup --- src/cJSON.c | 44 +++++++++++++++++++------------------- src/switch_core_media.c | 43 ++++++++++++++++++++++--------------- src/switch_core_memory.c | 5 ++++- src/switch_core_sqldb.c | 8 ++++--- src/switch_cpp.cpp | 13 +++++------ src/switch_curl.c | 34 ++++++++++++++++++++++++----- src/switch_event.c | 9 +++++--- src/switch_ivr.c | 12 +++++++++-- src/switch_ivr_async.c | 2 +- src/switch_ivr_originate.c | 8 ++----- src/switch_ivr_play_say.c | 10 ++++++--- src/switch_stun.c | 23 ++++++++++++++++---- src/switch_vpx.c | 2 +- src/switch_xml.c | 9 +++----- 14 files changed, 142 insertions(+), 80 deletions(-) diff --git a/src/cJSON.c b/src/cJSON.c index 6d0e4946fd..ae0a2e2007 100644 --- a/src/cJSON.c +++ b/src/cJSON.c @@ -1104,34 +1104,32 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i buffer->length = default_buffer_size; buffer->format = format; buffer->hooks = *hooks; - if (buffer->buffer == NULL) - { + + if (buffer->buffer == NULL) { goto fail; } /* print the value */ - if (!print_value(item, buffer)) - { + if (!print_value(item, buffer)) { goto fail; } + update_offset(buffer); /* check if reallocate is available */ - if (hooks->reallocate != NULL) - { + if (hooks->reallocate != NULL) { printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); if (printed == NULL) { goto fail; } + buffer->buffer = NULL; - } - else /* otherwise copy the JSON over to a new buffer */ - { + } else { /* otherwise copy the JSON over to a new buffer */ printed = (unsigned char*) hooks->allocate(buffer->offset + 1); - if (printed == NULL) - { + if (printed == NULL) { goto fail; } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); printed[buffer->offset] = '\0'; /* just to be sure */ @@ -1142,16 +1140,10 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i return printed; fail: - if (buffer->buffer != NULL) - { + if (buffer->buffer != NULL) { hooks->deallocate(buffer->buffer); } - if (printed != NULL) - { - hooks->deallocate(printed); - } - return NULL; } @@ -1942,33 +1934,41 @@ static cJSON_bool add_item_to_object(cJSON * const object, const char * const st CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { - add_item_to_object(object, string, item, &global_hooks, false); + cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, false); + (void)res; } /* Add an item to an object with constant string as key */ CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) { - add_item_to_object(object, string, item, &global_hooks, true); + cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, true); + (void)res; } CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { + cJSON_bool res; + if (array == NULL) { return; } - add_item_to_array(array, create_reference(item, &global_hooks)); + res = add_item_to_array(array, create_reference(item, &global_hooks)); + (void)res; } CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) { + cJSON_bool res; + if ((object == NULL) || (string == NULL)) { return; } - add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); + res = add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); + (void)res; } CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 252d947035..0c92a2a156 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -722,13 +722,10 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime)); break; case SWITCH_MEDIA_TYPE_VIDEO: - if (sdp_type == SDP_TYPE_RESPONSE) { - exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame)); - } else { - exists = (type == pmap->type && !strcasecmp(name, pmap->iananame)); - } + exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECK PMAP %s:%s %d %s:%s %d ... %d\n", - name, sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pt, + name, "RES", pt, pmap->iananame, pmap->sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pmap->pt, exists); @@ -2524,7 +2521,7 @@ static void check_jb_sync(switch_core_session_t *session) } if (!jb_sync_msec && frames) { - jb_sync_msec = (double)(1000 / fps) * frames; + jb_sync_msec = ((double)1000 / fps) * frames; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), @@ -4624,9 +4621,10 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s { switch_core_session_t *other_session = NULL; switch_core_session_message_t *msg; + switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_core_session_get_partner(session, &other_session); - + status = switch_core_session_get_partner(session, &other_session); + (void)status; if (switch_channel_test_flag(session->channel, CF_STREAM_CHANGED)) { switch_channel_clear_flag(session->channel, CF_STREAM_CHANGED); @@ -4662,13 +4660,15 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s if (switch_channel_test_flag(other_session->channel, CF_AWAITING_STREAM_CHANGE)) { uint8_t proceed = 1; const char *sdp_in, *other_ep; + uint8_t res = 0; if ((other_ep = switch_channel_get_variable(session->channel, "ep_codec_string"))) { switch_channel_set_variable(other_session->channel, "codec_string", other_ep); } sdp_in = switch_channel_get_variable(other_session->channel, SWITCH_R_SDP_VARIABLE); - switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST); + res = switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST); + (void)res; switch_core_media_activate_rtp(other_session); msg = switch_core_session_alloc(other_session, sizeof(*msg)); msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND; @@ -13587,6 +13587,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (zstr(attr->a_name)) { continue; } + if (!strcasecmp(attr->a_name, "ptime")) { dptime = atoi(attr->a_value); break; @@ -13599,22 +13600,27 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) { for (map = m->m_rtpmaps; map; map = map->rm_next) { int found = 0; + for (attr = m->m_attributes; attr && found < 2; attr = attr->a_next) { if (zstr(attr->a_name)) { continue; } + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { ptime = atoi(attr->a_value); found++; } + if (!strcasecmp(attr->a_name, "rtcp-mux")) { if (switch_channel_var_true(channel, "rtcp_mux_auto_detect")) { switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "setting rtcp-mux from sdp\n"); switch_channel_set_variable(channel, "rtcp_mux", "true"); } + found++; } } + switch_core_media_add_payload_map(session, m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, map->rm_encoding, @@ -13640,11 +13646,13 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (zstr(attr->a_name)) { continue; } + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { ptime = atoi(attr->a_value); break; } } + connection = sdp->sdp_connection; if (m->m_connections) { connection = m->m_connections; @@ -13658,7 +13666,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) { for (map = m->m_rtpmaps; map; map = map->rm_next) { - if (map->rm_pt > 127 || already_did[map->rm_pt]) { + if (already_did[map->rm_pt]) { continue; } @@ -13679,19 +13687,20 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (match) { add_audio_codec(map, imp, ptime, buf, sizeof(buf)); } - } } } else { for (i = 0; i < num_codecs; i++) { const switch_codec_implementation_t *imp = codecs[i]; + if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO || imp->ianacode > 127 || already_did[imp->ianacode]) { continue; } + for (map = m->m_rtpmaps; map; map = map->rm_next) { - if (map->rm_pt > 127 || already_did[map->rm_pt]) { + if (already_did[map->rm_pt]) { continue; } @@ -13724,11 +13733,10 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess break; } - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) { for (map = m->m_rtpmaps; map; map = map->rm_next) { - if (map->rm_pt > 127 || already_did[map->rm_pt]) { + if (already_did[map->rm_pt]) { continue; } @@ -13752,11 +13760,11 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess } else { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame); } + already_did[imp->ianacode] = 1; } } } - } else { for (i = 0; i < num_codecs; i++) { const switch_codec_implementation_t *imp = codecs[i]; @@ -13772,7 +13780,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess for (map = m->m_rtpmaps; map; map = map->rm_next) { - if (map->rm_pt > 127 || already_did[map->rm_pt]) { + if (already_did[map->rm_pt]) { continue; } @@ -13793,6 +13801,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess } else { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame); } + already_did[imp->ianacode] = 1; } } diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 7d3f4adbd7..77be1812c5 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -501,9 +501,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m #if APR_POOL_DEBUG fspr_pool_destroy_debug(tmp_pool, func); #else - fspr_pool_destroy(tmp_pool); + if (tmp_pool) { + fspr_pool_destroy(tmp_pool); + } #endif #ifdef USE_MEM_LOCK + switch_mutex_unlock(memory_manager.mem_lock); #endif } diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 5a75aeb573..817a7a7586 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2065,6 +2065,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) switch_status_t status; uint32_t ttl = 0; uint32_t i; + switch_status_t res; if (!zstr(qm->pre_trans_execute)) { switch_cache_db_execute_sql_real(qm->event_db, qm->pre_trans_execute, &errmsg); @@ -2126,7 +2127,8 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) for (i = 0; (qm->max_trans == 0 || ttl <= qm->max_trans) && (i < qm->numq); i++) { switch_mutex_lock(qm->mutex); - switch_queue_trypop(qm->sql_queue[i], &pop); + res = switch_queue_trypop(qm->sql_queue[i], &pop); + (void)res; switch_mutex_unlock(qm->mutex); if (pop) break; } @@ -2138,6 +2140,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) switch_mutex_unlock(qm->mutex); ttl++; } + switch_safe_free(pop); if (status != SWITCH_STATUS_SUCCESS) break; } else { @@ -2153,7 +2156,6 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) } } - end: switch(qm->event_db->type) { @@ -2190,11 +2192,11 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) } } - switch_mutex_lock(qm->mutex); for (i = 0; i < qm->numq; i++) { qm->written[i] = qm->pre_written[i]; } + switch_mutex_unlock(qm->mutex); return ttl; diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index fe71a6400a..cd234a30e5 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -98,6 +98,7 @@ SWITCH_DECLARE(Event *) EventConsumer::pop(int block, int timeout) void *pop = NULL; Event *ret = NULL; switch_event_t *event; + switch_status_t res; if (!ready) { return NULL; @@ -105,14 +106,16 @@ SWITCH_DECLARE(Event *) EventConsumer::pop(int block, int timeout) if (block) { if (timeout > 0) { - switch_queue_pop_timeout(events, &pop, (switch_interval_time_t) timeout * 1000); // millisec rather than microsec + res = switch_queue_pop_timeout(events, &pop, (switch_interval_time_t) timeout * 1000); // millisec rather than microsec } else { - switch_queue_pop(events, &pop); + res = switch_queue_pop(events, &pop); } } else { - switch_queue_trypop(events, &pop); + res = switch_queue_trypop(events, &pop); } + (void)res; + if ((event = (switch_event_t *) pop)) { ret = new Event(event, 1); } @@ -138,9 +141,7 @@ SWITCH_DECLARE(void) EventConsumer::cleanup() node_index = 0; - if (events) { - switch_queue_interrupt_all(events); - } + switch_queue_interrupt_all(events); while(switch_queue_trypop(events, &pop) == SWITCH_STATUS_SUCCESS) { switch_event_t *event = (switch_event_t *) pop; diff --git a/src/switch_curl.c b/src/switch_curl.c index d6cfd6ce19..0a8cb682c3 100644 --- a/src/switch_curl.c +++ b/src/switch_curl.c @@ -64,6 +64,7 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, curl_mime *mime = NULL; curl_mimepart *part = NULL; uint8_t added = 0; + switch_CURLcode curl_code = CURLE_OK; #else struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; @@ -98,9 +99,21 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, #if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) part = curl_mime_addpart(mime); - curl_mime_name(part, pname); - curl_mime_filename(part, fname); - curl_mime_filedata(part, hp->value); + if ((curl_code = curl_mime_name(part, pname))) { + free(pname); + goto error; + } + + if ((curl_code = curl_mime_filename(part, fname))) { + free(pname); + goto error; + } + + if ((curl_code = curl_mime_filedata(part, hp->value))) { + free(pname); + goto error; + } + added++; #else curl_formadd(&formpost, @@ -117,8 +130,14 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, } else { #if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) part = curl_mime_addpart(mime); - curl_mime_name(part, hp->name); - curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED); + if ((curl_code = curl_mime_name(part, hp->name))) { + goto error; + } + + if ((curl_code = curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED))) { + goto error; + } + added++; #else curl_formadd(&formpost, @@ -131,6 +150,11 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, } #if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + error: + if (curl_code) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CURL error occured. Error code: %d Error msg: [%s]\n", curl_code, switch_curl_easy_strerror(curl_code)); + } + if (!added) { curl_mime_free(mime); mime = NULL; diff --git a/src/switch_event.c b/src/switch_event.c index 02a6f81505..8a8c8d6c35 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -553,6 +553,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) switch_hash_index_t *hi; const void *var; void *val; + switch_status_t res; if (switch_core_test_flag(SCF_MINIMAL)) { return SWITCH_STATUS_SUCCESS; @@ -565,7 +566,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) unsub_all_switch_event_channel(); if (EVENT_CHANNEL_DISPATCH_QUEUE) { - switch_queue_trypush(EVENT_CHANNEL_DISPATCH_QUEUE, NULL); + res = switch_queue_trypush(EVENT_CHANNEL_DISPATCH_QUEUE, NULL); + (void)res; switch_queue_interrupt_all(EVENT_CHANNEL_DISPATCH_QUEUE); } @@ -573,10 +575,10 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch queues\n"); for(x = 0; x < (uint32_t)DISPATCH_THREAD_COUNT; x++) { - switch_queue_trypush(EVENT_DISPATCH_QUEUE, NULL); + res = switch_queue_trypush(EVENT_DISPATCH_QUEUE, NULL); + (void)res; } - switch_queue_interrupt_all(EVENT_DISPATCH_QUEUE); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch threads\n"); @@ -595,6 +597,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) if (THREAD_COUNT == last) { x++; } + last = THREAD_COUNT; } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 77d957fb7c..7bfe0186f6 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1788,6 +1788,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { switch_core_session_rwunlock(session); + return SWITCH_STATUS_INUSE; } @@ -1798,6 +1799,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ } if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + switch_status_t res = SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; /* If we had early media in bypass mode before, it is no longer relevant */ @@ -1816,6 +1819,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel)); switch_core_session_rwunlock(session); + return SWITCH_STATUS_GENERR; } @@ -1832,7 +1836,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); - switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + res = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); } if ((flags & SMF_REBRIDGE) @@ -1844,10 +1848,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); - switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + res = switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0); switch_channel_clear_state_handler(other_channel, NULL); switch_core_session_rwunlock(other_session); } + + (void)res; + if (other_channel) { switch_channel_clear_state_handler(channel, NULL); } @@ -1862,6 +1869,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ } else { switch_ivr_uuid_bridge(uuid, other_uuid); } + switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL); switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL); } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 9a33b43340..4075f0adce 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -474,7 +474,7 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin if (is_timeout) { if (both_bp) { - r_bp = exact_bp ? exact_bp : both_bp; + r_bp = exact_bp; } } diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index a39553e2f9..0b06d6029c 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -4961,9 +4961,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_orig_and_bridge(switch_cor switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key); } - if (peer_session) { - switch_core_session_rwunlock(peer_session); - } + switch_core_session_rwunlock(peer_session); } return status; @@ -5026,9 +5024,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_orig_and_bridge(switch_core_session_t switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key); } - if (peer_session) { - switch_core_session_rwunlock(peer_session); - } + switch_core_session_rwunlock(peer_session); } return status; diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 33f3a4e51a..b39d42f657 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -3202,6 +3202,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess const char *other_uuid, *moh = NULL; int moh_br = 0; switch_input_args_t args = { 0 }; + switch_status_t res; + args.input_callback = hold_on_dtmf; args.buf = (void *) unhold_key; args.buflen = (uint32_t) strlen(unhold_key); @@ -3232,11 +3234,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess } if (!zstr(moh) && strcasecmp(moh, "silence")) { - switch_ivr_play_file(session, NULL, moh, &args); + res = switch_ivr_play_file(session, NULL, moh, &args); } else { - switch_ivr_collect_digits_callback(session, &args, 0, 0); + res = switch_ivr_collect_digits_callback(session, &args, 0, 0); } + (void)res; + if (moh_br) { switch_channel_stop_broadcast(other_channel); } @@ -3246,10 +3250,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess return SWITCH_STATUS_SUCCESS; } - } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel)); + return SWITCH_STATUS_FALSE; } diff --git a/src/switch_stun.c b/src/switch_stun.c index b0ff45b3dc..d4a2c96503 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -696,8 +696,11 @@ SWITCH_DECLARE(char *) switch_stun_host_lookup(const char *host, switch_memory_p { switch_sockaddr_t *addr = NULL; char buf[30]; + switch_status_t res; + + res = switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool); + (void)res; - switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool); return switch_core_strdup(pool, switch_str_nil(switch_get_addr(buf, sizeof(buf), addr))); } @@ -720,6 +723,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, int funny = 0; int size = sizeof(buf); int xlen = sizeof(switch_stun_packet_header_t); + switch_status_t res; switch_assert(err); @@ -729,25 +733,30 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, *err = "Success"; - switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); + res = switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); + (void)res; if (switch_sockaddr_info_get(&local_addr, *ip, SWITCH_UNSPEC, *port, 0, pool) != SWITCH_STATUS_SUCCESS) { *err = "Local Address Error!"; + return SWITCH_STATUS_FALSE; } if (switch_sockaddr_info_get(&remote_addr, stunip, SWITCH_UNSPEC, stunport, 0, pool) != SWITCH_STATUS_SUCCESS) { *err = "Remote Address Error!"; + return SWITCH_STATUS_FALSE; } if (switch_socket_create(&sock, AF_INET, SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) { *err = "Socket Error!"; + return SWITCH_STATUS_FALSE; } if (switch_socket_bind(sock, local_addr) != SWITCH_STATUS_SUCCESS) { *err = "Bind Error!"; + return SWITCH_STATUS_FALSE; } @@ -779,7 +788,6 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, *ip = NULL; *port = 0; - for (;;) { bytes = sizeof(buf); if (switch_socket_recvfrom(from_addr, sock, 0, (char *) &buf, &bytes) == SWITCH_STATUS_SUCCESS && bytes > 0) { @@ -790,10 +798,12 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, *err = "Timeout"; switch_socket_shutdown(sock, SWITCH_SHUTDOWN_READWRITE); switch_socket_close(sock); + return SWITCH_STATUS_TIMEOUT; } switch_cond_next(); } + switch_socket_close(sock); if (funny) { @@ -803,14 +813,15 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, packet = switch_stun_packet_parse(start, size); if (!packet) { *err = "Invalid STUN/ICE packet"; + return SWITCH_STATUS_FALSE; } + end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf)); switch_stun_packet_first_attribute(packet, attr); switch_assert(attr); - do { switch (attr->type) { case SWITCH_STUN_ATTR_MAPPED_ADDRESS: @@ -818,6 +829,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, switch_stun_ip_t *tmp = (switch_stun_ip_t *) attr->value; tmp->address ^= ntohl(0xabcdabcd); } + switch_stun_packet_attribute_get_mapped_address(attr, rip, sizeof(rip), &rport); break; case SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS: @@ -831,12 +843,15 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, if (!switch_stun_packet_next_attribute(attr, end_buf)) { break; } + xlen += 4 + switch_stun_attribute_padded_length(attr); + } while (xlen <= packet->header.length); if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) { *ip = switch_core_strdup(pool, rip); *port = rport; + return SWITCH_STATUS_SUCCESS; } else { *err = "Invalid Reply"; diff --git a/src/switch_vpx.c b/src/switch_vpx.c index 751f2b8c5b..e65db6b6c8 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -1238,7 +1238,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * if (context->last_received_seq && context->last_received_seq + 1 != frame->seq) { switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "Packet loss detected last=%d got=%d lost=%d\n", context->last_received_seq, frame->seq, frame->seq - context->last_received_seq); - if (is_keyframe && context->vpx_packet_buffer) switch_buffer_zero(context->vpx_packet_buffer); + if (is_keyframe) switch_buffer_zero(context->vpx_packet_buffer); } context->last_received_seq = frame->seq; diff --git a/src/switch_xml.c b/src/switch_xml.c index 8ed7c27658..d54294df92 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1726,6 +1726,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file(const char *file) if ( rename(new_file_tmp,new_file) ) { goto done; } + if ((fd = open(new_file, O_RDONLY, 0)) > -1) { if ((xml = switch_xml_parse_fd(fd))) { if (strcmp(abs, SWITCH_GLOBAL_filenames.conf_name)) { @@ -1733,8 +1734,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file(const char *file) new_file = NULL; } } + close(fd); - fd = -1; } } @@ -1747,10 +1748,6 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file(const char *file) write_fd = NULL; } - if (fd > -1) { - close(fd); - } - switch_safe_free(new_file_tmp); switch_safe_free(new_file); @@ -2272,7 +2269,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, switch_event_destroy(&my_params); } - if (status != SWITCH_STATUS_SUCCESS && root && *root) { + if (status != SWITCH_STATUS_SUCCESS && *root) { switch_xml_free(*root); *root = NULL; *domain = NULL; From dc3c0f00f31d3ab6bd58c68b6fd87edac3263b51 Mon Sep 17 00:00:00 2001 From: tmancill <1195611+tmancill@users.noreply.github.com> Date: Sat, 9 Sep 2023 09:26:04 -0700 Subject: [PATCH 082/205] misc readme updates (#2235) * Update README.md regarding the archived freeswitch-users mailing list * update docker/README.md to suggest --network host --- README.md | 4 ++-- docker/README.md | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 15cda2e22f..728486f891 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,8 @@ This is the place to get answers faster and chat with other users in real time. Slack Community: * https://signalwire.community/ -Mailing list: +Mailing list (ARCHIVED): - * http://lists.freeswitch.org/mailman/listinfo/freeswitch-users + * http://lists.freeswitch.org/pipermail/freeswitch-users/ **Thank you for using FreeSWITCH!** diff --git a/docker/README.md b/docker/README.md index e9a321e699..e0ebfff2af 100644 --- a/docker/README.md +++ b/docker/README.md @@ -2,7 +2,7 @@ These are the official Docker files for master branch and the current release packages. ## Volumes -These containers are setup so that you can mount your freeswitch configuration form a host or data volume container. +These containers are set up so that you can mount your freeswitch configuration from a host or data volume container. To mount freeswitch Configuration ``` @@ -16,17 +16,19 @@ To mount tmp directory for storing recordings, etc The container also has a healthcheck where it does a fs_cli status check to make sure the freeswitch service is still running. -# Ports +## Ports -The container exposes the following ports: +The container should be run with host networking using `docker run --network host ...`. -- 5060/tcp 5060/udp 5080/tcp 5080/udp as SIP Signaling ports. -- 5066/tcp 7443/tcp as WebSocket Signaling ports. -- 8021/tcp as Event Socket port. -- 64535-65535/udp as media ports. -- 16384-32768/udp +If you prefer to (or for some reason must) publish individual ports via `--publish/-p`, refer to this [issue](https://github.com/moby/moby/issues/11185) and this [potential workaround](https://hub.docker.com/r/bettervoice/freeswitch-container/) regarding using docker with large port ranges. +The following ports will be used, depending upon your specific configuration: +- 5060/tcp, 5060/udp, 5080/tcp, 5080/udp - SIP signaling +- 5061/tcp, 5081/tcp - SIPS signaling +- 5066/tcp, 7443/tcp - WebSocket signaling +- 8021/tcp - the Event Socket +- 16384-32768/udp, 64535-65535/udp - media If you wish to help improve these please submit a pull request at: From c6ff92923d1f3ad008a0f872be6e4dc3fef72195 Mon Sep 17 00:00:00 2001 From: tmancill <1195611+tmancill@users.noreply.github.com> Date: Sat, 9 Sep 2023 09:38:50 -0700 Subject: [PATCH 083/205] updates for the Debian Dockerfile (#2234) * default to Debian bookworm * use DEBIAN_VERSION instead of lsb_release; gosu is in Debian since buster * update comments for FS_META_PACKAGE and exposed ports * fix SHELL invocation so 'RUN' works as expected in downstream builds See: https://docs.docker.com/engine/reference/builder/#shell --- docker/master/Dockerfile | 55 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/docker/master/Dockerfile b/docker/master/Dockerfile index e9b626b400..4c73ecc6e4 100644 --- a/docker/master/Dockerfile +++ b/docker/master/Dockerfile @@ -1,56 +1,61 @@ # vim:set ft=dockerfile: -ARG DEBIAN_VERSION=buster +ARG DEBIAN_VERSION=bookworm FROM debian:${DEBIAN_VERSION} + +# ARGs are cleared after every FROM +# see: https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG DEBIAN_VERSION ARG TOKEN +# By default, install the full set of FreeSWITCH packages. Specify an alternative with: +# --build-arg="FS_META_PACKAGE=freeswitch-meta-vanilla" +# alternatives include: +# freeswitch-meta-bare +# freeswitch-meta-vanilla +# freeswitch-meta-sorbet +# freeswitch-meta-all-dbg +ARG FS_META_PACKAGE=freeswitch-meta-all + # Source Dockerfile: # https://github.com/docker-library/postgres/blob/master/9.4/Dockerfile # explicitly set user/group IDs RUN groupadd -r freeswitch --gid=999 && useradd -r -g freeswitch --uid=999 freeswitch -# grab gosu for easy step-down from root -RUN apt-get update && apt-get install -y --no-install-recommends dirmngr gnupg2 ca-certificates wget \ - && gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 655DA1341B5207915210AFE936B4249FA7B0FB03 \ - && gpg2 --output /usr/share/keyrings/signalwire-freeswitch-repo.gpg --export 655DA1341B5207915210AFE936B4249FA7B0FB03 \ - && rm -rf /var/lib/apt/lists/* \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture).asc" \ - && gpg --verify /usr/local/bin/gosu.asc \ - && rm /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && apt-get purge -y --auto-remove ca-certificates wget dirmngr gnupg2 - # make the "en_US.UTF-8" locale so freeswitch will be utf-8 enabled by default -RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \ +RUN apt-get update -qq \ + && apt-get install -y --no-install-recommends ca-certificates gnupg2 gosu locales wget \ && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 ENV LANG en_US.utf8 # https://freeswitch.org/confluence/display/FREESWITCH/Debian +# https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/Linux/Debian_67240088/ -RUN apt-get update && apt-get install ca-certificates lsb-release -y --no-install-recommends \ +RUN wget --no-verbose --http-user=signalwire --http-password=${TOKEN} \ + -O /usr/share/keyrings/signalwire-freeswitch-repo.gpg \ + https://freeswitch.signalwire.com/repo/deb/debian-release/signalwire-freeswitch-repo.gpg \ && echo "machine freeswitch.signalwire.com login signalwire password ${TOKEN}" > /etc/apt/auth.conf \ - && echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ `lsb_release -sc` main" > /etc/apt/sources.list.d/freeswitch.list \ - && apt-get update && apt-get install -y freeswitch-all \ - && apt-get purge -y --auto-remove ca-certificates lsb-release \ + && echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ ${DEBIAN_VERSION} main" > /etc/apt/sources.list.d/freeswitch.list \ + && apt-get -qq update \ + && apt-get install -y ${FS_META_PACKAGE} \ + && apt-get purge -y --auto-remove \ && apt-get clean && rm -rf /var/lib/apt/lists/* COPY docker-entrypoint.sh / # Add anything else here ## Ports -# Open the container up to the world. -### 8021 fs_cli, 5060 5061 5080 5081 sip and sips, 64535-65535 rtp +# Document ports used by this container +### 8021 fs_cli, 5060 5061 5080 5081 sip and sips, 5066 ws, 7443 wss, 8081 8082 verto, 16384-32768, 64535-65535 rtp EXPOSE 8021/tcp EXPOSE 5060/tcp 5060/udp 5080/tcp 5080/udp EXPOSE 5061/tcp 5061/udp 5081/tcp 5081/udp +EXPOSE 5066/tcp EXPOSE 7443/tcp -EXPOSE 5070/udp 5070/tcp +EXPOSE 8081/tcp 8082/tcp EXPOSE 64535-65535/udp EXPOSE 16384-32768/udp - # Volumes ## Freeswitch Configuration VOLUME ["/etc/freeswitch"] @@ -61,11 +66,9 @@ VOLUME ["/tmp"] COPY build/freeswitch.limits.conf /etc/security/limits.d/ # Healthcheck to make sure the service is running -SHELL ["/bin/bash"] +SHELL ["/bin/bash", "-c"] HEALTHCHECK --interval=15s --timeout=5s \ CMD fs_cli -x status | grep -q ^UP || exit 1 ENTRYPOINT ["/docker-entrypoint.sh"] - - CMD ["freeswitch"] From 6f9e72c585265d8def8a613b36cd4f524c201980 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 4 Oct 2023 00:47:39 +0300 Subject: [PATCH 084/205] [libvpx] VP8: disallow thread count changes --- libs/libvpx/vp8/encoder/onyx_if.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/libvpx/vp8/encoder/onyx_if.c b/libs/libvpx/vp8/encoder/onyx_if.c index c091594121..00bab3f626 100644 --- a/libs/libvpx/vp8/encoder/onyx_if.c +++ b/libs/libvpx/vp8/encoder/onyx_if.c @@ -1447,6 +1447,11 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { last_h = cpi->oxcf.Height; prev_number_of_layers = cpi->oxcf.number_of_layers; + if (cpi->initial_width) { + // TODO(https://crbug.com/1486441): Allow changing thread counts; the + // allocation is done once in vp8_create_compressor(). + oxcf->multi_threaded = cpi->oxcf.multi_threaded; + } cpi->oxcf = *oxcf; switch (cpi->oxcf.Mode) { From c4115537e0c1c24abad011c102e25041d18bc7b4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 4 Oct 2023 18:24:16 +0300 Subject: [PATCH 085/205] [Core] Coverity: Use of 32-bit time_t * [Core] Coverity: 1500270 Use of 32-bit time_t * [Core] Coverity: 1500229 Use of 32-bit time_t * [Core] Coverity: 1500235 Use of 32-bit time_t * [Core] Coverity: 1500244 Use of 32-bit time_t * [Core] Coverity: 1500250 Use of 32-bit time_t * [Core] Coverity: 1500245 Use of 32-bit time_t * [Core] Coverity: 1500255 Use of 32-bit time_t * [Core] Coverity: 1500370 Use of 32-bit time_t * Cleanup --- src/switch_core_media.c | 12 ++++++------ src/switch_ivr_originate.c | 6 +++++- src/switch_rtp.c | 5 +++-- src/switch_utils.c | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ca6c05e0a9..4b6d8aff8b 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2066,13 +2066,13 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t switch_mutex_init(&session->media_handle->control_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc = - (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL)); + (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (switch_time_t) time(NULL)); session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssrc = - (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (uint32_t) time(NULL) / 2); + (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (switch_time_t) time(NULL) / 2); session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].ssrc = - (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT] + (uint32_t) time(NULL) / 2); + (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT] + (switch_time_t) time(NULL) / 2); @@ -10526,7 +10526,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (!smh->owner_id) { - smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port; + smh->owner_id = (uint32_t)(switch_time_t)switch_epoch_time_now(NULL) - port; } if (!smh->session_id) { @@ -11836,7 +11836,7 @@ SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t } if (!smh->owner_id) { - smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port; + smh->owner_id = (uint32_t)(switch_time_t)switch_epoch_time_now(NULL) - port; } if (!smh->session_id) { @@ -12050,7 +12050,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) family = strchr(smh->mparams->sipip, ':') ? "IP6" : "IP4"; if (!smh->owner_id) { - smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U; + smh->owner_id = (uint32_t)(switch_time_t) switch_epoch_time_now(NULL) * 31821U + 13849U; } if (!smh->session_id) { diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 0b06d6029c..3c1771682b 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -320,8 +320,10 @@ static int check_per_channel_timeouts(originate_global_t *oglobals, delayed_min = oglobals->originate_status[i].per_channel_delay_start; } } - early_exit_time = delayed_min - (uint32_t) elapsed; + + early_exit_time = delayed_min - (uint32_t)(switch_time_t) elapsed; } + for (i = 0; i < max; i++) { if (oglobals->originate_status[i].peer_channel && oglobals->originate_status[i].per_channel_delay_start && (elapsed > oglobals->originate_status[i].per_channel_delay_start || active_channels == 0)) { @@ -334,6 +336,7 @@ static int check_per_channel_timeouts(originate_global_t *oglobals, oglobals->originate_status[i].per_channel_timelimit_sec = 1; } } + if (oglobals->originate_status[i].per_channel_progress_timelimit_sec) { if (oglobals->originate_status[i].per_channel_progress_timelimit_sec > early_exit_time) { /* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */ @@ -342,6 +345,7 @@ static int check_per_channel_timeouts(originate_global_t *oglobals, oglobals->originate_status[i].per_channel_progress_timelimit_sec = 1; } } + oglobals->originate_status[i].per_channel_delay_start -= delayed_min; } else { oglobals->originate_status[i].per_channel_delay_start = 0; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 17c93f2fa2..506085d86d 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4324,8 +4324,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { switch_sockaddr_create(&rtp_session->rtcp_from_addr, pool); } + rtp_session->seq = (uint16_t) rand(); - rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL)); + rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (switch_time_t) switch_epoch_time_now(NULL)); #ifdef DEBUG_TS_ROLLOVER rtp_session->last_write_ts = TS_ROLLOVER_START; #endif @@ -8061,7 +8062,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, /* If the marker was set, and the timestamp seems to have started over - set a new SSRC, to indicate this is a new stream */ if (m && !switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND) && (rtp_session->rtp_bugs & RTP_BUG_CHANGE_SSRC_ON_MARKER) && (rtp_session->flags[SWITCH_RTP_FLAG_RESET] || (rtp_session->ts <= rtp_session->last_write_ts && rtp_session->last_write_ts > 0))) { - switch_rtp_set_ssrc(rtp_session, (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL))); + switch_rtp_set_ssrc(rtp_session, (uint32_t) ((intptr_t) rtp_session + (switch_time_t) switch_epoch_time_now(NULL))); } if (!switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && !switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) { diff --git a/src/switch_utils.c b/src/switch_utils.c index c51953f0cf..df7a507920 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1161,7 +1161,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, switch_safe_free(dupfile); } - switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int) switch_epoch_time_now(NULL), rand() & 0xffff); + switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int)(switch_time_t) switch_epoch_time_now(NULL), rand() & 0xffff); if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) > -1) { if (file) { From 79ce08810120b681992a3e666bcbe8d2ac2a7383 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 5 Oct 2023 00:26:26 +0300 Subject: [PATCH 086/205] [Core] Coverity: Dereference before null check * [Core] Coverity: 1060958 Dereference before null check * [Core] Coverity: 1024236 Dereference before null check --- src/switch_ivr.c | 4 +++- src/switch_ivr_originate.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 7bfe0186f6..c36149c0a5 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2814,11 +2814,13 @@ SWITCH_DECLARE(int) switch_ivr_set_xml_call_stats(switch_xml_t xml, switch_core_ static int switch_ivr_set_xml_chan_var(switch_xml_t xml, const char *var, const char *val, int off) { char *data; - switch_size_t dlen = strlen(val) * 3 + 1; + switch_size_t dlen; switch_xml_t variable; if (!val) val = ""; + dlen = strlen(val) * 3 + 1; + if (!zstr(var) && ((variable = switch_xml_add_child_d(xml, var, off++)))) { if ((data = malloc(dlen))) { memset(data, 0, dlen); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 3c1771682b..99c70991bd 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1309,7 +1309,7 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st } } - if (oglobals->session && (read_codec = switch_core_session_get_read_codec(oglobals->session))) { + if ((read_codec = switch_core_session_get_read_codec(oglobals->session))) { if (ringback_data && switch_is_file_path(ringback_data)) { if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) { ringback->asis++; From d08424384b643e6de7ef82e8d7550259e48dcc4a Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 5 Oct 2023 18:03:32 +0300 Subject: [PATCH 087/205] [Core] Coverity: 1024552 Logically dead code --- src/switch_utils.c | 23 ++++++++------- tests/unit/switch_core.c | 60 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index df7a507920..faffc1cc04 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -747,7 +747,7 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, ip_t *maskv = mask; ip_t *ipv = ip; - switch_copy_string(host, string, sizeof(host)-1); + switch_copy_string(host, string, sizeof(host) - 1); bit_str = strchr(host, '/'); if (!bit_str) { @@ -758,22 +758,20 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, bits = atoi(bit_str); ipv6 = strchr(string, ':'); if (ipv6) { - int i,n; + int32_t i, n; + uint32_t k; + if (bits < 0 || bits > 128) { return -2; } + bits = atoi(bit_str); switch_inet_pton(AF_INET6, host, (unsigned char *)ip); - for (n=bits,i=0 ;i < 16; i++){ - if (n >= 8) { - maskv->v6.s6_addr[i] = 0xFF; - n -= 8; - } else if (n < 8) { - maskv->v6.s6_addr[i] = 0xFF & ~(0xFF >> n); - n -= n; - } else if (n == 0) { - maskv->v6.s6_addr[i] = 0x00; - } + + for (n = bits, i = 0; i < 16; i++) { + k = (n > 8) ? 8 : n; + maskv->v6.s6_addr[i] = 0xFF & ~(0xFF >> k); /* k = 0 gives 0x00, k = 8 gives 0xFF */ + n -= k; } } else { if (bits < 0 || bits > 32) { @@ -786,6 +784,7 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, maskv->v4 = 0xFFFFFFFF & ~(0xFFFFFFFF >> bits); } + *bitp = bits; return 0; diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index da93fbdef4..1159017571 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -53,6 +53,66 @@ FST_CORE_BEGIN("./conf") } FST_TEARDOWN_END() + FST_TEST_BEGIN(test_switch_parse_cidr_v6) + { + ip_t ip, mask; + uint32_t bits; + + fst_check(!switch_parse_cidr("fe80::/10", &ip, &mask, &bits)); + fst_check_int_equals(bits, 10); + fst_check_int_equals(ip.v6.s6_addr[0], 0xfe); + fst_check_int_equals(ip.v6.s6_addr[1], 0x80); + fst_check_int_equals(ip.v6.s6_addr[2], 0); + fst_check_int_equals(mask.v6.s6_addr[0], 0xff); + fst_check_int_equals(mask.v6.s6_addr[1], 0xc0); + fst_check_int_equals(mask.v6.s6_addr[2], 0); + + fst_check(!switch_parse_cidr("::/0", &ip, &mask, &bits)); + fst_check_int_equals(bits, 0); + fst_check_int_equals(ip.v6.s6_addr[0], 0); + fst_check_int_equals(ip.v6.s6_addr[1], 0); + fst_check_int_equals(ip.v6.s6_addr[2], 0); + fst_check_int_equals(mask.v6.s6_addr[0], 0); + fst_check_int_equals(mask.v6.s6_addr[1], 0); + fst_check_int_equals(mask.v6.s6_addr[2], 0); + + fst_check(!switch_parse_cidr("::1/128", &ip, &mask, &bits)); + fst_check_int_equals(bits, 128); + fst_check_int_equals(ip.v6.s6_addr[0], 0); + fst_check_int_equals(ip.v6.s6_addr[1], 0); + fst_check_int_equals(ip.v6.s6_addr[2], 0); + fst_check_int_equals(ip.v6.s6_addr[3], 0); + fst_check_int_equals(ip.v6.s6_addr[4], 0); + fst_check_int_equals(ip.v6.s6_addr[5], 0); + fst_check_int_equals(ip.v6.s6_addr[6], 0); + fst_check_int_equals(ip.v6.s6_addr[7], 0); + fst_check_int_equals(ip.v6.s6_addr[8], 0); + fst_check_int_equals(ip.v6.s6_addr[9], 0); + fst_check_int_equals(ip.v6.s6_addr[10], 0); + fst_check_int_equals(ip.v6.s6_addr[11], 0); + fst_check_int_equals(ip.v6.s6_addr[12], 0); + fst_check_int_equals(ip.v6.s6_addr[13], 0); + fst_check_int_equals(ip.v6.s6_addr[14], 0); + fst_check_int_equals(ip.v6.s6_addr[15], 1); + fst_check_int_equals(mask.v6.s6_addr[0], 0xff); + fst_check_int_equals(mask.v6.s6_addr[1], 0xff); + fst_check_int_equals(mask.v6.s6_addr[2], 0xff); + fst_check_int_equals(mask.v6.s6_addr[3], 0xff); + fst_check_int_equals(mask.v6.s6_addr[4], 0xff); + fst_check_int_equals(mask.v6.s6_addr[5], 0xff); + fst_check_int_equals(mask.v6.s6_addr[6], 0xff); + fst_check_int_equals(mask.v6.s6_addr[7], 0xff); + fst_check_int_equals(mask.v6.s6_addr[8], 0xff); + fst_check_int_equals(mask.v6.s6_addr[9], 0xff); + fst_check_int_equals(mask.v6.s6_addr[10], 0xff); + fst_check_int_equals(mask.v6.s6_addr[11], 0xff); + fst_check_int_equals(mask.v6.s6_addr[12], 0xff); + fst_check_int_equals(mask.v6.s6_addr[13], 0xff); + fst_check_int_equals(mask.v6.s6_addr[14], 0xff); + fst_check_int_equals(mask.v6.s6_addr[15], 0xff); + } + FST_TEST_END() + #if ENABLE_SNPRINTFV_TESTS FST_TEST_BEGIN(test_snprintfv_1) { From f5a41d3092acc0d64c3912a2f8b0f692618b2f24 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 5 Oct 2023 18:05:32 +0300 Subject: [PATCH 088/205] [mod_pgsql] Coverity: 1227660 Logically dead code --- src/mod/databases/mod_pgsql/mod_pgsql.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mod/databases/mod_pgsql/mod_pgsql.c b/src/mod/databases/mod_pgsql/mod_pgsql.c index 0308f1f1fd..09d6b32e5c 100644 --- a/src/mod/databases/mod_pgsql/mod_pgsql.c +++ b/src/mod/databases/mod_pgsql/mod_pgsql.c @@ -113,7 +113,7 @@ static int db_is_up(switch_pgsql_handle_t *handle) char *err_str = NULL; int max_tries = DEFAULT_PGSQL_RETRIES; int code = 0; - int recon = 0; + switch_status_t recon = SWITCH_STATUS_FALSE; switch_byte_t sanity = 255; if (handle) { @@ -128,6 +128,7 @@ top: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n"); goto done; } + if (!handle->con) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n"); goto done; @@ -141,6 +142,7 @@ top: switch_yield(1); continue; } + break; } @@ -158,6 +160,7 @@ reset: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n"); goto error; } + handle->state = SWITCH_PGSQL_STATE_CONNECTED; handle->sock = PQsocket(handle->con); } @@ -193,6 +196,7 @@ error: switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n"); } + if (!max_tries) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n"); From 2ab7a3d323984a4df969ea19dadf86213308a361 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 6 Oct 2023 00:42:10 +0300 Subject: [PATCH 089/205] [libvpx] Fix bug with smaller width bigger size --- libs/libvpx/vp9/common/vp9_alloccommon.c | 12 +++++------ libs/libvpx/vp9/encoder/vp9_encoder.c | 27 ++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/libs/libvpx/vp9/common/vp9_alloccommon.c b/libs/libvpx/vp9/common/vp9_alloccommon.c index 7345e259b6..e2d76880bb 100644 --- a/libs/libvpx/vp9/common/vp9_alloccommon.c +++ b/libs/libvpx/vp9/common/vp9_alloccommon.c @@ -123,12 +123,6 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { if (cm->alloc_mi(cm, new_mi_size)) goto fail; } - if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) { - // Create the segmentation map structure and set to 0. - free_seg_map(cm); - if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail; - } - if (cm->above_context_alloc_cols < cm->mi_cols) { vpx_free(cm->above_context); cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc( @@ -143,6 +137,12 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { cm->above_context_alloc_cols = cm->mi_cols; } + if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) { + // Create the segmentation map structure and set to 0. + free_seg_map(cm); + if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail; + } + if (vp9_alloc_loop_filter(cm)) goto fail; return 0; diff --git a/libs/libvpx/vp9/encoder/vp9_encoder.c b/libs/libvpx/vp9/encoder/vp9_encoder.c index 7f82a470b3..80824e304c 100644 --- a/libs/libvpx/vp9/encoder/vp9_encoder.c +++ b/libs/libvpx/vp9/encoder/vp9_encoder.c @@ -1915,6 +1915,17 @@ static void alloc_copy_partition_data(VP9_COMP *cpi) { } } +static void free_copy_partition_data(VP9_COMP *cpi) { + vpx_free(cpi->prev_partition); + cpi->prev_partition = NULL; + vpx_free(cpi->prev_segment_id); + cpi->prev_segment_id = NULL; + vpx_free(cpi->prev_variance_low); + cpi->prev_variance_low = NULL; + vpx_free(cpi->copied_frame_cnt); + cpi->copied_frame_cnt = NULL; +} + void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; @@ -1999,6 +2010,8 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows); if (cm->mi_alloc_size < new_mi_size) { vp9_free_context_buffers(cm); + vp9_free_pc_tree(&cpi->td); + vpx_free(cpi->mbmi_ext_base); alloc_compressor_data(cpi); realloc_segmentation_maps(cpi); cpi->initial_width = cpi->initial_height = 0; @@ -2014,8 +2027,18 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { update_frame_size(cpi); if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) { - memset(cpi->consec_zero_mv, 0, - cm->mi_rows * cm->mi_cols * sizeof(*cpi->consec_zero_mv)); + vpx_free(cpi->consec_zero_mv); + CHECK_MEM_ERROR( + cm, cpi->consec_zero_mv, + vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv))); + + vpx_free(cpi->skin_map); + CHECK_MEM_ERROR( + cm, cpi->skin_map, + vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(cpi->skin_map[0]))); + + free_copy_partition_data(cpi); + alloc_copy_partition_data(cpi); if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_reset_resize(cpi); rc->rc_1_frame = 0; From 104c0b3fec793d414c4fdd6a18996fe9af4c0051 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 29 Sep 2023 08:21:15 +0000 Subject: [PATCH 090/205] [core] Fix flopping routes on ICE negotiation --- src/include/switch_rtp.h | 2 + src/switch_rtp.c | 335 +++++++++++++++++++++++++++++---------- 2 files changed, 251 insertions(+), 86 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index dfcad5453c..7986bdb622 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -103,6 +103,8 @@ typedef struct icand_s { switch_port_t rport; char *generation; uint8_t ready; + uint8_t responsive; + uint8_t use_candidate; } icand_t; #define MAX_CAND 50 diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 506085d86d..5ddf12ec3c 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -254,10 +254,11 @@ typedef struct { uint8_t sending; uint8_t ready; uint8_t rready; - uint8_t init; + uint8_t initializing; int missed_count; char last_sent_id[13]; switch_time_t last_ok; + uint8_t cand_responsive; } switch_rtp_ice_t; struct switch_rtp; @@ -401,7 +402,6 @@ struct switch_rtp { char *eff_remote_host_str; switch_time_t first_stun; switch_time_t last_stun; - uint32_t wrong_addrs; uint32_t samples_per_interval; uint32_t samples_per_second; uint32_t conf_samples_per_interval; @@ -474,7 +474,11 @@ struct switch_rtp { payload_map_t *pmap_tail; kalman_estimator_t *estimators[KALMAN_SYSTEM_MODELS]; cusum_kalman_detector_t *detectors[KALMAN_SYSTEM_MODELS]; - int ice_adj; + switch_time_t last_adj; + switch_time_t adj_window; + uint32_t elapsed_stun; + uint32_t elapsed_media; + uint32_t elapsed_adj; uint8_t has_rtp; uint8_t has_rtcp; uint8_t has_ice; @@ -540,9 +544,25 @@ static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice { int is_rtcp = ice == &rtp_session->rtcp_ice; const char *err = ""; + int i; + uint8_t ice_cand_found_idx = 0; + + for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) { + if (!strcmp(host, ice->ice_params->cands[i][ice->proto].con_addr) && port == ice->ice_params->cands[i][ice->proto].con_port) { + ice_cand_found_idx = i; + } + } + + if (!ice_cand_found_idx) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "ICE candidate [%s:%d] replaced with [%s:%d]\n", + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, host, port); + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr = switch_core_strdup(rtp_session->pool, host); + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port = port; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "ICE chosen candidate [%s:%d] set to idx [%d]\n", host, port, ice_cand_found_idx); + ice->ice_params->chosen[ice->proto] = ice_cand_found_idx; + } - ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr = switch_core_strdup(rtp_session->pool, host); - ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port = port; ice->missed_count = 0; if (is_rtcp) { @@ -796,7 +816,41 @@ static int rtp_common_write(switch_rtp_t *rtp_session, rtp_msg_t *send_msg, void *data, uint32_t datalen, switch_payload_t payload, uint32_t timestamp, switch_frame_flag_t *flags); -static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice) +#define MEDIA_TOO_LONG 2000 +#define STUN_TOO_LONG 20000 +#define ADJ_TOO_LONG 1000 + +static void calc_elapsed(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice) +{ + switch_time_t ref_point; + switch_time_t now; + + now = switch_micro_time_now(); + + if (ice->last_ok && (!rtp_session->dtls || rtp_session->dtls->state == DS_READY)) { + ref_point = ice->last_ok; + } else { + ref_point = rtp_session->first_stun; + } + + if (!ref_point) ref_point = now; + + rtp_session->elapsed_stun = (unsigned int) ((now - ref_point) / 1000); + + if (rtp_session->last_media) { + rtp_session->elapsed_media = (unsigned int) ((now - rtp_session->last_media) / 1000); + } else { + rtp_session->elapsed_media = MEDIA_TOO_LONG + 1; + } + + if (rtp_session->last_adj) { + rtp_session->elapsed_adj = (unsigned int) ((now - rtp_session->last_adj) / 1000); + } else { + rtp_session->elapsed_adj = ADJ_TOO_LONG + 1; + } +} + +static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, switch_bool_t force) { uint8_t buf[256] = { 0 }; switch_stun_packet_t *packet; @@ -812,7 +866,7 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice) return SWITCH_STATUS_BREAK; } - if (ice->next_run && ice->next_run > now) { + if (!force && ice->next_run && ice->next_run >= now) { return SWITCH_STATUS_BREAK; } @@ -907,8 +961,19 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d int ok = 1; uint32_t *pri = NULL; int is_rtcp = ice == &rtp_session->rtcp_ice; - uint32_t elapsed; - switch_time_t ref_point; + switch_channel_t *channel; + int i; + switch_sockaddr_t *from_addr = rtp_session->from_addr; + const char *from_host = NULL; + switch_port_t from_port = 0; + char faddr_buf[80] = ""; + + if (is_rtcp) { + from_addr = rtp_session->rtcp_from_addr; + } + + from_host = switch_get_addr(faddr_buf, sizeof(faddr_buf), from_addr); + from_port = switch_sockaddr_get_port(from_addr); //if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF OK %s CALL\n", rtp_type(rtp_session)); @@ -931,6 +996,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d cpylen = sizeof(buf); } + channel = switch_core_session_get_channel(rtp_session->session); memcpy(buf, data, cpylen); packet = switch_stun_packet_parse(buf, (uint32_t)cpylen); @@ -946,14 +1012,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d rtp_session->first_stun = rtp_session->last_stun; } - if (ice->last_ok && (!rtp_session->dtls || rtp_session->dtls->state == DS_READY)) { - ref_point = ice->last_ok; - } else { - ref_point = rtp_session->first_stun; - } - - elapsed = (unsigned int) ((switch_micro_time_now() - ref_point) / 1000); - + calc_elapsed(rtp_session, ice); end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf)); @@ -968,6 +1027,12 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d case SWITCH_STUN_ATTR_USE_CAND: { ice->rready = 1; + for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) { + if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host) && ice->ice_params->cands[i][ice->proto].con_port == from_port) { + ice->ice_params->cands[i][ice->proto].use_candidate = 1; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Got USE-CANDIDATE on %s:%d\n", ice->ice_params->cands[i][ice->proto].con_addr, ice->ice_params->cands[i][ice->proto].con_port); + } + } } break; case SWITCH_STUN_ATTR_ERROR_CODE: @@ -1048,18 +1113,33 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) { ok = 1; - if (!ice->rready) { - if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { - rtp_session->ice.rready = 1; - rtp_session->rtcp_ice.rready = 1; - } else { - ice->rready = 1; - } - if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - switch_core_session_video_reinit(rtp_session->session); + if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { + rtp_session->ice.rready = 1; + rtp_session->rtcp_ice.rready = 1; + } else { + ice->rready = 1; + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Received STUN Binding Response from %s\n", from_host); + + if (ice->ice_params) { + for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) { + if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host) && ice->ice_params->cands[i][ice->proto].con_port == from_port) { + ice->ice_params->cands[i][ice->proto].responsive = 1; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Marked ICE candidate %s:%d as responsive\n", ice->ice_params->cands[i][ice->proto].con_addr, ice->ice_params->cands[i][ice->proto].con_port); + if (!strcmp(ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, from_host) && ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port == from_port) { + ice->cand_responsive = 1; + ice->initializing = 0; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Chosen ICE candidate %s:%d is responsive\n", ice->ice_params->cands[i][ice->proto].con_addr, ice->ice_params->cands[i][ice->proto].con_port); + } + } } } + + if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { + switch_core_session_video_reinit(rtp_session->session); + } } if (!ok && ice == &rtp_session->ice && rtp_session->rtcp_ice.ice_params && pri && @@ -1084,7 +1164,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_port_t port = 0; char *host = NULL; - if (elapsed > 20000 && pri) { + if (rtp_session->elapsed_stun > STUN_TOO_LONG && pri) { int i, j; uint32_t old; //const char *tx_host; @@ -1176,6 +1256,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "missed too many: %d, looking for new ICE dest.\n", ice->missed_count); ice->rready = 0; + ice->cand_responsive = 0; ok = 1; } @@ -1185,9 +1266,8 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d //} if (ok) { - const char *host = NULL, *host2 = NULL; - switch_port_t port = 0, port2 = 0; - char buf[80] = ""; + const char *host2 = NULL; + switch_port_t port2 = 0; char buf2[80] = ""; if (packet->header.type == SWITCH_STUN_BINDING_REQUEST) { @@ -1196,16 +1276,13 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d const char *remote_ip; switch_size_t bytes; char ipbuf[50]; - switch_sockaddr_t *from_addr = rtp_session->from_addr; switch_socket_t *sock_output = rtp_session->sock_output; uint8_t do_adj = 0; switch_time_t now = switch_micro_time_now(); int cmp = 0; - int cur_idx = -1;//, is_relay = 0; - int i; - + int cur_idx = -1, is_relay = 0, is_responsive = 0, use_candidate = 0; + if (is_rtcp) { - from_addr = rtp_session->rtcp_from_addr; sock_output = rtp_session->rtcp_sock_output; } @@ -1231,58 +1308,123 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d bytes = switch_stun_packet_length(rpacket); - host = switch_get_addr(buf, sizeof(buf), from_addr); - port = switch_sockaddr_get_port(from_addr); host2 = switch_get_addr(buf2, sizeof(buf2), ice->addr); port2 = switch_sockaddr_get_port(ice->addr); cmp = switch_cmp_addr(from_addr, ice->addr, SWITCH_FALSE); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG2, - "STUN from %s:%d %s\n", host, port, cmp ? "EXPECTED" : "IGNORED"); + for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) { + if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host) && ice->ice_params->cands[i][ice->proto].con_port == from_port) { + if (!strcasecmp(ice->ice_params->cands[i][ice->proto].cand_type, "relay")) { + is_relay = 1; + } - if (ice->init && !cmp && switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE)) { - do_adj++; - rtp_session->ice_adj++; - rtp_session->wrong_addrs = 0; - ice->init = 0; - } - - if (cmp) { - ice->last_ok = now; - rtp_session->wrong_addrs = 0; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10, "ICE %d dt:%d i:%d i2:%d w:%d cmp:%d adj:%d\n", elapsed, (rtp_session->dtls && rtp_session->dtls->state != DS_READY), !ice->ready, !ice->rready, rtp_session->wrong_addrs, switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE), rtp_session->ice_adj); + if (ice->ice_params->cands[i][ice->proto].responsive) { + is_responsive = 1; + } - if ((rtp_session->dtls && rtp_session->dtls->state != DS_READY) || - ((!ice->ready || !ice->rready) && (rtp_session->wrong_addrs > 2 || switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE)) && - rtp_session->ice_adj < 10)) { - do_adj++; - rtp_session->ice_adj++; - rtp_session->wrong_addrs = 0; - } else if (rtp_session->wrong_addrs > 10 || elapsed >= 5000) { - do_adj++; - } - - if (!do_adj) { - rtp_session->wrong_addrs++; - } - - for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) { - if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, host)) { - cur_idx = i; - //if (!strcasecmp(ice->ice_params->cands[i][ice->proto].cand_type, "relay")) { - // is_relay = 1; - //} + if (ice->ice_params->cands[i][ice->proto].use_candidate) { + use_candidate = 1; } } - - - if (ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type && - !strcasecmp(ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type, "relay")) { + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, + "%s %s STUN from %s:%d %s is_relay: %d is_responsive: %d use_candidate: %d ready: %d, rready: %d\n", switch_channel_get_name(channel), rtp_type(rtp_session), from_host, from_port, cmp ? "EXPECTED" : "IGNORED", + is_relay, is_responsive, use_candidate, ice->ready, ice->rready); + + if (ice->initializing && !cmp) { + if (!rtp_session->adj_window && (!ice->ready || !ice->rready || (!rtp_session->dtls || rtp_session->dtls->state != DS_READY))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE set ADJUST window to 10 seconds on binding request from %s:%d (is_relay: %d, is_responsivie: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + rtp_session->adj_window = now + 10000000; + } + + if (rtp_session->adj_window) { + if (rtp_session->adj_window > now) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE check: %d >= 3000 or window closed and not from relay on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", rtp_session->elapsed_stun, from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + if (!is_relay && (rtp_session->elapsed_stun >= 3000 || rtp_session->adj_window == (now + 10000000))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 1 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + do_adj++; + rtp_session->last_adj = now; + } + } else { + rtp_session->adj_window = 0; + } + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE CHECK SAME IP DIFFT PORT %d %d on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp",ice->initializing, switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE), from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + if (!do_adj && (switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE) || use_candidate)) { do_adj++; + rtp_session->last_adj = now; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 2 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); } } - + + if (cmp) { + ice->last_ok = now; + } else if (!do_adj) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "ICE %d/%d dt:%d i:%d i2:%d cmp:%d\n", rtp_session->elapsed_stun, rtp_session->elapsed_media, (rtp_session->dtls && rtp_session->dtls->state != DS_READY), !ice->ready, !ice->rready, switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE)); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST ELAPSED vs 1000 %d on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp" ,rtp_session->elapsed_adj, from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + if (rtp_session->elapsed_adj > 1000) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE IF DTLS NOT READY or %d >= 3000 or media too long %d or stun too long %d on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", rtp_session->elapsed_stun, rtp_session->elapsed_media >= MEDIA_TOO_LONG, + rtp_session->elapsed_stun >= STUN_TOO_LONG, from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + if (!is_relay && ((rtp_session->dtls && rtp_session->dtls->state != DS_READY) || + ((!ice->ready || !ice->rready) && (rtp_session->elapsed_stun >= 3000 || switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE))))) { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 3 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + do_adj++; + rtp_session->last_adj = now; + } else if (is_relay && ice->initializing && rtp_session->elapsed_stun >= 1000) { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 4 (FLIP TO TURN) on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + do_adj++; + rtp_session->last_adj = now; + } else if ((ice->initializing && rtp_session->elapsed_stun >= 3000) || + (rtp_session->elapsed_media >= MEDIA_TOO_LONG || rtp_session->elapsed_stun >= STUN_TOO_LONG)) { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 5 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n", + switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate, + ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type); + + do_adj++; + rtp_session->last_adj = now; + } + + for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) { + if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host)) { + cur_idx = i; + } + } + } + } + if ((ice->type & ICE_VANILLA) && ice->ice_params && do_adj) { ice->missed_count = 0; ice->rready = 1; @@ -1294,15 +1436,29 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_NOTICE, "Auto Changing %s stun/%s/dtls port from %s:%u to %s:%u idx:%d\n", rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", host2, port2, - host, port, cur_idx); + from_host, from_port, cur_idx); + + switch_rtp_change_ice_dest(rtp_session, ice, from_host, from_port); + + ice->cand_responsive = is_responsive; + if (ice->cand_responsive) { + ice->initializing = 0; + } - switch_rtp_change_ice_dest(rtp_session, ice, host, port); ice->last_ok = now; - rtp_session->wrong_addrs = 0; } //if (cmp) { switch_socket_sendto(sock_output, from_addr, 0, (void *) rpacket, &bytes); //} + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Send STUN Binding Response to %s:%u\n", from_host, from_port); + + if (ice->initializing && !is_responsive) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Send STUN Binding Request on ICE candidate still unresponsive to %s:%u\n", from_host, from_port); + if (ice_out(rtp_session, ice, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Error sending STUN Binding Request on ICE candidate still unresponsive to %s:%u\n", from_host, from_port); + } + } } } else if (packet->header.type == SWITCH_STUN_BINDING_ERROR_RESPONSE) { @@ -2358,7 +2514,7 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) } if (rtp_session->ice.ice_user) { - if (ice_out(rtp_session, &rtp_session->ice) == SWITCH_STATUS_GENERR) { + if (ice_out(rtp_session, &rtp_session->ice, SWITCH_FALSE) == SWITCH_STATUS_GENERR) { ret = -1; goto end; } @@ -2366,7 +2522,7 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) if (!rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { if (rtp_session->rtcp_ice.ice_user) { - if (ice_out(rtp_session, &rtp_session->rtcp_ice) == SWITCH_STATUS_GENERR) { + if (ice_out(rtp_session, &rtp_session->rtcp_ice, SWITCH_FALSE) == SWITCH_STATUS_GENERR) { ret = -1; goto end; } @@ -2852,10 +3008,9 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session) memset(&rtp_session->ts_norm, 0, sizeof(rtp_session->ts_norm)); rtp_session->last_stun = rtp_session->first_stun = 0; - rtp_session->wrong_addrs = 0; rtp_session->rtcp_sent_packets = 0; rtp_session->rtcp_last_sent = 0; - rtp_session->ice_adj = 0; + rtp_session->last_adj = 0; //switch_rtp_del_dtls(rtp_session, DTLS_TYPE_RTP|DTLS_TYPE_RTCP); switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_PAUSE); @@ -2865,6 +3020,7 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session) if (rtp_session->ice.ready) { switch_rtp_reset_vb(rtp_session); rtp_session->ice.ready = rtp_session->ice.rready = 0; + rtp_session->ice.cand_responsive = 0; } } @@ -3210,13 +3366,18 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls) int r = 0, ret = 0, len; switch_size_t bytes; unsigned char buf[MAX_DTLS_MTU] = ""; - int ready = rtp_session->ice.ice_user ? (rtp_session->ice.rready && rtp_session->ice.ready) : 1; + uint8_t is_ice = rtp_session->ice.ice_user ? 1 : 0; + int ready = is_ice ? (rtp_session->ice.rready && rtp_session->ice.ready) : 1; int pending; if (!dtls->bytes && !ready) { return 0; } + if (is_ice && !rtp_session->ice.cand_responsive) { + return 0; + } + if (dtls->bytes > 0 && dtls->data) { ret = BIO_write(dtls->read_bio, dtls->data, (int)dtls->bytes); if (ret <= 0) { @@ -4764,11 +4925,13 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio switch_snprintf(user_ice, sizeof(user_ice), "%s:%s", rlogin, login); switch_snprintf(luser_ice, sizeof(luser_ice), "%s%s", rlogin, login); ice->ready = ice->rready = 0; + ice->cand_responsive = 0; } else { switch_snprintf(ice_user, sizeof(ice_user), "%s%s", login, rlogin); switch_snprintf(user_ice, sizeof(user_ice), "%s%s", rlogin, login); switch_snprintf(luser_ice, sizeof(luser_ice), ""); ice->ready = ice->rready = 1; + ice->cand_responsive = 0; } ice->ice_user = switch_core_strdup(rtp_session->pool, ice_user); @@ -4779,7 +4942,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio ice->pass = ""; ice->rpass = ""; ice->next_run = switch_micro_time_now(); - ice->init = 1; + ice->initializing = 1; if (password) { ice->pass = switch_core_strdup(rtp_session->pool, password); @@ -5725,7 +5888,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t /* version 2 probably rtp */ rtp_session->has_rtp = (rtp_session->recv_msg.header.version == 2); - if (rtp_session->media_timeout) { + if (rtp_session->media_timeout || rtp_session->ice.ice_user) { rtp_session->last_media = switch_micro_time_now(); } From f05b7507aa28c1a320d839d5c65a72210050dc4d Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Thu, 12 Oct 2023 15:42:23 -0400 Subject: [PATCH 091/205] [mod_conference] Avoid a race in member->read_impl access The conference output loop accesses the member's read_impl while resampling. The output loop also spawns off the input loop thread, which is where the member->read_impl is actually initialised. This results in an uncommon race where the output loop sometimes gets an uninitialised member->read_impl and bails with logs something like this: 2023-10-12 18:19:01.436844 [DEBUG] conference_loop.c:1340 Setup timer soft success interval: 20 samples: 960 from codec L16 2023-10-12 18:19:01.436844 [DEBUG] conference_loop.c:1497 Outbound conference channel answered, setting CFLAG_ANSWERED 2023-10-12 18:19:01.436844 [NOTICE] switch_core_media.c:15852 Activating write resampler 2023-10-12 18:19:01.436844 [DEBUG] switch_core_media.c:16097 Engaging Write Buffer at 1920 bytes to accommodate 0->1920 2023-10-12 18:19:01.436844 [ERR] switch_core_media.c:16112 Write Buffer 0 bytes Failed! As a solution, we initialise the member->read_impl even before we start up the input loop, so that this race can never happen. --- src/mod/applications/mod_conference/conference_loop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index 8f112f5453..f9b7894d0e 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -1316,15 +1316,15 @@ void conference_loop_output(conference_member_t *member) uint32_t flush_len; uint32_t low_count, bytes; call_list_t *call_list, *cp; - switch_codec_implementation_t read_impl = { 0 }, real_read_impl = { 0 }; + switch_codec_implementation_t real_read_impl = { 0 }; int sanity; - switch_core_session_get_read_impl(member->session, &read_impl); + switch_core_session_get_read_impl(member->session, &member->read_impl); switch_core_session_get_real_read_impl(member->session, &real_read_impl); channel = switch_core_session_get_channel(member->session); - interval = read_impl.microseconds_per_packet / 1000; + interval = member->read_impl.microseconds_per_packet / 1000; samples = switch_samples_per_packet(member->conference->rate, interval); //csamples = samples; tsamples = real_read_impl.samples_per_packet; From f7e19e513466e2e489eeebce7a0b72d7c786cad7 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 11 Dec 2023 22:48:00 +0300 Subject: [PATCH 092/205] [mod_sofia] BYE Reason header was limited in length. --- src/mod/endpoints/mod_sofia/mod_sofia.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index f58bb40ac0..458be3f875 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -488,7 +488,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) if (sofia_test_pflag(tech_pvt->profile, PFLAG_DESTROY)) { sofia_set_flag(tech_pvt, TFLAG_BYE); } else if (tech_pvt->nh && !sofia_test_flag(tech_pvt, TFLAG_BYE)) { - char reason[128] = ""; + char *reason = switch_core_session_sprintf(session, ""); char *bye_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX); const char *val = NULL; const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE); @@ -499,15 +499,15 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) if (!val || switch_false(val)) { if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason"))) { - switch_snprintf(reason, sizeof(reason), "%s", val); + reason = switch_core_session_sprintf(session, "%s", val); } else { if ((switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE) && !switch_true(switch_channel_get_variable(channel, "ignore_completed_elsewhere"))) { - switch_snprintf(reason, sizeof(reason), "SIP;cause=200;text=\"Call completed elsewhere\""); + reason = switch_core_session_sprintf(session, "SIP;cause=200;text=\"Call completed elsewhere\""); } else if (cause > 0 && cause < 128) { - switch_snprintf(reason, sizeof(reason), "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause)); + reason = switch_core_session_sprintf(session, "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause)); } else { - switch_snprintf(reason, sizeof(reason), "SIP;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause)); + reason = switch_core_session_sprintf(session, "SIP;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause)); } } } From 48608177d73c9797f9b98a322dcec153bf20b78d Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Tue, 12 Dec 2023 10:03:11 +0000 Subject: [PATCH 093/205] [core] Fix missing 192 key lengths --- src/switch_rtp.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 5ddf12ec3c..5d58e07aad 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4219,6 +4219,20 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_256_HMAC_SHA1_32"); } break; + case AES_CM_192_HMAC_SHA1_80: + srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&policy->rtp); + srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&policy->rtcp); + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_192_HMAC_SHA1_80"); + } + break; + case AES_CM_192_HMAC_SHA1_32: + srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&policy->rtp); + srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&policy->rtcp); + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_192_HMAC_SHA1_32"); + } + break; case AES_CM_128_NULL_AUTH: srtp_crypto_policy_set_aes_cm_128_null_auth(&policy->rtp); srtp_crypto_policy_set_aes_cm_128_null_auth(&policy->rtcp); @@ -4228,6 +4242,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess } break; default: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Missing crypto type!\n"); break; } From c155ea70082ea5a23e4badf757f842ecf6b6c142 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 14 Dec 2023 13:43:33 +0300 Subject: [PATCH 094/205] [Core] Fix implicit conversion from enumeration type 'switch_odbc_status_t' to different enumeration type 'switch_status_t'. --- src/switch_core_sqldb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 817a7a7586..165c9bd8b1 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -702,7 +702,7 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t case SCDB_TYPE_ODBC: { type = "ODBC"; - status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg); + status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; } break; case SCDB_TYPE_CORE_DB: @@ -904,7 +904,7 @@ SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t break; case SCDB_TYPE_ODBC: { - status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err); + status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; } break; case SCDB_TYPE_DATABASE_INTERFACE: @@ -1189,7 +1189,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback(switc break; case SCDB_TYPE_ODBC: { - status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err); + status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; } break; case SCDB_TYPE_CORE_DB: @@ -1248,7 +1248,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback_err(s break; case SCDB_TYPE_ODBC: { - status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err); + status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; if (err && *err) { (*err_callback)(pdata, (const char*)*err); } @@ -1305,7 +1305,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach break; case SCDB_TYPE_ODBC: { - status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err); + status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; } break; case SCDB_TYPE_CORE_DB: @@ -1358,7 +1358,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback_err(switch_ break; case SCDB_TYPE_ODBC: { - status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err); + status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; if (err && *err) { (*err_callback)(pdata, (const char*)*err); } From 2e7424169e7f39ba644f498769ca6b92c4951b4c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 19 Dec 2023 22:42:54 +0300 Subject: [PATCH 095/205] [mod_conference] Remove static from cJSON vars in conference_jlist --- src/mod/applications/mod_conference/mod_conference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index bf03d2a5bc..aa606170d5 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1363,7 +1363,7 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i void conference_jlist(conference_obj_t *conference, cJSON *json_conferences) { conference_member_t *member = NULL; - static cJSON *json_conference, *json_conference_variables, *json_conference_members, *json_conference_member, *json_conference_member_flags; + cJSON *json_conference, *json_conference_variables, *json_conference_members, *json_conference_member, *json_conference_member_flags; switch_event_header_t *hp; switch_assert(conference != NULL); From e9e8e7fe1aa0d62577874be244818b7e233cc296 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Dec 2023 01:09:19 +0300 Subject: [PATCH 096/205] Bump sofia-sip library requirement to version 1.13.17 --- configure.ac | 2 +- debian/bootstrap.sh | 4 ++-- freeswitch.spec | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 9f852e531a..56bf86f53c 100644 --- a/configure.ac +++ b/configure.ac @@ -716,7 +716,7 @@ PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[ AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent]) ]) -PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.15],[ +PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.17],[ AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[ AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent]) ]) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index a2f0261ab6..75a8957509 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -335,7 +335,7 @@ Build-Depends: uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev, # used by many modules libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev, - bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.15), + bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.17), libspandsp3-dev, # used to format the private freeswitch apt-repo key properly gnupg, @@ -374,7 +374,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: libfreeswitch1 Architecture: amd64 armhf -Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.15) +Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.17) Recommends: Suggests: libfreeswitch1-dbg Conflicts: freeswitch-all (<= 1.6.7) diff --git a/freeswitch.spec b/freeswitch.spec index ecf9dacf13..9e3d505e80 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -140,7 +140,7 @@ BuildRequires: curl-devel >= 7.19 BuildRequires: gcc-c++ BuildRequires: libtool >= 1.5.17 BuildRequires: openssl-devel >= 1.0.1e -BuildRequires: sofia-sip-devel >= 1.13.15 +BuildRequires: sofia-sip-devel >= 1.13.17 BuildRequires: spandsp3-devel >= 3.0 BuildRequires: pcre-devel BuildRequires: speex-devel From 6ea8c96c3db9944d0542a4a7b04fc54712334da2 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 29 Sep 2023 15:25:53 +0000 Subject: [PATCH 097/205] [Core] Reject DTLS packets coming from a source different than the current ICE negotiated path. --- src/switch_rtp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 5d58e07aad..1125e2f59b 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3374,7 +3374,20 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls) return 0; } - if (is_ice && !rtp_session->ice.cand_responsive) { + if (is_ice && !(rtp_session->ice.type & ICE_LITE) && !rtp_session->ice.cand_responsive) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Got DTLS packet but candidate is not responsive\n"); + + return 0; + } + + if (is_ice && !switch_cmp_addr(rtp_session->from_addr, rtp_session->ice.addr, SWITCH_TRUE)) { + char tmp_buf1[80] = ""; + char tmp_buf2[80] = ""; + const char *host_from = switch_get_addr(tmp_buf1, sizeof(tmp_buf1), rtp_session->from_addr); + const char *host_ice_cur_addr = switch_get_addr(tmp_buf2, sizeof(tmp_buf2), rtp_session->ice.addr); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Got DTLS packet from [%s] whilst current ICE negotiated address is [%s]. Ignored.\n", host_from, host_ice_cur_addr); + return 0; } From 6ae8ce604a7e4a55835bf3a01fd8a775c98211ff Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Dec 2023 17:12:41 +0000 Subject: [PATCH 098/205] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 44 +++++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 32 ++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 742e4f979e..bba26c8f9b 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -45237,6 +45237,50 @@ SWIGEXPORT unsigned char SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_ready_get_ } +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_responsive_set___(void * jarg1, unsigned char jarg2) { + icand_s *arg1 = (icand_s *) 0 ; + uint8_t arg2 ; + + arg1 = (icand_s *)jarg1; + arg2 = (uint8_t)jarg2; + if (arg1) (arg1)->responsive = arg2; +} + + +SWIGEXPORT unsigned char SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_responsive_get___(void * jarg1) { + unsigned char jresult ; + icand_s *arg1 = (icand_s *) 0 ; + uint8_t result; + + arg1 = (icand_s *)jarg1; + result = (uint8_t) ((arg1)->responsive); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_use_candidate_set___(void * jarg1, unsigned char jarg2) { + icand_s *arg1 = (icand_s *) 0 ; + uint8_t arg2 ; + + arg1 = (icand_s *)jarg1; + arg2 = (uint8_t)jarg2; + if (arg1) (arg1)->use_candidate = arg2; +} + + +SWIGEXPORT unsigned char SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_use_candidate_get___(void * jarg1) { + unsigned char jresult ; + icand_s *arg1 = (icand_s *) 0 ; + uint8_t result; + + arg1 = (icand_s *)jarg1; + result = (uint8_t) ((arg1)->use_candidate); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_FreeSWITCHfNative_new_icand_t___() { void * jresult ; icand_s *result = 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 02848257bf..fbab2f3f77 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -26316,6 +26316,18 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_ready_get___")] public static extern byte icand_t_ready_get(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_responsive_set___")] + public static extern void icand_t_responsive_set(global::System.Runtime.InteropServices.HandleRef jarg1, byte jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_responsive_get___")] + public static extern byte icand_t_responsive_get(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_use_candidate_set___")] + public static extern void icand_t_use_candidate_set(global::System.Runtime.InteropServices.HandleRef jarg1, byte jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_use_candidate_get___")] + public static extern byte icand_t_use_candidate_get(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_new_icand_t___")] public static extern global::System.IntPtr new_icand_t(); @@ -28339,6 +28351,26 @@ public class icand_t : global::System.IDisposable { } } + public byte responsive { + set { + freeswitchPINVOKE.icand_t_responsive_set(swigCPtr, value); + } + get { + byte ret = freeswitchPINVOKE.icand_t_responsive_get(swigCPtr); + return ret; + } + } + + public byte use_candidate { + set { + freeswitchPINVOKE.icand_t_use_candidate_set(swigCPtr, value); + } + get { + byte ret = freeswitchPINVOKE.icand_t_use_candidate_get(swigCPtr); + return ret; + } + } + public icand_t() : this(freeswitchPINVOKE.new_icand_t(), true) { } From 987e87bc0b37d5707b180d9834cdaf748a2e925d Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Dec 2023 22:37:54 +0300 Subject: [PATCH 099/205] version bump --- build/next-release.txt | 2 +- configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/next-release.txt b/build/next-release.txt index 63fd3adc74..a3426275e7 100644 --- a/build/next-release.txt +++ b/build/next-release.txt @@ -1 +1 @@ -1.10.11-dev +1.10.12-dev diff --git a/configure.ac b/configure.ac index 56bf86f53c..e4ab33ae5c 100644 --- a/configure.ac +++ b/configure.ac @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.10.11-dev], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.10.12-dev], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [10]) -AC_SUBST(SWITCH_VERSION_MICRO, [11-dev]) +AC_SUBST(SWITCH_VERSION_MICRO, [12-dev]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 0cea9811cd6c39604280ced6b16c0e2429c4ec6c Mon Sep 17 00:00:00 2001 From: tmancill <1195611+tmancill@users.noreply.github.com> Date: Fri, 5 Jan 2024 07:42:58 -0800 Subject: [PATCH 100/205] [Docker] Change default freeswitch UID and GID to 499 in docker/master/Dockerfile On several installs on recent Debian and Ubuntu systems, I have noticed that GID 999 is already allocated on the system running the container, making it a minor hassle to share a common freeswitch UID and GID between the Docker host and the container. The conflicting group id varies, but is typically either one of the systemd groups or polkitd, which are dynamically created when those packages are installed. The behavior stems from the range of system GIDs being between 100-999 ([see Debian Policy 9.2.2](https://www.debian.org/doc/debian-policy/ch-opersys.html#uid-and-gid-classes)) and the fact that system installation dynamically allocates from this range. I didn't track down exactly why these daemons are allocating from the top of the range, since the default behavior of `adduser` and `addgroup` ([link](https://salsa.debian.org/debian/adduser/-/blob/6c04aa701a2ca09efbff9094ab07e7dae14554fc/adduser#L1255-1269)) is to search from the bottom of the range, and the manpage for `groupadd` says that it's default is also to use the smallest id, but perhaps it was to avoid (other) conflicts. The approach taken in this PR is to default to 499, more in the middle of the range, which should reduce the chance of conflicting with an existing system UID and GID. The values are also now exposed as ARGs and so can be explicitly set during the build with `--build-arg="FREESWITCH_UID=xxx"` and `--build-arg="FREESWITCH_GID=yyy"` if desired. --- docker/master/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/master/Dockerfile b/docker/master/Dockerfile index 4c73ecc6e4..d036164ac7 100644 --- a/docker/master/Dockerfile +++ b/docker/master/Dockerfile @@ -20,7 +20,9 @@ ARG FS_META_PACKAGE=freeswitch-meta-all # https://github.com/docker-library/postgres/blob/master/9.4/Dockerfile # explicitly set user/group IDs -RUN groupadd -r freeswitch --gid=999 && useradd -r -g freeswitch --uid=999 freeswitch +ARG FREESWITCH_UID=499 +ARG FREESWITCH_GID=499 +RUN groupadd -r freeswitch --gid=${FREESWITCH_GID} && useradd -r -g freeswitch --uid=${FREESWITCH_UID} freeswitch # make the "en_US.UTF-8" locale so freeswitch will be utf-8 enabled by default RUN apt-get update -qq \ From a6e219062dd30a0c6b9b53b3dc0864a83924a8d9 Mon Sep 17 00:00:00 2001 From: Visytel <59720603+Visytel@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:00:28 +1100 Subject: [PATCH 101/205] [Build-System, ldns] config.h change to not define inline under Windows to avoid clash with Windows winsock2.h inline usage. Use updated ldns tarball on Windows. * [ldns] config.h change to not define inline under Windows to avoid clash with Windows winsock2.h inline usage * [Build-System] Use updated ldns tarball on Windows. --------- Co-authored-by: Andrey Volk --- libs/win32/ldns/ldns-lib/config.h | 4 +++- w32/download_LDNS.props | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/win32/ldns/ldns-lib/config.h b/libs/win32/ldns/ldns-lib/config.h index 58463456b3..fb29bc2c7c 100644 --- a/libs/win32/ldns/ldns-lib/config.h +++ b/libs/win32/ldns/ldns-lib/config.h @@ -260,7 +260,9 @@ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus -#define inline +#ifndef _WIN32 +#define inline /* Do not define inline for Windows to avoid warnings/errors with winsock2.h usage of inline within the latest Windows SDKs */ +#endif #endif #if _MSC_VER >= 1900 diff --git a/w32/download_LDNS.props b/w32/download_LDNS.props index 445fe9a2b9..0036e1f278 100644 --- a/w32/download_LDNS.props +++ b/w32/download_LDNS.props @@ -29,7 +29,7 @@ Date: Wed, 10 Jan 2024 17:01:26 +0100 Subject: [PATCH 102/205] [mod_amqp] Adjusting to Appropriate Log Level for Message * [mod_amqp] Adjusting to Appropriate Log Level for Message Refined Logging Level for FreeSWITCH's mod_amqp: The logging level for the AMQP module in FreeSWITCH has been updated from 'warning' to 'debug'. This adjustment ensures a more suitable level for the log message and eliminates any potential impact on production environments. Previously, the 'warning' level would lead to unnecessary log entries for each individual message, although there was no actual warning condition. This change improves logging efficiency and appropriateness for mod_amqp's operations within FreeSWITCH. * [MOD_AMQP] Change LogLevel to DEBUG1 as it is more appropriate for this message --- src/mod/event_handlers/mod_amqp/mod_amqp_command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c index 2789a6e252..48cdf55ce4 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c @@ -231,7 +231,7 @@ static void mod_amqp_command_response(mod_amqp_command_profile_t *profile, char } /* Construct the api response */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Preparing api command response: [%s]\n", (char *)stream.data); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Preparing api command response: [%s]\n", (char *)stream.data); message = cJSON_CreateObject(); cJSON_AddItemToObject(message, "output", cJSON_CreateString((const char *) stream.data)); From d148a3e412dbe1772a0e6f8a39e9a9b480c49268 Mon Sep 17 00:00:00 2001 From: Dmitry Kunilov <38783480+dkunilov@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:50:08 +0300 Subject: [PATCH 103/205] [mod_amr, mod_amrwb] Fix input data corruption * Fix input data corruption in AMR and AMRWB codecs * [amr/amrwb] Check encoded frame size before decoding * [mod_amr, mod_amrwb] Coding guidelines cleanup. --------- Co-authored-by: Dmitry Kunilov Co-authored-by: Andrey Volk --- src/mod/codecs/mod_amr/mod_amr.c | 19 ++++++++++++++++--- src/mod/codecs/mod_amrwb/mod_amrwb.c | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index e7c45c7aff..0769f62f3a 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -250,6 +250,7 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ int x, i, argc, fmtptmp_pos; char *argv[10]; char fmtptmp[128]; + char *fmtp_dup = NULL; encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); @@ -283,13 +284,19 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ switch_set_flag(context, AMR_OPT_OCTET_ALIGN); } if (codec->fmtp_in) { - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + fmtp_dup = strdup(codec->fmtp_in); + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { char *data = argv[x]; char *arg; + while (*data && *data == ' ') { data++; } + if ((arg = strchr(data, '='))) { *arg++ = '\0'; if (!strcasecmp(data, "octet-align")) { @@ -325,13 +332,17 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ } else if (!strcasecmp(data, "mode-set")) { int y, m_argc; char *m_argv[SWITCH_AMR_MODES-1]; + m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); + for (y = 0; y < m_argc; y++) { context->enc_modes |= (1 << atoi(m_argv[y])); } } } } + + free(fmtp_dup); } if (context->enc_modes) { @@ -475,13 +486,15 @@ static switch_status_t switch_amr_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; #else struct amr_context *context = codec->private_info; - unsigned char *buf = encoded_data; + unsigned char buf[SWITCH_AMR_OUT_MAX_SIZE]; uint8_t tmp[SWITCH_AMR_OUT_MAX_SIZE]; - if (!context) { + if (!context || encoded_data_len > SWITCH_AMR_OUT_MAX_SIZE) { return SWITCH_STATUS_FALSE; } + memcpy(buf, encoded_data, encoded_data_len); + if (globals.debug) { switch_amr_info(codec, buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder"); } diff --git a/src/mod/codecs/mod_amrwb/mod_amrwb.c b/src/mod/codecs/mod_amrwb/mod_amrwb.c index 8be5f4d541..4ac3f25f37 100644 --- a/src/mod/codecs/mod_amrwb/mod_amrwb.c +++ b/src/mod/codecs/mod_amrwb/mod_amrwb.c @@ -198,6 +198,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla int x, i, argc, fmtptmp_pos; char *argv[10]; char fmtptmp[128]; + char *fmtp_dup = NULL; encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); @@ -222,13 +223,19 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } if (codec->fmtp_in) { - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + fmtp_dup = strdup(codec->fmtp_in); + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { char *data = argv[x]; char *arg; + while (*data && *data == ' ') { data++; } + if ((arg = strchr(data, '='))) { *arg++ = '\0'; if (!strcasecmp(data, "octet-align")) { @@ -264,7 +271,9 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } else if (!strcasecmp(data, "mode-set")) { int y, m_argc; char *m_argv[SWITCH_AMRWB_MODES-1]; /* AMRWB has 9 modes */ + m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); + for (y = 0; y < m_argc; y++) { context->enc_modes |= (1 << atoi(m_argv[y])); context->enc_mode = atoi(m_argv[y]); @@ -272,6 +281,8 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } } } + + free(fmtp_dup); } if (context->enc_modes && !globals.mode_set_overwrite) { @@ -401,13 +412,15 @@ static switch_status_t switch_amrwb_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; #else struct amrwb_context *context = codec->private_info; - unsigned char *buf = encoded_data; + unsigned char buf[SWITCH_AMRWB_OUT_MAX_SIZE]; uint8_t tmp[SWITCH_AMRWB_OUT_MAX_SIZE]; - if (!context) { + if (!context || encoded_data_len > SWITCH_AMRWB_OUT_MAX_SIZE) { return SWITCH_STATUS_FALSE; } + memcpy(buf, encoded_data, encoded_data_len); + if (globals.debug) { switch_amrwb_info(codec, buf, encoded_data_len, switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, "AMRWB decoder"); } From 1c057191002b8fbcabf31d6810fb1a834a148607 Mon Sep 17 00:00:00 2001 From: wmasilva Date: Wed, 24 Jan 2024 19:04:32 +0000 Subject: [PATCH 104/205] [Core] softtimer: fix crash in timezones when reloading xml * switch_time: fix segfault null TIMEZONES_LIST.hash when reloading xml * Unbind before destroying TIMEZONES_LIST.hash. Protect TIMEZONES_LIST.hash with a mutex that's allocated in core's global runtime.memory_pool so the mutex does not die on softtimer shutdown. --------- Co-authored-by: Andrey Volk --- src/switch_time.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/switch_time.c b/src/switch_time.c index a56c5e96f1..1ee581453a 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -1384,10 +1384,13 @@ SWITCH_DECLARE(const char *) switch_lookup_timezone(const char *tz_name) return NULL; } + switch_mutex_lock(globals.mutex); if ((value = switch_core_hash_find(TIMEZONES_LIST.hash, tz_name)) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timezone '%s' not found!\n", tz_name); } + switch_mutex_unlock(globals.mutex); + return value; } @@ -1522,7 +1525,7 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load) #endif memset(&globals, 0, sizeof(globals)); - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); + switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); @@ -1599,18 +1602,21 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown) DeleteCriticalSection(&timer_section); #endif + if (NODE) { + switch_event_unbind(&NODE); + } + + switch_mutex_lock(globals.mutex); if (TIMEZONES_LIST.hash) { switch_core_hash_destroy(&TIMEZONES_LIST.hash); } + switch_mutex_unlock(globals.mutex); + if (TIMEZONES_LIST.pool) { switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool); } - if (NODE) { - switch_event_unbind(&NODE); - } - return SWITCH_STATUS_SUCCESS; } From 8b7a8c4aea5906ab3988764c4077c205151695e6 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Wed, 18 Oct 2023 20:24:14 +0300 Subject: [PATCH 105/205] [core] SDP: replace SIP lingo in SDP offer/answer. --- src/include/switch_types.h | 6 +- .../applications/mod_dptools/mod_dptools.c | 2 +- src/mod/endpoints/mod_loopback/mod_loopback.c | 2 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 22 ++--- src/mod/endpoints/mod_sofia/sofia.c | 50 +++++------ src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/mod/endpoints/mod_verto/mod_verto.c | 22 ++--- src/mod/languages/mod_managed/managed/swig.cs | 4 +- src/switch_core_media.c | 88 +++++++++---------- src/switch_ivr.c | 2 +- tests/unit/switch_rtp.c | 2 +- tests/unit/switch_rtp_pcap.c | 2 +- 12 files changed, 103 insertions(+), 101 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 94a4c62cca..d315e46fc8 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2656,10 +2656,12 @@ struct switch_live_array_s; typedef struct switch_live_array_s switch_live_array_t; typedef enum { - SDP_TYPE_REQUEST, - SDP_TYPE_RESPONSE + SDP_OFFER, + SDP_ANSWER } switch_sdp_type_t; +#define SDP_TYPE_REQUEST SDP_OFFER +#define SDP_TYPE_RESPONSE SDP_ANSWER typedef enum { AEAD_AES_256_GCM_8, diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index f52b1184e5..58fce5f5d3 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -593,7 +593,7 @@ SWITCH_STANDARD_APP(filter_codecs_function) r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); if (data && r_sdp) { - switch_core_media_merge_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST, data); + switch_core_media_merge_sdp_codec_string(session, r_sdp, SDP_OFFER, data); switch_channel_set_variable(channel, "filter_codec_string", data); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Incomplete data\n"); diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 456936562a..f5941eae36 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1429,7 +1429,7 @@ static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_sess // switch_core_media_check_video_codecs(session); // switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0); // switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0); - // switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, "127.0.0.1", 2000, NULL, 0); + // switch_core_media_gen_local_sdp(session, SDP_OFFER, "127.0.0.1", 2000, NULL, 0); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", mparams.local_sdp_str); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 458be3f875..c5ce6e3855 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -790,7 +790,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); tech_pvt->mparams.local_sdp_str = NULL; switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); } else if (is_3pcc_proxy) { if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY))) { @@ -802,7 +802,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } else { switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); } @@ -889,7 +889,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); //switch_mutex_lock(tech_pvt->sofia_mutex); //nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); @@ -904,7 +904,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) return status; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } @@ -1598,7 +1598,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE); port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); if (ip && port) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), msg->string_arg, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, ip, (switch_port_t)atoi(port), msg->string_arg, 1); } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { @@ -1783,7 +1783,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); status = SWITCH_STATUS_FALSE; goto end_lock; @@ -1793,7 +1793,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } - switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_TYPE_RESPONSE); + switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_ANSWER); switch_channel_set_variable(tech_pvt->channel, "absolute_codec_string", switch_channel_get_variable(tech_pvt->channel, "ep_codec_string")); switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); @@ -1802,7 +1802,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi goto end_lock; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); if (!msg->numeric_arg) { if (send_invite) { @@ -2256,7 +2256,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_clear_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE); switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -2584,7 +2584,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "CODEC NEGOTIATION ERROR. SDP:\n%s\n", r_sdp ? r_sdp : "NO SDP!"); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); @@ -2599,7 +2599,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end_lock; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c5b5bcc190..311052a619 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6683,7 +6683,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status tech_pvt->mparams.last_sdp_response = NULL; if (sip->sip_payload && sip->sip_payload->pl_data) { - switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE); + switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_ANSWER); if (!zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) { tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response; @@ -7506,9 +7506,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_mark_pre_answered(channel); } //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { - // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE); + // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_OFFER : SDP_ANSWER); //} - switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST); + switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_OFFER); sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp); sofia_set_flag(tech_pvt, TFLAG_NEW_SDP); @@ -7680,7 +7680,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } else { - if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END()); @@ -7776,7 +7776,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE); if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } if (!match) { @@ -7785,7 +7785,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END()); } } else { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED"); sofia_set_flag_locked(tech_pvt, TFLAG_READY); @@ -7909,7 +7909,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, uint8_t match = 0; if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } if (!match) { @@ -7995,7 +7995,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); switch_channel_set_state(channel, CS_HIBERNATE); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0); sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); if (sofia_use_soa(tech_pvt)) { @@ -8067,10 +8067,10 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(channel, CF_NOSDP_REINVITE); if (switch_channel_var_true(channel, "sip_unhold_nosdp")) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, "sendrecv", + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, "sendrecv", zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE)); } else { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE)); } @@ -8116,13 +8116,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag(tech_pvt, TFLAG_SDP); - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); if (match) { if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { goto done; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Media RTP Error!\n"); @@ -8191,7 +8191,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); switch_core_session_rwunlock(other_session); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -8210,7 +8210,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 1); if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -8320,7 +8320,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->mparams.num_codecs){ - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } if (!match) { @@ -8369,7 +8369,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_use_soa(tech_pvt)){ nua_respond(tech_pvt->nh, SIP_200_OK, SIPTAG_CONTACT_STR(tech_pvt->reply_contact), @@ -8419,7 +8419,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } @@ -8438,7 +8438,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n"); @@ -8462,7 +8462,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (is_ok) { if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); } if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) { @@ -8507,13 +8507,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); } if (match) { if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { goto done; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n"); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); @@ -8571,9 +8571,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (tech_pvt->mparams.num_codecs) { if (sofia_test_flag(tech_pvt, TFLAG_GOT_ACK)) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } else { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); } } @@ -8668,7 +8668,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, uint8_t match = 0; - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); sofia_set_flag_locked(tech_pvt, TFLAG_ANS); @@ -10466,7 +10466,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia if (r_sdp) { - switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST); + switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_OFFER); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index eceae218f8..1452a7cf0f 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1158,7 +1158,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0); } sofia_set_flag_locked(tech_pvt, TFLAG_READY); diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index ac042fe626..48c40527b5 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -1320,7 +1320,7 @@ static void tech_reattach(verto_pvt_t *tech_pvt, jsock_t *jsock) switch_channel_set_flag(tech_pvt->channel, CF_REATTACHED); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); switch_channel_set_flag(tech_pvt->channel, CF_RECOVERING); - switch_core_media_gen_local_sdp(tech_pvt->session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(tech_pvt->session, SDP_OFFER, NULL, 0, NULL, 0); switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE); switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING); switch_core_session_request_video_refresh(tech_pvt->session); @@ -2405,7 +2405,7 @@ static switch_status_t verto_connect(switch_core_session_t *session, const char } } - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0); } msg = jrpc_new_req(method, tech_pvt->call_id, ¶ms); @@ -2641,7 +2641,7 @@ static switch_status_t verto_media(switch_core_session_t *session) switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); if (tech_pvt->r_sdp) { - if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); return SWITCH_STATUS_FALSE; } @@ -2653,7 +2653,7 @@ static switch_status_t verto_media(switch_core_session_t *session) return status; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (switch_core_media_activate_rtp(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -2963,7 +2963,7 @@ static switch_bool_t verto__answer_func(const char *method, cJSON *params, jsock switch_channel_set_variable(tech_pvt->channel, SWITCH_R_SDP_VARIABLE, sdp); switch_channel_set_variable(tech_pvt->channel, "verto_client_address", jsock->name); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP %s:\n%s\n", switch_channel_get_name(tech_pvt->channel), sdp); - switch_core_media_set_sdp_codec_string(session, sdp, SDP_TYPE_RESPONSE); + switch_core_media_set_sdp_codec_string(session, sdp, SDP_ANSWER); if (!switch_channel_var_true(switch_core_session_get_channel(session),"verto_skip_set_user")) { switch_ivr_set_user(session, jsock->uid); @@ -2978,7 +2978,7 @@ static switch_bool_t verto__answer_func(const char *method, cJSON *params, jsock if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) { pass_sdp(tech_pvt); } else { - if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_TYPE_RESPONSE) != SWITCH_STATUS_SUCCESS) { + if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_ANSWER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); cJSON_AddItemToObject(obj, "message", cJSON_CreateString("CODEC ERROR")); err = 1; @@ -3448,8 +3448,8 @@ static switch_bool_t verto__modify_func(const char *method, cJSON *params, jsock //switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_BREAK); //switch_core_session_kill_channel(tech_pvt->session, SWITCH_SIG_BREAK); - if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_TYPE_REQUEST)) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_OFFER)) { + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (switch_core_media_activate_rtp(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "MEDIA ERROR"); @@ -3606,8 +3606,8 @@ static switch_bool_t verto__attach_func(const char *method, cJSON *params, jsock //switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_BREAK); //switch_core_session_kill_channel(tech_pvt->session, SWITCH_SIG_BREAK); - if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_TYPE_RESPONSE)) { - //switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_ANSWER)) { + //switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (switch_core_media_activate_rtp(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "MEDIA ERROR"); @@ -4020,7 +4020,7 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock tech_pvt->channel = channel; tech_pvt->jsock_uuid = switch_core_session_strdup(session, jsock->uuid_str); tech_pvt->r_sdp = switch_core_session_strdup(session, sdp); - switch_core_media_set_sdp_codec_string(session, sdp, SDP_TYPE_REQUEST); + switch_core_media_set_sdp_codec_string(session, sdp, SDP_OFFER); switch_core_session_set_private_class(session, tech_pvt, SWITCH_PVT_SECONDARY); tech_pvt->call_id = switch_core_session_strdup(session, call_id); diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index fbab2f3f77..dc3926cbbb 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -45055,8 +45055,8 @@ public class switch_scheduler_task : global::System.IDisposable { namespace FreeSWITCH.Native { public enum switch_sdp_type_t { - SDP_TYPE_REQUEST, - SDP_TYPE_RESPONSE + SDP_OFFER, + SDP_ANSWER } } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 4b6d8aff8b..58ef94a53e 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -713,7 +713,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { - if (sdp_type == SDP_TYPE_RESPONSE) { + if (sdp_type == SDP_ANSWER) { switch(type) { case SWITCH_MEDIA_TYPE_TEXT: exists = (type == pmap->type && !strcasecmp(name, pmap->iananame)); @@ -722,11 +722,11 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime)); break; case SWITCH_MEDIA_TYPE_VIDEO: - exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame)); + exists = (pmap->sdp_type == SDP_OFFER && type == pmap->type && !strcasecmp(name, pmap->iananame)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECK PMAP %s:%s %d %s:%s %d ... %d\n", name, "RES", pt, - pmap->iananame, pmap->sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pmap->pt, exists); + pmap->iananame, pmap->sdp_type == SDP_OFFER ? "REQ" : "RES", pmap->pt, exists); break; @@ -797,7 +797,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se } if (!zstr(fmtp)) { - if (sdp_type == SDP_TYPE_REQUEST || !exists) { + if (sdp_type == SDP_OFFER || !exists) { pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp); } } @@ -807,7 +807,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se pmap->recv_pt = (switch_payload_t) pt; - if (sdp_type == SDP_TYPE_REQUEST || !exists) { + if (sdp_type == SDP_OFFER || !exists) { pmap->pt = (switch_payload_t) pt; } @@ -818,7 +818,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se if (!exists) { pmap->sdp_type = sdp_type; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ADD PMAP %s %s %d\n", sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", name, pt); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ADD PMAP %s %s %d\n", sdp_type == SDP_OFFER ? "REQ" : "RES", name, pt); if (pmap == engine->payload_map) { engine->pmap_tail = pmap; @@ -1724,7 +1724,7 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio const char *a = switch_stristr("AE", engine->ssec[engine->crypto_type].remote_crypto_key); const char *b = switch_stristr("AE", crypto); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { if (!vval) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto); goto end; @@ -4633,7 +4633,7 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s switch_channel_set_flag(other_session->channel, CF_PROCESSING_STREAM_CHANGE); switch_channel_set_flag(session->channel, CF_AWAITING_STREAM_CHANGE); - if (sdp_type == SDP_TYPE_REQUEST && r_sdp) { + if (sdp_type == SDP_OFFER && r_sdp) { const char *filter_codec_string = switch_channel_get_variable(session->channel, "filter_codec_string"); switch_channel_set_variable(session->channel, "codec_string", NULL); @@ -4654,7 +4654,7 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s } if (other_session) { - if (sdp_type == SDP_TYPE_RESPONSE && switch_channel_test_flag(session->channel, CF_PROCESSING_STREAM_CHANGE)) { + if (sdp_type == SDP_ANSWER && switch_channel_test_flag(session->channel, CF_PROCESSING_STREAM_CHANGE)) { switch_channel_clear_flag(session->channel, CF_PROCESSING_STREAM_CHANGE); if (switch_channel_test_flag(other_session->channel, CF_AWAITING_STREAM_CHANGE)) { @@ -4667,7 +4667,7 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s } sdp_in = switch_channel_get_variable(other_session->channel, SWITCH_R_SDP_VARIABLE); - res = switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST); + res = switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_OFFER); (void)res; switch_core_media_activate_rtp(other_session); msg = switch_core_session_alloc(other_session, sizeof(*msg)); @@ -4715,11 +4715,11 @@ SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session, engine->pass_codecs = 0; if (switch_channel_var_true(session->channel, "rtp_pass_codecs_on_stream_change")) { - if (sdp_type == SDP_TYPE_REQUEST && switch_channel_test_flag(session->channel, CF_REINVITE) && + if (sdp_type == SDP_OFFER && switch_channel_test_flag(session->channel, CF_REINVITE) && switch_channel_media_up(session->channel) && (pass_codecs || old_smode != smode)) { if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - switch_core_media_set_smode(other_session, type, opp_smode, SDP_TYPE_REQUEST); + switch_core_media_set_smode(other_session, type, opp_smode, SDP_OFFER); switch_channel_set_flag(session->channel, CF_STREAM_CHANGED); switch_core_session_rwunlock(other_session); } @@ -4752,7 +4752,7 @@ static void switch_core_media_set_rmode(switch_core_session_t *session, switch_m if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { + if (sdp_type == SDP_ANSWER && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { switch_core_media_set_smode(other_session, type, rmode, sdp_type); } @@ -5099,7 +5099,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 REFUSE on %s\n", switch_channel_get_name(channel), - sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + sdp_type == SDP_ANSWER ? "response" : "request"); restore_pmaps(a_engine); fmatch = 0; @@ -5112,7 +5112,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 ACCEPT on %s\n", switch_channel_get_name(channel), - sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + sdp_type == SDP_ANSWER ? "response" : "request"); if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) { if (proceed) *proceed = 0; @@ -5217,7 +5217,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 %s POSSIBLE on %s\n", switch_channel_get_name(channel), fmatch ? "IS" : "IS NOT", - sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + sdp_type == SDP_ANSWER ? "response" : "request"); goto done; @@ -5249,7 +5249,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(m->m_mode), sdp_type); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { switch(a_engine->rmode) { case SWITCH_MEDIA_FLOW_RECVONLY: switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDONLY, sdp_type); @@ -5315,7 +5315,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(session->channel, "media_audio_mode", NULL); } - if (sdp_type == SDP_TYPE_RESPONSE) { + if (sdp_type == SDP_ANSWER) { if (inactive) { // When freeswitch had previously sent inactive in sip request. it should remain inactive otherwise smode should be sendrecv if (a_engine->smode==SWITCH_MEDIA_FLOW_INACTIVE) { @@ -5834,7 +5834,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (smh->mparams->dtmf_type == DTMF_AUTO || smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) { - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { smh->mparams->te = smh->mparams->recv_te = (switch_payload_t) best_te; switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833"); smh->mparams->dtmf_type = DTMF_2833; @@ -5902,7 +5902,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s map->rm_encoding, NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, map->rm_pt, 1000, 0, @@ -5980,7 +5980,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, sdp_media_flow(m->m_mode), sdp_type); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { sdp_bandwidth_t *bw; int tias = 0; @@ -6146,7 +6146,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } - if (sdp_type == SDP_TYPE_RESPONSE && consider_video_fmtp && vmatch && !zstr(map->rm_fmtp) && !zstr(smh->fmtps[i])) { + if (sdp_type == SDP_ANSWER && consider_video_fmtp && vmatch && !zstr(map->rm_fmtp) && !zstr(smh->fmtps[i])) { almost_vmatch = 1; vmatch = !strcasecmp(smh->fmtps[i], map->rm_fmtp); } @@ -6321,7 +6321,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s "L16", NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, 97, 8000, 20, @@ -6378,7 +6378,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (switch_channel_test_flag(channel, CF_VIDEO) && !saw_video) { //switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type); } } @@ -9708,7 +9708,7 @@ static const char *get_media_profile_name(switch_core_session_t *session, int se static char *get_setup(switch_rtp_engine_t *engine, switch_core_session_t *session, switch_sdp_type_t sdp_type) { - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { engine->dtls_controller = 0; engine->new_dtls = 1; engine->new_ice = 1; @@ -9809,7 +9809,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, } if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95) { - if (sdp_type == SDP_TYPE_RESPONSE) { + if (sdp_type == SDP_ANSWER) { switch_rtp_engine_t *a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; if (a_engine) { payload_map_t *pmap; @@ -9915,7 +9915,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, if ((smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) { - if (smh->mparams->dtmf_type == DTMF_2833 && sdp_type == SDP_TYPE_RESPONSE) { + if (smh->mparams->dtmf_type == DTMF_2833 && sdp_type == SDP_ANSWER) { switch_rtp_engine_t *a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; if (a_engine) { payload_map_t *pmap; @@ -10264,7 +10264,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess v_engine->rtcp_mux = -1; } - if ((a_engine->rtcp_mux != -1 && v_engine->rtcp_mux != -1) && (sdp_type == SDP_TYPE_REQUEST)) { + if ((a_engine->rtcp_mux != -1 && v_engine->rtcp_mux != -1) && (sdp_type == SDP_OFFER)) { a_engine->rtcp_mux = 1; v_engine->rtcp_mux = 1; } @@ -10347,7 +10347,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess continue; } - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { for (j = 0; j < SWITCH_MAX_CODECS; j++) { if (smh->rates[j] == 0) { break; @@ -10365,7 +10365,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess continue; } - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { switch_core_session_t *orig_session = NULL; switch_core_session_get_partner(session, &orig_session); @@ -11180,7 +11180,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } } - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { fir++; pli++; nack++; @@ -11441,7 +11441,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess // RTP TEXT - if (sdp_type == SDP_TYPE_RESPONSE && !switch_channel_test_flag(session->channel, CF_RTT)) { + if (sdp_type == SDP_ANSWER && !switch_channel_test_flag(session->channel, CF_RTT)) { if (switch_channel_test_flag(session->channel, CF_TEXT_SDP_RECVD)) { switch_channel_clear_flag(session->channel, CF_TEXT_SDP_RECVD); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=text 0 %s 19\r\n", @@ -11456,7 +11456,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess t_engine->t140_pt = 0; t_engine->red_pt = 0; - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { t_engine->t140_pt = 96; t_engine->red_pt = 97; @@ -11465,7 +11465,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess "red", NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, t_engine->red_pt, 1000, 0, @@ -11477,7 +11477,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess "t140", NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, t_engine->t140_pt, 1000, 0, @@ -11978,7 +11978,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) "PROXY", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 8000, 20, @@ -12135,7 +12135,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) "PROXY-VID", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 90000, 90000, @@ -12198,7 +12198,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) "PROXY-TXT", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 90000, 90000, @@ -13099,7 +13099,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_core_media_prepare_codecs(session, 1); clear_pmaps(a_engine); clear_pmaps(v_engine); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, ip, (switch_port_t)atoi(port), NULL, 1); } } @@ -13151,7 +13151,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_core_media_prepare_codecs(session, SWITCH_TRUE); switch_core_media_check_video_codecs(session); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); } if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) { @@ -13964,7 +13964,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ "PROXY", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 8000, 20, @@ -13980,7 +13980,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ "PROXY-VID", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 90000, 90000, @@ -14001,7 +14001,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ "PROXY-TXT", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 1000, 1000, @@ -14155,7 +14155,7 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s } } - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); switch_core_media_set_video_codec(session, 1); if (switch_core_media_activate_rtp(session) != SWITCH_STATUS_SUCCESS) { diff --git a/src/switch_ivr.c b/src/switch_ivr.c index c36149c0a5..1443f989cf 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2151,7 +2151,7 @@ SWITCH_DECLARE(void) switch_ivr_check_hold(switch_core_session_t *session) msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA_RENEG; msg.from = __FILE__; - switch_core_media_set_smode(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDRECV, SDP_TYPE_REQUEST); + switch_core_media_set_smode(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDRECV, SDP_OFFER); switch_core_session_receive_message(session, &msg); } diff --git a/tests/unit/switch_rtp.c b/tests/unit/switch_rtp.c index 48c0f80d6b..7d22524358 100644 --- a/tests/unit/switch_rtp.c +++ b/tests/unit/switch_rtp.c @@ -187,7 +187,7 @@ FST_TEARDOWN_END() switch_core_media_prepare_codecs(session, SWITCH_FALSE); - match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_TYPE_REQUEST); + match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_OFFER); fst_requires(match == 1); status = switch_core_media_choose_ports(session, SWITCH_TRUE, SWITCH_FALSE); diff --git a/tests/unit/switch_rtp_pcap.c b/tests/unit/switch_rtp_pcap.c index 647e481c8e..eb4993a616 100644 --- a/tests/unit/switch_rtp_pcap.c +++ b/tests/unit/switch_rtp_pcap.c @@ -206,7 +206,7 @@ static switch_status_t rtp_test_start_call(switch_core_session_t **psession) return SWITCH_STATUS_FALSE; } - match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_TYPE_REQUEST); + match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_OFFER); if (match != 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_core_media_negotiate_sdp() failed\n"); return SWITCH_STATUS_FALSE; From 9df3076f29a52a690ebd25b1972a8b97d55442e0 Mon Sep 17 00:00:00 2001 From: Anton Olofsson Date: Mon, 29 Jan 2024 17:05:45 +0100 Subject: [PATCH 106/205] [mod_event_socket] Check if listener is running before pushing more logs or events to its queue This fixes a possibility for MAX_MISSED to be exceeded if more logs are attempted to be pushed to the listener's queue after running kill_listener but before the listener thread gets CPU time and removes itself. On a heavily loaded system with a lot of logs in the event dispatch queue these excessive logs may prove fatal since socket_logger itself will produce logs about the full queue, resulting in a circular situation of never-ending logs. The same logic was applied to event_handler after finding the same behaviour mentioned in signalwire/freeswitch#2143. --- src/mod/event_handlers/mod_event_socket/mod_event_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 520bd92ac7..935f726ee1 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -173,7 +173,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l switch_status_t qstatus; switch_mutex_lock(globals.listener_mutex); for (l = listen_list.listeners; l; l = l->next) { - if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) { + if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level && switch_test_flag(l, LFLAG_RUNNING)) { switch_log_node_t *dnode = switch_log_node_dup(node); qstatus = switch_queue_trypush(l->log_queue, dnode); if (qstatus == SWITCH_STATUS_SUCCESS) { @@ -302,7 +302,7 @@ static void event_handler(switch_event_t *event) } } - if (l->expire_time || !switch_test_flag(l, LFLAG_EVENTS)) { + if (l->expire_time || !switch_test_flag(l, LFLAG_EVENTS) || !switch_test_flag(l, LFLAG_RUNNING)) { last = l; continue; } From 647035c323369acb75fac18d13f2cf1a635ffff4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 5 Feb 2024 23:50:01 +0300 Subject: [PATCH 107/205] [mod_opus] Fix status returned by switch_opus_decode(). Should be SWITCH_STATUS_FALSE instead of SWITCH_STATUS_NOOP. Add a unit-test. --- Freeswitch.2017.sln | 15 ++ src/mod/codecs/mod_opus/mod_opus.c | 2 +- tests/unit/switch_core_codec.c | 26 +++ .../unit/test_switch_core_codec.2017.vcxproj | 205 ++++++++++++++++++ 4 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test_switch_core_codec.2017.vcxproj diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 5f3259a6e0..0326ffac12 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -554,6 +554,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core_db", "test EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_ivr_originate", "tests\unit\test_switch_ivr_originate.2017.vcxproj", "{69A7464A-9B0D-4804-A108-835229DACF58}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core_codec", "tests\unit\test_switch_core_codec.2017.vcxproj", "{589A07E7-5DE5-49FD-A62C-27795B806AFB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Win32 = All|Win32 @@ -2516,6 +2518,18 @@ Global {69A7464A-9B0D-4804-A108-835229DACF58}.Release|Win32.Build.0 = Release|Win32 {69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.ActiveCfg = Release|x64 {69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.Build.0 = Release|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|Win32.ActiveCfg = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|Win32.Build.0 = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|x64.ActiveCfg = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|x64.Build.0 = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|Win32.ActiveCfg = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|Win32.Build.0 = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|x64.ActiveCfg = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|x64.Build.0 = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|Win32.ActiveCfg = Release|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|Win32.Build.0 = Release|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|x64.ActiveCfg = Release|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2714,6 +2728,7 @@ Global {0B612F84-7533-4DEC-AEDD-5C9CBCF15EAC} = {31C2761D-20E0-4BF8-98B9-E32F0D8DD6E1} {580675D7-C1C9-4197-AAC5-00F64FAFDE78} = {9388C266-C3FC-468A-92EF-0CBC35941412} {69A7464A-9B0D-4804-A108-835229DACF58} = {9388C266-C3FC-468A-92EF-0CBC35941412} + {589A07E7-5DE5-49FD-A62C-27795B806AFB} = {9388C266-C3FC-468A-92EF-0CBC35941412} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {09840DE7-9208-45AA-9667-1A71EE93BD1E} diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index a38389d031..96933e6ea5 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -930,7 +930,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, if (samples < 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n", opus_strerror(samples), frame_size, plc ? "true" : "false"); - return SWITCH_STATUS_NOOP; + return SWITCH_STATUS_FALSE; } *decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); diff --git a/tests/unit/switch_core_codec.c b/tests/unit/switch_core_codec.c index 61a70314a4..2c499e1314 100644 --- a/tests/unit/switch_core_codec.c +++ b/tests/unit/switch_core_codec.c @@ -127,6 +127,32 @@ FST_CORE_BEGIN("./conf") } FST_TEST_END() + + FST_TEST_BEGIN(test_mod_opus_switch_status_false) + { + signed char outbuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; + uint32_t decoded_len = 0; + uint32_t decoded_rate = 48000; + unsigned int flags = 0; + switch_codec_t orig_codec = { 0 }; + switch_status_t status; + switch_codec_settings_t codec_settings = { { 0 } }; + status = switch_core_codec_init(&orig_codec, + "OPUS", + "mod_opus", + NULL, + 48000, + 20, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + &codec_settings, fst_pool); + fst_check(status == SWITCH_STATUS_SUCCESS); + + status = switch_core_codec_decode(&orig_codec, NULL, "test", 5, 48000, outbuf, &decoded_len, &decoded_rate, &flags); + fst_check_int_equals(status, SWITCH_STATUS_FALSE); + switch_core_codec_destroy(&orig_codec); + } + FST_TEST_END() + } FST_SUITE_END() } diff --git a/tests/unit/test_switch_core_codec.2017.vcxproj b/tests/unit/test_switch_core_codec.2017.vcxproj new file mode 100644 index 0000000000..1434d80475 --- /dev/null +++ b/tests/unit/test_switch_core_codec.2017.vcxproj @@ -0,0 +1,205 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + test_switch_core_codec + test_switch_core_codec + Win32Proj + 10.0.17134.0 + {589A07E7-5DE5-49FD-A62C-27795B806AFB} + + + + Application + MultiByte + $(DefaultPlatformToolset) + + + Application + MultiByte + $(DefaultPlatformToolset) + + + Application + MultiByte + $(DefaultPlatformToolset) + + + Application + MultiByte + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(PlatformName)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(PlatformName)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + $(SolutionDir)src\include;%(AdditionalIncludeDirectories) + SWITCH_TEST_BASE_DIR_FOR_CONF="..\\..\\tests\\unit\\";%(PreprocessorDefinitions) + + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + true + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + true + Console + true + + + MachineX86 + + + + + + X64 + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + true + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + true + Console + true + + + MachineX64 + + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + false + Console + true + true + true + + + MachineX86 + + + + + + X64 + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + false + Console + true + true + true + + + MachineX64 + + + + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + \ No newline at end of file From eb5476ff6659035f3bd180354f37968797a4a557 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 15 Feb 2024 18:51:46 +0100 Subject: [PATCH 108/205] [build] Split `create_dsc` and `create-orig` functions in `util.sh`. --- debian/util.sh | 140 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 26 deletions(-) diff --git a/debian/util.sh b/debian/util.sh index 110e6d8763..bc11f0bac1 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -135,50 +135,94 @@ get_nightly_revision_human () { echo "git $(git rev-list -n1 --abbrev=7 --abbrev-commit HEAD) $(date -u '+%Y-%m-%d %H:%M:%SZ')" } -create_orig () { +prep_create_orig () { { set -e + local OPTIND OPTARG - local uver="" hrev="" bundle_deps=true modules_list="" zl=9e + local uver="" hrev="" bundle_deps=true + while getopts 'bm:nv:z:' o "$@"; do case "$o" in - m) modules_list="$OPTARG";; + b) ;; + m) ;; n) uver="nightly";; v) uver="$OPTARG";; - z) zl="$OPTARG";; + z) ;; esac done shift $(($OPTIND-1)) + if [ -z "$uver" ] || [ "$uver" = "nightly" ]; then uver="$(get_nightly_version)" hrev="$(get_nightly_revision_human)" fi - local treeish="$1" dver="$(mk_dver "$uver")" - local orig="../freeswitch_$dver~$(lsb_release -sc).orig.tar.xz" + + local treeish="$1" [ -n "$treeish" ] || treeish="HEAD" + check_repo_clean git reset --hard "$treeish" + + if $bundle_deps; then + (cd libs && getlibs) + fi + + ./build/set-fs-version.sh "$uver" "$hrev" # ToDo: Handle empty $hrev + + echo "$uver" > .version + } 1>&2 + echo "$uver" +} + +create_orig () { + { + set -e + + local OPTIND OPTARG + local bundle_deps=true modules_list="" zl=9e + + local uver="$(prep_create_orig "$@")" + + while getopts 'bm:nv:z:' o "$@"; do + case "$o" in + b) ;; + m) modules_list="$OPTARG";; + n) ;; + v) ;; + z) zl="$OPTARG";; + esac + done + shift $(($OPTIND-1)) + + local dver="$(mk_dver "$uver")" + local orig="../freeswitch_$dver~$(lsb_release -sc).orig.tar.xz" + mv .gitattributes .gitattributes.orig + local -a args=(-e '\bdebian-ignore\b') test "$modules_list" = "non-dfsg" || args+=(-e '\bdfsg-nonfree\b') grep .gitattributes.orig "${args[@]}" \ | while xread l; do echo "$l export-ignore" >> .gitattributes done + if $bundle_deps; then - (cd libs && getlibs) git add -f libs fi - ./build/set-fs-version.sh "$uver" "$hrev" && git add configure.ac - echo "$uver" > .version && git add -f .version + + git add -f configure.ac .version git commit --allow-empty -m "nightly v$uver" + git archive -v \ --worktree-attributes \ --format=tar \ --prefix=freeswitch-$uver/ \ HEAD \ | xz -c -${zl}v > $orig + mv .gitattributes.orig .gitattributes + git reset --hard HEAD^ && git clean -fdx } 1>&2 echo $orig @@ -190,11 +234,12 @@ applications/mod_commands EOF } -create_dsc () { +prep_create_dsc () { { set -e - local OPTIND OPTARG modules_conf="" modules_list="" speed="normal" suite_postfix="" suite_postfix_p=false zl=9 - local modules_add="" + + local OPTIND OPTARG modules_conf="" modules_add="" modules_list="" speed="normal" + while getopts 'a:f:m:p:s:u:z:' o "$@"; do case "$o" in a) avoid_mods_arch="$OPTARG";; @@ -202,46 +247,87 @@ create_dsc () { m) modules_list="$OPTARG";; p) modules_add="$modules_add $OPTARG";; s) speed="$OPTARG";; - u) suite_postfix="$OPTARG"; suite_postfix_p=true;; - z) zl="$OPTARG";; + u) ;; + z) ;; esac done shift $(($OPTIND-1)) - local distro="$(find_distro $1)" orig="$2" - local suite="$(find_suite $distro)" - local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')" - local dver="${orig_ver}-1~${distro}+1" - $suite_postfix_p && { suite="${distro}${suite_postfix}"; } - [ -x "$(which dch)" ] \ - || err "package devscripts isn't installed" + + local distro="$(find_distro $1)" + if [ -n "$modules_conf" ]; then cp $modules_conf debian/modules.conf fi + local bootstrap_args="" + if [ -n "$modules_list" ]; then if [ "$modules_list" = "non-dfsg" ]; then bootstrap_args="-mnon-dfsg" - else set_modules_${modules_list}; fi + else + set_modules_${modules_list} + fi fi + if test -n "$modules_add"; then for x in $modules_add; do bootstrap_args="$bootstrap_args -p${x}" done fi + (cd debian && ./bootstrap.sh -a "$avoid_mods_arch" -c $distro $bootstrap_args) + case "$speed" in paranoid) sed -i ./debian/rules \ -e '/\.stamp-bootstrap:/{:l2 n; /\.\/bootstrap.sh -j/{s/ -j//; :l3 n; b l3}; b l2};' ;; reckless) sed -i ./debian/rules \ -e '/\.stamp-build:/{:l2 n; /make/{s/$/ -j/; :l3 n; b l3}; b l2};' ;; esac + } 1>&2 +} + +create_dsc () { + { + set -e + + prep_create_dsc "$@" + + local OPTIND OPTARG suite_postfix="" suite_postfix_p=false zl=9 + + while getopts 'a:f:m:p:s:u:z:' o "$@"; do + case "$o" in + a) ;; + f) ;; + m) ;; + p) ;; + s) ;; + u) suite_postfix="$OPTARG"; suite_postfix_p=true;; + z) zl="$OPTARG";; + esac + done + shift $(($OPTIND-1)) + + local distro="$(find_distro $1)" orig="$2" + local suite="$(find_suite $distro)" + local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')" + local dver="${orig_ver}-1~${distro}+1" + + $suite_postfix_p && { suite="${distro}${suite_postfix}"; } + + [ -x "$(which dch)" ] \ + || err "package devscripts isn't installed" + [ "$zl" -ge "1" ] || zl=1 - git add debian/rules + dch -b -m -v "$dver" --force-distribution -D "$suite" "Nightly build." - git add debian/changelog && git commit -m "nightly v$orig_ver" + + git add debian/rules debian/changelog && git commit -m "nightly v$orig_ver" + dpkg-source -i.* -Zxz -z${zl} -b . dpkg-genchanges -S > ../$(dsc_base)_source.changes + local dsc="../$(dsc_base).dsc" + git reset --hard HEAD^ && git clean -fdx } 1>&2 echo $dsc @@ -588,7 +674,7 @@ commands: create-dbg-pkgs - create-dsc + create-dsc (same for 'prep-create-dsc') -f Build only modules listed in this file @@ -602,7 +688,7 @@ commands: Specify a custom suite postfix -z Set compression level - create-orig + create-orig (same for 'prep_create_orig') -m [ quicktest | non-dfsg ] Choose custom list of modules to build @@ -629,7 +715,9 @@ case "$cmd" in build-all) build_all "$@" ;; build-debs) build_debs "$@" ;; create-dbg-pkgs) create_dbg_pkgs ;; + prep-create-dsc) prep_create_dsc "$@" ;; create-dsc) create_dsc "$@" ;; + prep-create-orig) prep_create_orig "$@" ;; create-orig) create_orig "$@" ;; *) usage ;; esac From 70d76bcc0e9970f1d0f49d16413f3e061735d87f Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 21 Feb 2024 21:27:35 +0300 Subject: [PATCH 109/205] [Core] Remove mod_kazoo from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - conf/vanilla/autoload_configs/kazoo.conf.xml | 215 --- configure.ac | 1 - debian/bootstrap.sh | 2 - debian/control-modules | 6 - freeswitch.spec | 16 +- src/mod/event_handlers/mod_kazoo/Makefile.am | 37 - .../event_handlers/mod_kazoo/kazoo.conf.xml | 1275 ------------- src/mod/event_handlers/mod_kazoo/kazoo_api.c | 573 ------ src/mod/event_handlers/mod_kazoo/kazoo_cdr.c | 630 ------ .../event_handlers/mod_kazoo/kazoo_commands.c | 592 ------ .../event_handlers/mod_kazoo/kazoo_config.c | 553 ------ .../event_handlers/mod_kazoo/kazoo_config.h | 63 - .../mod_kazoo/kazoo_definitions.S | 8 - src/mod/event_handlers/mod_kazoo/kazoo_defs.h | 9 - .../event_handlers/mod_kazoo/kazoo_dptools.c | 980 ---------- src/mod/event_handlers/mod_kazoo/kazoo_ei.h | 295 --- .../mod_kazoo/kazoo_ei_config.c | 708 ------- .../event_handlers/mod_kazoo/kazoo_ei_utils.c | 1089 ----------- .../mod_kazoo/kazoo_endpoints.c | 500 ----- .../mod_kazoo/kazoo_event_stream.c | 750 -------- .../mod_kazoo/kazoo_fetch_agent.c | 803 -------- .../event_handlers/mod_kazoo/kazoo_fields.h | 203 -- .../event_handlers/mod_kazoo/kazoo_message.c | 488 ----- .../event_handlers/mod_kazoo/kazoo_message.h | 66 - src/mod/event_handlers/mod_kazoo/kazoo_node.c | 1694 ----------------- .../event_handlers/mod_kazoo/kazoo_tweaks.c | 666 ------- .../event_handlers/mod_kazoo/kazoo_tweaks.h | 32 - .../event_handlers/mod_kazoo/kazoo_utils.c | 700 ------- .../event_handlers/mod_kazoo/kazoo_utils.h | 51 - src/mod/event_handlers/mod_kazoo/kz_node.c | 91 - src/mod/event_handlers/mod_kazoo/mod_kazoo.c | 152 -- src/mod/event_handlers/mod_kazoo/mod_kazoo.h | 87 - 34 files changed, 1 insertion(+), 13336 deletions(-) delete mode 100644 conf/vanilla/autoload_configs/kazoo.conf.xml delete mode 100644 src/mod/event_handlers/mod_kazoo/Makefile.am delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo.conf.xml delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_api.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_cdr.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_commands.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_config.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_config.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_definitions.S delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_defs.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_dptools.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_ei.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_fields.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_message.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_message.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_node.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_utils.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_utils.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kz_node.c delete mode 100644 src/mod/event_handlers/mod_kazoo/mod_kazoo.c delete mode 100644 src/mod/event_handlers/mod_kazoo/mod_kazoo.h diff --git a/build/modules.conf.in b/build/modules.conf.in index 7bf59e2acc..8453e290b7 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -110,7 +110,6 @@ event_handlers/mod_event_socket #event_handlers/mod_json_cdr #event_handlers/mod_radius_cdr #event_handlers/mod_odbc_cdr -#event_handlers/mod_kazoo #event_handlers/mod_rayo #event_handlers/mod_smpp #event_handlers/mod_snmp diff --git a/build/modules.conf.most b/build/modules.conf.most index fbf8100a90..62595a4891 100644 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -104,7 +104,6 @@ event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_format_cdr event_handlers/mod_json_cdr -event_handlers/mod_kazoo #event_handlers/mod_radius_cdr event_handlers/mod_odbc_cdr event_handlers/mod_rayo diff --git a/conf/vanilla/autoload_configs/kazoo.conf.xml b/conf/vanilla/autoload_configs/kazoo.conf.xml deleted file mode 100644 index b730523d4c..0000000000 --- a/conf/vanilla/autoload_configs/kazoo.conf.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
- - - diff --git a/configure.ac b/configure.ac index e4ab33ae5c..348103f8db 100644 --- a/configure.ac +++ b/configure.ac @@ -2208,7 +2208,6 @@ AC_CONFIG_FILES([Makefile src/mod/event_handlers/mod_fail2ban/Makefile src/mod/event_handlers/mod_format_cdr/Makefile src/mod/event_handlers/mod_json_cdr/Makefile - src/mod/event_handlers/mod_kazoo/Makefile src/mod/event_handlers/mod_radius_cdr/Makefile src/mod/event_handlers/mod_odbc_cdr/Makefile src/mod/event_handlers/mod_rayo/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 75a8957509..aba9e38bf7 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -673,7 +673,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-event-multicast (= \${binary:Version}), freeswitch-mod-event-socket (= \${binary:Version}), freeswitch-mod-json-cdr (= \${binary:Version}), - freeswitch-mod-kazoo (= \${binary:Version}), freeswitch-mod-snmp (= \${binary:Version}), freeswitch-mod-local-stream (= \${binary:Version}), freeswitch-mod-native-file (= \${binary:Version}), @@ -910,7 +909,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-event-multicast-dbg (= \${binary:Version}), freeswitch-mod-event-socket-dbg (= \${binary:Version}), freeswitch-mod-json-cdr-dbg (= \${binary:Version}), - freeswitch-mod-kazoo-dbg (= \${binary:Version}), freeswitch-mod-snmp-dbg (= \${binary:Version}), freeswitch-mod-local-stream-dbg (= \${binary:Version}), freeswitch-mod-native-file-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 3179f8eeef..0f0784d3f5 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -542,12 +542,6 @@ Module: event_handlers/mod_json_cdr Description: mod_json_cdr Adds mod_json_cdr. -Module: event_handlers/mod_kazoo -Description: mod_kazoo - Adds mod_kazoo. -Build-Depends: erlang-dev -Depends: erlang - Module: event_handlers/mod_odbc_cdr Description: mod_odbc_cdr Adds mod_odbc_cdr. diff --git a/freeswitch.spec b/freeswitch.spec index 9e3d505e80..98ce36cb90 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -952,16 +952,6 @@ Requires: %{name} = %{version}-%{release} %description event-format-cdr JSON and XML Logger for the FreeSWITCH open source telephony platform -%package kazoo -Summary: Kazoo Module for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} -Requires: erlang -BuildRequires: erlang - -%description kazoo -Kazoo Module for FreeSWITCH. - %package event-multicast Summary: Multicast Event System for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1480,7 +1470,7 @@ ENDPOINTS_MODULES=" \ ###################################################################################################################### EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_sqlite \ event_handlers/mod_cdr_mongodb event_handlers/mod_format_cdr event_handlers/mod_erlang_event event_handlers/mod_event_multicast \ - event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_kazoo event_handlers/mod_radius_cdr \ + event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_radius_cdr \ event_handlers/mod_snmp" %if %{build_mod_rayo} EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo" @@ -1916,7 +1906,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/http_cache.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/ivr.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/java.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/kazoo.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/lcr.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/local_stream.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/logfile.conf.xml @@ -2286,9 +2275,6 @@ fi %files event-json-cdr %{MODINSTDIR}/mod_json_cdr.so* -%files kazoo -%{MODINSTDIR}/mod_kazoo.so* - %files event-radius-cdr %{MODINSTDIR}/mod_radius_cdr.so* diff --git a/src/mod/event_handlers/mod_kazoo/Makefile.am b/src/mod/event_handlers/mod_kazoo/Makefile.am deleted file mode 100644 index 36e7a9ea4a..0000000000 --- a/src/mod/event_handlers/mod_kazoo/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_kazoo - -if HAVE_ERLANG - -KAZOO_DEFS=kazoo_definitions.o - -mod_LTLIBRARIES = mod_kazoo.la -mod_kazoo_la_SOURCES = mod_kazoo.c kazoo_utils.c kazoo_dptools.c kazoo_tweaks.c -mod_kazoo_la_SOURCES += kazoo_api.c kazoo_commands.c kazoo_config.c -mod_kazoo_la_SOURCES += kazoo_message.c -mod_kazoo_la_SOURCES += kazoo_ei_config.c kazoo_ei_utils.c kazoo_event_stream.c -mod_kazoo_la_SOURCES += kazoo_fetch_agent.c kazoo_node.c -mod_kazoo_la_SOURCES += kazoo_endpoints.c -mod_kazoo_la_SOURCES += kazoo_cdr.c -mod_kazoo_la_SOURCES += kz_node.c - -mod_kazoo_la_CFLAGS = $(AM_CFLAGS) @ERLANG_CFLAGS@ -D_REENTRANT -DERLANG_VERSION=@ERLANG_VERSION@ -DERLANG_MAJOR=@ERLANG_MAJOR@ -DERLANG_MINOR=@ERLANG_MINOR@ -mod_kazoo_la_LIBADD = $(KAZOO_DEFS) $(switch_builddir)/libfreeswitch.la -mod_kazoo_la_LDFLAGS = -avoid-version -module -no-undefined -shared @ERLANG_LDFLAGS@ - -BUILT_SOURCES = $(KAZOO_DEFS) - -$(KAZOO_DEFS): kazoo.conf.xml - -.S.o: $< - @$(CC) $(CFLAGS) -o $@ -c $< - -install-exec-am: - @install `which epmd` $(DESTDIR)$(bindir)/fs_epmd - -else -install: error -all: error -error: - $(error You must install erlang to build this module) -endif diff --git a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml deleted file mode 100644 index 4422af121b..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml +++ /dev/null @@ -1,1275 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_api.c b/src/mod/event_handlers/mod_kazoo/kazoo_api.c deleted file mode 100644 index 96f9ff7bb4..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_api.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * mod_kazoo.c -- Socket Controlled Event Handler - * - */ -#include "mod_kazoo.h" - -#define KAZOO_DESC "kazoo information" -#define KAZOO_SYNTAX " []" - -#define API_COMMAND_DISCONNECT 0 -#define API_COMMAND_REMOTE_IP 1 -#define API_COMMAND_STREAMS 2 -#define API_COMMAND_BINDINGS 3 -#define API_COMMAND_OPTION 4 - -#define API_NODE_OPTION_FRAMING 0 -#define API_NODE_OPTION_KEEPALIVE 1 -#define API_NODE_OPTION_LEGACY 2 -#define API_NODE_OPTION_MAX 99 - -static const char *node_runtime_options[] = { - "event-stream-framing", - "event-stream-keepalive", - "enable-legacy", - NULL -}; - -static int api_find_node_option(char *option) { - int i; - for(i = 0; node_runtime_options[i] != NULL; i++) { - if(!strcasecmp(option, node_runtime_options[i])) { - return i; - } - } - return API_NODE_OPTION_MAX; -} - -static switch_status_t api_get_node_option(ei_node_t *ei_node, switch_stream_handle_t *stream, char *arg) { - int option = api_find_node_option(arg); - switch_status_t ret = SWITCH_STATUS_SUCCESS; - switch (option) { - case API_NODE_OPTION_FRAMING: - stream->write_function(stream, "+OK %i", ei_node->event_stream_framing); - break; - - case API_NODE_OPTION_KEEPALIVE: - stream->write_function(stream, "+OK %i", ei_node->event_stream_keepalive); - break; - - case API_NODE_OPTION_LEGACY: - stream->write_function(stream, "+OK %s", ei_node->legacy ? "true" : "false"); - break; - - default: - stream->write_function(stream, "-ERR invalid option %s", arg); - ret = SWITCH_STATUS_NOTFOUND; - break; - } - - return ret; -} - -static switch_status_t api_set_node_option(ei_node_t *ei_node, switch_stream_handle_t *stream, char *name, char *value) { - int option = api_find_node_option(name); - short val; - switch_status_t ret = SWITCH_STATUS_SUCCESS; - switch (option) { - case API_NODE_OPTION_FRAMING: - val = atoi(value); - if (val != 1 && val != 2 && val != 4) { - stream->write_function(stream, "-ERR Invalid event stream framing value (%i)", val); - ret = SWITCH_STATUS_GENERR; - } else { - stream->write_function(stream, "+OK %i", val); - ei_node->event_stream_framing = val; - } - break; - - case API_NODE_OPTION_KEEPALIVE: - val = switch_true(value); - stream->write_function(stream, "+OK %i", val); - ei_node->event_stream_keepalive = val; - break; - - case API_NODE_OPTION_LEGACY: - ei_node->legacy = switch_true(value); - stream->write_function(stream, "+OK %s", ei_node->legacy ? "true" : "false"); - break; - - default: - stream->write_function(stream, "-ERR invalid option %s", name); - ret = SWITCH_STATUS_NOTFOUND; - break; - } - - return ret; -} - -static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48]; - const char *ip_addr; - ei_node_t *ei_node; - - switch_socket_addr_get(&sa, SWITCH_FALSE, kazoo_globals.acceptor); - - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - - stream->write_function(stream, "Running %s\n", VERSION); - stream->write_function(stream, "Listening for new Erlang connections on %s:%u with cookie %s\n", ip_addr, port, kazoo_globals.ei_cookie); - stream->write_function(stream, "Registered as Erlang node %s, visible as %s\n", kazoo_globals.ei_cnode.thisnodename, kazoo_globals.ei_cnode.thisalivename); - - if (kazoo_globals.ei_compat_rel) { - stream->write_function(stream, "Using Erlang compatibility mode: %d\n", kazoo_globals.ei_compat_rel); - } - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - if (!ei_node) { - stream->write_function(stream, "No erlang nodes connected\n"); - } else { - stream->write_function(stream, "Connected to:\n"); - while(ei_node != NULL) { - unsigned int year, day, hour, min, sec, delta; - - delta = (switch_micro_time_now() - ei_node->created_time) / 1000000; - sec = delta % 60; - min = delta / 60 % 60; - hour = delta / 3600 % 24; - day = delta / 86400 % 7; - year = delta / 31556926 % 12; - stream->write_function(stream, " %s (%s:%d) up %d years, %d days, %d hours, %d minutes, %d seconds\n" - ,ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, year, day, hour, min, sec); - ei_node = ei_node->next; - } - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) { - switch_hash_index_t *hi = NULL; - int column = 0; - int idx = 0; - - for (hi = (switch_hash_index_t *)switch_core_hash_first_iter(kazoo_globals.event_filter, hi); hi; hi = switch_core_hash_next(&hi)) { - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - stream->write_function(stream, "%-50s", (char *)key); - if (++column > 2) { - stream->write_function(stream, "\n"); - column = 0; - } - } - - if (++column > 2) { - stream->write_function(stream, "\n"); - } - - while(kazoo_globals.kazoo_var_prefixes[idx] != NULL) { - char var[100]; - char *prefix = kazoo_globals.kazoo_var_prefixes[idx]; - sprintf(var, "%s*", prefix); - stream->write_function(stream, "%-50s", var); - idx++; - } - - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_nodes_list(switch_stream_handle_t *stream) { - ei_node_t *ei_node; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - stream->write_function(stream, "%s (%s)\n", ei_node->peer_nodename, ei_node->remote_ip); - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_nodes_count(switch_stream_handle_t *stream) { - ei_node_t *ei_node; - int count = 0; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - count++; - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - stream->write_function(stream, "%d\n", count); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_complete_erlang_node(const char *line, const char *cursor, switch_console_callback_match_t **matches) { - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - ei_node_t *ei_node; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - switch_console_push_match(&my_matches, ei_node->peer_nodename); - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_stream, switch_stream_handle_t *stream) { - ei_event_binding_t *binding; - int column = 0; - - switch_mutex_lock(event_stream->socket_mutex); - if (event_stream->connected == SWITCH_FALSE) { - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48] = {0}; - const char *ip_addr; - - switch_socket_addr_get(&sa, SWITCH_TRUE, event_stream->acceptor); - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - - if (zstr(ip_addr)) { - ip_addr = kazoo_globals.ip; - } - - stream->write_function(stream, "%s:%d -> disconnected\n" - ,ip_addr, port); - } else { - unsigned int year, day, hour, min, sec, delta; - - delta = (switch_micro_time_now() - event_stream->connected_time) / 1000000; - sec = delta % 60; - min = delta / 60 % 60; - hour = delta / 3600 % 24; - day = delta / 86400 % 7; - year = delta / 31556926 % 12; - - stream->write_function(stream, "%s:%d -> %s:%d for %d years, %d days, %d hours, %d minutes, %d seconds\n" - ,event_stream->local_ip, event_stream->local_port - ,event_stream->remote_ip, event_stream->remote_port - ,year, day, hour, min, sec); - } - - binding = event_stream->bindings; - while(binding != NULL) { - if (binding->type == SWITCH_EVENT_CUSTOM) { - stream->write_function(stream, "CUSTOM %-43s", binding->subclass_name); - } else { - stream->write_function(stream, "%-50s", switch_event_name(binding->type)); - } - - if (++column > 2) { - stream->write_function(stream, "\n"); - column = 0; - } - - binding = binding->next; - } - switch_mutex_unlock(event_stream->socket_mutex); - - if (!column) { - stream->write_function(stream, "\n"); - } else { - stream->write_function(stream, "\n\n"); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_node_api_event_streams(ei_node_t *ei_node, switch_stream_handle_t *stream) { - ei_event_stream_t *event_stream; - - switch_mutex_lock(ei_node->event_streams_mutex); - event_stream = ei_node->event_streams; - while(event_stream != NULL) { - handle_node_api_event_stream(event_stream, stream); - event_stream = event_stream->next; - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command) { - unsigned int year, day, hour, min, sec, delta; - - switch (command) { - case API_COMMAND_DISCONNECT: - stream->write_function(stream, "Disconnecting erlang node %s at managers request\n", ei_node->peer_nodename); - switch_clear_flag(ei_node, LFLAG_RUNNING); - break; - case API_COMMAND_REMOTE_IP: - delta = (switch_micro_time_now() - ei_node->created_time) / 1000000; - sec = delta % 60; - min = delta / 60 % 60; - hour = delta / 3600 % 24; - day = delta / 86400 % 7; - year = delta / 31556926 % 12; - - stream->write_function(stream, "Uptime %d years, %d days, %d hours, %d minutes, %d seconds\n", year, day, hour, min, sec); - stream->write_function(stream, "Local Address %s:%d\n", ei_node->local_ip, ei_node->local_port); - stream->write_function(stream, "Remote Address %s:%d\n", ei_node->remote_ip, ei_node->remote_port); - break; - case API_COMMAND_STREAMS: - handle_node_api_event_streams(ei_node, stream); - break; - case API_COMMAND_BINDINGS: - handle_api_command_streams(ei_node, stream); - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_node_command(switch_stream_handle_t *stream, const char *nodename, uint32_t command) { - ei_node_t *ei_node; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - int length = strlen(ei_node->peer_nodename); - - if (!strncmp(ei_node->peer_nodename, nodename, length)) { - handle_node_api_command(ei_node, stream, command); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - return SWITCH_STATUS_SUCCESS; - } - - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t handle_node_api_command_arg(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command, char *arg) { - - switch (command) { - case API_COMMAND_OPTION: - return api_get_node_option(ei_node, stream, arg); - break; - default: - break; - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t handle_node_api_command_args(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command, int argc, char *argv[]) { - - switch (command) { - case API_COMMAND_OPTION: - return api_set_node_option(ei_node, stream, argv[0], argv[1]); - break; - default: - break; - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t api_erlang_node_command_arg(switch_stream_handle_t *stream, const char *nodename, uint32_t command, char *arg) { - ei_node_t *ei_node; - switch_status_t ret = SWITCH_STATUS_NOTFOUND; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - int length = strlen(ei_node->peer_nodename); - - if (!strncmp(ei_node->peer_nodename, nodename, length)) { - ret = handle_node_api_command_arg(ei_node, stream, command, arg); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - return ret ; - } - - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return ret; -} - -static switch_status_t api_erlang_node_command_args(switch_stream_handle_t *stream, const char *nodename, uint32_t command, int argc, char *argv[]) { - ei_node_t *ei_node; - switch_status_t ret = SWITCH_STATUS_NOTFOUND; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - int length = strlen(ei_node->peer_nodename); - - if (!strncmp(ei_node->peer_nodename, nodename, length)) { - ret = handle_node_api_command_args(ei_node, stream, command, argc, argv); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - return ret; - } - - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return ret; -} - -SWITCH_STANDARD_API(exec_api_cmd) -{ - char *argv[1024] = { 0 }; - int unknown_command = 1, argc = 0; - char *mycmd = NULL; - - const char *usage_string = "USAGE:\n" - "--------------------------------------------------------------------------------------------------------------------\n" - "erlang status - provides an overview of the current status\n" - "erlang event_filter - lists the event headers that will be sent to Erlang nodes\n" - "erlang nodes list - lists connected Erlang nodes (usefull for monitoring tools)\n" - "erlang nodes count - provides a count of connected Erlang nodes (usefull for monitoring tools)\n" - "erlang node disconnect - disconnects an Erlang node\n" - "erlang node connection - Shows the connection info\n" - "erlang node event_streams - lists the event streams for an Erlang node\n" - "erlang node fetch_bindings - lists the XML fetch bindings for an Erlang node\n" - "---------------------------------------------------------------------------------------------------------------------\n"; - - if (zstr(cmd)) { - stream->write_function(stream, "%s", usage_string); - return SWITCH_STATUS_SUCCESS; - } - - if (!(mycmd = strdup(cmd))) { - return SWITCH_STATUS_MEMERR; - } - - if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - stream->write_function(stream, "%s", usage_string); - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; - } - - if (zstr(argv[0])) { - stream->write_function(stream, "%s", usage_string); - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; - } - - if (!strncmp(argv[0], "status", 7)) { - unknown_command = 0; - api_erlang_status(stream); - } else if (!strncmp(argv[0], "event_filter", 13)) { - unknown_command = 0; - api_erlang_event_filter(stream); - } else if (!strncmp(argv[0], "nodes", 6) && !zstr(argv[1])) { - if (!strncmp(argv[1], "list", 6)) { - unknown_command = 0; - api_erlang_nodes_list(stream); - } else if (!strncmp(argv[1], "count", 6)) { - unknown_command = 0; - api_erlang_nodes_count(stream); - } - } else if (!strncmp(argv[0], "node", 6) && !zstr(argv[1]) && !zstr(argv[2])) { - if (!strncmp(argv[2], "disconnect", 11)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_DISCONNECT); - } else if (!strncmp(argv[2], "connection", 11)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_REMOTE_IP); - } else if (!strncmp(argv[2], "event_streams", 14)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_STREAMS); - } else if (!strncmp(argv[2], "fetch_bindings", 15)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_BINDINGS); - } else if (!strncmp(argv[2], "option", 7) && !zstr(argv[3])) { - unknown_command = 0; - if(argc > 4 && !zstr(argv[4])) - api_erlang_node_command_args(stream, argv[1], API_COMMAND_OPTION, argc - 3, &argv[3]); - else - api_erlang_node_command_arg(stream, argv[1], API_COMMAND_OPTION, argv[3]); - } - } - - if (unknown_command) { - stream->write_function(stream, "%s", usage_string); - } - - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -void add_cli_api(switch_loadable_module_interface_t **module_interface) -{ - switch_api_interface_t *api_interface = NULL; - SWITCH_ADD_API(api_interface, "erlang", KAZOO_DESC, exec_api_cmd, KAZOO_SYNTAX); - switch_console_set_complete("add erlang status"); - switch_console_set_complete("add erlang event_filter"); - switch_console_set_complete("add erlang nodes list"); - switch_console_set_complete("add erlang nodes count"); - switch_console_set_complete("add erlang node ::erlang::node disconnect"); - switch_console_set_complete("add erlang node ::erlang::node connection"); - switch_console_set_complete("add erlang node ::erlang::node event_streams"); - switch_console_set_complete("add erlang node ::erlang::node fetch_bindings"); - switch_console_add_complete_func("::erlang::node", api_complete_erlang_node); - -} - -void remove_cli_api() -{ - switch_console_set_complete("del erlang"); - switch_console_del_complete_func("::erlang::node"); - -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_cdr.c b/src/mod/event_handlers/mod_kazoo/kazoo_cdr.c deleted file mode 100644 index fef66f8be3..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_cdr.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Luis Azedo - * - * mod_hacks.c -- hacks with state handlers - * - */ -#include "mod_kazoo.h" - -#define MY_EVENT_JSON_CDR "KZ_CDR" - -#define maybe_add_json_string(_json, _name, _string) \ - if (!zstr(_string)) cJSON_AddItemToObject(_json, _name, cJSON_CreateString((char *)_string)) - -static void kz_switch_ivr_set_json_profile_data(cJSON *json, switch_caller_profile_t *caller_profile) -{ - cJSON *soft = NULL; - profile_node_t *pn = NULL; - - maybe_add_json_string(json, "Username", caller_profile->username); - maybe_add_json_string(json, "Dialplan", caller_profile->dialplan); - maybe_add_json_string(json, "ANI", caller_profile->ani); - maybe_add_json_string(json, "ANIII", caller_profile->aniii); - maybe_add_json_string(json, "Caller-ID-Name", caller_profile->caller_id_name); - maybe_add_json_string(json, "Caller-ID-Number", caller_profile->caller_id_number); - maybe_add_json_string(json, "Caller-ID-Original-Name", caller_profile->orig_caller_id_name); - maybe_add_json_string(json, "Caller-ID-Original-Number", caller_profile->orig_caller_id_number); - maybe_add_json_string(json, "Network-Address", caller_profile->network_addr); - maybe_add_json_string(json, "RDNIS", caller_profile->rdnis); - maybe_add_json_string(json, "Destination-Number", caller_profile->destination_number); - maybe_add_json_string(json, "Callee-ID-Name", caller_profile->callee_id_name); - maybe_add_json_string(json, "Callee-ID-Number", caller_profile->callee_id_number); - maybe_add_json_string(json, "UUID", caller_profile->uuid); - maybe_add_json_string(json, "Source", caller_profile->source); - maybe_add_json_string(json, "Context", caller_profile->context); - maybe_add_json_string(json, "Channel-Name", caller_profile->chan_name); - maybe_add_json_string(json, "Profile-UUID", caller_profile->uuid_str); - maybe_add_json_string(json, "Profile-Clone-Of", caller_profile->clone_of); - maybe_add_json_string(json, "Transfer-Source", caller_profile->transfer_source); - cJSON_AddItemToObject(json, "Direction", cJSON_CreateString(caller_profile->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound")); - cJSON_AddItemToObject(json, "Logical-Direction", cJSON_CreateString(caller_profile->logical_direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound")); - - soft = cJSON_CreateObject(); - for (pn = caller_profile->soft; pn; pn = pn->next) { - maybe_add_json_string(soft, pn->var, pn->val); - } - - cJSON_AddItemToObject(json, "Directory", soft); -} - -SWITCH_DECLARE(void) kz_switch_ivr_set_json_call_flaws(cJSON *json, switch_core_session_t *session, switch_media_type_t type) -{ - const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "Video" : "Audio"; - cJSON *j_stat; - switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL); - - if (!stats) return; - - if (!stats->inbound.error_log && !stats->outbound.error_log) return; - - j_stat = cJSON_CreateObject(); - cJSON_AddItemToObject(json, name, j_stat); - - if (stats->inbound.error_log) { - cJSON *j_err_log, *j_err, *j_in; - switch_error_period_t *ep; - - j_in = cJSON_CreateObject(); - cJSON_AddItemToObject(j_stat, "Inbound", j_in); - - j_err_log = cJSON_CreateArray(); - cJSON_AddItemToObject(j_in, "Error-Log", j_err_log); - - for(ep = stats->inbound.error_log; ep; ep = ep->next) { - - if (!(ep->start && ep->stop)) continue; - - j_err = cJSON_CreateObject(); - - cJSON_AddItemToObject(j_err, "Start", cJSON_CreateNumber(ep->start)); - cJSON_AddItemToObject(j_err, "Stop", cJSON_CreateNumber(ep->stop)); - cJSON_AddItemToObject(j_err, "Flaws", cJSON_CreateNumber(ep->flaws)); - cJSON_AddItemToObject(j_err, "Consecutive-Flaws", cJSON_CreateNumber(ep->consecutive_flaws)); - cJSON_AddItemToObject(j_err, "Duration-MS", cJSON_CreateNumber((ep->stop - ep->start) / 1000)); - cJSON_AddItemToArray(j_err_log, j_err); - } - } - - if (stats->outbound.error_log) { - cJSON *j_err_log, *j_err, *j_out; - switch_error_period_t *ep; - - j_out = cJSON_CreateObject(); - cJSON_AddItemToObject(j_stat, "Outbound", j_out); - - j_err_log = cJSON_CreateArray(); - cJSON_AddItemToObject(j_out, "Error-Log", j_err_log); - - for(ep = stats->outbound.error_log; ep; ep = ep->next) { - - if (!(ep->start && ep->stop)) continue; - - j_err = cJSON_CreateObject(); - - cJSON_AddItemToObject(j_err, "Start", cJSON_CreateNumber(ep->start)); - cJSON_AddItemToObject(j_err, "Stop", cJSON_CreateNumber(ep->stop)); - cJSON_AddItemToObject(j_err, "Flaws", cJSON_CreateNumber(ep->flaws)); - cJSON_AddItemToObject(j_err, "Consecutive-Flaws", cJSON_CreateNumber(ep->consecutive_flaws)); - cJSON_AddItemToObject(j_err, "Duration-MS", cJSON_CreateNumber((ep->stop - ep->start) / 1000)); - cJSON_AddItemToArray(j_err_log, j_err); - } - } -} - -#define add_jstat(_j, _i, _s) \ - switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \ - cJSON_AddItemToObject(_j, _s, cJSON_CreateNumber(_i)) - -SWITCH_DECLARE(void) kz_switch_ivr_set_json_call_stats(cJSON *json, switch_core_session_t *session, switch_media_type_t type) -{ - const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "Video" : "Audio"; - cJSON *j_stat, *j_in, *j_out; - switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL); - char var_val[35] = ""; - - if (!stats) return; - - j_stat = cJSON_CreateObject(); - j_in = cJSON_CreateObject(); - j_out = cJSON_CreateObject(); - - cJSON_AddItemToObject(json, name, j_stat); - cJSON_AddItemToObject(j_stat, "Inbound", j_in); - cJSON_AddItemToObject(j_stat, "Outbound", j_out); - - stats->inbound.std_deviation = sqrt(stats->inbound.variance); - - add_jstat(j_in, stats->inbound.raw_bytes, "Raw-Bytes"); - add_jstat(j_in, stats->inbound.media_bytes, "Media-Bytes"); - add_jstat(j_in, stats->inbound.packet_count, "Packet-Count"); - add_jstat(j_in, stats->inbound.media_packet_count, "Media-Packet-Count"); - add_jstat(j_in, stats->inbound.skip_packet_count, "Skip-Packet-Count"); - add_jstat(j_in, stats->inbound.jb_packet_count, "Jitter-Packet-Count"); - add_jstat(j_in, stats->inbound.dtmf_packet_count, "DTMF-Packet-Count"); - add_jstat(j_in, stats->inbound.cng_packet_count, "CNG-Packet-Count"); - add_jstat(j_in, stats->inbound.flush_packet_count, "Flush-Packet-Count"); - add_jstat(j_in, stats->inbound.largest_jb_size, "Largest-JB-Size"); - add_jstat(j_in, stats->inbound.min_variance, "Jitter-Min-Variance"); - add_jstat(j_in, stats->inbound.max_variance, "Jitter-Max-Variance"); - add_jstat(j_in, stats->inbound.lossrate, "Jitter-Loss-Rate"); - add_jstat(j_in, stats->inbound.burstrate, "Jitter-Burst-Rate"); - add_jstat(j_in, stats->inbound.mean_interval, "Mean-Interval"); - add_jstat(j_in, stats->inbound.flaws, "Flaw-Total"); - add_jstat(j_in, stats->inbound.R, "Quality-Percentage"); - add_jstat(j_in, stats->inbound.mos, "MOS"); - - - add_jstat(j_out, stats->outbound.raw_bytes, "Raw-Bytes"); - add_jstat(j_out, stats->outbound.media_bytes, "Media-Bytes"); - add_jstat(j_out, stats->outbound.packet_count, "Packet-Count"); - add_jstat(j_out, stats->outbound.media_packet_count, "Media-Packet-Count"); - add_jstat(j_out, stats->outbound.skip_packet_count, "Skip-Packet-Count"); - add_jstat(j_out, stats->outbound.dtmf_packet_count, "DTMF-Packet-Count"); - add_jstat(j_out, stats->outbound.cng_packet_count, "CNG-Packet-Count"); - add_jstat(j_out, stats->rtcp.packet_count, "RTCP-Packet-Count"); - add_jstat(j_out, stats->rtcp.octet_count, "RTCP-Octet-Count"); -} - -static switch_status_t kz_report_channel_flaws(switch_core_session_t *session, switch_event_t *cdr_event) -{ - cJSON *callStats = cJSON_CreateObject(); - - kz_switch_ivr_set_json_call_flaws(callStats, session, SWITCH_MEDIA_TYPE_AUDIO); - kz_switch_ivr_set_json_call_flaws(callStats, session, SWITCH_MEDIA_TYPE_VIDEO); - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_channel_media_errors", cJSON_PrintUnformatted(callStats)); - - cJSON_Delete(callStats); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_report_channel_stats(switch_core_session_t *session, switch_event_t *cdr_event) -{ - cJSON *callStats = cJSON_CreateObject(); - - kz_switch_ivr_set_json_call_stats(callStats, session, SWITCH_MEDIA_TYPE_AUDIO); - kz_switch_ivr_set_json_call_stats(callStats, session, SWITCH_MEDIA_TYPE_VIDEO); - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_channel_stats", cJSON_PrintUnformatted(callStats)); - - cJSON_Delete(callStats); - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_report_app_log(switch_core_session_t *session, switch_event_t *cdr_event) -{ - switch_app_log_t *ap, *app_log = switch_core_session_get_app_log(session); - cJSON *j_apps = NULL; - - if (!app_log) { - return SWITCH_STATUS_FALSE; - } - - j_apps = cJSON_CreateArray(); - - for (ap = app_log; ap; ap = ap->next) { - cJSON *j_application = cJSON_CreateObject(); - cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app)); - cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg)); - cJSON_AddItemToObject(j_application, "app_stamp", cJSON_CreateNumber(ap->stamp)); - cJSON_AddItemToArray(j_apps, j_application); - } - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_application_log", cJSON_PrintUnformatted(j_apps)); - - cJSON_Delete(j_apps); - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_report_callflow_extension(switch_caller_profile_t *caller_profile, cJSON *j_profile) -{ - cJSON *j_caller_extension, *j_caller_extension_apps, *j_application, *j_inner_extension; - if (caller_profile->caller_extension) { - switch_caller_application_t *ap; - - j_caller_extension = cJSON_CreateObject(); - j_caller_extension_apps = cJSON_CreateArray(); - - cJSON_AddItemToObject(j_profile, "extension", j_caller_extension); - - cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name)); - cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number)); - cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps); - - if (caller_profile->caller_extension->current_application) { - cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name)); - } - - for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) { - j_application = cJSON_CreateObject(); - - cJSON_AddItemToArray(j_caller_extension_apps, j_application); - - if (ap == caller_profile->caller_extension->current_application) { - cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true")); - } - cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name)); - cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data))); - } - - if (caller_profile->caller_extension->children) { - switch_caller_profile_t *cp = NULL; - j_inner_extension = cJSON_CreateArray(); - cJSON_AddItemToObject(j_caller_extension, "sub_extensions", j_inner_extension); - for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) { - - if (!cp->caller_extension) { - continue; - } - - j_caller_extension = cJSON_CreateObject(); - cJSON_AddItemToArray(j_inner_extension, j_caller_extension); - - cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(cp->caller_extension->extension_name)); - cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(cp->caller_extension->extension_number)); - - cJSON_AddItemToObject(j_caller_extension, "dialplan", cJSON_CreateString((char *)cp->dialplan)); - - if (cp->caller_extension->current_application) { - cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(cp->caller_extension->current_application->application_name)); - } - - j_caller_extension_apps = cJSON_CreateArray(); - cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps); - for (ap = cp->caller_extension->applications; ap; ap = ap->next) { - j_application = cJSON_CreateObject(); - cJSON_AddItemToArray(j_caller_extension_apps, j_application); - - if (ap == cp->caller_extension->current_application) { - cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true")); - } - cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name)); - cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data))); - } - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_report_callflow(switch_core_session_t *session, switch_event_t *cdr_event) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t *caller_profile; - cJSON *j_main_cp, *j_times, *j_callflow, *j_profile, *j_o; - - - caller_profile = switch_channel_get_caller_profile(channel); - - j_callflow = cJSON_CreateArray(); - - while (caller_profile) { - - j_profile = cJSON_CreateObject(); - - if (!zstr(caller_profile->dialplan)) { - cJSON_AddItemToObject(j_profile, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan)); - } - - if (!zstr(caller_profile->profile_index)) { - cJSON_AddItemToObject(j_profile, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index)); - } - - kz_report_callflow_extension(caller_profile, j_profile); - - j_main_cp = cJSON_CreateObject(); - cJSON_AddItemToObject(j_profile, "Caller-Profile", j_main_cp); - - kz_switch_ivr_set_json_profile_data(j_main_cp, caller_profile); - - if (caller_profile->originator_caller_profile) { - j_o = cJSON_CreateObject(); - cJSON_AddItemToObject(j_main_cp, "originator", j_o); - kz_switch_ivr_set_json_profile_data(j_o, caller_profile->originator_caller_profile); - kz_report_callflow_extension(caller_profile->originator_caller_profile, j_o); - } - - if (caller_profile->originatee_caller_profile) { - j_o = cJSON_CreateObject(); - cJSON_AddItemToObject(j_main_cp, "originatee", j_o); - kz_switch_ivr_set_json_profile_data(j_o, caller_profile->originatee_caller_profile); - kz_report_callflow_extension(caller_profile->originatee_caller_profile, j_o); - } - - if (caller_profile->times) { - j_times = cJSON_CreateObject(); - cJSON_AddItemToObject(j_profile, "Time", j_times); - cJSON_AddItemToObject(j_times, "Created", cJSON_CreateNumber(caller_profile->times->created)); - cJSON_AddItemToObject(j_times, "Profile-Created", cJSON_CreateNumber(caller_profile->times->profile_created)); - cJSON_AddItemToObject(j_times, "Progress", cJSON_CreateNumber(caller_profile->times->progress)); - cJSON_AddItemToObject(j_times, "Progress-Media", cJSON_CreateNumber(caller_profile->times->progress_media)); - cJSON_AddItemToObject(j_times, "Answered", cJSON_CreateNumber(caller_profile->times->answered)); - cJSON_AddItemToObject(j_times, "Bridged", cJSON_CreateNumber(caller_profile->times->bridged)); - cJSON_AddItemToObject(j_times, "Last-Hold", cJSON_CreateNumber(caller_profile->times->last_hold)); - cJSON_AddItemToObject(j_times, "Hold-Accumulated", cJSON_CreateNumber(caller_profile->times->hold_accum)); - cJSON_AddItemToObject(j_times, "Hangup", cJSON_CreateNumber(caller_profile->times->hungup)); - cJSON_AddItemToObject(j_times, "Resurrect", cJSON_CreateNumber(caller_profile->times->resurrected)); - cJSON_AddItemToObject(j_times, "Transfer", cJSON_CreateNumber(caller_profile->times->transferred)); - } - cJSON_AddItemToArray(j_callflow, j_profile); - caller_profile = caller_profile->next; - } - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_callflow", cJSON_PrintUnformatted(j_callflow)); - - cJSON_Delete(j_callflow); - - - return SWITCH_STATUS_SUCCESS; - -} - - -#define ORIGINATED_LEGS_VARIABLE "originated_legs" -#define ORIGINATED_LEGS_ITEM_DELIM ';' - -#define ORIGINATE_CAUSES_VARIABLE "originate_causes" -#define ORIGINATE_CAUSES_ITEM_DELIM ';' - -static switch_status_t kz_report_originated_legs(switch_core_session_t *session, switch_event_t *cdr_event) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - cJSON *j_originated = cJSON_CreateArray(); - const char *originated_legs_var = NULL, *originate_causes_var = NULL; - int idx = 0; - - while(1) { - char *argv_leg[10] = { 0 }, *argv_cause[10] = { 0 }; - char *originated_legs, *originate_causes; - cJSON *j_originated_leg; - originated_legs_var = switch_channel_get_variable_dup(channel, ORIGINATED_LEGS_VARIABLE, SWITCH_FALSE, idx); - originate_causes_var = switch_channel_get_variable_dup(channel, ORIGINATE_CAUSES_VARIABLE, SWITCH_FALSE, idx); - - if (zstr(originated_legs_var) || zstr(originate_causes_var)) { - break; - } - - originated_legs = strdup(originated_legs_var); - originate_causes = strdup(originate_causes_var); - - switch_separate_string(originated_legs, ORIGINATED_LEGS_ITEM_DELIM, argv_leg, (sizeof(argv_leg) / sizeof(argv_leg[0]))); - switch_separate_string(originate_causes, ORIGINATE_CAUSES_ITEM_DELIM, argv_cause, (sizeof(argv_cause) / sizeof(argv_cause[0]))); - - j_originated_leg = cJSON_CreateObject(); - cJSON_AddItemToObject(j_originated_leg, "Call-ID", cJSON_CreateString(argv_leg[0])); - cJSON_AddItemToObject(j_originated_leg, "Caller-ID-Name", cJSON_CreateString(argv_leg[1])); - cJSON_AddItemToObject(j_originated_leg, "Caller-ID-Number", cJSON_CreateString(argv_leg[2])); - cJSON_AddItemToObject(j_originated_leg, "Result", cJSON_CreateString(argv_cause[1])); - - cJSON_AddItemToArray(j_originated, j_originated_leg); - - switch_safe_free(originated_legs); - switch_safe_free(originate_causes); - - idx++; - } - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_originated_legs", cJSON_PrintUnformatted(j_originated)); - - cJSON_Delete(j_originated); - - return SWITCH_STATUS_SUCCESS; -} - -#define MAX_HISTORY 50 -#define HST_ARRAY_DELIM "|:" -#define HST_ITEM_DELIM ':' - -static void kz_report_transfer_history_item(char* value, cJSON *json) -{ - char *argv[4] = { 0 }; - char *item = strdup(value); - int argc = switch_separate_string(item, HST_ITEM_DELIM, argv, (sizeof(argv) / sizeof(argv[0]))); - cJSON *jitem = cJSON_CreateObject(); - char *epoch = NULL, *callid = NULL, *type = NULL; - int add = 0; - if(argc == 4) { - add = 1; - epoch = argv[0]; - callid = argv[1]; - type = argv[2]; - - if(!strncmp(type, "bl_xfer", 7)) { - //char *split = strchr(argv[3], '/'); - //if(split) *(split++) = '\0'; - cJSON_AddItemToObject(jitem, "Caller-Profile-ID", cJSON_CreateString(callid)); - cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("blind")); - cJSON_AddItemToObject(jitem, "Extension", cJSON_CreateString(argv[3])); - cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL))); - } else if(!strncmp(type, "att_xfer", 8)) { - char *split = strchr(argv[3], '/'); - if(split) { - *(split++) = '\0'; - cJSON_AddItemToObject(jitem, "Caller-Profile-ID", cJSON_CreateString(callid)); - cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("attended")); - cJSON_AddItemToObject(jitem, "Transferee", cJSON_CreateString(argv[3])); - cJSON_AddItemToObject(jitem, "Transferer", cJSON_CreateString(split)); - cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL))); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE '%s' NOT HANDLED => %s\n", type, item); - add = 0; - } - } else if(!strncmp(type, "uuid_br", 7)) { - cJSON_AddItemToObject(jitem, "Caller-Profile-ID", cJSON_CreateString(callid)); - cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("bridge")); - cJSON_AddItemToObject(jitem, "Other-Leg", cJSON_CreateString(argv[3])); - cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL))); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE '%s' NOT HANDLED => %s\n", type, item); - add = 0; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE SPLIT ERROR %i => %s\n", argc, item); - } - if(add) { - cJSON_AddItemToArray(json, jitem); - } else { - cJSON_Delete(jitem); - } - switch_safe_free(item); -} - -static switch_status_t kz_report_transfer_history(switch_core_session_t *session, switch_event_t *cdr_event, const char* var_name) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - cJSON *j_transfer = NULL; - char *tmp_history = NULL, *history = NULL, *argv[MAX_HISTORY] = { 0 }; - char event_header[50]; - int n, argc = 0; - const char *transfer_var = switch_channel_get_variable_dup(channel, var_name, SWITCH_FALSE, -1); - if (zstr(transfer_var)) { - return SWITCH_STATUS_SUCCESS; - } - - if (!(tmp_history = strdup(transfer_var))) { - return SWITCH_STATUS_SUCCESS; - } - - sprintf(event_header, "_json_%s", var_name); - history = tmp_history; - j_transfer = cJSON_CreateArray(); - - if (!strncmp(history, "ARRAY::", 7)) { - history += 7; - argc = switch_separate_string_string(history, HST_ARRAY_DELIM, argv, (sizeof(argv) / sizeof(argv[0]))); - for(n=0; n < argc; n++) { - kz_report_transfer_history_item(argv[n], j_transfer); - } - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, event_header, cJSON_PrintUnformatted(j_transfer)); - } else if (strchr(history, HST_ITEM_DELIM)) { - kz_report_transfer_history_item(history, j_transfer); - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, event_header, cJSON_PrintUnformatted(j_transfer)); - } - cJSON_Delete(j_transfer); - switch_safe_free(tmp_history); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_report(switch_core_session_t *session, switch_event_t *cdr_event) -{ - kz_report_app_log(session, cdr_event); - kz_report_callflow(session, cdr_event); - kz_report_channel_stats(session, cdr_event); - kz_report_channel_flaws(session, cdr_event); - kz_report_originated_legs(session, cdr_event); - kz_report_transfer_history(session, cdr_event, SWITCH_TRANSFER_HISTORY_VARIABLE); - kz_report_transfer_history(session, cdr_event, SWITCH_TRANSFER_SOURCE_VARIABLE); - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t kz_cdr_on_reporting(switch_core_session_t *session) -{ - switch_event_t *cdr_event = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (switch_event_create_subclass(&cdr_event, SWITCH_EVENT_CUSTOM, MY_EVENT_JSON_CDR) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "error creating event for report data!\n"); - return SWITCH_STATUS_FALSE; - } - - kz_report(session, cdr_event); - switch_channel_event_set_data(channel, cdr_event); - switch_event_fire(&cdr_event); - - return SWITCH_STATUS_SUCCESS; -} - - -static switch_state_handler_table_t kz_cdr_state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ kz_cdr_on_reporting -}; - - -static void kz_cdr_register_state_handlers() -{ - switch_core_add_state_handler(&kz_cdr_state_handlers); -} - -static void kz_cdr_unregister_state_handlers() -{ - switch_core_remove_state_handler(&kz_cdr_state_handlers); -} - -static void kz_cdr_register_events() -{ - if (switch_event_reserve_subclass(MY_EVENT_JSON_CDR) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_JSON_CDR); - } -} - -static void kz_cdr_unregister_events() -{ - switch_event_free_subclass(MY_EVENT_JSON_CDR); -} - - -void kz_cdr_start() -{ - kz_cdr_register_events(); - kz_cdr_register_state_handlers(); -} - -void kz_cdr_stop() -{ - kz_cdr_unregister_state_handlers(); - kz_cdr_unregister_events(); -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c deleted file mode 100644 index 16f00ad1a0..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_commands.c -- clones of mod_commands commands slightly modified for kazoo - * - */ -#include "mod_kazoo.h" -#include -#include - -#define UUID_SET_DESC "Set a variable" -#define UUID_SET_SYNTAX " [value]" - -#define UUID_MULTISET_DESC "Set multiple variables" -#define UUID_MULTISET_SYNTAX " =;=..." - -#define KZ_HTTP_PUT_DESC "upload a local freeswitch file to a url" -#define KZ_HTTP_PUT_SYNTAX "localfile url" - -#define KZ_FIRST_OF_DESC "returns first-of existing event header in params" -#define KZ_FIRST_OF_SYNTAX "list of headers to check" - -#define MAX_FIRST_OF 25 - -SWITCH_STANDARD_API(kz_first_of) -{ - char delim = '|'; - char *mycmd = NULL, *mycmd_dup = NULL, *argv[MAX_FIRST_OF] = { 0 }; - int n, argc = 0; - switch_event_header_t *header = NULL; - switch_channel_t *channel = NULL; - - if (zstr(cmd)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid arg\n"); - return SWITCH_STATUS_GENERR; - } - - if ( session ) { - channel = switch_core_session_get_channel(session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT CHANNEL\n"); - } - - mycmd_dup = mycmd = strdup(cmd); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "FIRST-OF %s\n", mycmd); - if (!zstr(mycmd) && *mycmd == '^' && *(mycmd+1) == '^') { - mycmd += 2; - delim = *mycmd++; - } - argc = switch_separate_string(mycmd, delim, argv, (sizeof(argv) / sizeof(argv[0]))); - for(n=0; n < argc; n++) { - char* item = argv[n]; - if(*item == '#' || *item == '!' || *item == '?') { - if(*(++item) != '\0') { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING default %s\n", item); - stream->write_function(stream, item); - break; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING %s\n", item); - if (channel) { - const char *var = switch_channel_get_variable_dup(channel, item, SWITCH_FALSE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item); - if (var) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item, var); - stream->write_function(stream, var); - break; - } - if (!strncmp(item, "variable_", 9)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item+9); - var = switch_channel_get_variable_dup(channel, item+9, SWITCH_FALSE, -1); - if (var) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item+9, var); - stream->write_function(stream, var); - break; - } - } - } - header = switch_event_get_header_ptr(stream->param_event, item); - if(header) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING %s : %s\n", item, header->value); - stream->write_function(stream, header->value); - break; - } - } - } - - switch_safe_free(mycmd_dup); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t kz_uuid_setvar(int urldecode, const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream) -{ - switch_core_session_t *psession = NULL; - char *mycmd = NULL, *argv[3] = { 0 }; - int argc = 0; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if ((argc == 2 || argc == 3) && !zstr(argv[0])) { - char *uuid = argv[0]; - char *var_name = argv[1]; - char *var_value = NULL; - - if (argc == 3) { - var_value = argv[2]; - } - - if ((psession = switch_core_session_locate(uuid))) { - switch_channel_t *channel; - switch_event_t *event; - channel = switch_core_session_get_channel(psession); - - if (zstr(var_name)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - stream->write_function(stream, "-ERR No variable specified\n"); - } else { - if(urldecode) { - switch_url_decode(var_value); - } - switch_channel_set_variable(channel, var_name, var_value); - kz_check_set_profile_var(channel, var_name, var_value); - stream->write_function(stream, "+OK\n"); - } - - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - - switch_core_session_rwunlock(psession); - - } else { - stream->write_function(stream, "-ERR No such channel!\n"); - } - goto done; - } - } - - stream->write_function(stream, "-USAGE: %s\n", UUID_SET_SYNTAX); - - done: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(uuid_setvar_function) -{ - return kz_uuid_setvar(0, cmd, session, stream); -} - -SWITCH_STANDARD_API(uuid_setvar_encoded_function) -{ - return kz_uuid_setvar(1, cmd, session, stream); -} - -switch_status_t kz_uuid_setvar_multi(int urldecode, const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream) -{ - switch_core_session_t *psession = NULL; - char delim = ';'; - char *mycmd = NULL, *vars, *argv[64] = { 0 }; - int argc = 0; - char *var_name, *var_value = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - char *uuid = mycmd; - if (!(vars = strchr(uuid, ' '))) { - goto done; - } - *vars++ = '\0'; - if (*vars == '^' && *(vars+1) == '^') { - vars += 2; - delim = *vars++; - } - if ((psession = switch_core_session_locate(uuid))) { - switch_channel_t *channel = switch_core_session_get_channel(psession); - switch_event_t *event; - int x, y = 0; - argc = switch_separate_string(vars, delim, argv, (sizeof(argv) / sizeof(argv[0]))); - - for (x = 0; x < argc; x++) { - var_name = argv[x]; - if (var_name && (var_value = strchr(var_name, '='))) { - *var_value++ = '\0'; - } - if (zstr(var_name)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - stream->write_function(stream, "-ERR No variable specified\n"); - } else { - if(urldecode) { - switch_url_decode(var_value); - } - switch_channel_set_variable(channel, var_name, var_value); - kz_check_set_profile_var(channel, var_name, var_value); - - y++; - } - } - - /* keep kazoo nodes in sync */ - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - - switch_core_session_rwunlock(psession); - if (y) { - stream->write_function(stream, "+OK\n"); - goto done; - } - } else { - stream->write_function(stream, "-ERR No such channel!\n"); - } - } - - stream->write_function(stream, "-USAGE: %s\n", UUID_MULTISET_SYNTAX); - - done: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(uuid_setvar_multi_function) -{ - return kz_uuid_setvar_multi(0, cmd, session, stream); -} - -SWITCH_STANDARD_API(uuid_setvar_multi_encoded_function) -{ - return kz_uuid_setvar_multi(1, cmd, session, stream); -} - -static size_t body_callback(char *buffer, size_t size, size_t nitems, void *userdata) -{ - return size * nitems; -} - -static size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) -{ - switch_event_t* event = (switch_event_t*)userdata; - int len = strlen(buffer); - char buf[1024]; - if(len > 2 && len < 1024) { - snprintf(buf, sizeof(buf), "%s", buffer); - switch_event_add_header_string(event, SWITCH_STACK_PUSH | SWITCH_STACK_BOTTOM, "Reply-Headers", buf); - } - return nitems * size; -} - -SWITCH_STANDARD_API(kz_http_put) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_memory_pool_t *lpool = NULL; - switch_memory_pool_t *pool = NULL; - char *args = NULL; - char *argv[10] = { 0 }; - int argc = 0; - switch_event_t *params = NULL; - char *url = NULL; - char *filename = NULL; - int delete_file = 0; - - switch_curl_slist_t *headers = NULL; /* optional linked-list of HTTP headers */ - char *ext; /* file extension, used for MIME type identification */ - const char *mime_type = "application/octet-stream"; - char *buf = NULL; - char *error = NULL; - - CURL *curl_handle = NULL; - long httpRes = 0; - struct stat file_info = {0}; - FILE *file_to_put = NULL; - - if (session) { - pool = switch_core_session_get_pool(session); - } else { - switch_core_new_memory_pool(&lpool); - pool = lpool; - } - - if (zstr(cmd)) { - stream->write_function(stream, "USAGE: %s\n", KZ_HTTP_PUT_SYNTAX); - status = SWITCH_STATUS_SUCCESS; - goto done; - } - - args = strdup(cmd); - argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (argc != 2) { - stream->write_function(stream, "USAGE: %s\n", KZ_HTTP_PUT_SYNTAX); - status = SWITCH_STATUS_SUCCESS; - goto done; - } - - /* parse params and get profile */ - url = switch_core_strdup(pool, argv[0]); - if (*url == '{') { - if (switch_event_create_brackets(url, '{', '}', ',', ¶ms, &url, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - status = SWITCH_STATUS_FALSE; - stream->write_function(stream, "-ERR error parsing parameters\n"); - goto done; - } - } - - filename = switch_core_strdup(pool, argv[1]); - - /* guess what type of mime content this is going to be */ - if ((ext = strrchr(filename, '.'))) { - ext++; - if (!(mime_type = switch_core_mime_ext2type(ext))) { - mime_type = "application/octet-stream"; - } - } - - buf = switch_mprintf("Content-Type: %s", mime_type); - headers = switch_curl_slist_append(headers, buf); - - /* open file and get the file size */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opening %s for upload to %s\n", filename, url); - - /* libcurl requires FILE* */ - file_to_put = fopen(filename, "rb"); - if (!file_to_put) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fopen() error: %s\n", strerror(errno)); - stream->write_function(stream, "-ERR error opening file\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - - if (fstat(fileno(file_to_put), &file_info) == -1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fstat() error: %s\n", strerror(errno)); - stream->write_function(stream, "-ERR fstat error\n"); - goto done; - } - - curl_handle = switch_curl_easy_init(); - if (!curl_handle) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "switch_curl_easy_init() failure\n"); - status = SWITCH_STATUS_FALSE; - stream->write_function(stream, "-ERR switch_curl_easy init failure\n"); - goto done; - } - switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); -#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01) - switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); -#endif - switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); - switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url); - switch_curl_easy_setopt(curl_handle, CURLOPT_READDATA, file_to_put); - switch_curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); - switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10); - switch_curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-kazoo/1.0"); - switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, stream->param_event); - switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback); - switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, body_callback); - - switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); - switch_curl_easy_perform(curl_handle); - switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); - switch_curl_easy_cleanup(curl_handle); - - if (httpRes == 200 || httpRes == 201 || httpRes == 202 || httpRes == 204) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s saved to %s\n", filename, url); - switch_event_add_header(stream->param_event, SWITCH_STACK_BOTTOM, "API-Output", "%s saved to %s", filename, url); - stream->write_function(stream, "+OK %s saved to %s", filename, url); - delete_file = 1; - } else { - error = switch_mprintf("Received HTTP error %ld trying to save %s to %s", httpRes, filename, url); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", error); - switch_event_add_header(stream->param_event, SWITCH_STACK_BOTTOM, "API-Error", "%s", error); - switch_event_add_header(stream->param_event, SWITCH_STACK_BOTTOM, "API-HTTP-Error", "%ld", httpRes); - stream->write_function(stream, "-ERR %s", error); - status = SWITCH_STATUS_GENERR; - } - -done: - if (file_to_put) { - fclose(file_to_put); - if(delete_file) { - remove(filename); - } - } - - if (headers) { - switch_curl_slist_free_all(headers); - } - - switch_safe_free(buf); - switch_safe_free(error); - - switch_safe_free(args); - - if (lpool) { - switch_core_destroy_memory_pool(&lpool); - } - - if (params) { - switch_event_destroy(¶ms); - } - - return status; -} - -SWITCH_STANDARD_API(kz_expand_api) -{ - char *p = NULL, *input = NULL; - char *uuid = NULL, *mycmd; - - if (zstr(cmd)) { - stream->write_function(stream, "-ERR invalid input"); - return SWITCH_STATUS_GENERR; - } - - if (!(mycmd = strdup(cmd))) { - stream->write_function(stream, "-ERR no memory"); - return SWITCH_STATUS_GENERR; - } - - if (!strncasecmp(mycmd, "uuid:", 5)) { - uuid = mycmd + 5; - if ((input = strchr(uuid, ' ')) != NULL) { - *input++ = '\0'; - } else { - stream->write_function(stream, "-ERR invalid argument"); - switch_safe_free(mycmd); - return SWITCH_STATUS_GENERR; - } - } else { - input = mycmd; - } - - p = kz_expand(input, uuid); - stream->write_function(stream, "+OK %s", p); - if (p != input) { - switch_safe_free(p); - } - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(kz_eval_api) -{ - char *p = NULL, *input = NULL; - char *uuid = NULL, *mycmd; - switch_core_session_t *nsession = NULL; - switch_channel_t *channel = NULL; - - - if (zstr(cmd)) { - stream->write_function(stream, "-ERR invalid input"); - return SWITCH_STATUS_GENERR; - } - - if (!(mycmd = strdup(cmd))) { - stream->write_function(stream, "-ERR no memory"); - return SWITCH_STATUS_GENERR; - } - - if (!strncasecmp(mycmd, "uuid:", 5)) { - uuid = mycmd + 5; - if ((input = strchr(uuid, ' ')) != NULL) { - *input++ = '\0'; - if ((nsession = switch_core_session_locate(uuid)) != NULL) { - channel = switch_core_session_get_channel(nsession); - } else { - stream->write_function(stream, "-ERR invalid session"); - switch_safe_free(mycmd); - return SWITCH_STATUS_GENERR; - } - } else { - stream->write_function(stream, "-ERR invalid argument"); - switch_safe_free(mycmd); - return SWITCH_STATUS_GENERR; - } - } else if (session == NULL) { - stream->write_function(stream, "-ERR invalid argument"); - switch_safe_free(mycmd); - return SWITCH_STATUS_GENERR; - } else { - channel = switch_core_session_get_channel(session); - input = mycmd; - } - - p = switch_channel_expand_variables_check(channel, input, NULL, NULL, 0); - stream->write_function(stream, "+OK %s", p); - if (p != input) { - switch_safe_free(p); - } - switch_safe_free(mycmd); - if (nsession) { - switch_core_session_rwunlock(nsession); - } - return SWITCH_STATUS_SUCCESS; -} - -#define KZ_CONTACT_DESC "returns kazoo contact" -#define KZ_CONTACT_SYNTAX "endpoint@account" - -SWITCH_STANDARD_API(kz_contact_fun) -{ - switch_event_t *params = NULL; - const char *var = NULL; - switch_xml_t xml_node = NULL; - switch_xml_t xml_root = NULL; - - const char *reply = "error/subscriber_absent"; - - if (!cmd) { - stream->write_function(stream, "%s", reply); - return SWITCH_STATUS_SUCCESS; - } - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "call"); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Fetch-Exclude-Cache", "true"); - - /* - if (stream->param_event) { - switch_event_merge(params, stream->param_event); - } - */ - - /* - if (session) { - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Fetch-Call-UUID", switch_core_session_get_uuid(session)); - } else if (stream->param_event && (var = switch_event_get_header(stream->param_event, "ent_originate_aleg_uuid")) != NULL) { - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Fetch-Call-UUID", var); - } - */ - - if (switch_xml_locate("directory", "location", "id", cmd, &xml_root, &xml_node, params, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "%s", reply); - return SWITCH_STATUS_SUCCESS; - } - - var = switch_xml_attr(xml_node, "value"); - if (!zstr(var)) { - reply = var; - } - - stream->write_function(stream, "%s", reply); - - switch_xml_free(xml_root); - return SWITCH_STATUS_SUCCESS; -} - -void add_kz_commands(switch_loadable_module_interface_t **module_interface) { - switch_api_interface_t *api_interface = NULL; - SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi", UUID_SET_DESC, uuid_setvar_multi_function, UUID_MULTISET_SYNTAX); - SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi_encoded", UUID_SET_DESC, uuid_setvar_multi_encoded_function, UUID_MULTISET_SYNTAX); - switch_console_set_complete("add kz_uuid_setvar_multi ::console::list_uuid"); - switch_console_set_complete("add kz_uuid_setvar_multi_encoded ::console::list_uuid"); - SWITCH_ADD_API(api_interface, "kz_uuid_setvar", UUID_MULTISET_DESC, uuid_setvar_function, UUID_SET_SYNTAX); - SWITCH_ADD_API(api_interface, "kz_uuid_setvar_encoded", UUID_MULTISET_DESC, uuid_setvar_encoded_function, UUID_SET_SYNTAX); - switch_console_set_complete("add kz_uuid_setvar ::console::list_uuid"); - switch_console_set_complete("add kz_uuid_setvar_encoded ::console::list_uuid"); - SWITCH_ADD_API(api_interface, "kz_http_put", KZ_HTTP_PUT_DESC, kz_http_put, KZ_HTTP_PUT_SYNTAX); - SWITCH_ADD_API(api_interface, "first-of", KZ_FIRST_OF_DESC, kz_first_of, KZ_FIRST_OF_SYNTAX); - SWITCH_ADD_API(api_interface, "kz_expand", KZ_FIRST_OF_DESC, kz_expand_api, KZ_FIRST_OF_SYNTAX); - SWITCH_ADD_API(api_interface, "kz_eval", KZ_FIRST_OF_DESC, kz_eval_api, KZ_FIRST_OF_SYNTAX); - SWITCH_ADD_API(api_interface, "kz_contact", KZ_CONTACT_DESC, kz_contact_fun, KZ_CONTACT_SYNTAX); -} - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_config.c deleted file mode 100644 index a64677074b..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_config.c +++ /dev/null @@ -1,553 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#include "mod_kazoo.h" - -static const char *LOG_LEVEL_NAMES[] = { - "SWITCH_LOG_DEBUG10", - "SWITCH_LOG_DEBUG9", - "SWITCH_LOG_DEBUG8", - "SWITCH_LOG_DEBUG7", - "SWITCH_LOG_DEBUG6", - "SWITCH_LOG_DEBUG5", - "SWITCH_LOG_DEBUG4", - "SWITCH_LOG_DEBUG3", - "SWITCH_LOG_DEBUG2", - "SWITCH_LOG_DEBUG1", - "SWITCH_LOG_DEBUG", - "SWITCH_LOG_INFO", - "SWITCH_LOG_NOTICE", - "SWITCH_LOG_WARNING", - "SWITCH_LOG_ERROR", - "SWITCH_LOG_CRIT", - "SWITCH_LOG_ALERT", - "SWITCH_LOG_CONSOLE", - "SWITCH_LOG_INVALID", - "SWITCH_LOG_UNINIT", - NULL -}; - -static const switch_log_level_t LOG_LEVEL_VALUES[] = { - SWITCH_LOG_DEBUG10, - SWITCH_LOG_DEBUG9, - SWITCH_LOG_DEBUG8, - SWITCH_LOG_DEBUG7, - SWITCH_LOG_DEBUG6, - SWITCH_LOG_DEBUG5, - SWITCH_LOG_DEBUG4, - SWITCH_LOG_DEBUG3, - SWITCH_LOG_DEBUG2, - SWITCH_LOG_DEBUG1, - SWITCH_LOG_DEBUG, - SWITCH_LOG_INFO, - SWITCH_LOG_NOTICE, - SWITCH_LOG_WARNING, - SWITCH_LOG_ERROR, - SWITCH_LOG_CRIT, - SWITCH_LOG_ALERT, - SWITCH_LOG_CONSOLE, - SWITCH_LOG_INVALID, - SWITCH_LOG_UNINIT -}; - -switch_log_level_t log_str2level(const char *str) -{ - int x = 0; - switch_log_level_t level = SWITCH_LOG_INVALID; - - if (switch_is_number(str)) { - x = atoi(str); - - if (x > SWITCH_LOG_INVALID) { - return SWITCH_LOG_INVALID - 1; - } else if (x < 0) { - return 0; - } else { - return x; - } - } - - - for (x = 0;; x++) { - if (!LOG_LEVEL_NAMES[x]) { - break; - } - - if (!strcasecmp(LOG_LEVEL_NAMES[x], str)) { - level = LOG_LEVEL_VALUES[x]; //(switch_log_level_t) x; - break; - } - } - - return level; -} - -switch_status_t kazoo_config_loglevels(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_loglevels_ptr *ptr) -{ - switch_xml_t xml_level, xml_logging; - kazoo_loglevels_ptr loglevels = (kazoo_loglevels_ptr) switch_core_alloc(pool, sizeof(kazoo_loglevels_t)); - - loglevels->failed_log_level = SWITCH_LOG_ALERT; - loglevels->filtered_event_log_level = SWITCH_LOG_DEBUG1; - loglevels->filtered_field_log_level = SWITCH_LOG_DEBUG1; - loglevels->info_log_level = SWITCH_LOG_INFO; - loglevels->warn_log_level = SWITCH_LOG_WARNING; - loglevels->success_log_level = SWITCH_LOG_DEBUG; - loglevels->time_log_level = SWITCH_LOG_DEBUG1; - loglevels->trace_log_level = SWITCH_LOG_DEBUG1; - loglevels->debug_log_level = SWITCH_LOG_DEBUG; - loglevels->error_log_level = SWITCH_LOG_ERROR; - loglevels->hashing_log_level = SWITCH_LOG_DEBUG1; - - if ((xml_logging = switch_xml_child(cfg, "logging")) != NULL) { - for (xml_level = switch_xml_child(xml_logging, "log"); xml_level; xml_level = xml_level->next) { - char *var = (char *) switch_xml_attr_soft(xml_level, "name"); - char *val = (char *) switch_xml_attr_soft(xml_level, "value"); - - if (!var) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "logging param missing 'name' attribute\n"); - continue; - } - - if (!val) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "logging param[%s] missing 'value' attribute\n", var); - continue; - } - - if (!strncmp(var, "success", 7)) { - loglevels->success_log_level = log_str2level(val); - } else if (!strncmp(var, "failed", 6)) { - loglevels->failed_log_level = log_str2level(val); - } else if (!strncmp(var, "info", 4)) { - loglevels->info_log_level = log_str2level(val); - } else if (!strncmp(var, "warn", 4)) { - loglevels->warn_log_level = log_str2level(val); - } else if (!strncmp(var, "time", 4)) { - loglevels->time_log_level = log_str2level(val); - } else if (!strncmp(var, "filtered-event", 14)) { - loglevels->filtered_event_log_level = log_str2level(val); - } else if (!strncmp(var, "filtered-field", 14)) { - loglevels->filtered_field_log_level = log_str2level(val); - } else if (!strncmp(var, "trace", 5)) { - loglevels->trace_log_level = log_str2level(val); - } else if (!strncmp(var, "debug", 5)) { - loglevels->debug_log_level = log_str2level(val); - } else if (!strncmp(var, "error", 5)) { - loglevels->error_log_level = log_str2level(val); - } else if (!strncmp(var, "hashing", 7)) { - loglevels->hashing_log_level = log_str2level(val); - } - } /* xml_level for loop */ - } - - *ptr = loglevels; - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_filters(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_filter_ptr *ptr) -{ - switch_xml_t filters, filter; -// char *routing_key = NULL; - kazoo_filter_ptr root = NULL, prv = NULL, cur = NULL; - - - if ((filters = switch_xml_child(cfg, "filters")) != NULL) { - for (filter = switch_xml_child(filters, "filter"); filter; filter = filter->next) { - const char *var = switch_xml_attr(filter, "name"); - const char *val = switch_xml_attr(filter, "value"); - const char *type = switch_xml_attr(filter, "type"); - const char *compare = switch_xml_attr(filter, "compare"); - cur = (kazoo_filter_ptr) switch_core_alloc(pool, sizeof(kazoo_filter)); - memset(cur, 0, sizeof(kazoo_filter)); - if(prv == NULL) { - root = prv = cur; - } else { - prv->next = cur; - prv = cur; - } - cur->type = FILTER_EXCLUDE; - cur->compare = FILTER_COMPARE_VALUE; - - if(var) - cur->name = switch_core_strdup(pool, var); - - if(val) - cur->value = switch_core_strdup(pool, val); - - if(type) { - if (!strncmp(type, "exclude", 7)) { - cur->type = FILTER_EXCLUDE; - } else if (!strncmp(type, "include", 7)) { - cur->type = FILTER_INCLUDE; - } - } - - if(compare) { - if (!strncmp(compare, "value", 7)) { - cur->compare = FILTER_COMPARE_VALUE; - } else if (!strncmp(compare, "prefix", 6)) { - cur->compare = FILTER_COMPARE_PREFIX; - } else if (!strncmp(compare, "list", 4)) { - cur->compare = FILTER_COMPARE_LIST; - } else if (!strncmp(compare, "exists", 6)) { - cur->compare = FILTER_COMPARE_EXISTS; - } else if (!strncmp(compare, "regex", 5)) { - cur->compare = FILTER_COMPARE_REGEX; - } else if (!strncmp(compare, "field", 5)) { - cur->compare = FILTER_COMPARE_FIELD; - } - } - - if(cur->value == NULL) - cur->compare = FILTER_COMPARE_EXISTS; - - if(cur->compare == FILTER_COMPARE_LIST) { - cur->list.size = switch_separate_string(cur->value, '|', cur->list.value, MAX_LIST_FIELDS); - } - - } - - } - - *ptr = root; - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_field(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_field_ptr *ptr) -{ - const char *var = switch_xml_attr(cfg, "name"); - const char *val = switch_xml_attr(cfg, "value"); - const char *as = switch_xml_attr(cfg, "as"); - const char *type = switch_xml_attr(cfg, "type"); - const char *exclude_prefix = switch_xml_attr(cfg, "exclude-prefix"); - const char *serialize_as = switch_xml_attr(cfg, "serialize-as"); - const char *as_array = switch_xml_attr(cfg, "as-array"); - kazoo_field_ptr cur = (kazoo_field_ptr) switch_core_alloc(pool, sizeof(kazoo_field)); - cur->in_type = FIELD_NONE; - cur->out_type = JSON_NONE; - - if(var) - cur->name = switch_core_strdup(pool, var); - - if(val) - cur->value = switch_core_strdup(pool, val); - - if(as) - cur->as = switch_core_strdup(pool, as); - - if(type) { - if (!strncmp(type, "copy", 4)) { - cur->in_type = FIELD_COPY; - } else if (!strncmp(type, "static", 6)) { - cur->in_type = FIELD_STATIC; - } else if (!strncmp(type, "first-of", 8)) { - cur->in_type = FIELD_FIRST_OF; - } else if (!strncmp(type, "expand", 6)) { - cur->in_type = FIELD_EXPAND; - } else if (!strncmp(type, "prefix", 10)) { - cur->in_type = FIELD_PREFIX; - } else if (!strncmp(type, "group", 5)) { - cur->in_type = FIELD_GROUP; - } else if (!strncmp(type, "reference", 9)) { - cur->in_type = FIELD_REFERENCE; - } - } - - if(serialize_as) { - if (!strncmp(serialize_as, "string", 5)) { - cur->out_type = JSON_STRING; - } else if (!strncmp(serialize_as, "number", 6)) { - cur->out_type = JSON_NUMBER; - } else if (!strncmp(serialize_as, "boolean", 7)) { - cur->out_type = JSON_BOOLEAN; - } else if (!strncmp(serialize_as, "object", 6)) { - cur->out_type = JSON_OBJECT; - } else if (!strncmp(serialize_as, "raw", 6)) { - cur->out_type = JSON_RAW; - } - } - - if(as_array) { - cur->out_type_as_array = switch_true(as_array); - } - - if(exclude_prefix) - cur->exclude_prefix = switch_true(exclude_prefix); - - kazoo_config_filters(pool, cfg, &cur->filter); - kazoo_config_fields(definitions, pool, cfg, &cur->children); - - if(cur->children != NULL - && (cur->in_type == FIELD_STATIC) - && (cur->out_type == JSON_NONE) - ) { - cur->out_type = JSON_OBJECT; - } - if(cur->in_type == FIELD_NONE) { - cur->in_type = FIELD_COPY; - } - - if(cur->out_type == JSON_NONE) { - cur->out_type = JSON_STRING; - } - - if(cur->in_type == FIELD_FIRST_OF) { - cur->list.size = switch_separate_string(cur->value, '|', cur->list.value, MAX_LIST_FIELDS); - } - - if(cur->in_type == FIELD_REFERENCE) { - cur->ref = (kazoo_definition_ptr)switch_core_hash_find(definitions->hash, cur->name); - if(cur->ref == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "referenced field %s not found\n", cur->name); - } - } - - *ptr = cur; - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_fields_loop(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_field_ptr *ptr) -{ - switch_xml_t field; - kazoo_field_ptr root = NULL, prv = NULL; - - - for (field = switch_xml_child(cfg, "field"); field; field = field->next) { - kazoo_field_ptr cur = NULL; - kazoo_config_field(definitions, pool, field, &cur); - if(root == NULL) { - root = prv = cur; - } else { - prv->next = cur; - prv = cur; - } - } - - *ptr = root; - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_fields(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_fields_ptr *ptr) -{ - switch_xml_t fields; - kazoo_fields_ptr root = NULL; - - - if ((fields = switch_xml_child(cfg, "fields")) != NULL) { - const char *verbose = switch_xml_attr(fields, "verbose"); - root = (kazoo_fields_ptr) switch_core_alloc(pool, sizeof(kazoo_fields)); - root->verbose = SWITCH_TRUE; - if(verbose) { - root->verbose = switch_true(verbose); - } - - kazoo_config_fields_loop(definitions, pool, fields, &root->head); - - } - - *ptr = root; - - return SWITCH_STATUS_SUCCESS; - -} - -kazoo_config_ptr kazoo_config_event_handlers(kazoo_config_ptr definitions, switch_xml_t cfg) -{ - switch_xml_t xml_profiles = NULL, xml_profile = NULL; - kazoo_config_ptr profiles = NULL; - switch_memory_pool_t *pool = NULL; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "error creating memory pool for producers\n"); - return NULL; - } - - profiles = switch_core_alloc(pool, sizeof(kazoo_config)); - profiles->pool = pool; - switch_core_hash_init(&profiles->hash); - - if ((xml_profiles = switch_xml_child(cfg, "event-handlers"))) { - if ((xml_profile = switch_xml_child(xml_profiles, "profile"))) { - for (; xml_profile; xml_profile = xml_profile->next) { - const char *name = switch_xml_attr(xml_profile, "name"); - if(name == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing attr name\n" ); - continue; - } - kazoo_config_event_handler(definitions, profiles, xml_profile, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to locate a event-handler profile for kazoo\n" ); - } - } else { - destroy_config(&profiles); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate event-handlers section for kazoo, using default\n" ); - } - - return profiles; - -} - -kazoo_config_ptr kazoo_config_fetch_handlers(kazoo_config_ptr definitions, switch_xml_t cfg) -{ - switch_xml_t xml_profiles = NULL, xml_profile = NULL; - kazoo_config_ptr profiles = NULL; - switch_memory_pool_t *pool = NULL; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "error creating memory pool for producers\n"); - return NULL; - } - - profiles = switch_core_alloc(pool, sizeof(kazoo_config)); - profiles->pool = pool; - switch_core_hash_init(&profiles->hash); - - if ((xml_profiles = switch_xml_child(cfg, "fetch-handlers"))) { - if ((xml_profile = switch_xml_child(xml_profiles, "profile"))) { - for (; xml_profile; xml_profile = xml_profile->next) { - const char *name = switch_xml_attr(xml_profile, "name"); - if(name == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing attr name\n" ); - continue; - } - kazoo_config_fetch_handler(definitions, profiles, xml_profile, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to locate a fetch-handler profile for kazoo\n" ); - } - } else { - destroy_config(&profiles); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate fetch-handlers section for kazoo, using default\n" ); - } - - return profiles; - -} - - -switch_status_t kazoo_config_definition(kazoo_config_ptr root, switch_xml_t cfg) -{ - kazoo_definition_ptr definition = NULL; - char *name = (char *) switch_xml_attr_soft(cfg, "name"); - - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to load kazoo profile, check definition missing name attr\n"); - return SWITCH_STATUS_GENERR; - } - - definition = switch_core_alloc(root->pool, sizeof(kazoo_definition)); - definition->name = switch_core_strdup(root->pool, name); - - kazoo_config_filters(root->pool, cfg, &definition->filter); - kazoo_config_fields_loop(root, root->pool, cfg, &definition->head); - - if ( switch_core_hash_insert(root->hash, name, (void *) definition) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new definition [%s] into kazoo definitions hash\n", name); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "definition[%s] successfully configured\n", definition->name); - return SWITCH_STATUS_SUCCESS; -} - -kazoo_config_ptr kazoo_config_definitions(switch_xml_t cfg) -{ - switch_xml_t xml_definitions = NULL, xml_definition = NULL; - kazoo_config_ptr definitions = NULL; - switch_memory_pool_t *pool = NULL; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "error creating memory pool for definitions\n"); - return NULL; - } - - definitions = switch_core_alloc(pool, sizeof(kazoo_config)); - definitions->pool = pool; - switch_core_hash_init(&definitions->hash); - - if ((xml_definitions = switch_xml_child(cfg, "definitions"))) { - if ((xml_definition = switch_xml_child(xml_definitions, "definition"))) { - for (; xml_definition; xml_definition = xml_definition->next) { - kazoo_config_definition(definitions, xml_definition); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "no definitions for kazoo\n" ); - } - } else { - destroy_config(&definitions); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate definitions section for kazoo, using default\n" ); - } - - return definitions; -} - -void destroy_config(kazoo_config_ptr *ptr) -{ - kazoo_config_ptr config = NULL; - switch_memory_pool_t *pool; - - if (!ptr || !*ptr) { - return; - } - config = *ptr; - pool = config->pool; - - switch_core_hash_destroy(&(config->hash)); - switch_core_destroy_memory_pool(&pool); - - *ptr = NULL; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_config.h b/src/mod/event_handlers/mod_kazoo/kazoo_config.h deleted file mode 100644 index d0117fda5f..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_config.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#ifndef KAZOO_CONFIG_H -#define KAZOO_CONFIG_H - -#include - - -struct kazoo_config_t { - switch_hash_t *hash; - switch_memory_pool_t *pool; -}; - -switch_status_t kazoo_config_loglevels(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_loglevels_ptr *ptr); -switch_status_t kazoo_config_filters(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_filter_ptr *ptr); -switch_status_t kazoo_config_fields(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_fields_ptr *ptr); - -switch_status_t kazoo_config_event_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_event_profile_ptr *ptr); -switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_fetch_profile_ptr *ptr); -kazoo_config_ptr kazoo_config_event_handlers(kazoo_config_ptr definitions, switch_xml_t cfg); -kazoo_config_ptr kazoo_config_fetch_handlers(kazoo_config_ptr definitions, switch_xml_t cfg); -kazoo_config_ptr kazoo_config_definitions(switch_xml_t cfg); -switch_status_t kazoo_config_field(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_field_ptr *ptr); -void destroy_config(kazoo_config_ptr *ptr); - -#endif /* KAZOO_CONFIG_H */ - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_definitions.S b/src/mod/event_handlers/mod_kazoo/kazoo_definitions.S deleted file mode 100644 index 0bbe0137cb..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_definitions.S +++ /dev/null @@ -1,8 +0,0 @@ - .global kz_default_config - .global kz_default_config_size - .section .rodata -kz_default_config: - .incbin "kazoo.conf.xml" -1: -kz_default_config_size: - .int 1b - kz_default_config diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_defs.h b/src/mod/event_handlers/mod_kazoo/kazoo_defs.h deleted file mode 100644 index 7fe86dd354..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_defs.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef KAZOO_DEFS_H_ -#define KAZOO_DEFS_H_ - -#define INTERACTION_VARIABLE "Call-Interaction-ID" - -#define UNIX_EPOCH_IN_GREGORIAN 62167219200 -#define UNIX_EPOCH_IN_GREGORIAN_STR "62167219200" - -#endif /* KAZOO_DEFS_H_ */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c deleted file mode 100644 index 5a01650969..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ /dev/null @@ -1,980 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_dptools.c -- clones of mod_dptools commands slightly modified for kazoo - * - */ -#include "mod_kazoo.h" - -#define SET_SHORT_DESC "Set a channel variable" -#define SET_LONG_DESC "Set a channel variable for the channel calling the application." -#define SET_SYNTAX "=" - -#define MULTISET_SHORT_DESC "Set many channel variables" -#define MULTISET_LONG_DESC "Set many channel variables for the channel calling the application" -#define MULTISET_SYNTAX "[^^]= =" - -#define UNSET_SHORT_DESC "Unset a channel variable" -#define UNSET_LONG_DESC "Unset a channel variable for the channel calling the application." -#define UNSET_SYNTAX "" - -#define MULTIUNSET_SHORT_DESC "Unset many channel variables" -#define MULTIUNSET_LONG_DESC "Unset many channel variables for the channel calling the application." -#define MULTIUNSET_SYNTAX "[^^] " - -#define EXPORT_SHORT_DESC "Export many channel variables" -#define EXPORT_LONG_DESC "Export many channel variables for the channel calling the application" -#define EXPORT_SYNTAX "[^^]= =" - -#define PREFIX_UNSET_SHORT_DESC "clear variables by prefix" -#define PREFIX_UNSET_LONG_DESC "clears the channel variables that start with prefix supplied" -#define PREFIX_UNSET_SYNTAX "" - -#define UUID_MULTISET_SHORT_DESC "Set many channel variables" -#define UUID_MULTISET_LONG_DESC "Set many channel variables for a specific channel" -#define UUID_MULTISET_SYNTAX " [^^]= =" - -#define KZ_ENDLESS_PLAYBACK_SHORT_DESC "Playback File Endlessly until break" -#define KZ_ENDLESS_PLAYBACK_LONG_DESC "Endlessly Playback a file to the channel until a break occurs" -#define KZ_ENDLESS_PLAYBACK_SYNTAX "" - -#define NOOP_SHORT_DESC "no operation" -#define NOOP_LONG_DESC "no operation. serves as a control point" -#define NOOP_SYNTAX "[]" - -static void base_set (switch_core_session_t *session, const char *data, int urldecode, switch_stack_t stack) -{ - char *var, *val = NULL; - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - } else { - switch_channel_t *channel = switch_core_session_get_channel(session); - char *expanded = NULL; - - var = switch_core_session_strdup(session, data); - - if (!(val = strchr(var, '='))) { - val = strchr(var, ','); - } - - if (val) { - *val++ = '\0'; - if (zstr(val)) { - val = NULL; - } - } - - if (val) { - if(urldecode) { - switch_url_decode(val); - } - expanded = switch_channel_expand_variables(channel, val); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s] => [%s]\n", switch_channel_get_name(channel), var, val, - expanded ? expanded : "UNDEF"); - switch_channel_add_variable_var_check(channel, var, expanded, SWITCH_FALSE, stack); - kz_check_set_profile_var(channel, var, expanded); - if (expanded && expanded != val) { - switch_safe_free(expanded); - } - } -} - -static int kz_is_exported(switch_core_session_t *session, char *varname) -{ - char *array[256] = {0}; - int i, argc; - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE); - char *arg = switch_core_session_strdup(session, exports); - argc = switch_split(arg, ',', array); - for(i=0; i < argc; i++) { - if(!strcasecmp(array[i], varname)) - return 1; - } - - return 0; -} - -static void base_export (switch_core_session_t *session, const char *data, int urldecode, switch_stack_t stack) -{ - char *var, *val = NULL; - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - } else { - switch_channel_t *channel = switch_core_session_get_channel(session); - char *expanded = NULL; - - var = switch_core_session_strdup(session, data); - - if (!(val = strchr(var, '='))) { - val = strchr(var, ','); - } - - if (val) { - *val++ = '\0'; - if (zstr(val)) { - val = NULL; - } - } - - if (val) { - if(urldecode) { - switch_url_decode(val); - } - expanded = switch_channel_expand_variables(channel, val); - - if(!kz_is_exported(session, var)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s EXPORT [%s]=[%s]\n", switch_channel_get_name(channel), var, expanded ? expanded : "UNDEF"); - switch_channel_export_variable_var_check(channel, var, expanded, SWITCH_EXPORT_VARS_VARIABLE, SWITCH_FALSE); - } else { - if(strcmp(switch_str_nil(switch_channel_get_variable_dup(channel, var, SWITCH_FALSE, -1)), expanded)) { - switch_channel_set_variable(channel, var, expanded); - } - } - if (expanded && expanded != val) { - switch_safe_free(expanded); - } - } - } -} - -SWITCH_STANDARD_APP(prefix_unset_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_header_t *ei = NULL; - switch_event_t *clear; - char *arg = (char *) data; - - if(switch_event_create(&clear, SWITCH_EVENT_CLONE) != SWITCH_STATUS_SUCCESS) { - return; - } - - for (ei = switch_channel_variable_first(channel); ei; ei = ei->next) { - const char *name = ei->name; - char *value = ei->value; - if (!strncasecmp(name, arg, strlen(arg))) { - switch_event_add_header_string(clear, SWITCH_STACK_BOTTOM, name, value); - } - } - - switch_channel_variable_last(channel); - for (ei = clear->headers; ei; ei = ei->next) { - char *varname = ei->name; - switch_channel_set_variable(channel, varname, NULL); - } - - switch_event_destroy(&clear); -} - -void kz_multiset(switch_core_session_t *session, const char* data, int urldecode) -{ - char delim = ' '; - char *arg = (char *) data; - switch_event_t *event; - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - switch_channel_t *channel = switch_core_session_get_channel(session); - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - base_set(session, array[i], urldecode, SWITCH_STACK_BOTTOM); - } - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "multiset with empty args\n"); - } -} - -SWITCH_STANDARD_APP(multiset_function) -{ - kz_multiset(session, data, 0); -} - -SWITCH_STANDARD_APP(multiset_encoded_function) -{ - kz_multiset(session, data, 1); -} - -void kz_uuid_multiset(switch_core_session_t *session, const char* data, int urldecode) -{ - char delim = ' '; - char *arg0 = (char *) data; - char *arg = strchr(arg0, ' '); - switch_event_t *event; - - - if(arg == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "uuid_multiset with invalid args\n"); - return; - } - *arg = '\0'; - arg++; - - if(zstr(arg0)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "uuid_multiset with invalid uuid\n"); - return; - } - - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - switch_core_session_t *uuid_session = NULL; - if ((uuid_session = switch_core_session_locate(arg0)) != NULL) { - switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session); - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - base_set(uuid_session, array[i], urldecode, SWITCH_STACK_BOTTOM); - } - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(uuid_channel, event); - switch_event_fire(&event); - } - switch_core_session_rwunlock(uuid_session); - } else { - base_set(session, data, urldecode, SWITCH_STACK_BOTTOM); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "multiset with empty args\n"); - } -} - -SWITCH_STANDARD_APP(uuid_multiset_function) -{ - kz_uuid_multiset(session, data, 0); -} - -SWITCH_STANDARD_APP(uuid_multiset_encoded_function) -{ - kz_uuid_multiset(session, data, 1); -} - -void kz_set(switch_core_session_t *session, const char* data, int urldecode) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *event; - - base_set(session, data, urldecode, SWITCH_STACK_BOTTOM); - - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } -} - -SWITCH_STANDARD_APP(set_function) -{ - kz_set(session, data, 0); -} - -SWITCH_STANDARD_APP(set_encoded_function) -{ - kz_set(session, data, 1); -} - -SWITCH_STANDARD_APP(unset_function) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *event; - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UNSET [%s]\n", (char *) data); - switch_channel_set_variable(switch_core_session_get_channel(session), data, NULL); - } - - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } -} - -SWITCH_STANDARD_APP(multiunset_function) { - char delim = ' '; - char *arg = (char *) data; - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - switch_channel_set_variable(switch_core_session_get_channel(session), array[i], NULL); - } - - } else { - switch_channel_set_variable(switch_core_session_get_channel(session), arg, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "multiunset with empty args\n"); - } -} - - -void kz_export(switch_core_session_t *session, const char* data, int urldecode) -{ - char delim = ' '; - char *arg = (char *) data; - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - base_export(session, array[i], urldecode, SWITCH_STACK_BOTTOM); - } - } else { - base_export(session, data, urldecode, SWITCH_STACK_BOTTOM); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "export with empty args\n"); - } -} - -SWITCH_STANDARD_APP(export_function) -{ - kz_export(session, data, 0); -} - -SWITCH_STANDARD_APP(export_encoded_function) -{ - kz_export(session, data, 1); -} - -// copied from mod_dptools with allow SWITCH_STATUS_BREAK -SWITCH_STANDARD_APP(kz_endless_playback_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status = SWITCH_STATUS_SUCCESS; - const char *file = data; - - while (switch_channel_ready(channel)) { - status = switch_ivr_play_file(session, NULL, file, NULL); - - if (status != SWITCH_STATUS_SUCCESS) { - break; - } - } - - switch (status) { - case SWITCH_STATUS_SUCCESS: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE PLAYED"); - break; - case SWITCH_STATUS_BREAK: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK_INTERRUPTED"); - break; - case SWITCH_STATUS_NOTFOUND: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE NOT FOUND"); - break; - default: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK ERROR"); - break; - } - -} - -SWITCH_STANDARD_APP(kz_moh_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_file_handle_t fh = { 0 }; - const char *var_samples = switch_channel_get_variable_dup(channel, "moh_playback_samples", SWITCH_FALSE, -1); - unsigned int samples = 0; - char * my_data = NULL; - - if (var_samples) { - fh.samples = samples = atoi(var_samples); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING SAMPLES %d\n", samples); - } - - switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, ""); - - /* - * hack for proper position - */ - if (!strncmp(data, "http_cache://", 13) && session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - char * resolve = switch_mprintf("${http_get({prefetch=true}%s)}", data+13); - my_data = switch_channel_expand_variables_check(channel, resolve, NULL, NULL, 0); - } else { - my_data = strdup(data); - } - - status = switch_ivr_play_file(session, &fh, my_data, NULL); -// status = switch_ivr_play_file(session, &fh, data, NULL); - - switch_assert(!(fh.flags & SWITCH_FILE_OPEN)); - - switch (status) { - case SWITCH_STATUS_SUCCESS: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED SUCCESS\n"); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED"); - switch_channel_set_variable(channel, "moh_playback_samples", "0"); - break; - case SWITCH_STATUS_BREAK: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED BREAK\n"); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED"); - if ((var_samples = switch_channel_get_variable_dup(channel, "playback_samples", SWITCH_FALSE, -1)) != NULL) { - samples += atoi(var_samples); - if (samples >= fh.samples) { - samples = 0; - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING MOH SAMPLES %d\n", samples); - switch_channel_set_variable_printf(channel, "moh_playback_samples", "%d", samples); - } - break; - case SWITCH_STATUS_NOTFOUND: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED NOT FOUND\n"); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE NOT FOUND"); - break; - default: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MOH PLAYED DEFAULT\n"); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH PLAYBACK ERROR"); - break; - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH duration %" SWITCH_INT64_T_FMT "\n", fh.duration); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH offset_pos %d\n", fh.offset_pos); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH pos %" SWITCH_INT64_T_FMT "\n", fh.pos); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH sample_count %" SWITCH_SIZE_T_FMT "\n", fh.sample_count); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH samples %d\n", fh.samples); - - switch_safe_free(my_data); -} - -SWITCH_STANDARD_APP(noop_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - const char *response = uuid_str; - - if (zstr(data)) { - switch_uuid_str(uuid_str, sizeof(uuid_str)); - } else { - response = data; - } - - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, response); -} - -SWITCH_STANDARD_APP(kz_restore_caller_id_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t *cp = switch_channel_get_caller_profile(channel); - cp->caller_id_name = cp->orig_caller_id_name; - cp->caller_id_number = cp->orig_caller_id_number; -} - -SWITCH_STANDARD_APP(kz_audio_bridge_function) -{ - switch_channel_t *caller_channel = switch_core_session_get_channel(session); - switch_core_session_t *peer_session = NULL; - switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; - switch_status_t status = SWITCH_STATUS_FALSE; - - if (zstr(data)) { - return; - } - - status = switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); - - if (status != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(cause)); - - switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(cause)); - switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(cause)); - switch_channel_handle_cause(caller_channel, cause); - - return; - } else { - const char* uuid = switch_core_session_get_uuid(session); - const char* peer_uuid = switch_core_session_get_uuid(peer_session); - - - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) || - switch_true(switch_channel_get_variable(peer_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) { - switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE); - } - - while(1) { - const char *xfer_uuid; - switch_channel_state_t a_state , a_running_state; - switch_channel_state_t b_state , b_running_state; - status = switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BRIDGE RESULT %i\n", status); - if(status != 0) { - break; - } - - a_state = switch_channel_get_state(caller_channel); - a_running_state = switch_channel_get_running_state(caller_channel); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A STATE %s %s => %s , %s\n", switch_channel_state_name(a_running_state), switch_channel_state_name(a_state), uuid, peer_uuid); - - if(a_state >= CS_HANGUP) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A HANGUP = %s , %s\n", uuid, peer_uuid); - break; - } - - b_state = switch_channel_get_state(peer_channel); - b_running_state = switch_channel_get_running_state(peer_channel); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B STATE %s %s => %s , %s\n", switch_channel_state_name(b_running_state), switch_channel_state_name(b_state), uuid, peer_uuid); - - if(b_state >= CS_HANGUP) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B HANGUP = %s , %s\n", uuid, peer_uuid); - switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(switch_channel_get_cause(peer_channel))); - break; - } - - if(!(xfer_uuid=switch_channel_get_variable(caller_channel, "att_xfer_peer_uuid"))) { - if(!(xfer_uuid=switch_channel_get_variable(peer_channel, "att_xfer_peer_uuid"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER UUID NULL\n"); - break; - } - } - - switch_channel_set_variable(caller_channel, "att_xfer_peer_uuid", NULL); - switch_channel_set_variable(peer_channel, "att_xfer_peer_uuid", NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 1\n"); - - switch_channel_clear_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR); - switch_channel_set_state(peer_channel, CS_RESET); - switch_channel_wait_for_state(peer_channel, NULL, CS_RESET); - switch_channel_clear_state_handler(peer_channel, NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 3\n"); - - switch_channel_set_flag(caller_channel, CF_UUID_BRIDGE_ORIGINATOR); - switch_channel_clear_flag(caller_channel, CF_TRANSFER); - switch_channel_clear_flag(caller_channel, CF_REDIRECT); - switch_channel_set_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR); - switch_channel_clear_flag(peer_channel, CF_TRANSFER); - switch_channel_clear_flag(peer_channel, CF_REDIRECT); - - if(!switch_channel_media_up(caller_channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid); - } - if(!switch_channel_media_up(peer_channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid); - } - switch_channel_set_state(caller_channel, CS_EXECUTE); - switch_channel_set_state(peer_channel, CS_EXECUTE); - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER LOOP %s %s , %s\n", xfer_uuid, uuid, peer_uuid); - - } - - if (peer_session) { - switch_core_session_rwunlock(peer_session); - } - } -} - -SWITCH_STANDARD_APP(kz_audio_bridge_uuid_function) -{ - switch_core_session_t *peer_session = NULL; - const char * peer_uuid = NULL; - - if (zstr(data)) { - return; - } - - peer_uuid = switch_core_session_strdup(session, data); - if (peer_uuid && (peer_session = switch_core_session_locate(peer_uuid))) { - switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL); - } - - if (peer_session) { - switch_core_session_rwunlock(peer_session); - } -} - - -struct kz_att_keys { - const char *attxfer_cancel_key; - const char *attxfer_hangup_key; - const char *attxfer_conf_key; -}; - -static switch_status_t kz_att_xfer_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) -{ - switch_core_session_t *peer_session = (switch_core_session_t *) buf; - if (!buf || !peer_session) { - return SWITCH_STATUS_SUCCESS; - } - - switch (itype) { - case SWITCH_INPUT_TYPE_DTMF: - { - switch_dtmf_t *dtmf = (switch_dtmf_t *) input; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - struct kz_att_keys *keys = switch_channel_get_private(channel, "__kz_keys"); - - if (dtmf->digit == *keys->attxfer_hangup_key) { - switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER); - return SWITCH_STATUS_FALSE; - } - - if (dtmf->digit == *keys->attxfer_cancel_key) { - switch_channel_hangup(peer_channel, SWITCH_CAUSE_NORMAL_CLEARING); - return SWITCH_STATUS_FALSE; - } - - if (dtmf->digit == *keys->attxfer_conf_key) { - switch_caller_extension_t *extension = NULL; - const char *app = "three_way"; - const char *app_arg = switch_core_session_get_uuid(session); - const char *holding = switch_channel_get_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); - switch_core_session_t *b_session; - - if (holding && (b_session = switch_core_session_locate(holding))) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - if (!switch_channel_ready(b_channel)) { - app = "intercept"; - } - switch_core_session_rwunlock(b_session); - } - - if ((extension = switch_caller_extension_new(peer_session, app, app_arg)) == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); - abort(); - } - - switch_caller_extension_add_application(peer_session, extension, app, app_arg); - switch_channel_set_caller_extension(peer_channel, extension); - switch_channel_set_state(peer_channel, CS_RESET); - switch_channel_wait_for_state(peer_channel, channel, CS_RESET); - switch_channel_set_state(peer_channel, CS_EXECUTE); - switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, NULL); - return SWITCH_STATUS_FALSE; - } - - } - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_att_xfer_tmp_hanguphook(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_state_t state = switch_channel_get_state(channel); - - if (state == CS_HANGUP || state == CS_ROUTING) { - const char *bond = switch_channel_get_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); - - if (!zstr(bond)) { - switch_core_session_t *b_session; - - if ((b_session = switch_core_session_locate(bond))) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - if (switch_channel_up(b_channel)) { - switch_channel_set_flag(b_channel, CF_REDIRECT); - } - switch_core_session_rwunlock(b_session); - } - } - - switch_core_event_hook_remove_state_change(session, kz_att_xfer_tmp_hanguphook); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_att_xfer_hanguphook(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_state_t state = switch_channel_get_state(channel); - const char *id = NULL; - const char *peer_uuid = NULL; - - if (state == CS_HANGUP || state == CS_ROUTING) { - if ((id = switch_channel_get_variable(channel, "xfer_uuids"))) { - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - if ((peer_uuid = switch_channel_get_variable(channel, "xfer_peer_uuid"))) { - switch_core_session_t *peer_session = NULL; - if ((peer_session = switch_core_session_locate(peer_uuid)) != NULL ) { - switch_ivr_transfer_recordings(session, peer_session); - switch_core_session_rwunlock(peer_session); - } - } - switch_api_execute("uuid_bridge", id, NULL, &stream); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id, - switch_str_nil((char *) stream.data)); - switch_safe_free(stream.data); - } - - switch_core_event_hook_remove_state_change(session, kz_att_xfer_hanguphook); - } - return SWITCH_STATUS_SUCCESS; -} - - -static void kz_att_xfer_set_result(switch_channel_t *channel, switch_status_t status) -{ - switch_channel_set_variable(channel, SWITCH_ATT_XFER_RESULT_VARIABLE, status == SWITCH_STATUS_SUCCESS ? "success" : "failure"); -} - -struct kz_att_obj { - switch_core_session_t *session; - const char *data; - int running; -}; - -void *SWITCH_THREAD_FUNC kz_att_thread_run(switch_thread_t *thread, void *obj) -{ - struct kz_att_obj *att = (struct kz_att_obj *) obj; - struct kz_att_keys *keys = NULL; - switch_core_session_t *session = att->session; - switch_core_session_t *peer_session = NULL; - const char *data = att->data; - switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; - switch_channel_t *channel = switch_core_session_get_channel(session), *peer_channel = NULL; - const char *bond = NULL; - switch_bool_t follow_recording = switch_true(switch_channel_get_variable(channel, "recording_follow_attxfer")); - const char *attxfer_cancel_key = NULL, *attxfer_hangup_key = NULL, *attxfer_conf_key = NULL; - int br = 0; - switch_event_t *event = NULL; - switch_core_session_t *b_session = NULL; - switch_channel_t *b_channel = NULL; - - att->running = 1; - - if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { - return NULL; - } - - bond = switch_channel_get_partner_uuid(channel); - if ((b_session = switch_core_session_locate(bond)) == NULL) { - switch_core_session_rwunlock(session); - return NULL; - } - switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, bond); - switch_core_event_hook_add_state_change(session, kz_att_xfer_tmp_hanguphook); - - if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) - != SWITCH_STATUS_SUCCESS || !peer_session) { - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); - goto end; - } - - peer_channel = switch_core_session_get_channel(peer_session); - switch_channel_set_flag(peer_channel, CF_INNER_BRIDGE); - switch_channel_set_flag(channel, CF_INNER_BRIDGE); - - if (!(attxfer_cancel_key = switch_channel_get_variable(channel, "attxfer_cancel_key"))) { - if (!(attxfer_cancel_key = switch_channel_get_variable(peer_channel, "attxfer_cancel_key"))) { - attxfer_cancel_key = "#"; - } - } - - if (!(attxfer_hangup_key = switch_channel_get_variable(channel, "attxfer_hangup_key"))) { - if (!(attxfer_hangup_key = switch_channel_get_variable(peer_channel, "attxfer_hangup_key"))) { - attxfer_hangup_key = "*"; - } - } - - if (!(attxfer_conf_key = switch_channel_get_variable(channel, "attxfer_conf_key"))) { - if (!(attxfer_conf_key = switch_channel_get_variable(peer_channel, "attxfer_conf_key"))) { - attxfer_conf_key = "0"; - } - } - - keys = switch_core_session_alloc(session, sizeof(*keys)); - keys->attxfer_cancel_key = switch_core_session_strdup(session, attxfer_cancel_key); - keys->attxfer_hangup_key = switch_core_session_strdup(session, attxfer_hangup_key); - keys->attxfer_conf_key = switch_core_session_strdup(session, attxfer_conf_key); - switch_channel_set_private(channel, "__kz_keys", keys); - - switch_channel_set_variable(channel, "att_xfer_peer_uuid", switch_core_session_get_uuid(peer_session)); - - switch_ivr_multi_threaded_bridge(session, peer_session, kz_att_xfer_on_dtmf, peer_session, NULL); - - switch_channel_clear_flag(peer_channel, CF_INNER_BRIDGE); - switch_channel_clear_flag(channel, CF_INNER_BRIDGE); - - if (switch_channel_down(peer_channel)) { - switch_core_session_rwunlock(peer_session); - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); - goto end; - } - - /* - * we're emiting the transferee event so that callctl can update - */ - b_channel = switch_core_session_get_channel(b_session); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "sofia::transferee") == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(b_channel, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_call_id", switch_core_session_get_uuid(peer_session)); - switch_event_fire(&event); - } - - if (!switch_channel_ready(channel)) { - switch_status_t status; - - if (follow_recording) { - switch_ivr_transfer_recordings(session, peer_session); - } - status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond); - kz_att_xfer_set_result(peer_channel, status); - br++; - } else { - // switch_channel_set_variable_printf(b_channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session)); - switch_channel_set_variable_printf(channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), bond); - switch_channel_set_variable(channel, "xfer_peer_uuid", switch_core_session_get_uuid(peer_session)); - - switch_core_event_hook_add_state_change(session, kz_att_xfer_hanguphook); - // switch_core_event_hook_add_state_change(b_session, kz_att_xfer_hanguphook); - } - -/* - * this was commented so that the existing bridge - * doesn't end - * - if (!br) { - switch_status_t status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond); - att_xfer_set_result(channel, status); - } -*/ - - switch_core_session_rwunlock(peer_session); - - end: - - switch_core_event_hook_remove_state_change(session, kz_att_xfer_tmp_hanguphook); - - switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL); - switch_channel_clear_flag(channel, CF_XFER_ZOMBIE); - - switch_core_session_rwunlock(b_session); - switch_core_session_rwunlock(session); - att->running = 0; - - return NULL; -} - -SWITCH_STANDARD_APP(kz_att_xfer_function) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool = switch_core_session_get_pool(session); - struct kz_att_obj *att; - switch_channel_t *channel = switch_core_session_get_channel(session); - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_detach_set(thd_attr, 1); - - att = switch_core_session_alloc(session, sizeof(*att)); - att->running = -1; - att->session = session; - att->data = switch_core_session_strdup(session, data); - switch_thread_create(&thread, thd_attr, kz_att_thread_run, att, pool); - - while(att->running && switch_channel_up(channel)) { - switch_yield(100000); - } -} - -void add_kz_dptools(switch_loadable_module_interface_t **module_interface) { - switch_application_interface_t *app_interface = NULL; - SWITCH_ADD_APP(app_interface, "kz_set", SET_SHORT_DESC, SET_LONG_DESC, set_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_set_encoded", SET_SHORT_DESC, SET_LONG_DESC, set_encoded_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_multiset", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiset_function, MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_multiset_encoded", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiset_encoded_function, MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_unset", UNSET_SHORT_DESC, UNSET_LONG_DESC, unset_function, UNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_multiunset", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiunset_function, MULTIUNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_export", EXPORT_SHORT_DESC, EXPORT_LONG_DESC, export_function, EXPORT_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_export_encoded", EXPORT_SHORT_DESC, EXPORT_LONG_DESC, export_encoded_function, EXPORT_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_prefix_unset", PREFIX_UNSET_SHORT_DESC, PREFIX_UNSET_LONG_DESC, prefix_unset_function, PREFIX_UNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_uuid_multiset", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_uuid_multiset_encoded", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_encoded_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_endless_playback", KZ_ENDLESS_PLAYBACK_SHORT_DESC, KZ_ENDLESS_PLAYBACK_LONG_DESC, kz_endless_playback_function, KZ_ENDLESS_PLAYBACK_SYNTAX, SAF_NONE); - SWITCH_ADD_APP(app_interface, "kz_restore_caller_id", NOOP_SHORT_DESC, NOOP_LONG_DESC, kz_restore_caller_id_function, NOOP_SYNTAX, SAF_NONE); - SWITCH_ADD_APP(app_interface, "noop", NOOP_SHORT_DESC, NOOP_LONG_DESC, noop_function, NOOP_SYNTAX, SAF_NONE); - SWITCH_ADD_APP(app_interface, "kz_bridge", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_function, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); - SWITCH_ADD_APP(app_interface, "kz_bridge_uuid", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_uuid_function, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); - SWITCH_ADD_APP(app_interface, "kz_att_xfer", "Attended Transfer", "Attended Transfer", kz_att_xfer_function, "", SAF_NONE); - SWITCH_ADD_APP(app_interface, "kz_moh", "Kazoo MOH Playback", "Kazoo MOH Playback", kz_moh_function, "", SAF_NONE); -} diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h b/src/mod/event_handlers/mod_kazoo/kazoo_ei.h deleted file mode 100644 index 5f617b5f1d..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef KAZOO_EI_H -#define KAZOO_EI_H - -#include -#include - -#define MODNAME "mod_kazoo" -#define BUNDLE "community" -#define RELEASE "v1.5.0-1" -#define VERSION "mod_kazoo v1.5.0-1 community" - -#define KZ_MAX_SEPARATE_STRINGS 10 -#define HOSTNAME_MAX 1024 -#define NODENAME_MAX 1024 - -typedef enum {KAZOO_FETCH_PROFILE, KAZOO_EVENT_PROFILE} kazoo_profile_type; - -typedef enum {ERLANG_TUPLE, ERLANG_MAP} kazoo_json_term; - -typedef struct ei_xml_agent_s ei_xml_agent_t; -typedef ei_xml_agent_t *ei_xml_agent_ptr; - -typedef struct kazoo_event kazoo_event_t; -typedef kazoo_event_t *kazoo_event_ptr; - -typedef struct kazoo_event_profile kazoo_event_profile_t; -typedef kazoo_event_profile_t *kazoo_event_profile_ptr; - -typedef struct kazoo_fetch_profile kazoo_fetch_profile_t; -typedef kazoo_fetch_profile_t *kazoo_fetch_profile_ptr; - -typedef struct kazoo_config_t kazoo_config; -typedef kazoo_config *kazoo_config_ptr; - -#include "kazoo_fields.h" -#include "kazoo_config.h" - -struct ei_send_msg_s { - ei_x_buff buf; - erlang_pid pid; -}; -typedef struct ei_send_msg_s ei_send_msg_t; - -struct ei_received_msg_s { - ei_x_buff buf; - erlang_msg msg; -}; -typedef struct ei_received_msg_s ei_received_msg_t; - - -typedef struct ei_event_stream_s ei_event_stream_t; -typedef struct ei_node_s ei_node_t; - -struct ei_event_binding_s { - char id[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_event_node_t *node; - switch_event_types_t type; - const char *subclass_name; - ei_event_stream_t* stream; - kazoo_event_ptr event; - - struct ei_event_binding_s *next; -}; -typedef struct ei_event_binding_s ei_event_binding_t; - -struct ei_event_stream_s { - switch_memory_pool_t *pool; - ei_event_binding_t *bindings; - switch_queue_t *queue; - switch_socket_t *acceptor; - switch_pollset_t *pollset; - switch_pollfd_t *pollfd; - switch_socket_t *socket; - switch_mutex_t *socket_mutex; - switch_bool_t connected; - switch_time_t connected_time; - char remote_ip[48]; - uint16_t remote_port; - char local_ip[48]; - uint16_t local_port; - erlang_pid pid; - uint32_t flags; - ei_node_t *node; - short event_stream_framing; - short event_stream_keepalive; - switch_interval_time_t queue_timeout; - struct ei_event_stream_s *next; -}; - -struct ei_node_s { - int nodefd; - switch_atomic_t pending_bgapi; - switch_atomic_t receive_handlers; - switch_memory_pool_t *pool; - ei_event_stream_t *event_streams; - switch_mutex_t *event_streams_mutex; - switch_queue_t *send_msgs; - switch_queue_t *received_msgs; - char *peer_nodename; - switch_time_t created_time; - switch_socket_t *socket; - char remote_ip[48]; - uint16_t remote_port; - char local_ip[48]; - uint16_t local_port; - uint32_t flags; - int legacy; - short event_stream_framing; - short event_stream_keepalive; - switch_interval_time_t event_stream_queue_timeout; - switch_interval_time_t receiver_queue_timeout; - switch_interval_time_t sender_queue_timeout; - struct ei_node_s *next; -}; - - -struct xml_fetch_reply_s { - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - char *xml_str; - struct xml_fetch_reply_s *next; -}; -typedef struct xml_fetch_reply_s xml_fetch_reply_t; - -struct fetch_handler_s { - erlang_pid pid; - struct fetch_handler_s *next; -}; -typedef struct fetch_handler_s fetch_handler_t; - -struct ei_xml_client_s { - ei_node_t *ei_node; - fetch_handler_t *fetch_handlers; - struct ei_xml_client_s *next; -}; -typedef struct ei_xml_client_s ei_xml_client_t; - -struct ei_xml_agent_s { - switch_memory_pool_t *pool; - switch_xml_section_t section; - switch_thread_rwlock_t *lock; - ei_xml_client_t *clients; - switch_mutex_t *current_client_mutex; - ei_xml_client_t *current_client; - switch_mutex_t *replies_mutex; - switch_thread_cond_t *new_reply; - xml_fetch_reply_t *replies; - kazoo_fetch_profile_ptr profile; - -}; - -struct kz_globals_s { - switch_memory_pool_t *pool; - switch_atomic_t threads; - switch_socket_t *acceptor; - struct ei_cnode_s ei_cnode; - switch_thread_rwlock_t *ei_nodes_lock; - ei_node_t *ei_nodes; - - switch_xml_binding_t *config_fetch_binding; - switch_xml_binding_t *directory_fetch_binding; - switch_xml_binding_t *dialplan_fetch_binding; - switch_xml_binding_t *channels_fetch_binding; - switch_xml_binding_t *languages_fetch_binding; - switch_xml_binding_t *chatplan_fetch_binding; - - switch_hash_t *event_filter; - int epmdfd; - int node_worker_threads; - switch_bool_t nat_map; - switch_bool_t ei_shortname; - int ei_compat_rel; - char *ip; - char *hostname; - struct hostent* hostname_ent; - char *ei_cookie; - char *ei_nodename; - uint32_t flags; - int send_all_headers; - int send_all_private_headers; - int connection_timeout; - int ei_receive_timeout; - switch_interval_time_t node_sender_queue_timeout; - switch_interval_time_t node_receiver_queue_timeout; - int receive_msg_preallocate; - int event_stream_preallocate; - int send_msg_batch; - short event_stream_framing; - short event_stream_keepalive; - switch_interval_time_t event_stream_queue_timeout; - switch_port_t port; - int config_fetched; - int io_fault_tolerance; - switch_interval_time_t io_fault_tolerance_sleep; - kazoo_event_profile_ptr events; - kazoo_config_ptr definitions; - kazoo_config_ptr event_handlers; - kazoo_config_ptr fetch_handlers; - kazoo_json_term json_encoding; - - char **profile_vars_prefixes; - char **kazoo_var_prefixes; - - int legacy_events; - uint8_t tweaks[KZ_TWEAK_MAX]; - switch_bool_t expand_headers_on_fetch; - - switch_interval_time_t delay_before_initial_fetch; - - -}; -typedef struct kz_globals_s kz_globals_t; -extern kz_globals_t kazoo_globals; - -/* kazoo_event_stream.c */ -ei_event_stream_t *find_event_stream(ei_event_stream_t *event_streams, const erlang_pid *from); - -//ei_event_stream_t *new_event_stream(ei_event_stream_t **event_streams, const erlang_pid *from); -ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from); - - -switch_status_t remove_event_stream(ei_event_stream_t **event_streams, const erlang_pid *from); -switch_status_t remove_event_streams(ei_event_stream_t **event_streams); -unsigned long get_stream_port(const ei_event_stream_t *event_stream); -switch_status_t add_event_binding(ei_event_stream_t *event_stream, const char *event_name); -//switch_status_t add_event_binding(ei_event_stream_t *event_stream, const switch_event_types_t event_type, const char *subclass_name); -switch_status_t remove_event_binding(ei_event_stream_t *event_stream, const switch_event_types_t event_type, const char *subclass_name); -switch_status_t remove_event_bindings(ei_event_stream_t *event_stream); - -/* kazoo_node.c */ -switch_status_t new_kazoo_node(int nodefd, ErlConnect *conn); - -/* kazoo_ei_utils.c */ -void close_socket(switch_socket_t **sock); -void close_socketfd(int *sockfd); -switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port_t port); -switch_socket_t *create_socket(switch_memory_pool_t *pool); -switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei_cnode_s *ei_cnode); -switch_status_t ei_compare_pids(const erlang_pid *pid1, const erlang_pid *pid2); -void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event); -void ei_encode_switch_event_headers_2(ei_x_buff *ebuf, switch_event_t *event, int decode); -void ei_encode_json(ei_x_buff *ebuf, cJSON *JObj); -void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to); -void ei_encode_switch_event(ei_x_buff * ebuf, switch_event_t *event); -int ei_helper_send(ei_node_t *ei_node, erlang_pid* to, ei_x_buff *buf); -int ei_decode_atom_safe(char *buf, int *index, char *dst); -int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char *dst); -int ei_decode_string_or_binary(char *buf, int *index, char **dst); -switch_status_t create_acceptor(); -switch_hash_t *create_default_filter(); -void kz_erl_init(); -void kz_erl_shutdown(); -SWITCH_DECLARE(switch_status_t) ei_queue_pop(switch_queue_t *queue, void **data, switch_interval_time_t timeout); - -void fetch_config(); - -switch_status_t kazoo_load_config(); -void kazoo_destroy_config(); -void kz_set_hostname(); - -#define _ei_x_encode_string(buf, string) { ei_x_encode_binary(buf, string, strlen(string)); } - -/* kazoo_fetch_agent.c */ -switch_status_t bind_fetch_agents(); -switch_status_t unbind_fetch_agents(); -switch_status_t remove_xml_clients(ei_node_t *ei_node); -switch_status_t add_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding); -switch_status_t remove_fetch_handlers(ei_node_t *ei_node, erlang_pid *from); -switch_status_t fetch_reply(char *uuid_str, char *xml_str, switch_xml_binding_t *binding); -switch_status_t handle_api_command_streams(ei_node_t *ei_node, switch_stream_handle_t *stream); - -void bind_event_profiles(kazoo_event_ptr event); -void rebind_fetch_profiles(kazoo_config_ptr fetch_handlers); -switch_status_t kazoo_config_handlers(switch_xml_t cfg); - -/* runtime */ -SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime); - - - -#define kz_test_tweak(flag) (kazoo_globals.tweaks[flag] ? 1 : 0) -#define kz_set_tweak(flag) kazoo_globals.tweaks[flag] = 1 -#define kz_clear_tweak(flag) kazoo_globals.tweaks[flag] = 0 - -#endif /* KAZOO_EI_H */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c deleted file mode 100644 index 3c626c15da..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c +++ /dev/null @@ -1,708 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#include "mod_kazoo.h" - -#define KZ_DEFAULT_STREAM_PRE_ALLOCATE 8192 - -#define KAZOO_DECLARE_GLOBAL_STRING_FUNC(fname, vname) static void __attribute__((__unused__)) fname(const char *string) { if (!string) return;\ - if (vname) {free(vname); vname = NULL;}vname = strdup(string);} static void fname(const char *string) - -KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, kazoo_globals.ip); -KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_cookie, kazoo_globals.ei_cookie); -KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_nodename, kazoo_globals.ei_nodename); -//KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_kazoo_var_prefix, kazoo_globals.kazoo_var_prefix); - -static int read_cookie_from_file(char *filename) { - int fd; - char cookie[MAXATOMLEN + 1]; - char *end; - struct stat buf; - - if (!stat(filename, &buf)) { - if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename); - return 2; - } - if (buf.st_size > MAXATOMLEN) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s contains a cookie larger than the maximum atom size of %d.\n", filename, MAXATOMLEN); - return 2; - } - fd = open(filename, O_RDONLY); - if (fd < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno); - return 2; - } - - if (read(fd, cookie, MAXATOMLEN) < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno); - } - - cookie[MAXATOMLEN] = '\0'; - - /* replace any end of line characters with a null */ - if ((end = strchr(cookie, '\n'))) { - *end = '\0'; - } - - if ((end = strchr(cookie, '\r'))) { - *end = '\0'; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie from file %s: %s\n", filename, cookie); - - set_pref_ei_cookie(cookie); - return 0; - } else { - /* don't error here, because we might be blindly trying to read $HOME/.erlang.cookie, and that can fail silently */ - return 1; - } -} - -void kz_set_hostname() -{ - if (kazoo_globals.hostname == NULL) { - char hostname[NODENAME_MAX]; - memcpy(hostname, switch_core_get_hostname(), NODENAME_MAX); - kazoo_globals.hostname_ent = gethostbyname(hostname); - if(kazoo_globals.hostname_ent != NULL) { - kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, kazoo_globals.hostname_ent->h_name); - } else { - kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, hostname); - } - } -} - -switch_status_t kazoo_ei_config(switch_xml_t cfg) { - switch_xml_t child, param; - char* kazoo_var_prefix = NULL; - char* profile_vars_prefix = NULL; - char* sep_array[KZ_MAX_SEPARATE_STRINGS]; - int array_len, i; - kazoo_globals.send_all_headers = 0; - kazoo_globals.send_all_private_headers = 1; - kazoo_globals.connection_timeout = 500; - kazoo_globals.ei_receive_timeout = 200; - kazoo_globals.receive_msg_preallocate = 2000; - kazoo_globals.event_stream_preallocate = KZ_DEFAULT_STREAM_PRE_ALLOCATE; - kazoo_globals.send_msg_batch = 10; - kazoo_globals.event_stream_framing = 2; - kazoo_globals.event_stream_keepalive = 1; - kazoo_globals.event_stream_queue_timeout = 200000; - kazoo_globals.node_receiver_queue_timeout = 100000; - kazoo_globals.node_sender_queue_timeout = 0; - kazoo_globals.port = 0; - kazoo_globals.io_fault_tolerance = 3; - kazoo_globals.io_fault_tolerance_sleep = 100000; // 100 ms - kazoo_globals.json_encoding = ERLANG_TUPLE; - kazoo_globals.delay_before_initial_fetch = 10000000; - - kazoo_globals.legacy_events = SWITCH_FALSE; - kazoo_globals.expand_headers_on_fetch = SWITCH_TRUE; - - kz_set_tweak(KZ_TWEAK_INTERACTION_ID); - kz_set_tweak(KZ_TWEAK_EXPORT_VARS); - kz_set_tweak(KZ_TWEAK_SWITCH_URI); - kz_set_tweak(KZ_TWEAK_REPLACES_CALL_ID); - kz_set_tweak(KZ_TWEAK_LOOPBACK_VARS); - kz_set_tweak(KZ_TWEAK_CALLER_ID); - kz_set_tweak(KZ_TWEAK_TRANSFERS); - kz_set_tweak(KZ_TWEAK_BRIDGE); - kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG); - kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID); - kz_set_tweak(KZ_TWEAK_BRIDGE_VARIABLES); - kz_set_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER); - - - - if ((child = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(child, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcmp(var, "listen-ip")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val); - set_pref_ip(val); - } else if (!strcmp(var, "listen-port")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind port: %s\n", val); - kazoo_globals.port = atoi(val); - } else if (!strcmp(var, "cookie")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie: %s\n", val); - set_pref_ei_cookie(val); - } else if (!strcmp(var, "cookie-file")) { - if (read_cookie_from_file(val) == 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie from %s\n", val); - } - } else if (!strcmp(var, "nodename")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node name: %s\n", val); - set_pref_ei_nodename(val); - } else if (!strcmp(var, "shortname")) { - kazoo_globals.ei_shortname = switch_true(val); - } else if (!strcmp(var, "kazoo-var-prefix")) { - kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, val); - } else if (!strcmp(var, "set-profile-vars-prefix")) { - profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, val); - } else if (!strcmp(var, "compat-rel")) { - if (atoi(val) >= 7) - kazoo_globals.ei_compat_rel = atoi(val); - else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid compatibility release '%s' specified\n", val); - } else if (!strcmp(var, "nat-map")) { - kazoo_globals.nat_map = switch_true(val); - } else if (!strcmp(var, "send-all-headers")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-headers: %s\n", val); - kazoo_globals.send_all_headers = switch_true(val); - } else if (!strcmp(var, "send-all-private-headers")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-private-headers: %s\n", val); - kazoo_globals.send_all_private_headers = switch_true(val); - } else if (!strcmp(var, "connection-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set connection-timeout: %s\n", val); - kazoo_globals.connection_timeout = atoi(val); - } else if (!strcmp(var, "receive-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-timeout: %s\n", val); - kazoo_globals.ei_receive_timeout = atoi(val); - } else if (!strcmp(var, "receive-msg-preallocate")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-msg-preallocate: %s\n", val); - kazoo_globals.receive_msg_preallocate = atoi(val); - } else if (!strcmp(var, "event-stream-preallocate")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-preallocate: %s\n", val); - kazoo_globals.event_stream_preallocate = atoi(val); - } else if (!strcmp(var, "send-msg-batch-size")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-msg-batch-size: %s\n", val); - kazoo_globals.send_msg_batch = atoi(val); - } else if (!strcmp(var, "event-stream-framing")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-framing: %s\n", val); - kazoo_globals.event_stream_framing = atoi(val); - - } else if (!strcmp(var, "event-stream-keep-alive")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-keep-alive: %s\n", val); - kazoo_globals.event_stream_keepalive = switch_true(val); - - } else if (!strcmp(var, "io-fault-tolerance")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set io-fault-tolerance: %s\n", val); - kazoo_globals.io_fault_tolerance = atoi(val); - } else if (!strcmp(var, "io-fault-tolerance-sleep-micro")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.io_fault_tolerance_sleep = atoi(val); - } else if (!strcmp(var, "io-fault-tolerance-sleep-ms")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.io_fault_tolerance_sleep = atoi(val) * 1000; - } else if (!strcmp(var, "io-fault-tolerance-sleep-sec")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.io_fault_tolerance_sleep = atoi(val) * 1000000; - - - } else if (!strcmp(var, "node-worker-threads")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node-worker-threads: %s\n", val); - kazoo_globals.node_worker_threads = atoi(val); - } else if (!strcmp(var, "json-term-encoding")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set json-term-encoding: %s\n", val); - if(!strcmp(val, "map")) { - kazoo_globals.json_encoding = ERLANG_MAP; - } - } else if (!strcmp(var, "legacy-events")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set legacy-events: %s\n", val); - kazoo_globals.legacy_events = switch_true(val); - } else if (!strcmp(var, "expand-headers-on-fetch")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set expand-headers-on-fetch: %s\n", val); - kazoo_globals.expand_headers_on_fetch = switch_true(val); - } else if (!strcmp(var, "node-receiver-queue-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.node_receiver_queue_timeout = atoi(val); - } else if (!strcmp(var, "node-sender-queue-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.node_sender_queue_timeout = atoi(val); - } else if (!strcmp(var, "event-stream-queue-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.event_stream_queue_timeout = atoi(val); - } else if (!strcmp(var, "delay-before-initial-fetch-micro")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.delay_before_initial_fetch = atoi(val); - } else if (!strcmp(var, "delay-before-initial-fetch-ms")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.delay_before_initial_fetch = atoi(val) * 1000; - } else if (!strcmp(var, "delay-before-initial-fetch-sec")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.delay_before_initial_fetch = atoi(val) * 1000000; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unknown config option %s : %s\n", var, val); - } - } - } - - if ((child = switch_xml_child(cfg, "tweaks"))) { - char *default_tweaks = (char *) switch_xml_attr_soft(child, "default"); - if (default_tweaks && !zstr(default_tweaks)) { - int i, v = switch_true(default_tweaks) ? 1 : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak default : %s\n", default_tweaks); - for (i = 0; i < KZ_TWEAK_MAX; i++) kazoo_globals.tweaks[i] = v; - } - for (param = switch_xml_child(child, "tweak"); param; param = param->next) { - kz_tweak_t tweak = KZ_TWEAK_MAX; - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val && kz_name_tweak(var, &tweak) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak %s : %s\n", var, val); - if(switch_true(val)) { - kz_set_tweak(tweak); - } else { - kz_clear_tweak(tweak); - } - } - } - } - - if ((child = switch_xml_child(cfg, "variables"))) { - for (param = switch_xml_child(child, "variable"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set core variable %s : %s\n", var, val); - switch_core_set_variable(var, val); - } - } - } - - if ((child = switch_xml_child(cfg, "event-filter"))) { - switch_hash_t *filter; - - switch_core_hash_init(&filter); - for (param = switch_xml_child(child, "header"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - switch_core_hash_insert(filter, var, "1"); - } - kazoo_globals.event_filter = filter; - } - - if (kazoo_globals.receive_msg_preallocate < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n"); - kazoo_globals.receive_msg_preallocate = 0; - } - - if (kazoo_globals.event_stream_preallocate < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n"); - kazoo_globals.event_stream_preallocate = 0; - } - - if (kazoo_globals.send_msg_batch < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n"); - kazoo_globals.send_msg_batch = 10; - } - - if (kazoo_globals.io_fault_tolerance < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid I/O fault tolerance, reverting to default\n"); - kazoo_globals.io_fault_tolerance = 10; - } - - if (!kazoo_globals.event_filter) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n"); - kazoo_globals.event_filter = create_default_filter(); - } - - if (kazoo_globals.event_stream_framing < 1 || kazoo_globals.event_stream_framing > 4) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n"); - kazoo_globals.event_stream_framing = 2; - } - - if (zstr(kazoo_var_prefix)) { - kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, "ecallmgr_;cav_"); - } - - if (zstr(profile_vars_prefix)) { - profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, "effective_;origination_"); - } - - kazoo_globals.kazoo_var_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS); - array_len = switch_separate_string(kazoo_var_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1); - for(i=0; i < array_len; i++) { - char var[100]; - sprintf(var, "variable_%s", sep_array[i]); - kazoo_globals.kazoo_var_prefixes[i] = switch_core_strdup(kazoo_globals.pool, var); - } - - kazoo_globals.profile_vars_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS); - array_len = switch_separate_string(profile_vars_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1); - for(i=0; i < array_len; i++) { - kazoo_globals.profile_vars_prefixes[i] = switch_core_strdup(kazoo_globals.pool, sep_array[i]); - } - - if (!kazoo_globals.node_worker_threads) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of node worker threads not found in configuration, using default\n"); - kazoo_globals.node_worker_threads = 10; - } - - if (zstr(kazoo_globals.ip)) { - set_pref_ip("0.0.0.0"); - } - - if (zstr(kazoo_globals.ei_cookie)) { - int res; - char *home_dir = getenv("HOME"); - char path_buf[1024]; - - if (!zstr(home_dir)) { - /* $HOME/.erlang.cookie */ - switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf); - - res = read_cookie_from_file(path_buf); - if (res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n"); - set_pref_ei_cookie("ClueCon"); - } - } - } - - if (!kazoo_globals.ei_nodename) { - set_pref_ei_nodename("freeswitch"); - } - - if (!kazoo_globals.nat_map) { - kazoo_globals.nat_map = 0; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t kazoo_config_handlers(switch_xml_t cfg) -{ - switch_xml_t def = NULL; - switch_xml_t child, param; - char* xml = NULL; - kazoo_config_ptr definitions = NULL, fetch_handlers = NULL, event_handlers = NULL; - kazoo_event_profile_ptr events = NULL; - - xml = strndup(kz_default_config, kz_default_config_size); - def = switch_xml_parse_str_dup(xml); - - kz_xml_process(def); - kz_xml_process(cfg); - - if ((child = switch_xml_child(cfg, "variables"))) { - for (param = switch_xml_child(child, "variable"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val) { - switch_core_set_variable(var, val); - } - } - } else if ((child = switch_xml_child(def, "variables"))) { - for (param = switch_xml_child(child, "variable"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val) { - switch_core_set_variable(var, val); - } - } - } - - definitions = kazoo_config_definitions(cfg); - if(definitions == NULL) { - if(kazoo_globals.definitions == NULL) { - definitions = kazoo_config_definitions(def); - } else { - definitions = kazoo_globals.definitions; - } - } - - fetch_handlers = kazoo_config_fetch_handlers(definitions, cfg); - if(fetch_handlers == NULL) { - if(kazoo_globals.fetch_handlers == NULL) { - fetch_handlers = kazoo_config_fetch_handlers(definitions, def); - } else { - fetch_handlers = kazoo_globals.fetch_handlers; - } - } - - event_handlers = kazoo_config_event_handlers(definitions, cfg); - if(event_handlers == NULL) { - if(kazoo_globals.event_handlers == NULL) { - event_handlers = kazoo_config_event_handlers(definitions, def); - } else { - event_handlers = kazoo_globals.event_handlers; - } - } - - if(event_handlers != NULL) { - events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default"); - } - - if(events == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get default handler for events\n"); - destroy_config(&event_handlers); - event_handlers = kazoo_config_event_handlers(definitions, def); - events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default"); - } - - if(kazoo_globals.events != events) { - bind_event_profiles(events->events); - kazoo_globals.events = events; - } - - if(kazoo_globals.event_handlers != event_handlers) { - kazoo_config_ptr tmp = kazoo_globals.event_handlers; - kazoo_globals.event_handlers = event_handlers; - destroy_config(&tmp); - } - - if(kazoo_globals.fetch_handlers != fetch_handlers) { - kazoo_config_ptr tmp = kazoo_globals.fetch_handlers; - kazoo_globals.fetch_handlers = fetch_handlers; - rebind_fetch_profiles(fetch_handlers); - destroy_config(&tmp); - } - - if(kazoo_globals.definitions != definitions) { - kazoo_config_ptr tmp = kazoo_globals.definitions; - kazoo_globals.definitions = definitions; - destroy_config(&tmp); - } - - - switch_xml_free(def); - switch_safe_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t kazoo_load_config() -{ - char *cf = "kazoo.conf"; - switch_xml_t cfg, xml; - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); - return SWITCH_STATUS_FALSE; - } else { - kazoo_ei_config(cfg); - kazoo_config_handlers(cfg); - switch_xml_free(xml); - } - - return SWITCH_STATUS_SUCCESS; -} - -void kazoo_destroy_config() -{ - destroy_config(&kazoo_globals.event_handlers); - destroy_config(&kazoo_globals.fetch_handlers); - destroy_config(&kazoo_globals.definitions); -} - -switch_status_t kazoo_config_events(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_event_profile_ptr profile) -{ - switch_xml_t events, event; - kazoo_event_ptr prv = NULL, cur = NULL; - - - if ((events = switch_xml_child(cfg, "events")) != NULL) { - for (event = switch_xml_child(events, "event"); event; event = event->next) { - const char *var = switch_xml_attr(event, "name"); - cur = (kazoo_event_ptr) switch_core_alloc(pool, sizeof(kazoo_event_t)); - memset(cur, 0, sizeof(kazoo_event_t)); - if(prv == NULL) { - profile->events = prv = cur; - } else { - prv->next = cur; - prv = cur; - } - cur->profile = profile; - cur->name = switch_core_strdup(pool, var); - kazoo_config_filters(pool, event, &cur->filter); - kazoo_config_fields(definitions, pool, event, &cur->fields); - if (switch_xml_child(event, "logging") != NULL) { - kazoo_config_loglevels(pool, event, &cur->logging); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - - -switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_fetch_profile_ptr *ptr) -{ - kazoo_fetch_profile_ptr profile = NULL; - switch_xml_t params, param; - switch_xml_section_t fetch_section; - int fetch_timeout = 2000000; - switch_memory_pool_t *pool = NULL; - - char *name = (char *) switch_xml_attr_soft(cfg, "name"); - - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n"); - - return SWITCH_STATUS_GENERR; - } - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name); - - return SWITCH_STATUS_GENERR; - } - - profile = switch_core_alloc(pool, sizeof(kazoo_fetch_profile_t)); - profile->pool = pool; - profile->root = root; - profile->name = switch_core_strdup(profile->pool, name); - - fetch_section = switch_xml_parse_section_string(name); - - if ((params = switch_xml_child(cfg, "params")) != NULL) { - - for (param = switch_xml_child(params, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!var) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", name); - continue; - } - - if (!val) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", name, var); - continue; - } - - if (!strncmp(var, "fetch-timeout", 13)) { - fetch_timeout = atoi(val); - } else if (!strncmp(var, "fetch-section", 13)) { - fetch_section = switch_xml_parse_section_string(val); - } - } - } - - if (fetch_section == SWITCH_XML_SECTION_RESULT) { - char *tmp = switch_xml_toxml(cfg, SWITCH_FALSE); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, tmp); - free(tmp); - goto err; - } - - - profile->fetch_timeout = fetch_timeout; - profile->section = fetch_section; - kazoo_config_fields(definitions, pool, cfg, &profile->fields); - kazoo_config_loglevels(pool, cfg, &profile->logging); - - if(root) { - if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new fetch profile [%s] into kazoo profile hash\n", name); - goto err; - } - } - - if (ptr) { - *ptr = profile; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetch handler profile %s successfully configured\n", name); - - return SWITCH_STATUS_SUCCESS; - - err: - /* Cleanup */ - if(pool) { - switch_core_destroy_memory_pool(&pool); - } - - return SWITCH_STATUS_GENERR; - -} - -switch_status_t kazoo_config_event_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_event_profile_ptr *ptr) -{ - kazoo_event_profile_ptr profile = NULL; - switch_memory_pool_t *pool = NULL; - - char *name = (char *) switch_xml_attr_soft(cfg, "name"); - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n"); - return SWITCH_STATUS_GENERR; - } - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name); - return SWITCH_STATUS_GENERR; - } - - profile = switch_core_alloc(pool, sizeof(kazoo_event_profile_t)); - profile->pool = pool; - profile->root = root; - profile->name = switch_core_strdup(profile->pool, name); - - kazoo_config_filters(pool, cfg, &profile->filter); - kazoo_config_fields(definitions, pool, cfg, &profile->fields); - kazoo_config_events(definitions, pool, cfg, profile); - kazoo_config_loglevels(pool, cfg, &profile->logging); - - if(root) { - if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into kazoo profile hash\n", name); - goto err; - } - } - - if(ptr) - *ptr = profile; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler profile %s successfully configured\n", name); - return SWITCH_STATUS_SUCCESS; - - err: - /* Cleanup */ - if(pool) { - switch_core_destroy_memory_pool(&pool); - } - return SWITCH_STATUS_GENERR; - -} - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c deleted file mode 100644 index ef45af0ea3..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Andrew Thompson - * Rob Charlton - * Karl Anderson - * - * Original from mod_erlang_event. - * ei_helpers.c -- helper functions for ei - * - */ -#include "mod_kazoo.h" - -/* Stolen from code added to ei in R12B-5. - * Since not everyone has this version yet; - * provide our own version. - * */ - -#define put8(s,n) do { \ - (s)[0] = (char)((n) & 0xff); \ - (s) += 1; \ - } while (0) - -#define put32be(s,n) do { \ - (s)[0] = ((n) >> 24) & 0xff; \ - (s)[1] = ((n) >> 16) & 0xff; \ - (s)[2] = ((n) >> 8) & 0xff; \ - (s)[3] = (n) & 0xff; \ - (s) += 4; \ - } while (0) - -#ifdef EI_DEBUG -static void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send) { - char *mbuf = NULL; - int i = 1; - - ei_s_print_term(&mbuf, buf->buff, &i); - - if (send) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoded term %s to '%s'\n", mbuf, dest); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoded term %s for '%s'\n", mbuf, dest); - } - - free(mbuf); -} - -static void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send) { - char *pbuf = NULL; - int i = 0; - ei_x_buff pidbuf; - - ei_x_new(&pidbuf); - ei_x_encode_pid(&pidbuf, pid); - - ei_s_print_term(&pbuf, pidbuf.buff, &i); - - ei_x_print_reg_msg(buf, pbuf, send); - free(pbuf); -} -#endif - -void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event) -{ - ei_encode_switch_event_headers_2(ebuf, event, 1); -} - -void ei_encode_switch_event_headers_2(ei_x_buff *ebuf, switch_event_t *event, int encode) -{ - switch_event_header_t *hp; - char *uuid = switch_event_get_header(event, "unique-id"); - int i; - - for (i = 0, hp = event->headers; hp; hp = hp->next, i++) - ; - - if (event->body) - i++; - - ei_x_encode_list_header(ebuf, i + 1); - - if (uuid) { - char *unique_id = switch_event_get_header(event, "unique-id"); - ei_x_encode_binary(ebuf, unique_id, strlen(unique_id)); - } else { - ei_x_encode_atom(ebuf, "undefined"); - } - - for (hp = event->headers; hp; hp = hp->next) { - ei_x_encode_tuple_header(ebuf, 2); - ei_x_encode_binary(ebuf, hp->name, strlen(hp->name)); - if (encode) { - switch_url_decode(hp->value); - } - ei_x_encode_binary(ebuf, hp->value, strlen(hp->value)); - } - - if (event->body) { - ei_x_encode_tuple_header(ebuf, 2); - ei_x_encode_binary(ebuf, "body", strlen("body")); - ei_x_encode_binary(ebuf, event->body, strlen(event->body)); - } - - ei_x_encode_empty_list(ebuf); -} - -int ei_json_child_count(cJSON *JObj) -{ - int mask = cJSON_False | cJSON_True | cJSON_NULL | cJSON_Number | cJSON_String | cJSON_Array | cJSON_Object | cJSON_Raw; - - cJSON *item = JObj->child; - int i = 0; - while (item) { - if (item->type & mask) - i++; - item = item->next; - } - return i; - -} - -void ei_encode_json_array(ei_x_buff *ebuf, cJSON *JObj) -{ - cJSON *item; - int count = ei_json_child_count(JObj); - - ei_x_encode_list_header(ebuf, count); - if (count == 0) - return; - - item = JObj->child; - while (item) { - switch (item->type){ - case cJSON_String: - ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring)); - break; - - case cJSON_Number: - if ((fabs(((double) item->valueint) - item->valuedouble) <= DBL_EPSILON) && (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN)) { - ei_x_encode_longlong(ebuf, item->valueint); - } else { - if (fmod(item->valuedouble, 1) == 0) { - ei_x_encode_ulonglong(ebuf, item->valuedouble); - } else { - ei_x_encode_double(ebuf, item->valuedouble); - } - } - break; - - case cJSON_True: - ei_x_encode_boolean(ebuf, 1); - break; - - case cJSON_False: - ei_x_encode_boolean(ebuf, 0); - break; - - case cJSON_Object: - ei_encode_json(ebuf, item); - break; - - case cJSON_Array: - ei_encode_json_array(ebuf, item); - break; - - case cJSON_Raw: { - cJSON *Decoded = cJSON_Parse(item->valuestring); - if (!Decoded) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring); - ei_x_encode_tuple_header(ebuf, 0); - } else { - ei_encode_json(ebuf, Decoded); - cJSON_Delete(Decoded); - } - break; - } - - case cJSON_NULL: - ei_x_encode_atom(ebuf, "null"); - break; - - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type); - break; - - } - item = item->next; - } - - ei_x_encode_empty_list(ebuf); - -} - -void ei_encode_json(ei_x_buff *ebuf, cJSON *JObj) -{ - cJSON *item; - int count = ei_json_child_count(JObj); - - if (kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_tuple_header(ebuf, 1); - ei_x_encode_list_header(ebuf, count); - } else { - ei_x_encode_map_header(ebuf, count); - } - - if (count == 0) - return; - - item = JObj->child; - while (item) { - if (kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_tuple_header(ebuf, 2); - } - ei_x_encode_binary(ebuf, item->string, strlen(item->string)); - - switch (item->type){ - case cJSON_String: - ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring)); - break; - - case cJSON_Number: - if ((fabs(((double) item->valueint) - item->valuedouble) <= DBL_EPSILON) && (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN)) { - ei_x_encode_longlong(ebuf, item->valueint); - } else { - if (fmod(item->valuedouble, 1) == 0) { - ei_x_encode_ulonglong(ebuf, item->valuedouble); - } else { - ei_x_encode_double(ebuf, item->valuedouble); - } - } - break; - - case cJSON_True: - ei_x_encode_boolean(ebuf, 1); - break; - - case cJSON_False: - ei_x_encode_boolean(ebuf, 0); - break; - - case cJSON_Object: - ei_encode_json(ebuf, item); - break; - - case cJSON_Array: - ei_encode_json_array(ebuf, item); - break; - - case cJSON_Raw: { - cJSON *Decoded = cJSON_Parse(item->valuestring); - if (!Decoded) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring); - ei_x_encode_tuple_header(ebuf, 0); - } else { - ei_encode_json(ebuf, Decoded); - cJSON_Delete(Decoded); - } - break; - } - - case cJSON_NULL: - ei_x_encode_atom(ebuf, "null"); - break; - - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type); - break; - - } - item = item->next; - } - - if (kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_empty_list(ebuf); - } - -} - -void close_socket(switch_socket_t ** sock) -{ - if (*sock) { - switch_socket_shutdown(*sock, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(*sock); - *sock = NULL; - } -} - -void close_socketfd(int *sockfd) -{ - if (*sockfd) { - shutdown(*sockfd, SHUT_RDWR); - close(*sockfd); - } -} - -switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port_t port) -{ - switch_sockaddr_t *sa; - switch_socket_t *socket; - - if (switch_sockaddr_info_get(&sa, kazoo_globals.ip, SWITCH_UNSPEC, port, 0, pool)) { - return NULL; - } - - if (switch_socket_create(&socket, switch_sockaddr_get_family(sa), SOCK_STREAM, SWITCH_PROTO_TCP, pool)) { - return NULL; - } - - if (switch_socket_opt_set(socket, SWITCH_SO_REUSEADDR, 1)) { - return NULL; - } - - if (switch_socket_bind(socket, sa)) { - return NULL; - } - - if (switch_socket_listen(socket, 5)) { - return NULL; - } - - if (kazoo_globals.nat_map && switch_nat_get_type()) { - switch_nat_add_mapping(port, SWITCH_NAT_TCP, NULL, SWITCH_FALSE); - } - - return socket; -} - -switch_socket_t *create_socket(switch_memory_pool_t *pool) -{ - return create_socket_with_port(pool, 0); - -} - -switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei_cnode_s *ei_cnode) -{ - char hostname[EI_MAXHOSTNAMELEN + 1]; - char nodename[MAXNODELEN + 1]; - char cnodename[EI_MAXALIVELEN + 1]; - char *atsign; - - /* copy the erlang interface nodename into something we can modify */ - strncpy(cnodename, name, EI_MAXALIVELEN); - - if ((atsign = strchr(cnodename, '@'))) { - /* we got a qualified node name, don't guess the host/domain */ - snprintf(nodename, MAXNODELEN + 1, "%s", name); - /* truncate the alivename at the @ */ - *atsign++ = '\0'; - strncpy(hostname, atsign, EI_MAXHOSTNAMELEN); - } else { - strncpy(hostname, kazoo_globals.hostname, EI_MAXHOSTNAMELEN); - snprintf(nodename, MAXNODELEN + 1, "%s@%s", name, hostname); - } - - if (kazoo_globals.ei_shortname) { - char *off; - if ((off = strchr(nodename, '.'))) { - *off = '\0'; - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "creating nodename: %s\n", nodename); - - /* init the ec stuff */ - if (ei_connect_xinit(ei_cnode, hostname, cnodename, nodename, (Erl_IpAddr) ip_addr, kazoo_globals.ei_cookie, 0) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to initialize the erlang interface connection structure\n"); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t ei_compare_pids(const erlang_pid *pid1, const erlang_pid *pid2) -{ - if ((!strcmp(pid1->node, pid2->node)) && pid1->creation == pid2->creation && pid1->num == pid2->num && pid1->serial == pid2->serial) { - return SWITCH_STATUS_SUCCESS; - } else { - return SWITCH_STATUS_FALSE; - } -} - -void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to) -{ - char msgbuf[2048]; - char *s; - int index = 0; - - index = 5; /* max sizes: */ - ei_encode_version(msgbuf, &index); /* 1 */ - ei_encode_tuple_header(msgbuf, &index, 3); - ei_encode_long(msgbuf, &index, ERL_LINK); - ei_encode_pid(msgbuf, &index, from); /* 268 */ - ei_encode_pid(msgbuf, &index, to); /* 268 */ - - /* 5 byte header missing */ - s = msgbuf; - put32be(s, index - 4); /* 4 */ - put8(s, ERL_PASS_THROUGH); /* 1 */ - /* sum: 542 */ - - if (write(ei_node->nodefd, msgbuf, index) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", ei_node->peer_nodename); - } -} - -void ei_encode_switch_event(ei_x_buff *ebuf, switch_event_t *event) -{ - ei_x_encode_tuple_header(ebuf, 2); - ei_x_encode_atom(ebuf, "event"); - ei_encode_switch_event_headers(ebuf, event); -} - -int ei_helper_send(ei_node_t *ei_node, erlang_pid *to, ei_x_buff *buf) -{ - int ret = 0; - - if (ei_node->nodefd) { -#ifdef EI_DEBUG - ei_x_print_msg(buf, to, 1); -#endif - ret = ei_send(ei_node->nodefd, to, buf->buff, buf->index); - } - - return ret; -} - -int ei_decode_atom_safe(char *buf, int *index, char *dst) -{ - int type, size; - - ei_get_type(buf, index, &type, &size); - - if (type != ERL_ATOM_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed atom\n", type, size); - return -1; - } else if (size > MAXATOMLEN) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of atom with size %d into a buffer of size %d\n", size, MAXATOMLEN); - return -1; - } else { - return ei_decode_atom(buf, index, dst); - } -} - -int ei_decode_string_or_binary(char *buf, int *index, char **dst) -{ - int type, size, res; - long len; - - ei_get_type(buf, index, &type, &size); - - if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size); - return -1; - } - - *dst = malloc(size + 1); - - if (type == ERL_NIL_EXT) { - res = 0; - **dst = '\0'; - } else if (type == ERL_BINARY_EXT) { - res = ei_decode_binary(buf, index, *dst, &len); - (*dst)[len] = '\0'; - } else { - res = ei_decode_string(buf, index, *dst); - } - - return res; -} - -int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char *dst) -{ - int type, size, res; - long len; - - ei_get_type(buf, index, &type, &size); - - if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size); - return -1; - } - - if (size > maxsize) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n", - type == ERL_BINARY_EXT ? "binary" : "string", size, maxsize); - return -1; - } - - if (type == ERL_NIL_EXT) { - res = 0; - *dst = '\0'; - } else if (type == ERL_BINARY_EXT) { - res = ei_decode_binary(buf, index, dst, &len); - dst[len] = '\0'; /* binaries aren't null terminated */ - } else { - res = ei_decode_string(buf, index, dst); - } - - return res; -} - -switch_status_t create_acceptor() -{ - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48]; - const char *ip_addr; - - /* if the config has specified an erlang release compatibility then pass that along to the erlang interface */ - if (kazoo_globals.ei_compat_rel) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Compatability with OTP R%d requested\n", kazoo_globals.ei_compat_rel); - ei_set_compat_rel(kazoo_globals.ei_compat_rel); - } - - if (!(kazoo_globals.acceptor = create_socket_with_port(kazoo_globals.pool, kazoo_globals.port))) { - return SWITCH_STATUS_SOCKERR; - } - - switch_socket_addr_get(&sa, SWITCH_FALSE, kazoo_globals.acceptor); - - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof(ipbuf), sa); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor listening on %s:%u\n", ip_addr, port); - - /* try to initialize the erlang interface */ - if (create_ei_cnode(ip_addr, kazoo_globals.ei_nodename, &kazoo_globals.ei_cnode) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_SOCKERR; - } - - /* tell the erlang port manager where we can be reached. this returns a file descriptor pointing to epmd or -1 */ - if ((kazoo_globals.epmdfd = ei_publish(&kazoo_globals.ei_cnode, port)) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to publish port to epmd, trying to start epmd via system()\n"); - if (system("fs_epmd -daemon")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Failed to start epmd manually! Is epmd in $PATH? If not, start it yourself or run an erl shell with -sname or -name\n"); - return SWITCH_STATUS_SOCKERR; - } - switch_yield(100000); - if ((kazoo_globals.epmdfd = ei_publish(&kazoo_globals.ei_cnode, port)) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to publish port to epmd AGAIN\n"); - return SWITCH_STATUS_SOCKERR; - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to epmd and published erlang cnode name %s at port %d\n", kazoo_globals.ei_cnode.thisnodename, - port); - - return SWITCH_STATUS_SUCCESS; -} - -switch_hash_t *create_default_filter() -{ - switch_hash_t *filter; - - switch_core_hash_init(&filter); - - switch_core_hash_insert(filter, "Acquired-UUID", "1"); - switch_core_hash_insert(filter, "action", "1"); - switch_core_hash_insert(filter, "Action", "1"); - switch_core_hash_insert(filter, "alt_event_type", "1"); - switch_core_hash_insert(filter, "Answer-State", "1"); - switch_core_hash_insert(filter, "Application", "1"); - switch_core_hash_insert(filter, "Application-Data", "1"); - switch_core_hash_insert(filter, "Application-Name", "1"); - switch_core_hash_insert(filter, "Application-Response", "1"); - switch_core_hash_insert(filter, "att_xfer_replaced_by", "1"); - switch_core_hash_insert(filter, "Auth-Method", "1"); - switch_core_hash_insert(filter, "Auth-Realm", "1"); - switch_core_hash_insert(filter, "Auth-User", "1"); - switch_core_hash_insert(filter, "Bridge-A-Unique-ID", "1"); - switch_core_hash_insert(filter, "Bridge-B-Unique-ID", "1"); - switch_core_hash_insert(filter, "Call-Direction", "1"); - switch_core_hash_insert(filter, "Caller-Callee-ID-Name", "1"); - switch_core_hash_insert(filter, "Caller-Callee-ID-Number", "1"); - switch_core_hash_insert(filter, "Caller-Caller-ID-Name", "1"); - switch_core_hash_insert(filter, "Caller-Caller-ID-Number", "1"); - switch_core_hash_insert(filter, "Caller-Screen-Bit", "1"); - switch_core_hash_insert(filter, "Caller-Privacy-Hide-Name", "1"); - switch_core_hash_insert(filter, "Caller-Privacy-Hide-Number", "1"); - switch_core_hash_insert(filter, "Caller-Context", "1"); - switch_core_hash_insert(filter, "Caller-Controls", "1"); - switch_core_hash_insert(filter, "Caller-Destination-Number", "1"); - switch_core_hash_insert(filter, "Caller-Dialplan", "1"); - switch_core_hash_insert(filter, "Caller-Network-Addr", "1"); - switch_core_hash_insert(filter, "Caller-Unique-ID", "1"); - switch_core_hash_insert(filter, "Call-ID", "1"); - switch_core_hash_insert(filter, "Channel-Call-State", "1"); - switch_core_hash_insert(filter, "Channel-Call-UUID", "1"); - switch_core_hash_insert(filter, "Channel-Presence-ID", "1"); - switch_core_hash_insert(filter, "Channel-State", "1"); - switch_core_hash_insert(filter, "Chat-Permissions", "1"); - switch_core_hash_insert(filter, "Conference-Name", "1"); - switch_core_hash_insert(filter, "Conference-Profile-Name", "1"); - switch_core_hash_insert(filter, "Conference-Unique-ID", "1"); - switch_core_hash_insert(filter, "contact", "1"); - switch_core_hash_insert(filter, "Detected-Tone", "1"); - switch_core_hash_insert(filter, "dialog_state", "1"); - switch_core_hash_insert(filter, "direction", "1"); - switch_core_hash_insert(filter, "Distributed-From", "1"); - switch_core_hash_insert(filter, "DTMF-Digit", "1"); - switch_core_hash_insert(filter, "DTMF-Duration", "1"); - switch_core_hash_insert(filter, "Event-Date-Timestamp", "1"); - switch_core_hash_insert(filter, "Event-Name", "1"); - switch_core_hash_insert(filter, "Event-Subclass", "1"); - switch_core_hash_insert(filter, "expires", "1"); - switch_core_hash_insert(filter, "Expires", "1"); - switch_core_hash_insert(filter, "Ext-SIP-IP", "1"); - switch_core_hash_insert(filter, "File", "1"); - switch_core_hash_insert(filter, "FreeSWITCH-Hostname", "1"); - switch_core_hash_insert(filter, "from", "1"); - switch_core_hash_insert(filter, "Hunt-Destination-Number", "1"); - switch_core_hash_insert(filter, "ip", "1"); - switch_core_hash_insert(filter, "Message-Account", "1"); - switch_core_hash_insert(filter, "metadata", "1"); - switch_core_hash_insert(filter, "old_node_channel_uuid", "1"); - switch_core_hash_insert(filter, "Other-Leg-Callee-ID-Name", "1"); - switch_core_hash_insert(filter, "Other-Leg-Callee-ID-Number", "1"); - switch_core_hash_insert(filter, "Other-Leg-Caller-ID-Name", "1"); - switch_core_hash_insert(filter, "Other-Leg-Caller-ID-Number", "1"); - switch_core_hash_insert(filter, "Other-Leg-Destination-Number", "1"); - switch_core_hash_insert(filter, "Other-Leg-Direction", "1"); - switch_core_hash_insert(filter, "Other-Leg-Unique-ID", "1"); - switch_core_hash_insert(filter, "Other-Leg-Channel-Name", "1"); - switch_core_hash_insert(filter, "Participant-Type", "1"); - switch_core_hash_insert(filter, "Path", "1"); - switch_core_hash_insert(filter, "profile_name", "1"); - switch_core_hash_insert(filter, "Profiles", "1"); - switch_core_hash_insert(filter, "proto-specific-event-name", "1"); - switch_core_hash_insert(filter, "Raw-Application-Data", "1"); - switch_core_hash_insert(filter, "realm", "1"); - switch_core_hash_insert(filter, "Resigning-UUID", "1"); - switch_core_hash_insert(filter, "set", "1"); - switch_core_hash_insert(filter, "sip_auto_answer", "1"); - switch_core_hash_insert(filter, "sip_auth_method", "1"); - switch_core_hash_insert(filter, "sip_from_host", "1"); - switch_core_hash_insert(filter, "sip_from_user", "1"); - switch_core_hash_insert(filter, "sip_to_host", "1"); - switch_core_hash_insert(filter, "sip_to_user", "1"); - switch_core_hash_insert(filter, "sub-call-id", "1"); - switch_core_hash_insert(filter, "technology", "1"); - switch_core_hash_insert(filter, "to", "1"); - switch_core_hash_insert(filter, "Unique-ID", "1"); - switch_core_hash_insert(filter, "URL", "1"); - switch_core_hash_insert(filter, "username", "1"); - switch_core_hash_insert(filter, "variable_channel_is_moving", "1"); - switch_core_hash_insert(filter, "variable_collected_digits", "1"); - switch_core_hash_insert(filter, "variable_current_application", "1"); - switch_core_hash_insert(filter, "variable_current_application_data", "1"); - switch_core_hash_insert(filter, "variable_domain_name", "1"); - switch_core_hash_insert(filter, "variable_effective_caller_id_name", "1"); - switch_core_hash_insert(filter, "variable_effective_caller_id_number", "1"); - switch_core_hash_insert(filter, "variable_holding_uuid", "1"); - switch_core_hash_insert(filter, "variable_hold_music", "1"); - switch_core_hash_insert(filter, "variable_media_group_id", "1"); - switch_core_hash_insert(filter, "variable_originate_disposition", "1"); - switch_core_hash_insert(filter, "variable_origination_uuid", "1"); - switch_core_hash_insert(filter, "variable_playback_terminator_used", "1"); - switch_core_hash_insert(filter, "variable_presence_id", "1"); - switch_core_hash_insert(filter, "variable_record_ms", "1"); - switch_core_hash_insert(filter, "variable_recovered", "1"); - switch_core_hash_insert(filter, "variable_silence_hits_exhausted", "1"); - switch_core_hash_insert(filter, "variable_sip_auth_realm", "1"); - switch_core_hash_insert(filter, "variable_sip_from_host", "1"); - switch_core_hash_insert(filter, "variable_sip_from_user", "1"); - switch_core_hash_insert(filter, "variable_sip_from_tag", "1"); - switch_core_hash_insert(filter, "variable_sip_h_X-AUTH-IP", "1"); - switch_core_hash_insert(filter, "variable_sip_received_ip", "1"); - switch_core_hash_insert(filter, "variable_sip_to_host", "1"); - switch_core_hash_insert(filter, "variable_sip_to_user", "1"); - switch_core_hash_insert(filter, "variable_sip_to_tag", "1"); - switch_core_hash_insert(filter, "variable_sofia_profile_name", "1"); - switch_core_hash_insert(filter, "variable_transfer_history", "1"); - switch_core_hash_insert(filter, "variable_user_name", "1"); - switch_core_hash_insert(filter, "variable_endpoint_disposition", "1"); - switch_core_hash_insert(filter, "variable_originate_disposition", "1"); - switch_core_hash_insert(filter, "variable_bridge_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_last_bridge_proto_specific_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_proto_specific_hangup_cause", "1"); - switch_core_hash_insert(filter, "VM-Call-ID", "1"); - switch_core_hash_insert(filter, "VM-sub-call-id", "1"); - switch_core_hash_insert(filter, "whistle_application_name", "1"); - switch_core_hash_insert(filter, "whistle_application_response", "1"); - switch_core_hash_insert(filter, "whistle_event_name", "1"); - switch_core_hash_insert(filter, "kazoo_application_name", "1"); - switch_core_hash_insert(filter, "kazoo_application_response", "1"); - switch_core_hash_insert(filter, "kazoo_event_name", "1"); - switch_core_hash_insert(filter, "sip_auto_answer_notify", "1"); - switch_core_hash_insert(filter, "eavesdrop_group", "1"); - switch_core_hash_insert(filter, "origination_caller_id_name", "1"); - switch_core_hash_insert(filter, "origination_caller_id_number", "1"); - switch_core_hash_insert(filter, "origination_callee_id_name", "1"); - switch_core_hash_insert(filter, "origination_callee_id_number", "1"); - switch_core_hash_insert(filter, "sip_auth_username", "1"); - switch_core_hash_insert(filter, "sip_auth_password", "1"); - switch_core_hash_insert(filter, "effective_caller_id_name", "1"); - switch_core_hash_insert(filter, "effective_caller_id_number", "1"); - switch_core_hash_insert(filter, "effective_callee_id_name", "1"); - switch_core_hash_insert(filter, "effective_callee_id_number", "1"); - switch_core_hash_insert(filter, "variable_destination_number", "1"); - switch_core_hash_insert(filter, "variable_effective_callee_id_name", "1"); - switch_core_hash_insert(filter, "variable_effective_callee_id_number", "1"); - switch_core_hash_insert(filter, "variable_record_silence_hits", "1"); - switch_core_hash_insert(filter, "variable_refer_uuid", "1"); - switch_core_hash_insert(filter, "variable_sip_call_id", "1"); - switch_core_hash_insert(filter, "variable_sip_h_Referred-By", "1"); - switch_core_hash_insert(filter, "variable_sip_h_X-AUTH-PORT", "1"); - switch_core_hash_insert(filter, "variable_sip_loopback_req_uri", "1"); - switch_core_hash_insert(filter, "variable_sip_received_port", "1"); - switch_core_hash_insert(filter, "variable_sip_refer_to", "1"); - switch_core_hash_insert(filter, "variable_sip_req_host", "1"); - switch_core_hash_insert(filter, "variable_sip_req_uri", "1"); - switch_core_hash_insert(filter, "variable_transfer_source", "1"); - switch_core_hash_insert(filter, "variable_uuid", "1"); - - /* Registration headers */ - switch_core_hash_insert(filter, "call-id", "1"); - switch_core_hash_insert(filter, "profile-name", "1"); - switch_core_hash_insert(filter, "from-user", "1"); - switch_core_hash_insert(filter, "from-host", "1"); - switch_core_hash_insert(filter, "presence-hosts", "1"); - switch_core_hash_insert(filter, "contact", "1"); - switch_core_hash_insert(filter, "rpid", "1"); - switch_core_hash_insert(filter, "status", "1"); - switch_core_hash_insert(filter, "expires", "1"); - switch_core_hash_insert(filter, "to-user", "1"); - switch_core_hash_insert(filter, "to-host", "1"); - switch_core_hash_insert(filter, "network-ip", "1"); - switch_core_hash_insert(filter, "network-port", "1"); - switch_core_hash_insert(filter, "username", "1"); - switch_core_hash_insert(filter, "realm", "1"); - switch_core_hash_insert(filter, "user-agent", "1"); - - switch_core_hash_insert(filter, "Hangup-Cause", "1"); - switch_core_hash_insert(filter, "Unique-ID", "1"); - switch_core_hash_insert(filter, "variable_switch_r_sdp", "1"); - switch_core_hash_insert(filter, "variable_rtp_local_sdp_str", "1"); - switch_core_hash_insert(filter, "variable_sip_to_uri", "1"); - switch_core_hash_insert(filter, "variable_sip_from_uri", "1"); - switch_core_hash_insert(filter, "variable_sip_user_agent", "1"); - switch_core_hash_insert(filter, "variable_duration", "1"); - switch_core_hash_insert(filter, "variable_billsec", "1"); - switch_core_hash_insert(filter, "variable_billmsec", "1"); - switch_core_hash_insert(filter, "variable_progresssec", "1"); - switch_core_hash_insert(filter, "variable_progress_uepoch", "1"); - switch_core_hash_insert(filter, "variable_progress_media_uepoch", "1"); - switch_core_hash_insert(filter, "variable_start_uepoch", "1"); - switch_core_hash_insert(filter, "variable_digits_dialed", "1"); - switch_core_hash_insert(filter, "Member-ID", "1"); - switch_core_hash_insert(filter, "Floor", "1"); - switch_core_hash_insert(filter, "Video", "1"); - switch_core_hash_insert(filter, "Hear", "1"); - switch_core_hash_insert(filter, "Speak", "1"); - switch_core_hash_insert(filter, "Talking", "1"); - switch_core_hash_insert(filter, "Current-Energy", "1"); - switch_core_hash_insert(filter, "Energy-Level", "1"); - switch_core_hash_insert(filter, "Mute-Detect", "1"); - - /* RTMP headers */ - switch_core_hash_insert(filter, "RTMP-Session-ID", "1"); - switch_core_hash_insert(filter, "RTMP-Profile", "1"); - switch_core_hash_insert(filter, "RTMP-Flash-Version", "1"); - switch_core_hash_insert(filter, "RTMP-SWF-URL", "1"); - switch_core_hash_insert(filter, "RTMP-TC-URL", "1"); - switch_core_hash_insert(filter, "RTMP-Page-URL", "1"); - switch_core_hash_insert(filter, "User", "1"); - switch_core_hash_insert(filter, "Domain", "1"); - - /* Fax headers */ - switch_core_hash_insert(filter, "variable_fax_bad_rows", "1"); - switch_core_hash_insert(filter, "variable_fax_document_total_pages", "1"); - switch_core_hash_insert(filter, "variable_fax_document_transferred_pages", "1"); - switch_core_hash_insert(filter, "variable_fax_ecm_used", "1"); - switch_core_hash_insert(filter, "variable_fax_result_code", "1"); - switch_core_hash_insert(filter, "variable_fax_result_text", "1"); - switch_core_hash_insert(filter, "variable_fax_success", "1"); - switch_core_hash_insert(filter, "variable_fax_transfer_rate", "1"); - switch_core_hash_insert(filter, "variable_fax_local_station_id", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_station_id", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_country", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_vendor", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_model", "1"); - switch_core_hash_insert(filter, "variable_fax_image_resolution", "1"); - switch_core_hash_insert(filter, "variable_fax_file_image_resolution", "1"); - switch_core_hash_insert(filter, "variable_fax_image_size", "1"); - switch_core_hash_insert(filter, "variable_fax_image_pixel_size", "1"); - switch_core_hash_insert(filter, "variable_fax_file_image_pixel_size", "1"); - switch_core_hash_insert(filter, "variable_fax_longest_bad_row_run", "1"); - switch_core_hash_insert(filter, "variable_fax_encoding", "1"); - switch_core_hash_insert(filter, "variable_fax_encoding_name", "1"); - switch_core_hash_insert(filter, "variable_fax_header", "1"); - switch_core_hash_insert(filter, "variable_fax_ident", "1"); - switch_core_hash_insert(filter, "variable_fax_timezone", "1"); - switch_core_hash_insert(filter, "variable_fax_doc_id", "1"); - switch_core_hash_insert(filter, "variable_fax_doc_database", "1"); - switch_core_hash_insert(filter, "variable_has_t38", "1"); - - /* Secure headers */ - switch_core_hash_insert(filter, "variable_sdp_secure_savp_only", "1"); - switch_core_hash_insert(filter, "variable_rtp_has_crypto", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media_confirmed", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media_confirmed_audio", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media_confirmed_video", "1"); - switch_core_hash_insert(filter, "sdp_secure_savp_only", "1"); - switch_core_hash_insert(filter, "rtp_has_crypto", "1"); - switch_core_hash_insert(filter, "rtp_secure_media", "1"); - switch_core_hash_insert(filter, "rtp_secure_media_confirmed", "1"); - switch_core_hash_insert(filter, "rtp_secure_media_confirmed_audio", "1"); - switch_core_hash_insert(filter, "rtp_secure_media_confirmed_video", "1"); - - /* Device Redirect headers */ - switch_core_hash_insert(filter, "variable_last_bridge_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_sip_redirected_by", "1"); - switch_core_hash_insert(filter, "intercepted_by", "1"); - switch_core_hash_insert(filter, "variable_bridge_uuid", "1"); - switch_core_hash_insert(filter, "Record-File-Path", "1"); - - /* Loopback headers */ - switch_core_hash_insert(filter, "variable_loopback_bowout_on_execute", "1"); - switch_core_hash_insert(filter, "variable_loopback_bowout", "1"); - switch_core_hash_insert(filter, "variable_other_loopback_leg_uuid", "1"); - switch_core_hash_insert(filter, "variable_loopback_leg", "1"); - switch_core_hash_insert(filter, "variable_is_loopback", "1"); - - // SMS - switch_core_hash_insert(filter, "Message-ID", "1"); - switch_core_hash_insert(filter, "Delivery-Failure", "1"); - switch_core_hash_insert(filter, "Delivery-Result-Code", "1"); - - return filter; -} - -static void fetch_config_filters(switch_memory_pool_t *pool) -{ - char *cf = "kazoo.conf"; - switch_xml_t cfg, xml, child, param; - switch_event_t *params; - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Action", "request-filter"); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); - } else { - if ((child = switch_xml_child(cfg, "event-filter"))) { - switch_hash_t *filter; - switch_hash_t *old_filter; - - switch_core_hash_init(&filter); - for (param = switch_xml_child(child, "header"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - switch_core_hash_insert(filter, var, "1"); - } - - old_filter = kazoo_globals.event_filter; - kazoo_globals.event_filter = filter; - if (old_filter) { - switch_core_hash_destroy(&old_filter); - } - } - - kazoo_globals.config_fetched = 1; - switch_xml_free(xml); - } - switch_event_destroy(¶ms); - -} - -static void fetch_config_handlers(switch_memory_pool_t *pool) -{ - char *cf = "kazoo.conf"; - switch_xml_t cfg, xml; - switch_event_t *params; - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Action", "request-handlers"); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); - } else { - kazoo_config_handlers(cfg); - kazoo_globals.config_fetched = 1; - switch_xml_free(xml); - } - switch_event_destroy(¶ms); - -} - -static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj) -{ - switch_memory_pool_t *pool = (switch_memory_pool_t *) obj; - ei_node_t *node; - int fetch_filters = 0, fetch_handlers = 0; - - // give some time for node initialization - switch_sleep(kazoo_globals.delay_before_initial_fetch); - - for (node = kazoo_globals.ei_nodes; node != NULL; node = node->next) { - if (node->legacy ) { - fetch_filters++; - } else { - fetch_handlers++; - } - } - - if (fetch_filters) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "fetching filters for kazoo\n"); - fetch_config_filters(pool); - } - - if (fetch_handlers) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "fetching kazoo handlers\n"); - fetch_config_handlers(pool); - } - - kazoo_globals.config_fetched = 1; - - return NULL; -} - -void fetch_config() -{ - switch_memory_pool_t *pool; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_uuid_t uuid; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "scheduling fetch for kazoo config\n"); - - switch_core_new_memory_pool(&pool); - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - - switch_uuid_get(&uuid); - switch_thread_create(&thread, thd_attr, fetch_config_exec, pool, pool); - -} - -#ifdef WITH_KAZOO_ERL_SHUTDOWN -#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 -typedef struct ei_mutex_s { -#ifdef __WIN32__ - HANDLE lock; -#elif VXWORKS - SEM_ID lock; -#else /* unix */ -#if defined(HAVE_MIT_PTHREAD_H) || defined(HAVE_PTHREAD_H) - pthread_mutex_t *lock; -#else /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */ - void *dummy; /* Actually never used */ -#endif /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */ -#endif /* unix */ -}ei_mutex_t; - -typedef struct ei_socket_info_s { - int socket; - ei_socket_callbacks *cbs; - void *ctx; - int dist_version; - ei_cnode cnode; /* A copy, not a pointer. We don't know when freed */ - char cookie[EI_MAX_COOKIE_SIZE+1]; -}ei_socket_info; - -extern ei_socket_info *ei_sockets; -extern ei_mutex_t* ei_sockets_lock; -extern int ei_n_sockets; -extern int ei_sz_sockets; - -int ei_mutex_free(ei_mutex_t *l, int nblock); - -#endif -#endif - -void kz_erl_init() -{ -#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 - ei_init(); -#endif -} - -void kz_erl_shutdown() -{ -#ifdef WITH_KAZOO_ERL_SHUTDOWN -#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 - ei_mutex_free(ei_sockets_lock, 1); - ei_sockets_lock = NULL; - free(ei_sockets); - ei_sockets = NULL; - ei_n_sockets = ei_sz_sockets = 0; -#endif -#endif -} - -SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) -{ - switch_os_socket_t os_socket; - - if (create_acceptor() != SWITCH_STATUS_SUCCESS) { - // TODO: what would we need to clean up here - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create erlang connection acceptor!\n"); - close_socket(&kazoo_globals.acceptor); - return SWITCH_STATUS_TERM; - } - - switch_atomic_inc(&kazoo_globals.threads); - switch_os_sock_get(&os_socket, kazoo_globals.acceptor); - - while (switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - int nodefd; - ErlConnect conn; - - /* zero out errno because ei_accept doesn't differentiate between a */ - /* failed authentication or a socket failure, or a client version */ - /* mismatch or a godzilla attack (and a godzilla attack is highly likely) */ - errno = 0; - - /* wait here for an erlang node to connect, timming out to check if our module is still running every now-and-again */ - if ((nodefd = ei_accept_tmo(&kazoo_globals.ei_cnode, (int) os_socket, &conn, kazoo_globals.connection_timeout)) == ERL_ERROR) { - if (erl_errno == ETIMEDOUT) { - continue; - } else if (errno) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang connection acceptor socket error %d %d\n", erl_errno, errno); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Erlang node connection failed - ensure your cookie matches '%s' and you are using a good nodename\n", kazoo_globals.ei_cookie); - } - continue; - } - - if (!switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - break; - } - - /* NEW ERLANG NODE CONNECTION! Hello friend! */ - new_kazoo_node(nodefd, &conn); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor shut down\n"); - - switch_atomic_dec(&kazoo_globals.threads); - - return SWITCH_STATUS_TERM; -} - -SWITCH_DECLARE(switch_status_t) ei_queue_pop(switch_queue_t *queue, void **data, switch_interval_time_t timeout) -{ - if (timeout == 0) { - return switch_queue_trypop(queue, data); - } else { - return switch_queue_pop_timeout(queue, data, timeout); - } -} -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c b/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c deleted file mode 100644 index 4ddfeddae4..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_dptools.c -- clones of mod_dptools commands slightly modified for kazoo - * - */ -#include "mod_kazoo.h" - -#define INTERACTION_VARIABLE "Call-Interaction-ID" - -static const char *x_bridge_variables[] = { - "Call-Control-Queue", - "Call-Control-PID", - "Call-Control-Node", - INTERACTION_VARIABLE, - "ecallmgr_Ecallmgr-Node", - "sip_h_k-cid", - "Switch-URI", - "Switch-URL", - NULL -}; - -static void kz_tweaks_variables_to_event(switch_core_session_t *session, switch_event_t *event) -{ - int i; - switch_channel_t *channel = switch_core_session_get_channel(session); - for(i = 0; x_bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(channel, x_bridge_variables[i], SWITCH_FALSE, -1); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, x_bridge_variables[i], val); - } -} - -static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile_in, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause) -{ - switch_xml_t x_user = NULL, x_param, x_params, x_callfwd; - char *user = NULL, *domain = NULL, *dup_domain = NULL, *dialed_user = NULL; - char *dest = NULL; - switch_call_cause_t cause = SWITCH_CAUSE_NONE; - unsigned int timelimit = SWITCH_DEFAULT_TIMEOUT; - switch_channel_t *new_channel = NULL; - switch_event_t *params = NULL, *var_event_orig = var_event; - char stupid[128] = ""; - const char *skip = NULL, *var = NULL; - switch_core_session_t *a_session = NULL, *e_session = NULL; - cJSON * ctx = NULL; - const char *endpoint_dial = NULL; - const char *callforward_dial = NULL; - const char *failover_dial = NULL; - char *b_failover_dial = NULL; - const char *endpoint_separator = NULL; - const char *varval = NULL; - char *d_dest = NULL; - switch_channel_t *channel = NULL; - switch_originate_flag_t myflags = SOF_NONE; - char *cid_name_override = NULL; - char *cid_num_override = NULL; - switch_event_t *event = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_caller_profile_t *outbound_profile = NULL; - - - if (zstr(outbound_profile_in->destination_number)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "NO DESTINATION NUMBER\n"); - goto done; - } - - user = strdup(outbound_profile_in->destination_number); - - if (!user) - goto done; - - if ((domain = strchr(user, '@'))) { - *domain++ = '\0'; - } else { - domain = switch_core_get_domain(SWITCH_TRUE); - dup_domain = domain; - } - - if (!domain) { - goto done; - } - - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true"); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "user_call"); - if (session) { - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); - } - - if (var_event) { - switch_event_merge(params, var_event); - } - - if (var_event && (skip = switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) { - if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) { - timelimit = atoi(var); - } - var_event = NULL; - } - - if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain); - cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT; - goto done; - } - - if (var_event) { - const char * str_ctx = switch_event_get_header(var_event, "kz-endpoint-runtime-context"); - if ( str_ctx ) { - ctx = cJSON_Parse(str_ctx); - if (ctx) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call context parsed => %s\n", str_ctx); - } - } - } - - if ((x_params = switch_xml_child(x_user, "variables"))) { - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding variable to var_event => %s = %s\n", pvar, val); - if (!var_event) { - switch_event_create(&var_event, SWITCH_EVENT_GENERAL); - } else { - switch_event_del_header(var_event, pvar); - } - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, pvar, val); - } - } - - if ((x_params = switch_xml_child(x_user, "params"))) { - for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (!strcasecmp(pvar, "endpoint-dial-string")) { - endpoint_dial = val; - } else if (!strcasecmp(pvar, "callforward-dial-string")) { - callforward_dial = val; - } else if (!strcasecmp(pvar, "endpoint-separator")) { - endpoint_separator = val; - } else if (!strncasecmp(pvar, "dial-var-", 9)) { - if (!var_event) { - switch_event_create(&var_event, SWITCH_EVENT_GENERAL); - } else { - switch_event_del_header(var_event, pvar + 9); - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding dialog var to var_event => %s = %s\n", pvar + 9, val); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, pvar + 9, val); - } - } - } - - x_callfwd = switch_xml_child(x_user, "call-forward"); - if (x_callfwd) { - switch_bool_t call_fwd_is_substitute = SWITCH_FALSE, - call_fwd_is_failover = SWITCH_FALSE, - call_fwd_direct_calls_only = SWITCH_FALSE, - call_fwd_is_valid = SWITCH_TRUE; - for (x_param = switch_xml_child(x_callfwd, "variable"); x_param; x_param = x_param->next) { - const char *var = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "cfw %s => %s\n", var, val); - if (!strcasecmp(var, "Is-Substitute")) { - call_fwd_is_substitute = switch_true(val); - } else if (!strcasecmp(var, "Is-Failover")) { - call_fwd_is_failover = switch_true(val); - } else if (!strcasecmp(var, "Direct-Calls-Only")) { - call_fwd_direct_calls_only = switch_true(val); - } - } - - if (call_fwd_direct_calls_only) { - call_fwd_is_valid = SWITCH_FALSE; - if (ctx ) { - cJSON *json_flags = cJSON_GetObjectItem(ctx, "Flags"); - if (json_flags && json_flags->type == cJSON_Array) { - cJSON *item; - cJSON_ArrayForEach(item, json_flags) { - if (!strcmp(item->valuestring, "direct_call")) { - call_fwd_is_valid = SWITCH_TRUE; - break; - } - } - if (!call_fwd_is_valid) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call fwd requires direct_call and it was not found\n"); - } - } - } - } - - if (!call_fwd_is_valid) { - dest = endpoint_dial ? strdup(endpoint_dial) : strdup(""); - } else if (call_fwd_is_failover) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting failover => %s\n", callforward_dial); - dest = endpoint_dial ? strdup(endpoint_dial) : strdup(""); - failover_dial = callforward_dial; - } else if (call_fwd_is_substitute) { - dest = callforward_dial ? strdup(callforward_dial) : strdup(""); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting call fwd substitute => %s\n", dest); - } else { - dest = switch_mprintf("%s%s%s", endpoint_dial ? endpoint_dial : "", (endpoint_dial ? endpoint_separator ? endpoint_separator : "," : ""), callforward_dial); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting call fwd append => %s => %s\n", callforward_dial, dest); - } - } else { - dest = endpoint_dial ? strdup(endpoint_dial) : strdup(""); - } - - dialed_user = (char *)switch_xml_attr(x_user, "id"); - - if (var_event) { - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); - } - - if (!dest) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); - cause = SWITCH_CAUSE_MANDATORY_IE_MISSING; - goto done; - } - - if (var_event) { - cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name"); - cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number"); - } - - if(session) { - a_session = session; - } else if(var_event) { - const char* uuid_e_session = switch_event_get_header(var_event, "ent_originate_aleg_uuid"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHECKING ORIGINATE-UUID : %s\n", uuid_e_session); - if (uuid_e_session && (e_session = switch_core_session_locate(uuid_e_session)) != NULL) { - a_session = e_session; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FOUND ORIGINATE-UUID : %s\n", uuid_e_session); - } - } - - if (a_session) { - switch_event_create(&event, SWITCH_EVENT_GENERAL); - channel = switch_core_session_get_channel(a_session); - if ((varval = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) - || (var_event && (varval = switch_event_get_header(var_event, "leg_timeout")))) { - timelimit = atoi(varval); - } - switch_channel_event_set_data(channel, event); - - switch_channel_set_variable(channel, "dialed_user", dialed_user); - switch_channel_set_variable(channel, "dialed_domain", domain); - - } else { - if (var_event) { - switch_event_dup(&event, var_event); - switch_event_del_header(event, "dialed_user"); - switch_event_del_header(event, "dialed_domain"); - if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || - (varval = switch_event_get_header(var_event, "leg_timeout"))) { - timelimit = atoi(varval); - } - } else { - switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(event); - } - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); - } - - if ((x_params = switch_xml_child(x_user, "profile-variables"))) { - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding profile variable to event => %s = %s\n", pvar, val); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pvar, val); - } - } - - if ((x_params = switch_xml_child(x_user, "variables"))) { - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding variable to event => %s = %s\n", pvar, val); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pvar, val); - } - } - - if ((x_params = switch_xml_child(x_user, "params"))) { - for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (!strncasecmp(pvar, "dial-var-", 9)) { - switch_event_del_header(event, pvar + 9); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding dialog var to event => %s = %s\n", pvar + 9, val); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pvar + 9, val); - } - } - } - - // add runtime vars to event for expand - if (ctx) { - kz_expand_json_to_event(ctx, event, "kz_ctx"); - } - - d_dest = kz_event_expand_headers(event, dest); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "dialing %s => %s\n", dest, d_dest); - - if(failover_dial) { - b_failover_dial = kz_event_expand_headers(event, failover_dial); - } - - if (var_event) { - kz_expand_headers(event, var_event); - } - - switch_event_destroy(&event); - - - if ((flags & SOF_NO_LIMITS)) { - myflags |= SOF_NO_LIMITS; - } - - if ((flags & SOF_FORKED_DIAL)) { - myflags |= SOF_NOBLOCK; - } - - if ( a_session ) { - if(var_event) { - kz_tweaks_variables_to_event(a_session, var_event); - } - } - - if(e_session) { - switch_core_session_rwunlock(e_session); - } - - switch_snprintf(stupid, sizeof(stupid), "kz/%s", dialed_user); - if (switch_stristr(stupid, d_dest)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n", stupid); - cause = SWITCH_CAUSE_INVALID_IE_CONTENTS; - goto done; - } - - // - outbound_profile = outbound_profile_in; - /* - outbound_profile = switch_caller_profile_dup(outbound_profile_in->pool, outbound_profile_in); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); - if ((x_params = switch_xml_child(x_user, "profile-variables"))) { - const char* val = NULL; - outbound_profile->soft = NULL; - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "setting profile var %s = %s\n", pvar, val); - switch_caller_profile_set_var(outbound_profile, pvar, val); - } - // * TODO * verify onnet/offnet - if((val=switch_caller_get_field_by_name(outbound_profile, "Endpoint-Caller-ID-Name"))) { - outbound_profile->callee_id_name = val; - outbound_profile->orig_caller_id_name = val; - } - if((val=switch_caller_get_field_by_name(outbound_profile, "Endpoint-Caller-ID-Number"))) { - outbound_profile->callee_id_number = val; - outbound_profile->orig_caller_id_number = val; - } - } - */ - - status = switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL, - cid_name_override, cid_num_override, outbound_profile, var_event, myflags, - cancel_cause, NULL); - - if (status != SWITCH_STATUS_SUCCESS && b_failover_dial) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "trying failover => %s\n", failover_dial); - status = switch_ivr_originate(session, new_session, &cause, b_failover_dial, timelimit, NULL, - cid_name_override, cid_num_override, outbound_profile, var_event, myflags, - cancel_cause, NULL); - } - - if (status == SWITCH_STATUS_SUCCESS) { - const char *context; - switch_caller_profile_t *cp; - - if (var_event) { - switch_event_del_header(var_event, "origination_uuid"); - } - - new_channel = switch_core_session_get_channel(*new_session); - - if ((context = switch_channel_get_variable(new_channel, "user_context"))) { - if ((cp = switch_channel_get_caller_profile(new_channel))) { - cp->context = switch_core_strdup(cp->pool, context); - } - } - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); - if ((x_params = switch_xml_child(x_user, "profile-variables"))) { - switch_caller_profile_t *cp = switch_channel_get_caller_profile(new_channel); - const char* val = NULL; - cp->soft = NULL; - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "setting profile var %s = %s\n", pvar, val); - switch_channel_set_profile_var(new_channel, pvar, val); - //switch_caller_profile_set_var(cp, pvar, val); - } - // * TODO * verify onnet/offnet - if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Name"))) { - cp->callee_id_name = val; - cp->orig_caller_id_name = val; - } - if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Number"))) { - cp->callee_id_number = val; - cp->orig_caller_id_number = val; - } - } - switch_core_session_rwunlock(*new_session); - } - - done: - - if (d_dest && d_dest != dest) { - switch_safe_free(d_dest); - } - - if(b_failover_dial && b_failover_dial != failover_dial) { - switch_safe_free(b_failover_dial); - } - - switch_safe_free(dest); - - if (ctx) { - cJSON_Delete(ctx); - } - - if (x_user) { - switch_xml_free(x_user); - } - - if (params) { - switch_event_destroy(¶ms); - } - - if (var_event && var_event_orig != var_event) { - switch_event_destroy(&var_event); - } - - switch_safe_free(user); - switch_safe_free(dup_domain); - return cause; -} - - -/* kazoo endpoint */ - - -switch_io_routines_t kz_endpoint_io_routines = { - /*.outgoing_channel */ kz_endpoint_outgoing_channel -}; - -void add_kz_endpoints(switch_loadable_module_interface_t **module_interface) { - switch_endpoint_interface_t *kz_endpoint_interface; - kz_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - kz_endpoint_interface->interface_name = "kz"; - kz_endpoint_interface->io_routines = &kz_endpoint_io_routines; -} diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c deleted file mode 100644 index 3d1f18326b..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_event_streams.c -- Event Publisher - * - */ -#include "mod_kazoo.h" - -#define MAX_FRAMING 4 - -/* Blatantly repurposed from switch_eventc */ -static char *my_dup(const char *s) { - size_t len = strlen(s) + 1; - void *new = malloc(len); - switch_assert(new); - - return (char *) memcpy(new, s, len); -} - -#ifndef DUP -#define DUP(str) my_dup(str) -#endif - -static const char* private_headers[] = {"variable_sip_h_", "sip_h_", "P-", "X-"}; - -static int is_private_header(const char *name) { - int i; - for(i=0; i < 4; i++) { - if(!strncmp(name, private_headers[i], strlen(private_headers[i]))) { - return 1; - } - } - return 0; -} - -static int is_kazoo_var(char* header) -{ - int idx = 0; - while(kazoo_globals.kazoo_var_prefixes[idx] != NULL) { - char *prefix = kazoo_globals.kazoo_var_prefixes[idx]; - if(!strncasecmp(header, prefix, strlen(prefix))) { - return 1; - } - idx++; - } - - return 0; -} - -static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *event, switch_hash_t *filter) { - switch_event_header_t *header; - - if (switch_event_create_subclass(clone, SWITCH_EVENT_CLONE, event->subclass_name) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_GENERR; - } - - (*clone)->event_id = event->event_id; - (*clone)->event_user_data = event->event_user_data; - (*clone)->bind_user_data = event->bind_user_data; - (*clone)->flags = event->flags; - - for (header = event->headers; header; header = header->next) { - if (event->subclass_name && !strcmp(header->name, "Event-Subclass")) { - continue; - } - - if (!is_kazoo_var(header->name) - && filter - && !switch_core_hash_find(filter, header->name) - && (!kazoo_globals.send_all_headers) - && (!(kazoo_globals.send_all_private_headers && is_private_header(header->name))) - ) - { - continue; - } - - if (header->idx) { - int i; - for (i = 0; i < header->idx; i++) { - switch_event_add_header_string(*clone, SWITCH_STACK_PUSH, header->name, header->array[i]); - } - } else { - switch_event_add_header_string(*clone, SWITCH_STACK_BOTTOM, header->name, header->value); - } - } - - if (event->body) { - (*clone)->body = DUP(event->body); - } - - (*clone)->key = event->key; - - return SWITCH_STATUS_SUCCESS; -} - -static int encode_event_old(switch_event_t *event, ei_x_buff *ebuf) { - switch_event_t *clone = NULL; - - if (kazoo_event_dup(&clone, event, kazoo_globals.event_filter) != SWITCH_STATUS_SUCCESS) { - return 0; - } - - ei_encode_switch_event(ebuf, clone); - - switch_event_destroy(&clone); - - return 1; -} - -static int encode_event_new(switch_event_t *event, ei_x_buff *ebuf) { - kazoo_message_ptr msg = NULL; - ei_event_binding_t *event_binding = (ei_event_binding_t *) event->bind_user_data; - - msg = kazoo_message_create_event(event, event_binding->event, kazoo_globals.events); - - if(msg == NULL) { - return 0; - } - - ei_x_encode_tuple_header(ebuf, 3); - ei_x_encode_atom(ebuf, "event"); - if(kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_atom(ebuf, "json"); - } else { - ei_x_encode_atom(ebuf, "map"); - } - ei_encode_json(ebuf, msg->JObj); - - kazoo_message_destroy(&msg); - - return 1; -} - -/* - * event_handler is duplicated when there are 2+ nodes connected - * with the same bindings - * we should maintain a list of event_streams in event_binding struct - * and build a ref count in the message - * - */ -static void event_handler(switch_event_t *event) { - ei_event_binding_t *event_binding = (ei_event_binding_t *) event->bind_user_data; - ei_event_stream_t *event_stream = event_binding->stream; - ei_x_buff *ebuf = NULL; - int res = 0; - - /* if mod_kazoo or the event stream isn't running dont push a new event */ - if (!switch_test_flag(event_stream, LFLAG_RUNNING) || !switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - return; - } - - kz_event_decode(event); - - switch_malloc(ebuf, sizeof(*ebuf)); - if(ebuf == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate erlang buffer for mod_kazoo message\n"); - return; - } - memset(ebuf, 0, sizeof(*ebuf)); - - if(kazoo_globals.event_stream_preallocate > 0) { - ebuf->buff = malloc(kazoo_globals.event_stream_preallocate); - ebuf->buffsz = kazoo_globals.event_stream_preallocate; - ebuf->index = 0; - if(ebuf->buff == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not pre-allocate memory for mod_kazoo message\n"); - switch_safe_free(ebuf); - return; - } - } else { - ei_x_new(ebuf); - } - - ebuf->index = MAX_FRAMING; - - ei_x_encode_version(ebuf); - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Node", event_binding->stream->node->peer_nodename); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename); - - if(event_stream->node->legacy) { - res = encode_event_old(event, ebuf); - } else { - res = encode_event_new(event, ebuf); - } - - switch_event_del_header(event, "Switch-Nodename"); - switch_event_del_header(event, "Target-Node"); - - if(!res) { - ei_x_free(ebuf); - switch_safe_free(ebuf); - return; - } - - if (kazoo_globals.event_stream_preallocate > 0 && ebuf->buffsz > kazoo_globals.event_stream_preallocate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "increased event stream buffer size to %d\n", ebuf->buffsz); - } - - if (switch_queue_trypush(event_stream->queue, ebuf) != SWITCH_STATUS_SUCCESS) { - /* if we couldn't place the cloned event into the listeners */ - /* event queue make sure we destroy it, real good like */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error placing the event in the listeners queue\n"); - ei_x_free(ebuf); - switch_safe_free(ebuf); - } - -} - -static void *SWITCH_THREAD_FUNC event_stream_loop(switch_thread_t *thread, void *obj) { - ei_event_stream_t *event_stream = (ei_event_stream_t *) obj; - ei_event_binding_t *event_binding; - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48]; - const char *ip_addr; - void *pop; - short event_stream_framing; - short event_stream_keepalive; - short ok = 1; - - switch_atomic_inc(&kazoo_globals.threads); - - switch_assert(event_stream != NULL); - - event_stream_framing = event_stream->event_stream_framing; - event_stream_keepalive = event_stream->event_stream_keepalive; - - /* figure out what socket we just opened */ - switch_socket_addr_get(&sa, SWITCH_FALSE, event_stream->acceptor); - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof(ipbuf), sa); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting erlang event stream %p on %s:%u for %s <%d.%d.%d>\n" - ,(void *)event_stream, ip_addr, port, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial); - - while (switch_test_flag(event_stream, LFLAG_RUNNING) && switch_test_flag(&kazoo_globals, LFLAG_RUNNING) && ok) { - const switch_pollfd_t *fds; - int32_t numfds; - - /* check if a new connection is pending */ - if (switch_pollset_poll(event_stream->pollset, 0, &numfds, &fds) == SWITCH_STATUS_SUCCESS) { - int32_t i; - for (i = 0; i < numfds; i++) { - switch_socket_t *newsocket; - - /* accept the new client connection */ - if (switch_socket_accept(&newsocket, event_stream->acceptor, event_stream->pool) == SWITCH_STATUS_SUCCESS) { - switch_sockaddr_t *sa; - - if (switch_socket_opt_set(newsocket, SWITCH_SO_NONBLOCK, TRUE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't set socket as non-blocking\n"); - } - - if (event_stream_keepalive) { - if (switch_socket_opt_set(newsocket, SWITCH_SO_KEEPALIVE, TRUE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't set socket keep-alive\n"); - } - } - - if (switch_socket_opt_set(newsocket, SWITCH_SO_TCP_NODELAY, 1)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't disable Nagle.\n"); - } - - /* close the current client, if there is one */ - close_socket(&event_stream->socket); - - switch_mutex_lock(event_stream->socket_mutex); - /* start sending to the new client */ - event_stream->socket = newsocket; - - switch_socket_addr_get(&sa, SWITCH_TRUE, newsocket); - event_stream->remote_port = switch_sockaddr_get_port(sa); - switch_get_addr(event_stream->remote_ip, sizeof (event_stream->remote_ip), sa); - - switch_socket_addr_get(&sa, SWITCH_FALSE, newsocket); - event_stream->local_port = switch_sockaddr_get_port(sa); - switch_get_addr(event_stream->local_ip, sizeof (event_stream->local_ip), sa); - - event_stream->connected = SWITCH_TRUE; - event_stream->connected_time = switch_micro_time_now(); - - switch_mutex_unlock(event_stream->socket_mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang event stream %p client %s:%u\n", (void *)event_stream, event_stream->remote_ip, event_stream->remote_port); - } - } - } - - /* if there was an event waiting in our queue send it to the client */ - if (ei_queue_pop(event_stream->queue, &pop, event_stream->queue_timeout) == SWITCH_STATUS_SUCCESS) { - ei_x_buff *ebuf = (ei_x_buff *) pop; - - if (event_stream->socket) { - switch_size_t size = 1, expected = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if(ebuf->index >= pow(2, 8 * event_stream_framing)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sending frame size %d with insufficient frame capacity, change event_stream_framing here and tcp_packet_type in ecallmgr\n", ebuf->index); - } else { - if(event_stream_framing) { - int index = ebuf->index - MAX_FRAMING; - char byte; - short i = event_stream_framing; - while (i) { - byte = index >> (8 * --i); - ebuf->buff[MAX_FRAMING - i - 1] = byte; - } - } - expected = size = (switch_size_t)ebuf->index - MAX_FRAMING + event_stream_framing; - if((status = switch_socket_send(event_stream->socket, ebuf->buff + (MAX_FRAMING - event_stream_framing), &size)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error %d sending event stream\n", status); - ok = 0; - } else if(expected != size) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error sending event stream, sent bytes is different of expected\n"); - ok = 0; - } - } - } - - ei_x_free(ebuf); - switch_safe_free(ebuf); - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutting down erlang event stream %p\n", (void *)event_stream); - - /* unbind from the system events */ - event_binding = event_stream->bindings; - while(event_binding != NULL) { - switch_event_unbind(&event_binding->node); - event_binding = event_binding->next; - } - event_stream->bindings = NULL; - - /* clear and destroy any remaining queued events */ - while (switch_queue_trypop(event_stream->queue, &pop) == SWITCH_STATUS_SUCCESS) { - ei_x_buff *ebuf = (ei_x_buff *) pop; - ei_x_free(ebuf); - switch_safe_free(ebuf); - } - - /* remove the acceptor pollset */ - switch_pollset_remove(event_stream->pollset, event_stream->pollfd); - - /* close any open sockets */ - close_socket(&event_stream->acceptor); - - switch_mutex_lock(event_stream->socket_mutex); - event_stream->connected = SWITCH_FALSE; - close_socket(&event_stream->socket); - switch_mutex_unlock(event_stream->socket_mutex); - - switch_mutex_destroy(event_stream->socket_mutex); - - /* clean up the memory */ - switch_core_destroy_memory_pool(&event_stream->pool); - - switch_atomic_dec(&kazoo_globals.threads); - - return NULL; -} - -ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from) { - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool = NULL; - ei_event_stream_t *event_stream; - ei_event_stream_t **event_streams = &ei_node->event_streams; - - /* create memory pool for this event stream */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: How many Alzheimer's patients does it take to screw in a light bulb? To get to the other side.\n"); - return NULL; - } - - /* from the memory pool, allocate the event stream structure */ - if (!(event_stream = switch_core_alloc(pool, sizeof (*event_stream)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: I may have Alzheimers but at least I dont have Alzheimers.\n"); - goto cleanup; - } - - /* prepare the event stream */ - memset(event_stream, 0, sizeof(*event_stream)); - event_stream->bindings = NULL; - event_stream->pool = pool; - event_stream->connected = SWITCH_FALSE; - event_stream->node = ei_node; - event_stream->event_stream_framing = ei_node->event_stream_framing; - event_stream->event_stream_keepalive = ei_node->event_stream_keepalive; - event_stream->queue_timeout = ei_node->event_stream_queue_timeout; - memcpy(&event_stream->pid, from, sizeof(erlang_pid)); - switch_queue_create(&event_stream->queue, MAX_QUEUE_LEN, pool); - - /* create a socket for accepting the event stream client */ - if (!(event_stream->acceptor = create_socket(pool))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Like car accidents, most hardware problems are due to driver error.\n"); - goto cleanup; - } - - if (switch_socket_opt_set(event_stream->acceptor, SWITCH_SO_NONBLOCK, TRUE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Hey, it compiles!\n"); - goto cleanup; - } - - /* create a pollset so we can efficiently check for new client connections */ - if (switch_pollset_create(&event_stream->pollset, 1000, pool, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "My software never has bugs. It just develops random features.\n"); - goto cleanup; - } - - switch_socket_create_pollfd(&event_stream->pollfd, event_stream->acceptor, SWITCH_POLLIN | SWITCH_POLLERR, NULL, pool); - if (switch_pollset_add(event_stream->pollset, event_stream->pollfd) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "If you saw a heat wave, would you wave back?\n"); - goto cleanup; - } - - switch_mutex_init(&event_stream->socket_mutex, SWITCH_MUTEX_DEFAULT, pool); - - /* add the new event stream to the link list - * since the event streams link list is only - * accessed from the same thread no locks - * are required */ - if (!*event_streams) { - *event_streams = event_stream; - } else { - event_stream->next = *event_streams; - *event_streams = event_stream; - } - - /* when we start we are running */ - switch_set_flag(event_stream, LFLAG_RUNNING); - - switch_threadattr_create(&thd_attr, event_stream->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, event_stream_loop, event_stream, event_stream->pool); - - return event_stream; - -cleanup: - - if (event_stream) { - /* remove the acceptor pollset */ - if (event_stream->pollset) { - switch_pollset_remove(event_stream->pollset, event_stream->pollfd); - } - - /* close any open sockets */ - if (event_stream->acceptor) { - close_socket(&event_stream->acceptor); - } - } - - /* clean up the memory */ - switch_core_destroy_memory_pool(&pool); - - return NULL; - -} - -unsigned long get_stream_port(const ei_event_stream_t *event_stream) { - switch_sockaddr_t *sa; - switch_socket_addr_get(&sa, SWITCH_FALSE, event_stream->acceptor); - return (unsigned long) switch_sockaddr_get_port(sa); -} - -ei_event_stream_t *find_event_stream(ei_event_stream_t *event_stream, const erlang_pid *from) { - while (event_stream != NULL) { - if (ei_compare_pids(&event_stream->pid, from) == SWITCH_STATUS_SUCCESS) { - return event_stream; - } - event_stream = event_stream->next; - } - - return NULL; -} - -switch_status_t remove_event_stream(ei_event_stream_t **event_streams, const erlang_pid *from) { - ei_event_stream_t *event_stream, *prev = NULL; - int found = 0; - - /* if there are no event bindings there is nothing to do */ - if (!*event_streams) { - return SWITCH_STATUS_SUCCESS; - } - - /* try to find the event stream for the client process */ - event_stream = *event_streams; - while(event_stream != NULL) { - if (ei_compare_pids(&event_stream->pid, from) == SWITCH_STATUS_SUCCESS) { - found = 1; - break; - } - - prev = event_stream; - event_stream = event_stream->next; - } - - if (found) { - /* if we found an event stream remove it from - * from the link list */ - if (!prev) { - *event_streams = event_stream->next; - } else { - prev->next = event_stream->next; - } - - /* stop the event stream thread */ - switch_clear_flag(event_stream, LFLAG_RUNNING); - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_event_streams(ei_event_stream_t **event_streams) { - ei_event_stream_t *event_stream = *event_streams; - - while(event_stream != NULL) { - /* stop the event bindings publisher thread */ - switch_clear_flag(event_stream, LFLAG_RUNNING); - - event_stream = event_stream->next; - } - - *event_streams = NULL; - - return SWITCH_STATUS_SUCCESS; -} - -void bind_event_profile(ei_event_binding_t *event_binding, kazoo_event_ptr event) -{ - switch_event_types_t event_type; - while(event != NULL) { - if (switch_name_event(event->name, &event_type) != SWITCH_STATUS_SUCCESS) { - event_type = SWITCH_EVENT_CUSTOM; - } - if(event_binding->type != SWITCH_EVENT_CUSTOM - && event_binding->type == event_type) { - break; - } - if (event_binding->type == SWITCH_EVENT_CUSTOM - && event_binding->type == event_type - && !strcasecmp(event_binding->subclass_name, event->name)) { - break; - } - event = event->next; - } - event_binding->event = event; - if(event == NULL && (!event_binding->stream->node->legacy)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "event binding to an event without profile in non legacy mode => %s - %s\n",switch_event_name(event_binding->type), event_binding->subclass_name); - } -} - -void bind_event_profiles(kazoo_event_ptr event) -{ - ei_node_t *ei_node = kazoo_globals.ei_nodes; - while(ei_node) { - ei_event_stream_t *event_streams = ei_node->event_streams; - while(event_streams) { - ei_event_binding_t *bindings = event_streams->bindings; - while(bindings) { - bind_event_profile(bindings, event); - bindings = bindings->next; - } - event_streams = event_streams->next; - } - ei_node = ei_node->next; - } -} - -switch_status_t add_event_binding(ei_event_stream_t *event_stream, const char *event_name) { - ei_event_binding_t *event_binding = event_stream->bindings; - switch_event_types_t event_type; - - if(!strcasecmp(event_name, "CUSTOM")) { - return SWITCH_STATUS_SUCCESS; - } - - if (switch_name_event(event_name, &event_type) != SWITCH_STATUS_SUCCESS) { - event_type = SWITCH_EVENT_CUSTOM; - } - - /* check if the event binding already exists, ignore if so */ - while(event_binding != NULL) { - if (event_binding->type == SWITCH_EVENT_CUSTOM) { - if(event_type == SWITCH_EVENT_CUSTOM - && event_name - && event_binding->subclass_name - && !strcasecmp(event_name, event_binding->subclass_name)) { - return SWITCH_STATUS_SUCCESS; - } - } else if (event_binding->type == event_type) { - return SWITCH_STATUS_SUCCESS; - } - event_binding = event_binding->next; - } - - /* from the event stream memory pool, allocate the event binding structure */ - if (!(event_binding = switch_core_alloc(event_stream->pool, sizeof (*event_binding)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of random-access memory, attempting write-only memory\n"); - return SWITCH_STATUS_FALSE; - } - - /* prepare the event binding struct */ - event_binding->stream = event_stream; - event_binding->type = event_type; - if(event_binding->type == SWITCH_EVENT_CUSTOM) { - event_binding->subclass_name = switch_core_strdup(event_stream->pool, event_name); - } else { - event_binding->subclass_name = SWITCH_EVENT_SUBCLASS_ANY; - } - event_binding->next = NULL; - - bind_event_profile(event_binding, kazoo_globals.events->events); - - - /* bind to the event with a unique ID and capture the event_node pointer */ - switch_uuid_str(event_binding->id, sizeof(event_binding->id)); - if (switch_event_bind_removable(event_binding->id, event_type, event_binding->subclass_name, event_handler, event_binding, &event_binding->node) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to bind to event %s %s!\n" - ,switch_event_name(event_binding->type), event_binding->subclass_name ? event_binding->subclass_name : ""); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding event binding %s to stream %p for %s <%d.%d.%d>: %s %s\n" - ,event_binding->id, (void *)event_stream, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial, switch_event_name(event_binding->type) - ,event_binding->subclass_name ? event_binding->subclass_name : ""); - - /* add the new binding to the list */ - if (!event_stream->bindings) { - event_stream->bindings = event_binding; - } else { - event_binding->next = event_stream->bindings; - event_stream->bindings = event_binding; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_event_binding(ei_event_stream_t *event_stream, const switch_event_types_t event_type, const char *subclass_name) { - ei_event_binding_t *event_binding = event_stream->bindings, *prev = NULL; - int found = 0; - - /* if there are no bindings then there is nothing to do */ - if (!event_binding) { - return SWITCH_STATUS_SUCCESS; - } - - /* try to find the event binding specified */ - while(event_binding != NULL) { - if (event_binding->type == SWITCH_EVENT_CUSTOM - && subclass_name - && event_binding->subclass_name - && !strcmp(subclass_name, event_binding->subclass_name)) { - found = 1; - break; - } else if (event_binding->type == event_type) { - found = 1; - break; - } - - prev = event_binding; - event_binding = event_binding->next; - } - - if (found) { - /* if the event binding exists, unbind from the system */ - switch_event_unbind(&event_binding->node); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing event binding %s from %p for %s <%d.%d.%d>: %s %s\n" - ,event_binding->id, (void *)event_stream, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial, switch_event_name(event_binding->type) - ,event_binding->subclass_name ? event_binding->subclass_name : ""); - - /* remove the event binding from the list */ - if (!prev) { - event_stream->bindings = event_binding->next; - } else { - prev->next = event_binding->next; - } - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_event_bindings(ei_event_stream_t *event_stream) { - ei_event_binding_t *event_binding = event_stream->bindings; - - /* if there are no bindings then there is nothing to do */ - if (!event_binding) { - return SWITCH_STATUS_SUCCESS; - } - - /* try to find the event binding specified */ - while(event_binding != NULL) { - /* if the event binding exists, unbind from the system */ - switch_event_unbind(&event_binding->node); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing event binding %s from %p for %s <%d.%d.%d>: %s %s\n" - ,event_binding->id, (void *)event_stream, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial, switch_event_name(event_binding->type) - ,event_binding->subclass_name ? event_binding->subclass_name : ""); - - event_binding = event_binding->next; - } - - event_stream->bindings = NULL; - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c b/src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c deleted file mode 100644 index 5023e39344..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c +++ /dev/null @@ -1,803 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_fetch.c -- XML fetch request handler - * - */ -#include "mod_kazoo.h" - -static const char *fetch_uuid_sources[] = { - "Fetch-Call-UUID", - "refer-from-channel-id", - "sip_call_id", - NULL -}; - -static char *xml_section_to_string(switch_xml_section_t section) { - switch(section) { - case SWITCH_XML_SECTION_CONFIG: - return "configuration"; - case SWITCH_XML_SECTION_DIRECTORY: - return "directory"; - case SWITCH_XML_SECTION_DIALPLAN: - return "dialplan"; - case SWITCH_XML_SECTION_CHATPLAN: - return "chatplan"; - case SWITCH_XML_SECTION_CHANNELS: - return "channels"; - case SWITCH_XML_SECTION_LANGUAGES: - return "languages"; - default: - return "unknown"; - } -} - -static char *expand_vars(char *xml_str) { - char *var, *val; - char *rp = xml_str; /* read pointer */ - char *ep, *wp, *buff; /* end pointer, write pointer, write buffer */ - - if (!(strstr(xml_str, "$${"))) { - return xml_str; - } - - switch_zmalloc(buff, strlen(xml_str) * 2); - wp = buff; - ep = buff + (strlen(xml_str) * 2) - 1; - - while (*rp && wp < ep) { - if (*rp == '$' && *(rp + 1) == '$' && *(rp + 2) == '{') { - char *e = switch_find_end_paren(rp + 2, '{', '}'); - - if (e) { - rp += 3; - var = rp; - *e++ = '\0'; - rp = e; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "trying to expand %s \n", var); - if ((val = switch_core_get_variable_dup(var))) { - char *p; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "expanded %s to %s\n", var, val); - for (p = val; p && *p && wp <= ep; p++) { - *wp++ = *p; - } - switch_safe_free(val); - } - continue; - } - } - - *wp++ = *rp++; - } - - *wp++ = '\0'; - - switch_safe_free(xml_str); - return buff; -} - -static switch_xml_t fetch_handler(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) { - switch_xml_t xml = NULL; - switch_uuid_t uuid; - switch_time_t now = 0; - ei_xml_agent_t *agent = (ei_xml_agent_t *) user_data; - ei_xml_client_t *client; - fetch_handler_t *fetch_handler; - xml_fetch_reply_t reply, *pending, *prev = NULL; - switch_event_t *event = params; - kazoo_fetch_profile_ptr profile = agent->profile; - const char *fetch_call_id; - ei_send_msg_t *send_msg = NULL; - int sent = 0; - - now = switch_micro_time_now(); - - if (!switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - return xml; - } - - /* read-lock the agent */ - switch_thread_rwlock_rdlock(agent->lock); - - /* serialize access to current, used to round-robin requests */ - /* TODO: check kazoo_globals for round-robin boolean or loop all clients */ - switch_mutex_lock(agent->current_client_mutex); - if (!agent->current_client) { - client = agent->clients; - } else { - client = agent->current_client; - } - if (client) { - agent->current_client = client->next; - } - switch_mutex_unlock(agent->current_client_mutex); - - /* no client, no work required */ - if (!client || !client->fetch_handlers) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "No %s XML erlang handler currently available\n" - ,section); - switch_thread_rwlock_unlock(agent->lock); - return xml; - } - - /* no profile, no work required */ - if (!profile) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "weird case where client is available but there's no profile for %s. try reloading mod_kazoo.\n" - ,section); - switch_thread_rwlock_unlock(agent->lock); - return xml; - } - - if(event == NULL) { - if (switch_event_create(&event, SWITCH_EVENT_GENERAL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error creating event for fetch handler\n"); - return xml; - } - } - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename); - - /* prepare the reply collector */ - switch_uuid_get(&uuid); - switch_uuid_format(reply.uuid_str, &uuid); - reply.next = NULL; - reply.xml_str = NULL; - - if(switch_event_get_header(event, "Unique-ID") == NULL) { - int i; - for(i = 0; fetch_uuid_sources[i] != NULL; i++) { - if((fetch_call_id = switch_event_get_header(event, fetch_uuid_sources[i])) != NULL) { - switch_core_session_t *session = NULL; - if((session = switch_core_session_locate(fetch_call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - uint32_t verbose = switch_channel_test_flag(channel, CF_VERBOSE_EVENTS); - switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); - switch_channel_event_set_data(channel, event); - switch_channel_set_flag_value(channel, CF_VERBOSE_EVENTS, verbose); - switch_core_session_rwunlock(session); - break; - } - } - } - } - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-UUID", reply.uuid_str); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Section", section); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Tag", tag_name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Key-Name", key_name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Key-Value", key_value); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Fetch-Timeout", "%u", profile->fetch_timeout); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Fetch-Timestamp-Micro", "%" SWITCH_UINT64_T_FMT, (uint64_t)now); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Kazoo-Version", VERSION); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Kazoo-Bundle", BUNDLE); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Kazoo-Release", RELEASE); - - kz_event_decode(event); - - switch_malloc(send_msg, sizeof(*send_msg)); - - if(client->ei_node->legacy) { - ei_x_new_with_version(&send_msg->buf); - ei_x_encode_tuple_header(&send_msg->buf, 7); - ei_x_encode_atom(&send_msg->buf, "fetch"); - ei_x_encode_atom(&send_msg->buf, section); - _ei_x_encode_string(&send_msg->buf, tag_name ? tag_name : "undefined"); - _ei_x_encode_string(&send_msg->buf, key_name ? key_name : "undefined"); - _ei_x_encode_string(&send_msg->buf, key_value ? key_value : "undefined"); - _ei_x_encode_string(&send_msg->buf, reply.uuid_str); - ei_encode_switch_event_headers(&send_msg->buf, event); - } else { - kazoo_message_ptr msg = kazoo_message_create_fetch(event, profile); - ei_x_new_with_version(&send_msg->buf); - ei_x_encode_tuple_header(&send_msg->buf, 2); - ei_x_encode_atom(&send_msg->buf, "fetch"); - ei_encode_json(&send_msg->buf, msg->JObj); - kazoo_message_destroy(&msg); - } - - /* add our reply placeholder to the replies list */ - switch_mutex_lock(agent->replies_mutex); - if (!agent->replies) { - agent->replies = &reply; - } else { - reply.next = agent->replies; - agent->replies = &reply; - } - switch_mutex_unlock(agent->replies_mutex); - - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL && sent == 0) { - memcpy(&send_msg->pid, &fetch_handler->pid, sizeof(erlang_pid)); - if (switch_queue_trypush(client->ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send %s XML request to %s <%d.%d.%d>\n" - ,section - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending %s XML request (%s) to %s <%d.%d.%d>\n" - ,section - ,reply.uuid_str - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - sent = 1; - } - fetch_handler = fetch_handler->next; - } - - if(!sent) { - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - if(params == NULL) - switch_event_destroy(&event); - - /* wait for a reply (if there isnt already one...amazingly improbable but lets not take shortcuts */ - switch_mutex_lock(agent->replies_mutex); - - switch_thread_rwlock_unlock(agent->lock); - - if (!reply.xml_str) { - switch_time_t timeout; - - timeout = switch_micro_time_now() + 3000000; - while (switch_micro_time_now() < timeout) { - /* unlock the replies list and go to sleep, calculate a three second timeout before we started the loop - * plus 100ms to add a little hysteresis between the timeout and the while loop */ - switch_thread_cond_timedwait(agent->new_reply, agent->replies_mutex, (timeout - switch_micro_time_now() + 100000)); - - /* if we woke up (and therefore have locked replies again) check if we got our reply - * otherwise we either timed-out (the while condition will fail) or one of - * our sibling processes got a reply and we should go back to sleep */ - if (reply.xml_str) { - break; - } - } - } - - /* find our reply placeholder in the linked list and remove it */ - pending = agent->replies; - while (pending != NULL) { - if (pending->uuid_str == reply.uuid_str) { - break; - } - - prev = pending; - pending = pending->next; - } - - if (pending) { - if (!prev) { - agent->replies = reply.next; - } else { - prev->next = reply.next; - } - } - - /* we are done with the replies link-list */ - switch_mutex_unlock(agent->replies_mutex); - - /* after all that did we get what we were after?! */ - if (reply.xml_str) { - /* HELL YA WE DID */ - if (kazoo_globals.expand_headers_on_fetch) { - reply.xml_str = expand_vars(reply.xml_str); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received %s XML (%s) after %dms: %s\n" - ,section - ,reply.uuid_str - ,(unsigned int) (switch_micro_time_now() - now) / 1000 - ,reply.xml_str); - if ((xml = switch_xml_parse_str_dynamic(reply.xml_str, SWITCH_FALSE)) == NULL) { - switch_safe_free(reply.xml_str); - } - } else { - /* facepalm */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Request for %s XML (%s) timed-out after %dms\n" - ,section - ,reply.uuid_str - ,(unsigned int) (switch_micro_time_now() - now) / 1000); - } - - return xml; -} - -void bind_fetch_profile(ei_xml_agent_t *agent, kazoo_config_ptr fetch_handlers) -{ - switch_hash_index_t *hi; - kazoo_fetch_profile_ptr val = NULL, ptr = NULL; - - if (!fetch_handlers) return; - - for (hi = switch_core_hash_first(fetch_handlers->hash); hi; hi = switch_core_hash_next(&hi)) { - switch_core_hash_this(hi, NULL, NULL, (void**) &val); - if (val && val->section == agent->section) { - ptr = val; - break; - } - } - agent->profile = ptr; - switch_safe_free(hi); -} - -void rebind_fetch_profiles(kazoo_config_ptr fetch_handlers) -{ - if(kazoo_globals.config_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.config_fetch_binding), fetch_handlers); - - if(kazoo_globals.directory_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.directory_fetch_binding), fetch_handlers); - - if(kazoo_globals.dialplan_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.dialplan_fetch_binding), fetch_handlers); - - if(kazoo_globals.channels_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.channels_fetch_binding), fetch_handlers); - - if(kazoo_globals.languages_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.languages_fetch_binding), fetch_handlers); - - if(kazoo_globals.chatplan_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.chatplan_fetch_binding), fetch_handlers); -} - -static switch_status_t bind_fetch_agent(switch_xml_section_t section, switch_xml_binding_t **binding) { - switch_memory_pool_t *pool = NULL; - ei_xml_agent_t *agent; - - /* create memory pool for this xml search binging (lives for duration of mod_kazoo runtime) */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: They're not people; they're hippies!\n"); - return SWITCH_STATUS_MEMERR; - } - - /* allocate some memory to store the fetch bindings for this section */ - if (!(agent = switch_core_alloc(pool, sizeof (*agent)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: Oh, Jesus tap-dancing Christ!\n"); - return SWITCH_STATUS_MEMERR; - } - - /* try to bind to the switch */ - if (switch_xml_bind_search_function_ret(fetch_handler, section, agent, binding) != SWITCH_STATUS_SUCCESS) { - switch_core_destroy_memory_pool(&pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not bind to FreeSWITCH %s XML requests\n" - ,xml_section_to_string(section)); - return SWITCH_STATUS_GENERR; - } - - agent->pool = pool; - agent->section = section; - switch_thread_rwlock_create(&agent->lock, pool); - agent->clients = NULL; - switch_mutex_init(&agent->current_client_mutex, SWITCH_MUTEX_DEFAULT, pool); - agent->current_client = NULL; - switch_mutex_init(&agent->replies_mutex, SWITCH_MUTEX_DEFAULT, pool); - switch_thread_cond_create(&agent->new_reply, pool); - agent->replies = NULL; - - bind_fetch_profile(agent, kazoo_globals.fetch_handlers); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Bound to %s XML requests\n" - ,xml_section_to_string(section)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unbind_fetch_agent(switch_xml_binding_t **binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - - if(*binding == NULL) - return SWITCH_STATUS_GENERR; - - /* get a pointer to our user_data */ - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(*binding); - - /* unbind from the switch */ - switch_xml_unbind_search_function(binding); - - /* LOCK ALL THE THINGS */ - switch_thread_rwlock_wrlock(agent->lock); - switch_mutex_lock(agent->current_client_mutex); - switch_mutex_lock(agent->replies_mutex); - - /* cleanly destroy each client */ - client = agent->clients; - while(client != NULL) { - ei_xml_client_t *tmp_client = client; - fetch_handler_t *fetch_handler; - - fetch_handler = client->fetch_handlers; - while(fetch_handler != NULL) { - fetch_handler_t *tmp_fetch_handler = fetch_handler; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - fetch_handler = fetch_handler->next; - switch_safe_free(tmp_fetch_handler); - } - - client = client->next; - switch_safe_free(tmp_client); - } - - /* keep the pointers clean, even if its just for a moment */ - agent->clients = NULL; - agent->current_client = NULL; - - /* release the locks! */ - switch_thread_rwlock_unlock(agent->lock); - switch_mutex_unlock(agent->current_client_mutex); - switch_mutex_unlock(agent->replies_mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unbound from %s XML requests\n" - ,xml_section_to_string(agent->section)); - - /* cleanly destroy the bindings */ - switch_thread_rwlock_destroy(agent->lock); - switch_mutex_destroy(agent->current_client_mutex); - switch_mutex_destroy(agent->replies_mutex); - switch_thread_cond_destroy(agent->new_reply); - switch_core_destroy_memory_pool(&agent->pool); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t remove_xml_client(ei_node_t *ei_node, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client, *prev = NULL; - int found = 0; - - if(binding == NULL) - return SWITCH_STATUS_GENERR; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* write-lock the agent */ - switch_thread_rwlock_wrlock(agent->lock); - - client = agent->clients; - while (client != NULL) { - if (client->ei_node == ei_node) { - found = 1; - break; - } - - prev = client; - client = client->next; - } - - if (found) { - fetch_handler_t *fetch_handler; - - if (!prev) { - agent->clients = client->next; - } else { - prev->next = client->next; - } - - /* the mutex lock is not required since we have the write lock - * but hey its fun and safe so do it anyway */ - switch_mutex_lock(agent->current_client_mutex); - if (agent->current_client == client) { - agent->current_client = agent->clients; - } - switch_mutex_unlock(agent->current_client_mutex); - - fetch_handler = client->fetch_handlers; - while(fetch_handler != NULL) { - fetch_handler_t *tmp_fetch_handler = fetch_handler; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - fetch_handler = fetch_handler->next; - switch_safe_free(tmp_fetch_handler); - } - - switch_safe_free(client); - } - - switch_thread_rwlock_unlock(agent->lock); - - return SWITCH_STATUS_SUCCESS; -} - -static ei_xml_client_t *add_xml_client(ei_node_t *ei_node, ei_xml_agent_t *agent) { - ei_xml_client_t *client; - - switch_malloc(client, sizeof(*client)); - - client->ei_node = ei_node; - client->fetch_handlers = NULL; - client->next = NULL; - - if (agent->clients) { - client->next = agent->clients; - } - - agent->clients = client; - - return client; -} - -static ei_xml_client_t *find_xml_client(ei_node_t *ei_node, ei_xml_agent_t *agent) { - ei_xml_client_t *client; - - client = agent->clients; - while (client != NULL) { - if (client->ei_node == ei_node) { - return client; - } - - client = client->next; - } - - return NULL; -} - -static switch_status_t remove_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - fetch_handler_t *fetch_handler, *prev = NULL; - int found = 0; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* write-lock the agent */ - switch_thread_rwlock_wrlock(agent->lock); - - if (!(client = find_xml_client(ei_node, agent))) { - switch_thread_rwlock_unlock(agent->lock); - return SWITCH_STATUS_SUCCESS; - } - - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL) { - if (ei_compare_pids(&fetch_handler->pid, from) == SWITCH_STATUS_SUCCESS) { - found = 1; - break; - } - - prev = fetch_handler; - fetch_handler = fetch_handler->next; - } - - if (found) { - if (!prev) { - client->fetch_handlers = fetch_handler->next; - } else { - prev->next = fetch_handler->next; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - switch_safe_free(fetch_handler); - } - - switch_thread_rwlock_unlock(agent->lock); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_api_command_stream(ei_node_t *ei_node, switch_stream_handle_t *stream, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - - if (!binding) { - return SWITCH_STATUS_GENERR; - } - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* read-lock the agent */ - switch_thread_rwlock_rdlock(agent->lock); - client = agent->clients; - while (client != NULL) { - if (client->ei_node == ei_node) { - fetch_handler_t *fetch_handler; - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL) { - stream->write_function(stream, "XML %s handler <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - fetch_handler = fetch_handler->next; - } - break; - } - - client = client->next; - } - switch_thread_rwlock_unlock(agent->lock); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t bind_fetch_agents() { - bind_fetch_agent(SWITCH_XML_SECTION_CONFIG, &kazoo_globals.config_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_DIRECTORY, &kazoo_globals.directory_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_DIALPLAN, &kazoo_globals.dialplan_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_CHANNELS, &kazoo_globals.channels_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_LANGUAGES, &kazoo_globals.languages_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_CHATPLAN, &kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t unbind_fetch_agents() { - unbind_fetch_agent(&kazoo_globals.config_fetch_binding); - unbind_fetch_agent(&kazoo_globals.directory_fetch_binding); - unbind_fetch_agent(&kazoo_globals.dialplan_fetch_binding); - unbind_fetch_agent(&kazoo_globals.channels_fetch_binding); - unbind_fetch_agent(&kazoo_globals.languages_fetch_binding); - unbind_fetch_agent(&kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_xml_clients(ei_node_t *ei_node) { - remove_xml_client(ei_node, kazoo_globals.config_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.directory_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.dialplan_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.channels_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.languages_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t add_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - fetch_handler_t *fetch_handler; - - if(binding == NULL) - return SWITCH_STATUS_GENERR; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* write-lock the agent */ - switch_thread_rwlock_wrlock(agent->lock); - - if (!(client = find_xml_client(ei_node, agent))) { - client = add_xml_client(ei_node, agent); - } - - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL) { - if (ei_compare_pids(&fetch_handler->pid, from) == SWITCH_STATUS_SUCCESS) { - switch_thread_rwlock_unlock(agent->lock); - return SWITCH_STATUS_SUCCESS; - } - fetch_handler = fetch_handler->next; - } - - switch_malloc(fetch_handler, sizeof(*fetch_handler)); - - memcpy(&fetch_handler->pid, from, sizeof(erlang_pid));; - - fetch_handler->next = NULL; - if (client->fetch_handlers) { - fetch_handler->next = client->fetch_handlers; - } - - client->fetch_handlers = fetch_handler; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - switch_thread_rwlock_unlock(agent->lock); - - ei_link(ei_node, ei_self(&kazoo_globals.ei_cnode), from); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_fetch_handlers(ei_node_t *ei_node, erlang_pid *from) { - remove_fetch_handler(ei_node, from, kazoo_globals.config_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.directory_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.dialplan_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.channels_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.languages_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t fetch_reply(char *uuid_str, char *xml_str, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - xml_fetch_reply_t *reply; - switch_status_t status = SWITCH_STATUS_NOTFOUND; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - switch_mutex_lock(agent->replies_mutex); - reply = agent->replies; - while (reply != NULL) { - if (!strncmp(reply->uuid_str, uuid_str, SWITCH_UUID_FORMATTED_LENGTH)) { - if (!reply->xml_str) { - reply->xml_str = xml_str; - switch_thread_cond_broadcast(agent->new_reply); - status = SWITCH_STATUS_SUCCESS; - } - break; - } - - reply = reply->next; - } - switch_mutex_unlock(agent->replies_mutex); - - return status; -} - -switch_status_t handle_api_command_streams(ei_node_t *ei_node, switch_stream_handle_t *stream) { - handle_api_command_stream(ei_node, stream, kazoo_globals.config_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.directory_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.dialplan_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.channels_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.languages_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_fields.h b/src/mod/event_handlers/mod_kazoo/kazoo_fields.h deleted file mode 100644 index 8d17378768..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_fields.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#ifndef KAZOO_FIELDS_H -#define KAZOO_FIELDS_H - -#include - -#define MAX_LIST_FIELDS 25 - -typedef struct kazoo_log_levels kazoo_loglevels_t; -typedef kazoo_loglevels_t *kazoo_loglevels_ptr; - -struct kazoo_log_levels -{ - switch_log_level_t success_log_level; - switch_log_level_t failed_log_level; - switch_log_level_t warn_log_level; - switch_log_level_t info_log_level; - switch_log_level_t time_log_level; - switch_log_level_t filtered_event_log_level; - switch_log_level_t filtered_field_log_level; - switch_log_level_t trace_log_level; - switch_log_level_t debug_log_level; - switch_log_level_t error_log_level; - switch_log_level_t hashing_log_level; - -}; - -typedef struct kazoo_logging kazoo_logging_t; -typedef kazoo_logging_t *kazoo_logging_ptr; - -struct kazoo_logging -{ - kazoo_loglevels_ptr levels; - const char *profile_name; - const char *event_name; -}; - -typedef struct kazoo_list_s { - char *value[MAX_LIST_FIELDS]; - int size; -} kazoo_list_t; - -typedef enum { - FILTER_COMPARE_REGEX, - FILTER_COMPARE_LIST, - FILTER_COMPARE_VALUE, - FILTER_COMPARE_PREFIX, - FILTER_COMPARE_EXISTS, - FILTER_COMPARE_FIELD - -} kazoo_filter_compare_type; - -typedef enum { - FILTER_EXCLUDE, - FILTER_INCLUDE, - FILTER_ENSURE -} kazoo_filter_type; - -typedef struct kazoo_filter_t { - kazoo_filter_type type; - kazoo_filter_compare_type compare; - char* name; - char* value; - kazoo_list_t list; - struct kazoo_filter_t* next; -} kazoo_filter, *kazoo_filter_ptr; - - -typedef enum { - JSON_NONE, - JSON_STRING, - JSON_NUMBER, - JSON_BOOLEAN, - JSON_OBJECT, - JSON_RAW -} kazoo_json_field_type; - -typedef enum { - FIELD_NONE, - FIELD_COPY, - FIELD_STATIC, - FIELD_FIRST_OF, - FIELD_EXPAND, - FIELD_PREFIX, - FIELD_OBJECT, - FIELD_GROUP, - FIELD_REFERENCE - -} kazoo_field_type; - -typedef struct kazoo_field_t kazoo_field; -typedef kazoo_field *kazoo_field_ptr; - -typedef struct kazoo_fields_t kazoo_fields; -typedef kazoo_fields *kazoo_fields_ptr; - -typedef struct kazoo_definition_t kazoo_definition; -typedef kazoo_definition *kazoo_definition_ptr; - -struct kazoo_field_t { - char* name; - char* value; - char* as; - kazoo_list_t list; - switch_bool_t exclude_prefix; - kazoo_field_type in_type; - kazoo_json_field_type out_type; - int out_type_as_array; - kazoo_filter_ptr filter; - - kazoo_definition_ptr ref; - kazoo_field_ptr next; - kazoo_fields_ptr children; -}; - -struct kazoo_fields_t { - kazoo_field_ptr head; - int verbose; -}; - - -struct kazoo_definition_t { - char* name; - kazoo_field_ptr head; - kazoo_filter_ptr filter; -}; - -struct kazoo_event { - kazoo_event_profile_ptr profile; - char *name; - kazoo_fields_ptr fields; - kazoo_filter_ptr filter; - kazoo_loglevels_ptr logging; - - kazoo_event_t* next; -}; - -struct kazoo_event_profile { - char *name; - kazoo_config_ptr root; - switch_bool_t running; - switch_memory_pool_t *pool; - kazoo_filter_ptr filter; - kazoo_fields_ptr fields; - kazoo_event_ptr events; - - kazoo_loglevels_ptr logging; -}; - -struct kazoo_fetch_profile { - char *name; - kazoo_config_ptr root; - switch_bool_t running; - switch_memory_pool_t *pool; - kazoo_fields_ptr fields; - int fetch_timeout; - switch_mutex_t *fetch_reply_mutex; - switch_hash_t *fetch_reply_hash; - switch_xml_binding_t *fetch_binding; - switch_xml_section_t section; - - kazoo_loglevels_ptr logging; -}; - -#endif /* KAZOO_FIELDS_H */ - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_message.c b/src/mod/event_handlers/mod_kazoo/kazoo_message.c deleted file mode 100644 index 43716a8e02..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_message.c +++ /dev/null @@ -1,488 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#include "mod_kazoo.h" - -/* deletes then add */ -void kazoo_cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) -{ - cJSON_DeleteItemFromObject(object, string); - cJSON_AddItemToObject(object, string, item); -} - -static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter, kazoo_logging_ptr logging) -{ - switch_event_header_t *header; - int hasValue = 0, n; - char *value = NULL, *expr = NULL; - - switch(filter->compare) { - - case FILTER_COMPARE_EXISTS: - hasValue = switch_event_get_header(evt, filter->name) != NULL ? 1 : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s checking if %s exists => %s\n", logging->profile_name, logging->event_name, filter->name, hasValue ? "true" : "false"); - break; - - case FILTER_COMPARE_VALUE: - if (*filter->name == '$') { - value = expr = kz_event_expand_headers(evt, filter->name); - } else { - value = switch_event_get_header(evt, filter->name); - } - hasValue = value ? !strcmp(value, filter->value) : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s compare value %s to %s => %s == %s => %s\n", logging->profile_name, logging->event_name, filter->name, filter->value, value, filter->value, hasValue ? "true" : "false"); - break; - - case FILTER_COMPARE_FIELD: - if (*filter->name == '$') { - value = expr = kz_event_expand_headers(evt, filter->name); - } else { - value = switch_event_get_header(evt, filter->name); - } - hasValue = value ? !strcmp(value, switch_event_get_header_nil(evt, filter->value)) : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s compare field %s to %s => %s == %s => %s\n", logging->profile_name, logging->event_name, filter->name, filter->value, value, switch_event_get_header_nil(evt, filter->value), hasValue ? "true" : "false"); - break; - - case FILTER_COMPARE_PREFIX: - for (header = evt->headers; header; header = header->next) { - if(!strncmp(header->name, filter->value, strlen(filter->value))) { - hasValue = 1; - break; - } - } - break; - - case FILTER_COMPARE_LIST: - if (*filter->name == '$') { - value = expr = kz_event_expand_headers(evt, filter->name); - } else { - value = switch_event_get_header(evt, filter->name); - } - if(value) { - for(n = 0; n < filter->list.size; n++) { - if(!strncmp(value, filter->list.value[n], strlen(filter->list.value[n]))) { - hasValue = 1; - break; - } - } - } - break; - - case FILTER_COMPARE_REGEX: - break; - - default: - break; - } - - switch_safe_free(expr); - - return hasValue; -} - -static kazoo_filter_ptr inline filter_event(switch_event_t* evt, kazoo_filter_ptr filter, kazoo_logging_ptr logging) -{ - while(filter) { - int hasValue = filter_compare(evt, filter, logging); - if(filter->type == FILTER_EXCLUDE) { - if(hasValue) - break; - } else if(filter->type == FILTER_INCLUDE) { - if(!hasValue) - break; - } - filter = filter->next; - } - return filter; -} - -static void kazoo_event_init_json_fields(switch_event_t *event, cJSON *json) -{ - switch_event_header_t *hp; - for (hp = event->headers; hp; hp = hp->next) { - if (strncmp(hp->name, "_json_", 6)) { - if (hp->idx) { - cJSON *a = cJSON_CreateArray(); - int i; - - for(i = 0; i < hp->idx; i++) { - cJSON_AddItemToArray(a, cJSON_CreateString(hp->array[i])); - } - - cJSON_AddItemToObject(json, hp->name, a); - - } else { - cJSON_AddItemToObject(json, hp->name, cJSON_CreateString(hp->value)); - } - } - } -} - -static switch_status_t kazoo_event_init_json(kazoo_fields_ptr fields1, kazoo_fields_ptr fields2, switch_event_t* evt, cJSON** clone) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - if( (fields2 && fields2->verbose) - || (fields1 && fields1->verbose) - || ( (!fields2) && (!fields1)) ) { - *clone = cJSON_CreateObject(); - if((*clone) == NULL) { - status = SWITCH_STATUS_GENERR; - } else { - kazoo_event_init_json_fields(evt, *clone); - } - } else { - *clone = cJSON_CreateObject(); - if((*clone) == NULL) { - status = SWITCH_STATUS_GENERR; - } - } - return status; -} - -static cJSON * kazoo_event_json_value(kazoo_json_field_type type, const char *value) { - cJSON *item = NULL; - switch(type) { - case JSON_STRING: - item = cJSON_CreateString(value); - break; - - case JSON_NUMBER: - item = cJSON_CreateNumber(strtod(value, NULL)); - break; - - case JSON_BOOLEAN: - item = cJSON_CreateBool(switch_true(value)); - break; - - case JSON_OBJECT: - item = cJSON_CreateObject(); - break; - - case JSON_RAW: - item = cJSON_Parse(value); - if (!item) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "parse from raw error!\n"); - item = cJSON_CreateRaw(value); - } - break; - - default: - break; - }; - - return item; -} - -static cJSON * kazoo_event_add_json_value(cJSON *dst, kazoo_field_ptr field, const char *as, const char *value) { - cJSON *item = NULL; - if(value || field->out_type == JSON_OBJECT) { - if((item = kazoo_event_json_value(field->out_type, value)) != NULL) { - kazoo_cJSON_AddItemToObject(dst, as, item); - } - } - return item; -} - - -cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_field_ptr field) -{ - switch_event_header_t *header; - char *expanded; - int i, n; - cJSON *item = NULL; - - switch(field->in_type) { - case FIELD_COPY: - if (!strcmp(field->name, "_body")) { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, src->body); - } else if((header = switch_event_get_header_ptr(src, field->name)) != NULL) { - if (header->idx) { - item = cJSON_CreateArray(); - - for(i = 0; i < header->idx; i++) { - cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); - } - - kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); - } else if (field->out_type_as_array) { - item = cJSON_CreateArray(); - cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->value)); - kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); - } else { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value); - } - } - break; - - case FIELD_EXPAND: - expanded = kz_event_expand_headers(src, field->value); - if(expanded != NULL && !zstr(expanded)) { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, expanded); - } - - if (expanded != field->value) { - switch_safe_free(expanded); - } - - break; - - case FIELD_FIRST_OF: - - for(n = 0; n < field->list.size; n++) { - if(*field->list.value[n] == '#') { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, ++field->list.value[n]); - break; - } else { - header = switch_event_get_header_ptr(src, field->list.value[n]); - if(header) { - if (header->idx) { - item = cJSON_CreateArray(); - - for(i = 0; i < header->idx; i++) { - cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); - } - - kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); - } else { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value); - } - - break; - } - } - } - - break; - - case FIELD_PREFIX: - - for (header = src->headers; header; header = header->next) { - if(!strncmp(header->name, field->name, strlen(field->name))) { - if (header->idx) { - cJSON *array = cJSON_CreateArray(); - - for(i = 0; i < header->idx; i++) { - cJSON_AddItemToArray(array, kazoo_event_json_value(field->out_type, header->array[i])); - } - - kazoo_cJSON_AddItemToObject(dst, field->exclude_prefix ? header->name+strlen(field->name) : header->name, array); - } else { - kazoo_event_add_json_value(dst, field, field->exclude_prefix ? header->name+strlen(field->name) : header->name, header->value); - } - } - } - - break; - - case FIELD_STATIC: - item = kazoo_event_add_json_value(dst, field, field->name, field->value); - break; - - case FIELD_GROUP: - item = dst; - break; - - default: - break; - } - - return item; -} - -static switch_status_t kazoo_event_add_fields_to_json(kazoo_logging_ptr logging, cJSON *dst, switch_event_t *src, kazoo_field_ptr field) { - - kazoo_filter_ptr filter; - cJSON *item = NULL; - while(field) { - if(field->in_type == FIELD_REFERENCE) { - if(field->ref) { - if((filter = filter_event(src, field->ref->filter, logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, referenced field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->ref->name, filter->name, filter->value); - } else { - kazoo_event_add_fields_to_json(logging, dst, src, field->ref->head); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "profile[%s] event %s, referenced field %s not found\n", logging->profile_name, logging->event_name, field->name); - } - } else { - if((filter = filter_event(src, field->filter, logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->name, filter->name, filter->value); - } else { - item = kazoo_event_add_field_to_json(dst, src, field); - if(field->children && item != NULL) { - if(field->children->verbose && field->out_type == JSON_OBJECT) { - kazoo_event_init_json_fields(src, item); - } - kazoo_event_add_fields_to_json(logging, field->out_type == JSON_OBJECT ? item : dst, src, field->children->head); - } - } - } - - field = field->next; - } - - return SWITCH_STATUS_SUCCESS; -} - -#define EVENT_TIMESTAMP_FIELD "Event-Date-Timestamp" -#define JSON_TIMESTAMP_FIELD "Event-Timestamp" - -static switch_status_t kazoo_event_add_timestamp(switch_event_t* evt, cJSON* JObj) -{ - switch_event_header_t *header; - cJSON *item = NULL; - if((header = switch_event_get_header_ptr(evt, EVENT_TIMESTAMP_FIELD)) != NULL) { - if ((item = kazoo_event_json_value(JSON_NUMBER, header->value)) != NULL) { - kazoo_cJSON_AddItemToObject(JObj, JSON_TIMESTAMP_FIELD, item); - return SWITCH_STATUS_SUCCESS; - } - } - return SWITCH_STATUS_NOTFOUND; -} - -kazoo_message_ptr kazoo_message_create_event(switch_event_t* evt, kazoo_event_ptr event, kazoo_event_profile_ptr profile) -{ - kazoo_message_ptr message; - cJSON *JObj = NULL; - kazoo_filter_ptr filtered; - kazoo_logging_t logging; - - logging.levels = profile->logging; - logging.event_name = evt->subclass_name ? evt->subclass_name : switch_event_get_header_nil(evt, "Event-Name"); - logging.profile_name = profile->name; - - message = malloc(sizeof(kazoo_message_t)); - if(message == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n"); - return NULL; - } - memset(message, 0, sizeof(kazoo_message_t)); - - if(profile->filter) { - // filtering - if((filtered = filter_event(evt, profile->filter, &logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by profile settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value); - kazoo_message_destroy(&message); - return NULL; - } - } - - if (event->logging) { - logging.levels = event->logging; - } - - if (event && event->filter) { - if((filtered = filter_event(evt, event->filter, &logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by event settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value); - kazoo_message_destroy(&message); - return NULL; - } - } - - kazoo_event_init_json(profile->fields, event ? event->fields : NULL, evt, &JObj); - - kazoo_event_add_timestamp(evt, JObj); - - if(profile->fields) - kazoo_event_add_fields_to_json(&logging, JObj, evt, profile->fields->head); - - if(event && event->fields) - kazoo_event_add_fields_to_json(&logging, JObj, evt, event->fields->head); - - message->JObj = JObj; - - - return message; - - -} - -kazoo_message_ptr kazoo_message_create_fetch(switch_event_t* evt, kazoo_fetch_profile_ptr profile) -{ - kazoo_message_ptr message; - cJSON *JObj = NULL; - kazoo_logging_t logging; - - logging.levels = profile->logging; - logging.event_name = switch_event_get_header_nil(evt, "Event-Name"); - logging.profile_name = profile->name; - - message = malloc(sizeof(kazoo_message_t)); - if(message == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n"); - return NULL; - } - memset(message, 0, sizeof(kazoo_message_t)); - - - kazoo_event_init_json(profile->fields, NULL, evt, &JObj); - - kazoo_event_add_timestamp(evt, JObj); - - if(profile->fields) - kazoo_event_add_fields_to_json(&logging, JObj, evt, profile->fields->head); - - message->JObj = JObj; - - - return message; - - -} - - -void kazoo_message_destroy(kazoo_message_ptr *msg) -{ - if (!msg || !*msg) return; - if((*msg)->JObj != NULL) - cJSON_Delete((*msg)->JObj); - switch_safe_free(*msg); - -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_message.h b/src/mod/event_handlers/mod_kazoo/kazoo_message.h deleted file mode 100644 index eade6c4e7b..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_message.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#ifndef KAZOO_MESSAGE_H -#define KAZOO_MESSAGE_H - -#include - -typedef struct { - uint64_t timestamp; - uint64_t start; - uint64_t filter; - uint64_t serialize; - uint64_t print; - uint64_t rk; -} kazoo_message_times_t, *kazoo_message_times_ptr; - -typedef struct { - cJSON *JObj; -} kazoo_message_t, *kazoo_message_ptr; - -void kazoo_cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); -cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_field_ptr field); -kazoo_message_ptr kazoo_message_create_event(switch_event_t* evt, kazoo_event_ptr event, kazoo_event_profile_ptr profile); -kazoo_message_ptr kazoo_message_create_fetch(switch_event_t* evt, kazoo_fetch_profile_ptr profile); - -void kazoo_message_destroy(kazoo_message_ptr *msg); - - -#endif /* KAZOO_MESSAGE_H */ - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c deleted file mode 100644 index f75c327023..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c +++ /dev/null @@ -1,1694 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Andrew Thompson - * Rob Charlton - * Darren Schreiber - * Mike Jerris - * Tamas Cseke - * - * - * handle_msg.c -- handle messages received from erlang nodes - * - */ -#include "mod_kazoo.h" - -struct api_command_struct_s { - char *cmd; - char *arg; - ei_node_t *ei_node; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - erlang_pid pid; - switch_memory_pool_t *pool; -}; -typedef struct api_command_struct_s api_command_struct_t; - -static char *REQUEST_ATOMS[] = { - "noevents", - "exit", - "link", - "nixevent", - "sendevent", - "sendmsg", - "commands", - "command", - "bind", - "getpid", - "version", - "bgapi", - "api", - "event", - "fetch_reply", - "config", - "bgapi4", - "api4", - "json_api" -}; - -typedef enum { - REQUEST_NOEVENTS, - REQUEST_EXIT, - REQUEST_LINK, - REQUEST_NIXEVENT, - REQUEST_SENDEVENT, - REQUEST_SENDMSG, - REQUEST_COMMANDS, - REQUEST_COMMAND, - REQUEST_BIND, - REQUEST_GETPID, - REQUEST_VERSION, - REQUEST_BGAPI, - REQUEST_API, - REQUEST_EVENT, - REQUEST_FETCH_REPLY, - REQUEST_CONFIG, - REQUEST_BGAPI4, - REQUEST_API4, - REQUEST_JSON_API, - REQUEST_MAX -} request_atoms_t; - -static switch_status_t find_request(char *atom, int *request) { - int i; - for (i = 0; i < REQUEST_MAX; i++) { - if(!strncmp(atom, REQUEST_ATOMS[i], MAXATOMLEN)) { - *request = i; - return SWITCH_STATUS_SUCCESS; - } - } - - return SWITCH_STATUS_FALSE; -} - -static void destroy_node_handler(ei_node_t *ei_node) { - int pending = 0; - void *pop; - switch_memory_pool_t *pool = ei_node->pool; - - switch_clear_flag(ei_node, LFLAG_RUNNING); - - /* wait for pending bgapi requests to complete */ - while ((pending = switch_atomic_read(&ei_node->pending_bgapi))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d pending bgapi requests to complete\n", pending); - switch_yield(500000); - } - - /* wait for receive handlers to complete */ - while ((pending = switch_atomic_read(&ei_node->receive_handlers))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d receive handlers to complete\n", pending); - switch_yield(500000); - } - - switch_mutex_lock(ei_node->event_streams_mutex); - remove_event_streams(&ei_node->event_streams); - switch_mutex_unlock(ei_node->event_streams_mutex); - - remove_xml_clients(ei_node); - - while (switch_queue_trypop(ei_node->received_msgs, &pop) == SWITCH_STATUS_SUCCESS) { - ei_received_msg_t *received_msg = (ei_received_msg_t *) pop; - - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - - while (switch_queue_trypop(ei_node->send_msgs, &pop) == SWITCH_STATUS_SUCCESS) { - ei_send_msg_t *send_msg = (ei_send_msg_t *) pop; - - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - close_socketfd(&ei_node->nodefd); - - switch_mutex_destroy(ei_node->event_streams_mutex); - - switch_core_destroy_memory_pool(&pool); -} - -static switch_status_t add_to_ei_nodes(ei_node_t *this_ei_node) { - switch_thread_rwlock_wrlock(kazoo_globals.ei_nodes_lock); - - if (!kazoo_globals.ei_nodes) { - kazoo_globals.ei_nodes = this_ei_node; - } else { - this_ei_node->next = kazoo_globals.ei_nodes; - kazoo_globals.ei_nodes = this_ei_node; - } - - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t remove_from_ei_nodes(ei_node_t *this_ei_node) { - ei_node_t *ei_node, *prev = NULL; - int found = 0; - - switch_thread_rwlock_wrlock(kazoo_globals.ei_nodes_lock); - - /* try to find the event bindings list for the requestor */ - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - if (ei_node == this_ei_node) { - found = 1; - break; - } - - prev = ei_node; - ei_node = ei_node->next; - } - - if (found) { - if (!prev) { - kazoo_globals.ei_nodes = this_ei_node->next; - } else { - prev->next = ei_node->next; - } - } - - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -void kazoo_event_add_unique_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data) { - if(!switch_event_get_header_ptr(event, header_name)) - switch_event_add_header_string(event, stack, header_name, data); -} - - -SWITCH_DECLARE(switch_status_t) kazoo_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream, char** reply) -{ - switch_api_interface_t *api; - switch_status_t status; - char *arg_used; - char *cmd_used; - int fire_event = 0; - char *arg_expanded = NULL; - switch_event_t* evt; - - switch_assert(stream != NULL); - switch_assert(stream->data != NULL); - switch_assert(stream->write_function != NULL); - - switch_event_create(&evt, SWITCH_EVENT_GENERAL); - arg_expanded = switch_event_expand_headers(evt, arg); - switch_event_destroy(&evt); - - cmd_used = (char *) cmd; - arg_used = arg_expanded; - - if (!stream->param_event) { - switch_event_create(&stream->param_event, SWITCH_EVENT_API); - fire_event = 1; - } - - if (stream->param_event) { - if (cmd_used && *cmd_used) { - switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command", cmd_used); - } - if (arg_used && *arg_used) { - switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument", arg_used); - } - if (arg_expanded && *arg_expanded) { - switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument-Expanded", arg_expanded); - } - } - - - if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) { - if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) { - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Result", "error"); - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Error", stream->data); - } else { - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Result", "success"); - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Output", stream->data); - } - UNPROTECT_INTERFACE(api); - } else { - status = SWITCH_STATUS_FALSE; - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Result", "error"); - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Error", "invalid command"); - } - - if (stream->param_event && fire_event) { - switch_event_fire(&stream->param_event); - } - - if (cmd_used != cmd) { - switch_safe_free(cmd_used); - } - - if (arg_used != arg_expanded) { - switch_safe_free(arg_used); - } - - if (arg_expanded != arg) { - switch_safe_free(arg_expanded); - } - - return status; -} - -static switch_status_t api_exec_stream(char *cmd, char *arg, switch_stream_handle_t *stream, char **reply) { - switch_status_t status = SWITCH_STATUS_FALSE; - - if (kazoo_api_execute(cmd, arg, NULL, stream, reply) != SWITCH_STATUS_SUCCESS) { - if(stream->data && strlen(stream->data)) { - *reply = strdup(stream->data); - status = SWITCH_STATUS_FALSE; - } else { - *reply = switch_mprintf("%s: Command not found", cmd); - status = SWITCH_STATUS_NOTFOUND; - } - } else if (!stream->data || !strlen(stream->data)) { - *reply = switch_mprintf("%s: Command returned no output", cmd); - status = SWITCH_STATUS_SUCCESS; - } else { - *reply = strdup(stream->data); - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -static switch_status_t api_exec(char *cmd, char *arg, char **reply) { - switch_stream_handle_t stream = { 0 }; - switch_status_t status = SWITCH_STATUS_FALSE; - - SWITCH_STANDARD_STREAM(stream); - - status = api_exec_stream(cmd, arg, &stream, reply); - - switch_safe_free(stream.data); - - return status; -} - -static void *SWITCH_THREAD_FUNC bgapi3_exec(switch_thread_t *thread, void *obj) { - api_command_struct_t *acs = (api_command_struct_t *) obj; - switch_memory_pool_t *pool = acs->pool; - char *reply = NULL; - char *cmd = acs->cmd; - char *arg = acs->arg; - ei_node_t *ei_node = acs->ei_node; - ei_send_msg_t *send_msg; - - if(!switch_test_flag(ei_node, LFLAG_RUNNING) || !switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring command while shuting down\n"); - switch_atomic_dec(&ei_node->pending_bgapi); - return NULL; - } - - switch_malloc(send_msg, sizeof(*send_msg)); - memcpy(&send_msg->pid, &acs->pid, sizeof(erlang_pid)); - - ei_x_new_with_version(&send_msg->buf); - - ei_x_encode_tuple_header(&send_msg->buf, 3); - - if (api_exec(cmd, arg, &reply) == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(&send_msg->buf, "bgok"); - } else { - ei_x_encode_atom(&send_msg->buf, "bgerror"); - } - - _ei_x_encode_string(&send_msg->buf, acs->uuid_str); - _ei_x_encode_string(&send_msg->buf, reply); - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send bgapi response %s to %s <%d.%d.%d>\n" - ,acs->uuid_str - ,acs->pid.node - ,acs->pid.creation - ,acs->pid.num - ,acs->pid.serial); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - switch_atomic_dec(&ei_node->pending_bgapi); - - switch_safe_free(reply); - switch_safe_free(acs->arg); - switch_core_destroy_memory_pool(&pool); - - return NULL; -} - - -static void *SWITCH_THREAD_FUNC bgapi4_exec(switch_thread_t *thread, void *obj) { - api_command_struct_t *acs = (api_command_struct_t *) obj; - switch_memory_pool_t *pool = acs->pool; - char *reply = NULL; - char *cmd = acs->cmd; - char *arg = acs->arg; - ei_node_t *ei_node = acs->ei_node; - ei_send_msg_t *send_msg; - switch_stream_handle_t stream = { 0 }; - - if(!switch_test_flag(ei_node, LFLAG_RUNNING) || !switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring command while shuting down\n"); - switch_atomic_dec(&ei_node->pending_bgapi); - return NULL; - } - - SWITCH_STANDARD_STREAM(stream); - switch_event_create(&stream.param_event, SWITCH_EVENT_API); - - switch_malloc(send_msg, sizeof(*send_msg)); - memcpy(&send_msg->pid, &acs->pid, sizeof(erlang_pid)); - - ei_x_new_with_version(&send_msg->buf); - ei_x_encode_tuple_header(&send_msg->buf, (stream.param_event ? 4 : 3)); - - if (api_exec_stream(cmd, arg, &stream, &reply) == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(&send_msg->buf, "bgok"); - } else { - ei_x_encode_atom(&send_msg->buf, "bgerror"); - } - - _ei_x_encode_string(&send_msg->buf, acs->uuid_str); - _ei_x_encode_string(&send_msg->buf, reply); - - if (stream.param_event) { - ei_encode_switch_event_headers_2(&send_msg->buf, stream.param_event, 0); - } - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send bgapi response %s to %s <%d.%d.%d>\n" - ,acs->uuid_str - ,acs->pid.node - ,acs->pid.creation - ,acs->pid.num - ,acs->pid.serial); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - switch_atomic_dec(&ei_node->pending_bgapi); - - if (stream.param_event) { - switch_event_fire(&stream.param_event); - } - - switch_safe_free(reply); - switch_safe_free(acs->arg); - switch_core_destroy_memory_pool(&pool); - switch_safe_free(stream.data); - - return NULL; -} - -static void log_sendmsg_request(char *uuid, switch_event_t *event) -{ - char *cmd = switch_event_get_header(event, "call-command"); - unsigned long cmd_hash; - switch_ssize_t hlen = -1; - unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen); - unsigned long CMD_XFEREXT = switch_hashfunc_default("xferext", &hlen); - - if (zstr(cmd)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|invalid \n", uuid); - DUMP_EVENT(event); - return; - } - - cmd_hash = switch_hashfunc_default(cmd, &hlen); - - if (cmd_hash == CMD_EXECUTE) { - char *app_name = switch_event_get_header(event, "execute-app-name"); - char *app_arg = switch_event_get_header(event, "execute-app-arg"); - - if(app_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|executing %s %s \n", uuid, app_name, switch_str_nil(app_arg)); - } - } else if (cmd_hash == CMD_XFEREXT) { - switch_event_header_t *hp; - - for (hp = event->headers; hp; hp = hp->next) { - char *app_name; - char *app_arg; - - if (!strcasecmp(hp->name, "application")) { - app_name = strdup(hp->value); - app_arg = strchr(app_name, ' '); - - if (app_arg) { - *app_arg++ = '\0'; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|building xferext extension: %s %s\n", uuid, app_name, app_arg); - switch_safe_free(app_name); - } - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|transfered call to xferext extension\n", uuid); - } -} - -static switch_status_t build_event(switch_event_t *event, ei_x_buff * buf) { - int propslist_length, arity; - int n=0; - - if(!event) { - return SWITCH_STATUS_FALSE; - } - - if (ei_decode_list_header(buf->buff, &buf->index, &propslist_length)) { - return SWITCH_STATUS_FALSE; - } - - while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && n < propslist_length) { - char key[1024]; - char *value; - - if (arity != 2) { - return SWITCH_STATUS_FALSE; - } - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(key), key)) { - return SWITCH_STATUS_FALSE; - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &value)) { - return SWITCH_STATUS_FALSE; - } - - if (!strcmp(key, "body")) { - switch_safe_free(event->body); - event->body = value; - } else { - if(!strcasecmp(key, "Call-ID")) { - switch_core_session_t *session = NULL; - if(!zstr(value)) { - if ((session = switch_core_session_locate(value)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_event_set_data(channel, event); - switch_core_session_rwunlock(session); - } - } - } - switch_event_add_header_string_nodup(event, SWITCH_STACK_BOTTOM, key, value); - } - n++; - } - ei_skip_term(buf->buff, &buf->index); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t erlang_response_badarg(ei_x_buff * rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "error"); - ei_x_encode_atom(rbuf, "badarg"); - } - - return SWITCH_STATUS_GENERR; -} - -static switch_status_t erlang_response_baduuid(ei_x_buff * rbuf) { - if (rbuf) { - ei_x_format_wo_ver(rbuf, "{~a,~a}", "error", "baduuid"); - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t erlang_response_notimplemented(ei_x_buff * rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "error"); - ei_x_encode_atom(rbuf, "not_implemented"); - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t erlang_response_ok(ei_x_buff *rbuf) { - if (rbuf) { - ei_x_encode_atom(rbuf, "ok"); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t erlang_response_ok_uuid(ei_x_buff *rbuf, const char * uuid) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - ei_x_encode_binary(rbuf, uuid, strlen(uuid)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_noevents(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - ei_event_stream_t *event_stream; - - switch_mutex_lock(ei_node->event_streams_mutex); - if ((event_stream = find_event_stream(ei_node->event_streams, pid))) { - remove_event_bindings(event_stream); - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_exit(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_link(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - ei_link(ei_node, ei_self(&kazoo_globals.ei_cnode), pid); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_nixevent(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char event_name[MAXATOMLEN + 1]; - switch_event_types_t event_type; - ei_event_stream_t *event_stream; - int custom = 0, length = 0; - int i; - - if (ei_decode_list_header(buf->buff, &buf->index, &length) - || length == 0) { - return erlang_response_badarg(rbuf); - } - - switch_mutex_lock(ei_node->event_streams_mutex); - if (!(event_stream = find_event_stream(ei_node->event_streams, pid))) { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_ok(rbuf); - } - - for (i = 1; i <= length; i++) { - if (ei_decode_atom_safe(buf->buff, &buf->index, event_name)) { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_badarg(rbuf); - } - - if (custom) { - remove_event_binding(event_stream, SWITCH_EVENT_CUSTOM, event_name); - } else if (switch_name_event(event_name, &event_type) == SWITCH_STATUS_SUCCESS) { - switch (event_type) { - - case SWITCH_EVENT_CUSTOM: - custom++; - break; - - case SWITCH_EVENT_ALL: - { - switch_event_types_t type; - for (type = 0; type < SWITCH_EVENT_ALL; type++) { - if(type != SWITCH_EVENT_CUSTOM) { - remove_event_binding(event_stream, type, NULL); - } - } - break; - } - - default: - remove_event_binding(event_stream, event_type, NULL); - } - } else { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_badarg(rbuf); - } - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_sendevent(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char event_name[MAXATOMLEN + 1]; - char subclass_name[MAXATOMLEN + 1]; - switch_event_types_t event_type; - switch_event_t *event = NULL; - - if (ei_decode_atom_safe(buf->buff, &buf->index, event_name) - || switch_name_event(event_name, &event_type) != SWITCH_STATUS_SUCCESS) - { - return erlang_response_badarg(rbuf); - } - - if (!strncasecmp(event_name, "CUSTOM", MAXATOMLEN)) { - if(ei_decode_atom(buf->buff, &buf->index, subclass_name)) { - return erlang_response_badarg(rbuf); - } - switch_event_create_subclass(&event, event_type, subclass_name); - } else { - switch_event_create(&event, event_type); - } - - if (build_event(event, buf) == SWITCH_STATUS_SUCCESS) { - switch_event_fire(&event); - return erlang_response_ok(rbuf); - } - - if(event) { - switch_event_destroy(&event); - } - - return erlang_response_badarg(rbuf); -} - -static switch_status_t handle_request_command(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_core_session_t *session; - switch_event_t *event = NULL; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_uuid_t cmd_uuid; - char cmd_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str)) { - return erlang_response_badarg(rbuf); - } - - if (zstr_buf(uuid_str) || !(session = switch_core_session_locate(uuid_str))) { - return erlang_response_baduuid(rbuf); - } - - switch_uuid_get(&cmd_uuid); - switch_uuid_format(cmd_uuid_str, &cmd_uuid); - - switch_event_create(&event, SWITCH_EVENT_COMMAND); - if (build_event(event, buf) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - return erlang_response_badarg(rbuf); - } - - log_sendmsg_request(uuid_str, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-uuid", cmd_uuid_str); - - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); - switch_core_session_rwunlock(session); - - return erlang_response_ok_uuid(rbuf, cmd_uuid_str); -} - -static switch_status_t handle_request_commands(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_core_session_t *session; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - int propslist_length, n; - switch_uuid_t cmd_uuid; - char cmd_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str)) { - return erlang_response_badarg(rbuf); - } - - if (zstr_buf(uuid_str) || !(session = switch_core_session_locate(uuid_str))) { - return erlang_response_baduuid(rbuf); - } - - switch_uuid_get(&cmd_uuid); - switch_uuid_format(cmd_uuid_str, &cmd_uuid); - - if (ei_decode_list_header(buf->buff, &buf->index, &propslist_length)) { - switch_core_session_rwunlock(session); - return SWITCH_STATUS_FALSE; - } - - for(n = 0; n < propslist_length; n++) { - switch_event_t *event = NULL; - switch_event_create(&event, SWITCH_EVENT_COMMAND); - if (build_event(event, buf) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - return erlang_response_badarg(rbuf); - } - log_sendmsg_request(uuid_str, event); - if(n == (propslist_length - 1)) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-uuid", cmd_uuid_str); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-uuid", "null"); -// switch_event_del_header_val(event, "event-uuid-name", NULL); - } - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); - } - - switch_core_session_rwunlock(session); - - return erlang_response_ok_uuid(rbuf, cmd_uuid_str); - -} - -static switch_status_t handle_request_sendmsg(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_core_session_t *session; - switch_event_t *event = NULL; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str)) { - return erlang_response_badarg(rbuf); - } - - if (zstr_buf(uuid_str) || !(session = switch_core_session_locate(uuid_str))) { - return erlang_response_baduuid(rbuf); - } - - switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE); - if (build_event(event, buf) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - return erlang_response_badarg(rbuf); - } - - log_sendmsg_request(uuid_str, event); - - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); - switch_core_session_rwunlock(session); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_config(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - - fetch_config(); - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_bind(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char section_str[MAXATOMLEN + 1]; - switch_xml_section_t section; - - if (ei_decode_atom_safe(buf->buff, &buf->index, section_str) - || !(section = switch_xml_parse_section_string(section_str))) { - return erlang_response_badarg(rbuf); - } - - switch(section) { - case SWITCH_XML_SECTION_CONFIG: - add_fetch_handler(ei_node, pid, kazoo_globals.config_fetch_binding); - if(!kazoo_globals.config_fetched) { - kazoo_globals.config_fetched = 1; - fetch_config(); - } - break; - case SWITCH_XML_SECTION_DIRECTORY: - add_fetch_handler(ei_node, pid, kazoo_globals.directory_fetch_binding); - break; - case SWITCH_XML_SECTION_DIALPLAN: - add_fetch_handler(ei_node, pid, kazoo_globals.dialplan_fetch_binding); - break; - case SWITCH_XML_SECTION_CHANNELS: - add_fetch_handler(ei_node, pid, kazoo_globals.channels_fetch_binding); - break; - case SWITCH_XML_SECTION_LANGUAGES: - add_fetch_handler(ei_node, pid, kazoo_globals.languages_fetch_binding); - break; - case SWITCH_XML_SECTION_CHATPLAN: - add_fetch_handler(ei_node, pid, kazoo_globals.chatplan_fetch_binding); - break; - default: - return erlang_response_badarg(rbuf); - } - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_getpid(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - ei_x_encode_pid(rbuf, ei_self(&kazoo_globals.ei_cnode)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_version(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - _ei_x_encode_string(rbuf, VERSION); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_bgapi(switch_thread_start_t func, ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - api_command_struct_t *acs = NULL; - switch_memory_pool_t *pool; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_uuid_t uuid; - char cmd[MAXATOMLEN + 1]; - - if (ei_decode_atom_safe(buf->buff, &buf->index, cmd)) { - return erlang_response_badarg(rbuf); - } - - switch_core_new_memory_pool(&pool); - acs = switch_core_alloc(pool, sizeof(*acs)); - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &acs->arg)) { - switch_core_destroy_memory_pool(&pool); - return erlang_response_badarg(rbuf); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "bgexec: %s(%s)\n", cmd, acs->arg); - - acs->pool = pool; - acs->ei_node = ei_node; - acs->cmd = switch_core_strdup(pool, cmd); - memcpy(&acs->pid, pid, sizeof(erlang_pid)); - - switch_threadattr_create(&thd_attr, acs->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - - switch_uuid_get(&uuid); - switch_uuid_format(acs->uuid_str, &uuid); - switch_thread_create(&thread, thd_attr, func, acs, acs->pool); - - switch_atomic_inc(&ei_node->pending_bgapi); - - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - _ei_x_encode_string(rbuf, acs->uuid_str); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_bgapi3(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - return handle_request_bgapi(bgapi3_exec, ei_node, pid, buf, rbuf); -} - -static switch_status_t handle_request_bgapi4(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - return handle_request_bgapi(bgapi4_exec, ei_node, pid, buf, rbuf); -} - -static switch_status_t handle_request_api4(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char cmd[MAXATOMLEN + 1]; - char *arg; - switch_stream_handle_t stream = { 0 }; - - SWITCH_STANDARD_STREAM(stream); - switch_event_create(&stream.param_event, SWITCH_EVENT_API); - - if (ei_decode_atom_safe(buf->buff, &buf->index, cmd)) { - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { - return erlang_response_badarg(rbuf); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "exec: %s(%s)\n", cmd, arg); - - if (rbuf) { - char *reply; - switch_status_t status; - - status = api_exec_stream(cmd, arg, &stream, &reply); - - if (status == SWITCH_STATUS_SUCCESS) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - } else { - ei_x_encode_tuple_header(rbuf, (stream.param_event ? 3 : 2)); - ei_x_encode_atom(rbuf, "error"); - } - - _ei_x_encode_string(rbuf, reply); - - if (stream.param_event && status != SWITCH_STATUS_SUCCESS) { - ei_encode_switch_event_headers(rbuf, stream.param_event); - } - - switch_safe_free(reply); - } - - if (stream.param_event) { - switch_event_fire(&stream.param_event); - } - - switch_safe_free(arg); - switch_safe_free(stream.data); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_json_api(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) -{ - char *arg; - cJSON *jcmd = NULL; - switch_core_session_t *session = NULL; - const char *uuid = NULL; - char *response = NULL; - const char *parse_end = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { - return erlang_response_badarg(rbuf); - } - - jcmd = cJSON_ParseWithOpts(arg, &parse_end, 0); - - if (!jcmd) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "json api error: %s\n", parse_end); - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "error"); - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "parse_error"); - _ei_x_encode_string(rbuf, parse_end); - switch_safe_free(arg); - return status; - } - - if ((uuid = cJSON_GetObjectCstr(jcmd, "uuid"))) { - if (!(session = switch_core_session_locate(uuid))) { - cJSON_Delete(jcmd); - switch_safe_free(arg); - return erlang_response_baduuid(rbuf); - } - } - - status = switch_json_api_execute(jcmd, session, NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "json api (%i): %s\n", status , arg); - - response = cJSON_PrintUnformatted(jcmd); - ei_x_encode_tuple_header(rbuf, 2); - if (status == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(rbuf, "ok"); - } else { - ei_x_encode_atom(rbuf, "error"); - } - _ei_x_encode_string(rbuf, response); - switch_safe_free(response); - - cJSON_Delete(jcmd); - switch_safe_free(arg); - - if (session) { - switch_core_session_rwunlock(session); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_api(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char cmd[MAXATOMLEN + 1]; - char *arg; - - if (ei_decode_atom_safe(buf->buff, &buf->index, cmd)) { - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { - return erlang_response_badarg(rbuf); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "exec: %s(%s)\n", cmd, arg); - - if (rbuf) { - char *reply; - - ei_x_encode_tuple_header(rbuf, 2); - - if (api_exec(cmd, arg, &reply) == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(rbuf, "ok"); - } else { - ei_x_encode_atom(rbuf, "error"); - } - - _ei_x_encode_string(rbuf, reply); - switch_safe_free(reply); - } - - switch_safe_free(arg); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_event(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char event_name[MAXATOMLEN + 1]; - ei_event_stream_t *event_stream; - int length = 0; - int i; - - if (ei_decode_list_header(buf->buff, &buf->index, &length) || !length) { - return erlang_response_badarg(rbuf); - } - - switch_mutex_lock(ei_node->event_streams_mutex); - if (!(event_stream = find_event_stream(ei_node->event_streams, pid))) { - event_stream = new_event_stream(ei_node, pid); - /* ensure we are notified if the requesting processes dies so we can clean up */ - ei_link(ei_node, ei_self(&kazoo_globals.ei_cnode), pid); - } - - for (i = 1; i <= length; i++) { - if (ei_decode_atom_safe(buf->buff, &buf->index, event_name)) { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_badarg(rbuf); - } - add_event_binding(event_stream, event_name); - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_string(rbuf, ei_node->local_ip); - ei_x_encode_ulong(rbuf, get_stream_port(event_stream)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_fetch_reply(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char section_str[MAXATOMLEN + 1]; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - char *xml_str; - switch_xml_section_t section; - switch_status_t result; - - if (ei_decode_atom_safe(buf->buff, &buf->index, section_str) - || !(section = switch_xml_parse_section_string(section_str))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without a configuration section\n"); - - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str) - || zstr_buf(uuid_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without request UUID\n"); - - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &xml_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without XML : %s \n", uuid_str); - - return erlang_response_badarg(rbuf); - } - - if (zstr(xml_str)) { - switch_safe_free(xml_str); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring an empty fetch reply : %s\n", uuid_str); - - return erlang_response_badarg(rbuf); - } - - switch(section) { - case SWITCH_XML_SECTION_CONFIG: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.config_fetch_binding); - break; - case SWITCH_XML_SECTION_DIRECTORY: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.directory_fetch_binding); - break; - case SWITCH_XML_SECTION_DIALPLAN: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.dialplan_fetch_binding); - break; - case SWITCH_XML_SECTION_CHANNELS: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.channels_fetch_binding); - break; - case SWITCH_XML_SECTION_LANGUAGES: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.languages_fetch_binding); - break; - case SWITCH_XML_SECTION_CHATPLAN: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.chatplan_fetch_binding); - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received fetch reply %s for an unknown configuration section: %s : %s\n", uuid_str, section_str, xml_str); - switch_safe_free(xml_str); - - return erlang_response_badarg(rbuf); - } - - if (result == SWITCH_STATUS_SUCCESS) { - switch_safe_free(xml_str); - - return erlang_response_ok(rbuf); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received fetch reply %s is unknown or has expired : %s\n", uuid_str, xml_str); - switch_safe_free(xml_str); - - return erlang_response_baduuid(rbuf); - } -} - -static switch_status_t handle_kazoo_request(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char atom[MAXATOMLEN + 1]; - int type, size, arity = 0, request; - - /* ...{_, _}} | ...atom()} = Buf */ - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Type) */ - if (type == ERL_SMALL_TUPLE_EXT) { - /* ..._, _} = Buf */ - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - } - - if (ei_decode_atom_safe(buf->buff, &buf->index, atom)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received mod_kazoo message that did not contain a command (ensure you are using Kazoo v2.14+).\n"); - return erlang_response_badarg(rbuf); - } - - if (find_request(atom, &request) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received mod_kazoo message for unimplemented feature (ensure you are using Kazoo v2.14+): %s\n", atom); - return erlang_response_badarg(rbuf); - } - - switch(request) { - case REQUEST_NOEVENTS: - return handle_request_noevents(ei_node, pid, buf, rbuf); - case REQUEST_EXIT: - return handle_request_exit(ei_node, pid, buf, rbuf); - case REQUEST_LINK: - return handle_request_link(ei_node, pid, buf, rbuf); - case REQUEST_NIXEVENT: - return handle_request_nixevent(ei_node, pid, buf, rbuf); - case REQUEST_SENDEVENT: - return handle_request_sendevent(ei_node, pid, buf, rbuf); - case REQUEST_SENDMSG: - return handle_request_sendmsg(ei_node, pid, buf, rbuf); - case REQUEST_COMMAND: - return handle_request_command(ei_node, pid, buf, rbuf); - case REQUEST_COMMANDS: - return handle_request_commands(ei_node, pid, buf, rbuf); - case REQUEST_BIND: - return handle_request_bind(ei_node, pid, buf, rbuf); - case REQUEST_GETPID: - return handle_request_getpid(ei_node, pid, buf, rbuf); - case REQUEST_VERSION: - return handle_request_version(ei_node, pid, buf, rbuf); - case REQUEST_BGAPI: - return handle_request_bgapi3(ei_node, pid, buf, rbuf); - case REQUEST_API: - return handle_request_api(ei_node, pid, buf, rbuf); - case REQUEST_EVENT: - return handle_request_event(ei_node, pid, buf, rbuf); - case REQUEST_FETCH_REPLY: - return handle_request_fetch_reply(ei_node, pid, buf, rbuf); - case REQUEST_CONFIG: - return handle_request_config(ei_node, pid, buf, rbuf); - case REQUEST_BGAPI4: - return handle_request_bgapi4(ei_node, pid, buf, rbuf); - case REQUEST_API4: - return handle_request_api4(ei_node, pid, buf, rbuf); - case REQUEST_JSON_API: - return handle_request_json_api(ei_node, pid, buf, rbuf); - default: - return erlang_response_notimplemented(rbuf); - } -} - -static switch_status_t handle_mod_kazoo_request(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - char atom[MAXATOMLEN + 1]; - int version, type, size, arity; - - buf->index = 0; - ei_decode_version(buf->buff, &buf->index, &version); - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Type) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message of an unexpected type (ensure you are using Kazoo v2.14+).\n"); - return SWITCH_STATUS_GENERR; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - if (ei_decode_atom_safe(buf->buff, &buf->index, atom)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message tuple that did not start with an atom (ensure you are using Kazoo v2.14+).\n"); - return SWITCH_STATUS_GENERR; - } - - /* {'$gen_cast', {_, _}} = Buf */ - if (arity == 2 && !strncmp(atom, "$gen_cast", 9)) { - return handle_kazoo_request(ei_node, &msg->from, buf, NULL); - /* {'$gen_call', {_, _}, {_, _}} = Buf */ - } else if (arity == 3 && !strncmp(atom, "$gen_call", 9)) { - switch_status_t status; - ei_send_msg_t *send_msg = NULL; - erlang_ref ref; - - switch_malloc(send_msg, sizeof(*send_msg)); - ei_x_new_with_version(&send_msg->buf); - - /* ...{_, _}, {_, _}} = Buf */ - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Type) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang call message of an unexpected type (ensure you are using Kazoo v2.14+).\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; - } - - /* ..._, _}, {_, _}} = Buf */ - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* ...pid(), _}, {_, _}} = Buf */ - if (ei_decode_pid(buf->buff, &buf->index, &send_msg->pid)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang call without a reply pid (ensure you are using Kazoo v2.14+).\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; - } - - /* ...ref()}, {_, _}} = Buf */ - if (ei_decode_ref(buf->buff, &buf->index, &ref)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang call without a reply tag (ensure you are using Kazoo v2.14+).\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; - } - - /* send_msg->buf = {ref(), ... */ - ei_x_encode_tuple_header(&send_msg->buf, 2); - ei_x_encode_ref(&send_msg->buf, &ref); - - status = handle_kazoo_request(ei_node, &msg->from, buf, &send_msg->buf); - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error queuing reply\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - return status; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received inappropriate erlang message (ensure you are using Kazoo v2.14+)\n"); - return SWITCH_STATUS_GENERR; - } -} - -/* fake enough of the net_kernel module to be able to respond to net_adm:ping */ -static switch_status_t handle_net_kernel_request(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - int version, size, type, arity; - char atom[MAXATOMLEN + 1]; - ei_send_msg_t *send_msg = NULL; - erlang_ref ref; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel message, attempting to reply\n"); - - switch_malloc(send_msg, sizeof(*send_msg)); - ei_x_new_with_version(&send_msg->buf); - - buf->index = 0; - ei_decode_version(buf->buff, &buf->index, &version); - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Buff) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel message of an unexpected type\n"); - goto error; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* {_, _, _} = Buf */ - if (arity != 3) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel tuple has an unexpected arity\n"); - goto error; - } - - /* {'$gen_call', _, _} = Buf */ - if (ei_decode_atom_safe(buf->buff, &buf->index, atom) || strncmp(atom, "$gen_call", 9)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel message tuple does not begin with the atom '$gen_call'\n"); - goto error; - } - - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* {_, Sender, _}=Buff, is_tuple(Sender) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Second element of the net_kernel tuple is an unexpected type\n"); - goto error; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* {_, _}=Sender */ - if (arity != 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Second element of the net_kernel message has an unexpected arity\n"); - goto error; - } - - /* {Pid, Ref}=Sender */ - if (ei_decode_pid(buf->buff, &buf->index, &send_msg->pid) || ei_decode_ref(buf->buff, &buf->index, &ref)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unable to decode erlang pid or ref of the net_kernel tuple second element\n"); - goto error; - } - - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* {_, _, Request}=Buff, is_tuple(Request) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Third element of the net_kernel message is an unexpected type\n"); - goto error; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* {_, _}=Request */ - if (arity != 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Third element of the net_kernel message has an unexpected arity\n"); - goto error; - } - - /* {is_auth, _}=Request */ - if (ei_decode_atom_safe(buf->buff, &buf->index, atom) || strncmp(atom, "is_auth", MAXATOMLEN)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "The net_kernel message third element does not begin with the atom 'is_auth'\n"); - goto error; - } - - /* To ! {Tag, Reply} */ - ei_x_encode_tuple_header(&send_msg->buf, 2); - ei_x_encode_ref(&send_msg->buf, &ref); - ei_x_encode_atom(&send_msg->buf, "yes"); - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to queue net kernel message\n"); - goto error; - } - - return SWITCH_STATUS_SUCCESS; - -error: - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; -} - -static switch_status_t handle_erl_send(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - if (!strncmp(msg->toname, "net_kernel", MAXATOMLEN)) { - return handle_net_kernel_request(ei_node, msg, buf); - } else if (!strncmp(msg->toname, "mod_kazoo", MAXATOMLEN)) { - return handle_mod_kazoo_request(ei_node, msg, buf); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message to unknown process \"%s\" (ensure you are using Kazoo v2.14+).\n", msg->toname); - return SWITCH_STATUS_GENERR; - } -} - -static switch_status_t handle_erl_msg(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - switch (msg->msgtype) { - case ERL_SEND: - case ERL_REG_SEND: - return handle_erl_send(ei_node, msg, buf); - case ERL_LINK: - /* we received an erlang link request? Should we be linking or are they linking to us and this just informs us? */ - return SWITCH_STATUS_SUCCESS; - case ERL_UNLINK: - /* we received an erlang unlink request? Same question as the ERL_LINK, are we expected to do something? */ - return SWITCH_STATUS_SUCCESS; - case ERL_EXIT: - /* we received a notice that a process we were linked to has exited, clean up any bindings */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received erlang exit notice for %s <%d.%d.%d>\n", msg->from.node, msg->from.creation, msg->from.num, msg->from.serial); - - switch_mutex_lock(ei_node->event_streams_mutex); - remove_event_stream(&ei_node->event_streams, &msg->from); - switch_mutex_unlock(ei_node->event_streams_mutex); - - remove_fetch_handlers(ei_node, &msg->from); - return SWITCH_STATUS_SUCCESS; - case ERL_EXIT2: - /* erlang nodes appear to send both the old and new style exit notices so just ignore these */ - return SWITCH_STATUS_FALSE; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Received unexpected erlang message type %d\n", (int) (msg->msgtype)); - return SWITCH_STATUS_FALSE; - } -} - -static void *SWITCH_THREAD_FUNC receive_handler(switch_thread_t *thread, void *obj) { - ei_node_t *ei_node = (ei_node_t *) obj; - - switch_atomic_inc(&kazoo_globals.threads); - switch_atomic_inc(&ei_node->receive_handlers); - - switch_assert(ei_node != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting erlang receive handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - while (switch_test_flag(ei_node, LFLAG_RUNNING) && switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - void *pop = NULL; - - if (ei_queue_pop(ei_node->received_msgs, &pop, ei_node->receiver_queue_timeout) == SWITCH_STATUS_SUCCESS) { - ei_received_msg_t *received_msg = (ei_received_msg_t *) pop; - handle_erl_msg(ei_node, &received_msg->msg, &received_msg->buf); - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutdown erlang receive handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - switch_atomic_dec(&ei_node->receive_handlers); - switch_atomic_dec(&kazoo_globals.threads); - - return NULL; -} - -static void *SWITCH_THREAD_FUNC handle_node(switch_thread_t *thread, void *obj) { - ei_node_t *ei_node = (ei_node_t *) obj; - ei_received_msg_t *received_msg = NULL; - int fault_count = 0; - - switch_atomic_inc(&kazoo_globals.threads); - - switch_assert(ei_node != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting node request handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - add_to_ei_nodes(ei_node); - - while (switch_test_flag(ei_node, LFLAG_RUNNING) && switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - int status; - int send_msg_count = 0; - void *pop = NULL; - - if (!received_msg) { - switch_malloc(received_msg, sizeof(*received_msg)); - /* create a new buf for the erlang message and a rbuf for the reply */ - if(kazoo_globals.receive_msg_preallocate > 0) { - switch_malloc(received_msg->buf.buff, kazoo_globals.receive_msg_preallocate); - received_msg->buf.buffsz = kazoo_globals.receive_msg_preallocate; - received_msg->buf.index = 0; - if(received_msg->buf.buff == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not pre-allocate memory for mod_kazoo message\n"); - goto exit; - } - } else { - ei_x_new(&received_msg->buf); - } - } else { - received_msg->buf.index = 0; - } - - while (++send_msg_count <= kazoo_globals.send_msg_batch - && ei_queue_pop(ei_node->send_msgs, &pop, ei_node->sender_queue_timeout) == SWITCH_STATUS_SUCCESS) { - ei_send_msg_t *send_msg = (ei_send_msg_t *) pop; - ei_helper_send(ei_node, &send_msg->pid, &send_msg->buf); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sent erlang message to %s <%d.%d.%d>\n" - ,send_msg->pid.node - ,send_msg->pid.creation - ,send_msg->pid.num - ,send_msg->pid.serial); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - /* wait for a erlang message, or timeout to check if the module is still running */ - status = ei_xreceive_msg_tmo(ei_node->nodefd, &received_msg->msg, &received_msg->buf, kazoo_globals.ei_receive_timeout); - - switch (status) { - case ERL_TICK: - /* erlang nodes send ticks to eachother to validate they are still reachable, we dont have to do anything here */ - fault_count = 0; - break; - case ERL_MSG: - fault_count = 0; - - if (kazoo_globals.receive_msg_preallocate > 0 && received_msg->buf.buffsz > kazoo_globals.receive_msg_preallocate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "increased received message buffer size to %d\n", received_msg->buf.buffsz); - } - - if (switch_queue_trypush(ei_node->received_msgs, received_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to push erlang received message from %s <%d.%d.%d> into queue\n", received_msg->msg.from.node, received_msg->msg.from.creation, received_msg->msg.from.num, received_msg->msg.from.serial); - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - - received_msg = NULL; - break; - case ERL_ERROR: - switch (erl_errno) { - case ETIMEDOUT: - case EAGAIN: - /* if ei_xreceive_msg_tmo just timed out, ignore it and let the while loop check if we are still running */ - /* the erlang lib just wants us to try to receive again, so we will! */ - fault_count = 0; - break; - case EMSGSIZE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang communication fault with node %p %s (%s:%d): my spoon is too big\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - switch_clear_flag(ei_node, LFLAG_RUNNING); - break; - case EIO: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Erlang communication fault with node %p %s (%s:%d): socket closed or I/O error [fault count %d]\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, ++fault_count); - - if (fault_count >= kazoo_globals.io_fault_tolerance) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - } else { - switch_sleep(kazoo_globals.io_fault_tolerance_sleep); - } - - break; - default: - /* OH NOS! something has gone horribly wrong, shutdown the connection if status set by ei_xreceive_msg_tmo is less than or equal to 0 */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang communication fault with node %p %s (%s:%d): erl_errno=%d errno=%d\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, erl_errno, errno); - if (status < 0) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - } - break; - } - break; - default: - /* HUH? didnt plan for this, whatevs shutdown the connection if status set by ei_xreceive_msg_tmo is less than or equal to 0 */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang receive status %p %s (%s:%d): %d\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, status); - if (status < 0) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - } - break; - } - } - - exit: - - if (received_msg) { - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - - remove_from_ei_nodes(ei_node); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutdown erlang node handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - destroy_node_handler(ei_node); - - switch_atomic_dec(&kazoo_globals.threads); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutdown Complete for erlang node handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - return NULL; -} - -/* Create a thread to wait for messages from an erlang node and process them */ -switch_status_t new_kazoo_node(int nodefd, ErlConnect *conn) { - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool = NULL; - switch_sockaddr_t *sa; - ei_node_t *ei_node; - int i = 0; - - /* create memory pool for this erlang node */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: Too bad drinking scotch isn't a paying job or Kenny's dad would be a millionare!\n"); - return SWITCH_STATUS_MEMERR; - } - - /* from the erlang node's memory pool, allocate some memory for the structure */ - if (!(ei_node = switch_core_alloc(pool, sizeof (*ei_node)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: Stan, don't you know the first law of physics? Anything that's fun costs at least eight dollars.\n"); - return SWITCH_STATUS_MEMERR; - } - - memset(ei_node, 0, sizeof(*ei_node)); - - /* store the location of our pool */ - ei_node->pool = pool; - - /* save the file descriptor that the erlang interface lib uses to communicate with the new node */ - ei_node->nodefd = nodefd; - ei_node->peer_nodename = switch_core_strdup(ei_node->pool, conn->nodename); - ei_node->created_time = switch_micro_time_now(); - ei_node->legacy = kazoo_globals.legacy_events; - ei_node->event_stream_framing = kazoo_globals.event_stream_framing; - ei_node->event_stream_keepalive = kazoo_globals.event_stream_keepalive; - ei_node->event_stream_queue_timeout = kazoo_globals.event_stream_queue_timeout; - ei_node->receiver_queue_timeout = kazoo_globals.node_receiver_queue_timeout; - ei_node->sender_queue_timeout = kazoo_globals.node_sender_queue_timeout; - - /* store the IP and node name we are talking with */ - switch_os_sock_put(&ei_node->socket, (switch_os_socket_t *)&nodefd, pool); - - switch_socket_addr_get(&sa, SWITCH_TRUE, ei_node->socket); - ei_node->remote_port = switch_sockaddr_get_port(sa); - switch_get_addr(ei_node->remote_ip, sizeof (ei_node->remote_ip), sa); - - switch_socket_addr_get(&sa, SWITCH_FALSE, ei_node->socket); - ei_node->local_port = switch_sockaddr_get_port(sa); - switch_get_addr(ei_node->local_ip, sizeof (ei_node->local_ip), sa); - - switch_queue_create(&ei_node->send_msgs, MAX_QUEUE_LEN, pool); - switch_queue_create(&ei_node->received_msgs, MAX_QUEUE_LEN, pool); - - switch_mutex_init(&ei_node->event_streams_mutex, SWITCH_MUTEX_DEFAULT, pool); - - /* when we start we are running */ - switch_set_flag(ei_node, LFLAG_RUNNING); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "New erlang connection from node %s (%s:%d) -> (%s:%d)\n", ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, ei_node->local_ip, ei_node->local_port); - - for(i = 0; i < kazoo_globals.node_worker_threads; i++) { - switch_threadattr_create(&thd_attr, ei_node->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, receive_handler, ei_node, ei_node->pool); - } - - switch_threadattr_create(&thd_attr, ei_node->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, handle_node, ei_node, ei_node->pool); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c deleted file mode 100644 index e647871855..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Luis Azedo - * - * mod_hacks.c -- hacks with state handlers - * - */ -#include "mod_kazoo.h" - -static char *TWEAK_NAMES[] = { - "interaction-id", - "export-vars", - "switch-uri", - "replaces-call-id", - "loopback-vars", - "caller-id", - "transfers", - "bridge", - "bridge-replaces-aleg", - "bridge-replaces-call-id", - "bridge-variables", - "restore-caller-id-on-blind-xfer" -}; - -static const char *bridge_variables[] = { - "Call-Control-Queue", - "Call-Control-PID", - "Call-Control-Node", - INTERACTION_VARIABLE, - "ecallmgr_Ecallmgr-Node", - "sip_h_k-cid", - "Switch-URI", - "Switch-URL", - NULL -}; - -static switch_status_t kz_tweaks_signal_bridge_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *my_event; - - const char *peer_uuid = switch_channel_get_variable(channel, "Bridge-B-Unique-ID"); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid); - - if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid); - switch_channel_event_set_data(channel, my_event); - switch_event_fire(&my_event); - } - - return SWITCH_STATUS_SUCCESS; -} - -static const switch_state_handler_table_t kz_tweaks_signal_bridge_state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ kz_tweaks_signal_bridge_on_hangup, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ NULL -}; - -static void kz_tweaks_handle_bridge_variables(switch_event_t *event) -{ - switch_core_session_t *a_session = NULL, *b_session = NULL; - const char *a_leg = switch_event_get_header(event, "Bridge-A-Unique-ID"); - const char *b_leg = switch_event_get_header(event, "Bridge-B-Unique-ID"); - const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed"); - int i; - - if (!kz_test_tweak(KZ_TWEAK_BRIDGE_VARIABLES)) return; - - if(reentry) return; - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg); - - if (a_leg && (a_session = switch_core_session_locate(a_leg)) != NULL) { - switch_channel_t *a_channel = switch_core_session_get_channel(a_session); - switch_channel_timetable_t *a_times = switch_channel_get_timetable(a_channel); - if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - switch_channel_timetable_t *b_times = switch_channel_get_timetable(b_channel); - if (a_times->created <= b_times->created) { - for(i = 0; bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1); - switch_channel_set_variable(b_channel, bridge_variables[i], val); - } - } else { - for(i = 0; bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_FALSE, -1); - switch_channel_set_variable(a_channel, bridge_variables[i], val); - } - } - switch_core_session_rwunlock(b_session); - } - switch_core_session_rwunlock(a_session); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg); - } -} - -static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) -{ - switch_event_t *my_event; - - const char *replaced_call_id = switch_event_get_header(event, "variable_sip_replaces_call_id"); - const char *peer_uuid = switch_event_get_header(event, "Unique-ID"); - const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed"); - - if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID)) return; - - if(reentry) return; - - if(replaced_call_id) { - switch_core_session_t *call_session = NULL; - const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID"); - if (call_id && (call_session = switch_core_session_locate(call_id)) != NULL) { - switch_channel_t *call_channel = switch_core_session_get_channel(call_session); - if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(call_session)); - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid); - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-Event-Processed", "true"); - switch_channel_event_set_data(call_channel, my_event); - switch_event_fire(&my_event); - } - switch_channel_set_variable(call_channel, "Bridge-B-Unique-ID", peer_uuid); - switch_channel_add_state_handler(call_channel, &kz_tweaks_signal_bridge_state_handlers); - switch_core_session_rwunlock(call_session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", call_id); - } - } -} - -static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event) -{ - if (!kz_test_tweak(KZ_TWEAK_BRIDGE)) return; - - kz_tweaks_handle_bridge_replaces_call_id(event); - kz_tweaks_handle_bridge_variables(event); -} - -// TRANSFERS - -static void kz_tweaks_channel_replaced_event_handler(switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *replaced_by = switch_event_get_header(event, "att_xfer_replaced_by"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REPLACED : %s , %s\n", uuid, replaced_by); -} - -static void kz_tweaks_channel_intercepted_event_handler(switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *peer_uuid = switch_event_get_header(event, "intercepted_by"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "INTERCEPTED : %s => %s\n", uuid, peer_uuid); -} - -static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event) -{ - switch_core_session_t *uuid_session = NULL; - switch_event_t *evt = NULL; - const char *uuid = switch_event_get_header(event, "Unique-ID"); - - const char *orig_call_id = switch_event_get_header(event, "att_xfer_original_call_id"); - const char *dest_peer_uuid = switch_event_get_header(event, "att_xfer_destination_peer_uuid"); - const char *dest_call_id = switch_event_get_header(event, "att_xfer_destination_call_id"); - - const char *file = switch_event_get_header(event, "Event-Calling-File"); - const char *func = switch_event_get_header(event, "Event-Calling-Function"); - const char *line = switch_event_get_header(event, "Event-Calling-Line-Number"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR : %s , %s , %s, %s, %s , %s , %s \n", uuid, orig_call_id, dest_peer_uuid, dest_call_id, file, func, line); - if ((uuid_session = switch_core_session_locate(uuid)) != NULL) { - switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session); - const char* interaction_id = switch_channel_get_variable_dup(uuid_channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - // set to uuid & peer_uuid - if(interaction_id != NULL) { - switch_core_session_t *session = NULL; - if(dest_call_id && (session = switch_core_session_locate(dest_call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING UUID PRV : %s : %s\n", prv_interaction_id, interaction_id); - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, evt); - switch_event_fire(&evt); - } - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO UUID SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - if(dest_peer_uuid && (session = switch_core_session_locate(dest_peer_uuid)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id); - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, evt); - switch_event_fire(&evt); - } - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO PEER SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - if(orig_call_id && (session = switch_core_session_locate(orig_call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id); - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, evt); - switch_event_fire(&evt); - } - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO PEER SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR ID = NULL : %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - switch_core_session_rwunlock(uuid_session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SESSION NOT FOUND : %s\n", uuid); - } -} - -static void kz_tweaks_channel_transferee_event_handler(switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *replaced_by_uuid = switch_event_get_header(event, "att_xfer_replaced_call_id"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEREE : %s replaced by %s\n", uuid, replaced_by_uuid); -} - -// END TRANSFERS - - -static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_t *a_channel = NULL; - const char * loopback_leg = NULL; - const char * loopback_aleg = NULL; - switch_core_session_t *a_session = NULL; - switch_event_t *event = NULL; - switch_event_header_t *header = NULL; - switch_event_t *to_add = NULL; - switch_event_t *to_remove = NULL; - switch_caller_profile_t *caller; - int n = 0; - - if (!kz_test_tweak(KZ_TWEAK_LOOPBACK_VARS)) { - return SWITCH_STATUS_SUCCESS; - } - - caller = switch_channel_get_caller_profile(channel); - if(strncmp(caller->source, "mod_loopback", 12)) - return SWITCH_STATUS_SUCCESS; - - if((loopback_leg = switch_channel_get_variable(channel, "loopback_leg")) == NULL) - return SWITCH_STATUS_SUCCESS; - - if(strncmp(loopback_leg, "B", 1)) - return SWITCH_STATUS_SUCCESS; - - switch_channel_get_variables(channel, &event); - switch_event_create_plain(&to_add, SWITCH_EVENT_CHANNEL_DATA); - switch_event_create_plain(&to_remove, SWITCH_EVENT_CHANNEL_DATA); - - for(header = event->headers; header; header = header->next) { - if(!strncmp(header->name, "Export-Loopback-", 16)) { - kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "%s", header->name+16); - switch_channel_set_variable(channel, header->name, NULL); - n++; - } else if(!strncmp(header->name, "sip_loopback_", 13)) { - kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "sip_%s", header->name+13); - } else if(!strncmp(header->name, "ecallmgr_", 9)) { - switch_event_add_header_string(to_remove, SWITCH_STACK_BOTTOM, header->name, header->value); - } - } - if(n) { - for(header = to_remove->headers; header; header = header->next) { - switch_channel_set_variable(channel, header->name, NULL); - } - } - - for(header = to_add->headers; header; header = header->next) { - switch_channel_set_variable(channel, header->name, header->value); - } - - // cleanup leg A - loopback_aleg = switch_channel_get_variable(channel, "other_loopback_leg_uuid"); - if(loopback_aleg != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found loopback a-leg uuid - %s\n", loopback_aleg); - if ((a_session = switch_core_session_locate(loopback_aleg))) { - a_channel = switch_core_session_get_channel(a_session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found loopback session a - %s\n", loopback_aleg); - switch_channel_del_variable_prefix(a_channel, "Export-Loopback-"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Couldn't locate loopback session a - %s\n", loopback_aleg); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Couldn't find loopback a-leg uuid!\n"); - } - - /* - * set Interaction-ID - * if we're not crossing account boundaries - */ - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - if (a_channel) { - const char *interaction_id = switch_channel_get_variable_dup(a_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - const char *a_account_id = switch_channel_get_variable_dup(a_channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); - const char *b_account_id = switch_channel_get_variable_dup(channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); - if ((!a_account_id) || (!b_account_id) || (!strcmp(a_account_id, b_account_id))) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - } - } - } - - if (a_session){ - switch_core_session_rwunlock(a_session); - } - switch_event_destroy(&event); - switch_event_destroy(&to_add); - switch_event_destroy(&to_remove); - - return SWITCH_STATUS_SUCCESS; - -} - -static void kz_tweaks_handle_caller_id(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_CALLER_ID)) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t* caller = switch_channel_get_caller_profile(channel); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); - if (caller && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - const char* val = NULL; - if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) { - caller->caller_id_name = val; - caller->orig_caller_id_name = val; - } - if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Number"))) { - caller->caller_id_number = val; - caller->orig_caller_id_number = val; - } - } - } -} - -static switch_status_t kz_tweaks_handle_nightmare_xfer_interaction_id(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - switch_core_session_t *replace_session = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *replaced_call_id = switch_channel_get_variable(channel, "sip_replaces_call_id"); - const char *core_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-From-Core-UUID"); - const char *partner_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-Refer-Partner-UUID"); - const char *interaction_id = switch_channel_get_variable(channel, "sip_h_X-FS-Call-Interaction-ID"); - if(core_uuid && partner_uuid && replaced_call_id && interaction_id) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "checking nightmare xfer tweak for %s\n", switch_channel_get_uuid(channel)); - if ((replace_session = switch_core_session_locate(replaced_call_id))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); - switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); - switch_core_session_rwunlock(replace_session); - } - if ((replace_session = switch_core_session_locate(partner_uuid))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); - switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); - switch_core_session_rwunlock(replace_session); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_tweaks_handle_replaces_call_id(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_REPLACES_CALL_ID)) { - switch_core_session_t *replace_call_session = NULL; - switch_event_t *event; - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *replaced_call_id = switch_channel_get_variable(channel, "sip_replaces_call_id"); - const char *core_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-From-Core-UUID"); - if((!core_uuid) && replaced_call_id) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id); - if ((replace_call_session = switch_core_session_locate(replaced_call_id))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session); - int i; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting bridge variables from %s to %s\n", replaced_call_id, switch_channel_get_uuid(channel)); - for(i = 0; bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(replaced_call_channel, bridge_variables[i], SWITCH_TRUE, -1); - switch_channel_set_variable(channel, bridge_variables[i], val); - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - switch_core_session_rwunlock(replace_call_session); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - - -static switch_status_t kz_tweaks_handle_switch_uri(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - if (kz_test_tweak(KZ_TWEAK_SWITCH_URI)) { - const char *profile_url = switch_channel_get_variable(channel, "sofia_profile_url"); - if(profile_url) { - int n = strcspn(profile_url, "@"); - switch_channel_set_variable(channel, "Switch-URL", profile_url); - switch_channel_set_variable_printf(channel, "Switch-URI", "sip:%s", n > 0 ? profile_url + n + 1 : profile_url); - } - } - - return SWITCH_STATUS_SUCCESS; - -} - -static char * kz_tweaks_new_interaction_id() -{ - long int first = (switch_micro_time_now() / 1000000) + UNIX_EPOCH_IN_GREGORIAN; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_uuid_t uuid; - switch_uuid_get(&uuid); - switch_uuid_format(uuid_str, &uuid); - uuid_str[8] = '\0'; - return switch_mprintf("%ld-%s", first, uuid_str); -} - -static void kz_tweaks_handle_interaction_id(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - char * val = NULL; - switch_core_session_t *peer_session = NULL; - const char* peer_interaction_id = NULL; - - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - val = kz_tweaks_new_interaction_id(); - if (val) { - switch_channel_set_variable(channel, "Original-"INTERACTION_VARIABLE, val); - if(switch_core_session_get_partner(session, &peer_session) == SWITCH_STATUS_SUCCESS) { - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - peer_interaction_id = switch_channel_get_variable_dup(peer_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "PEER_SESSION => %s\n", peer_interaction_id); - if(peer_interaction_id) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, peer_interaction_id); - } - switch_core_session_rwunlock(peer_session); - } else if (!switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, val); - } - } - - switch_safe_free(val); - } - -} - -static switch_status_t kz_outgoing_channel(switch_core_session_t * session, switch_event_t * event, switch_caller_profile_t * cp, switch_core_session_t * peer_session, switch_originate_flag_t flag) -{ - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "GOT OUTGOING\n"); - if (peer_session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SESSION && PEER_SESSION => %s\n", interaction_id ); - if (interaction_id) { - switch_channel_set_variable(peer_channel, INTERACTION_VARIABLE, interaction_id); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO SESSION && PEER_SESSION\n"); - } - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_tweaks_register_handle_blind_xfer(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER)) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_set_variable(channel, "execute_on_blind_transfer", "kz_restore_caller_id"); - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_tweaks_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "checking tweaks for %s\n", switch_channel_get_uuid(channel)); - switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); - switch_core_event_hook_add_outgoing_channel(session, kz_outgoing_channel); - kz_tweaks_handle_interaction_id(session); - kz_tweaks_handle_switch_uri(session); - kz_tweaks_handle_caller_id(session); - kz_tweaks_handle_nightmare_xfer_interaction_id(session); - kz_tweaks_handle_replaces_call_id(session); - kz_tweaks_handle_loopback(session); - kz_tweaks_register_handle_blind_xfer(session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_state_handler_table_t kz_tweaks_state_handlers = { - /*.on_init */ kz_tweaks_on_init, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ NULL -}; - - -static void kz_tweaks_register_state_handlers() -{ -/* - * we may need two handlers - * one with SSH_FLAG_PRE_EXEC - * and another without it - * mod_loopback tweaks needs post-init (SSH_FLAG_PRE_EXEC off) - * - * kz_tweaks_state_handlers.flags = SSH_FLAG_PRE_EXEC; - * - */ - switch_core_add_state_handler(&kz_tweaks_state_handlers); -} - -static void kz_tweaks_unregister_state_handlers() -{ - switch_core_remove_state_handler(&kz_tweaks_state_handlers); -} - -static void kz_tweaks_bind_events() -{ - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CHANNEL_BRIDGE, SWITCH_EVENT_SUBCLASS_ANY, kz_tweaks_channel_bridge_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::replaced", kz_tweaks_channel_replaced_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::intercepted", kz_tweaks_channel_intercepted_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::transferor", kz_tweaks_channel_transferor_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::transferee", kz_tweaks_channel_transferee_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } -} - -static void kz_tweaks_unbind_events() -{ - switch_event_unbind_callback(kz_tweaks_channel_bridge_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_replaced_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_intercepted_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_transferor_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_transferee_event_handler); -} - -void kz_tweaks_add_core_variables() -{ - switch_core_set_variable("UNIX_EPOCH_IN_GREGORIAN", UNIX_EPOCH_IN_GREGORIAN_STR); -} - -void kz_tweaks_start() -{ - kz_tweaks_add_core_variables(); - kz_tweaks_register_state_handlers(); - kz_tweaks_bind_events(); -} - -void kz_tweaks_stop() -{ - kz_tweaks_unbind_events(); - kz_tweaks_unregister_state_handlers(); -} - -SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak) -{ - return TWEAK_NAMES[tweak]; -} - -SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type) -{ - kz_tweak_t x; - for (x = 0; x < KZ_TWEAK_MAX; x++) { - if (!strcasecmp(name, TWEAK_NAMES[x])) { - *type = x; - return SWITCH_STATUS_SUCCESS; - } - } - - return SWITCH_STATUS_FALSE; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ - - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h deleted file mode 100644 index 11cf5f6561..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include - -typedef enum { - KZ_TWEAK_INTERACTION_ID, - KZ_TWEAK_EXPORT_VARS, - KZ_TWEAK_SWITCH_URI, - KZ_TWEAK_REPLACES_CALL_ID, - KZ_TWEAK_LOOPBACK_VARS, - KZ_TWEAK_CALLER_ID, - KZ_TWEAK_TRANSFERS, - KZ_TWEAK_BRIDGE, - KZ_TWEAK_BRIDGE_REPLACES_ALEG, - KZ_TWEAK_BRIDGE_REPLACES_CALL_ID, - KZ_TWEAK_BRIDGE_VARIABLES, - KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER, - - /* No new flags below this line */ - KZ_TWEAK_MAX -} kz_tweak_t; - -void kz_tweaks_start(); -void kz_tweaks_stop(); -SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak); -SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type); - - -#define kz_test_tweak(flag) (kazoo_globals.tweaks[flag] ? 1 : 0) -#define kz_set_tweak(flag) kazoo_globals.tweaks[flag] = 1 -#define kz_clear_tweak(flag) kazoo_globals.tweaks[flag] = 0 - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c deleted file mode 100644 index 951707d179..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Andrew Thompson - * Rob Charlton - * Karl Anderson - * - * Original from mod_erlang_event. - * ei_helpers.c -- helper functions for ei - * - */ -#include "mod_kazoo.h" - -#define kz_resize(l) {\ -char *dp;\ -olen += (len + l + block);\ -cpos = c - data;\ -if ((dp = realloc(data, olen))) {\ - data = dp;\ - c = data + cpos;\ - memset(c, 0, olen - cpos);\ - }} \ - - -void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val) -{ - int idx = 0; - while(kazoo_globals.profile_vars_prefixes[idx] != NULL) { - char *prefix = kazoo_globals.profile_vars_prefixes[idx]; - if (!strncasecmp(var, prefix, strlen(prefix))) { - switch_channel_set_profile_var(channel, var + strlen(prefix), val); - - } - idx++; - } -} - -SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event) -{ - switch_event_t *global_vars; - switch_status_t status = switch_core_get_variables(&global_vars); - if(status == SWITCH_STATUS_SUCCESS) { - switch_event_merge(event, global_vars); - switch_event_destroy(&global_vars); - } - return status; -} - -SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event) -{ - switch_status_t status = SWITCH_STATUS_GENERR; - *event = NULL; - if(switch_event_create(event, SWITCH_EVENT_GENERAL) == SWITCH_STATUS_SUCCESS) { - status = kz_switch_core_merge_variables(*event); - } - return status; -} - -SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream) -{ - switch_api_interface_t *api; - switch_status_t status; - char *arg_used; - char *cmd_used; - - switch_assert(stream != NULL); - switch_assert(stream->data != NULL); - switch_assert(stream->write_function != NULL); - - cmd_used = switch_strip_whitespace(cmd); - arg_used = switch_strip_whitespace(arg); - - if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "executing [%s] => [%s]\n", cmd_used, arg_used); - if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "COMMAND RETURNED ERROR!\n"); - } - UNPROTECT_INTERFACE(api); - } else { - status = SWITCH_STATUS_FALSE; - stream->write_function(stream, "INVALID COMMAND!\n"); - } - - if (cmd_used != cmd) { - switch_safe_free(cmd_used); - } - - if (arg_used != arg) { - switch_safe_free(arg_used); - } - - return status; -} - - -SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur) -{ - char *p, *c = NULL; - char *data, *indup, *endof_indup; - size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128; - const char *sub_val = NULL; - char *cloned_sub_val = NULL, *expanded_sub_val = NULL; - char *func_val = NULL; - int nv = 0; - char *gvar = NULL, *sb = NULL; - - if (recur > 100) { - return (char *) in; - } - - if (zstr(in)) { - return (char *) in; - } - - nv = switch_string_var_check_const(in) || switch_string_has_escaped_data(in); - - if (!nv) { - return (char *) in; - } - - nv = 0; - olen = strlen(in) + 1; - indup = strdup(in); - switch_assert(indup); - endof_indup = end_of_p(indup) + 1; - - if ((data = malloc(olen))) { - memset(data, 0, olen); - c = data; - for (p = indup; p && p < endof_indup && *p; p++) { - int global = 0; - vtype = 0; - - if (*p == '\\') { - if (*(p + 1) == '$') { - nv = 1; - p++; - if (*(p + 1) == '$') { - p++; - } - } else if (*(p + 1) == '\'') { - p++; - continue; - } else if (*(p + 1) == '\\') { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = *p++; - len++; - continue; - } - } - - if (*p == '$' && !nv) { - if (*(p + 1) == '$') { - p++; - global++; - } - - if (*(p + 1)) { - if (*(p + 1) == '{') { - vtype = global ? 3 : 1; - } else { - nv = 1; - } - } else { - nv = 1; - } - } - - if (nv) { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = *p; - len++; - nv = 0; - continue; - } - - if (vtype) { - char *s = p, *e, *vname, *vval = NULL; - size_t nlen; - - s++; - - if ((vtype == 1 || vtype == 3) && *s == '{') { - br = 1; - s++; - } - - e = s; - vname = s; - while (*e) { - if (br == 1 && *e == '}') { - br = 0; - *e++ = '\0'; - break; - } - - if (br > 0) { - if (e != s && *e == '{') { - br++; - } else if (br > 1 && *e == '}') { - br--; - } - } - - e++; - } - p = e > endof_indup ? endof_indup : e; - - vval = NULL; - for(sb = vname; sb && *sb; sb++) { - if (*sb == ' ') { - vval = sb; - break; - } else if (*sb == '(') { - vval = sb; - br = 1; - break; - } - } - - if (vval) { - e = vval - 1; - *vval++ = '\0'; - - while (*e == ' ') { - *e-- = '\0'; - } - e = vval; - - while (e && *e) { - if (*e == '(') { - br++; - } else if (br > 1 && *e == ')') { - br--; - } else if (br == 1 && *e == ')') { - *e = '\0'; - break; - } - e++; - } - - vtype = 2; - } - - if (vtype == 1 || vtype == 3) { - char *expanded = NULL; - int offset = 0; - int ooffset = 0; - char *ptr; - int idx = -1; - - if ((expanded = kz_event_expand_headers_check(event, (char *) vname, var_list, api_list, recur+1)) == vname) { - expanded = NULL; - } else { - vname = expanded; - } - if ((ptr = strchr(vname, ':'))) { - *ptr++ = '\0'; - offset = atoi(ptr); - if ((ptr = strchr(ptr, ':'))) { - ptr++; - ooffset = atoi(ptr); - } - } - - if ((ptr = strchr(vname, '[')) && strchr(ptr, ']')) { - *ptr++ = '\0'; - idx = atoi(ptr); - } - - if (vtype == 3 || !(sub_val = switch_event_get_header_idx(event, vname, idx))) { - switch_safe_free(gvar); - if ((gvar = switch_core_get_variable_dup(vname))) { - sub_val = gvar; - } - - if (var_list && !switch_event_check_permission_list(var_list, vname)) { - sub_val = ""; - } - - - if ((expanded_sub_val = kz_event_expand_headers_check(event, sub_val, var_list, api_list, recur+1)) == sub_val) { - expanded_sub_val = NULL; - } else { - sub_val = expanded_sub_val; - } - } - - if (sub_val) { - if (offset || ooffset) { - cloned_sub_val = strdup(sub_val); - switch_assert(cloned_sub_val); - sub_val = cloned_sub_val; - } - - if (offset >= 0) { - sub_val += offset; - } else if ((size_t) abs(offset) <= strlen(sub_val)) { - sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset); - } - - if (ooffset > 0 && (size_t) ooffset < strlen(sub_val)) { - if ((ptr = (char *) sub_val + ooffset)) { - *ptr = '\0'; - } - } - } - - switch_safe_free(expanded); - } else { - char *expanded = NULL; - char *expanded_vname = NULL; - - if ((expanded_vname = kz_event_expand_headers_check(event, (char *) vname, var_list, api_list, recur+1)) == vname) { - expanded_vname = NULL; - } else { - vname = expanded_vname; - } - - if ((expanded = kz_event_expand_headers_check(event, vval, var_list, api_list, recur+1)) == vval) { - expanded = NULL; - } else { - vval = expanded; - } - - if (!switch_core_test_flag(SCF_API_EXPANSION) || (api_list && !switch_event_check_permission_list(api_list, vname))) { - func_val = NULL; - sub_val = ""; - } else { - switch_stream_handle_t stream = { 0 }; - - SWITCH_STANDARD_STREAM(stream); - stream.param_event = event; - if (kz_expand_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) { - func_val = stream.data; - sub_val = func_val; - } else { - free(stream.data); - } - } - - switch_safe_free(expanded); - switch_safe_free(expanded_vname); - } - if ((nlen = sub_val ? strlen(sub_val) : 0)) { - if (len + nlen >= olen) { - kz_resize(nlen); - } - - len += nlen; - strcat(c, sub_val); - c += nlen; - } - - switch_safe_free(func_val); - switch_safe_free(cloned_sub_val); - switch_safe_free(expanded_sub_val); - sub_val = NULL; - vname = NULL; - br = 0; - } - - if (sp) { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = ' '; - sp = 0; - len++; - } - - if (*p == '$') { - p--; - } else { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = *p; - len++; - } - } - } - free(indup); - switch_safe_free(gvar); - - return data; -} - -SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in) -{ - return kz_event_expand_headers_check(event, in, NULL, NULL, 0); -} - -SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool, switch_event_t *event, char *val) -{ - char *expanded; - char *dup = NULL; - - expanded = kz_event_expand_headers(event, val); - dup = switch_core_strdup(pool, expanded); - - if (expanded != val) { - free(expanded); - } - - return dup; -} - -SWITCH_DECLARE(char *) kz_expand(const char *in, const char *uuid) -{ - switch_event_t *event = NULL; - char *ret = NULL; - kz_switch_core_base_headers_for_expand(&event); - if (uuid != NULL) { - switch_core_session_t *nsession = NULL; - if ((nsession = switch_core_session_locate(uuid))) { - switch_channel_event_set_data(switch_core_session_get_channel(nsession), event); - switch_core_session_rwunlock(nsession); - } - } - ret = kz_event_expand_headers_check(event, in, NULL, NULL, 0); - switch_event_destroy(&event); - return ret; -} - -SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in) -{ - char *expanded; - char *dup = NULL; - - if(!(expanded = kz_expand(in, NULL))) { - return NULL; - } - dup = switch_core_strdup(pool, expanded); - - if (expanded != in) { - switch_safe_free(expanded); - } - - return dup; -} - -char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]) -{ - switch_event_header_t *header = NULL; - int i = 0; - while(list[i] != NULL) { - if((header = switch_event_get_header_ptr(event, list[i])) != NULL) - break; - i++; - } - if(header != NULL) { - return header->value; - } else { - return "nodomain"; - } -} - -SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...) -{ - int ret = 0; - char *varname; - va_list ap; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_assert(event != NULL); - - - va_start(ap, fmt); - ret = switch_vasprintf(&varname, fmt, ap); - va_end(ap); - - if (ret == -1) { - return SWITCH_STATUS_MEMERR; - } - - status = switch_event_add_header_string(event, stack, varname, val); - - free(varname); - - return status; -} - -SWITCH_DECLARE(switch_status_t) kz_expand_json_to_event(cJSON *json, switch_event_t *event, char * prefix) -{ - char * fmt = switch_mprintf("%s%s%%s", prefix ? prefix : "", prefix ? "_" : ""); - if (event) { - cJSON *item = NULL; - char *response = NULL; - cJSON_ArrayForEach(item, json) { - if (item->type == cJSON_String) { - response = strdup(item->valuestring); - } else if (item->type == cJSON_Object) { - char * fmt1 = switch_mprintf(fmt, item->string); - kz_expand_json_to_event(item, event, fmt1); - switch_safe_free(fmt1); - continue; - } else { - response = cJSON_PrintUnformatted(item); - } - kz_switch_event_add_variable_name_printf(event, SWITCH_STACK_BOTTOM, response, fmt, item->string); - switch_safe_free(response); - } - } - - switch_safe_free(fmt); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_xml_t) kz_xml_child(switch_xml_t xml, const char *name) -{ - xml = (xml) ? xml->child : NULL; - while (xml && strcasecmp(name, xml->name)) - xml = xml->sibling; - return xml; -} - -void kz_xml_process(switch_xml_t cfg) -{ - switch_xml_t xml_process; - for (xml_process = kz_xml_child(cfg, "X-PRE-PROCESS"); xml_process; xml_process = xml_process->next) { - const char *cmd = switch_xml_attr(xml_process, "cmd"); - const char *data = switch_xml_attr(xml_process, "data"); - if(cmd != NULL && !strcasecmp(cmd, "set") && data) { - char *name = (char *) data; - char *val = strchr(name, '='); - - if (val) { - char *ve = val++; - while (*val && *val == ' ') { - val++; - } - *ve-- = '\0'; - while (*ve && *ve == ' ') { - *ve-- = '\0'; - } - } - - if (name && val) { - switch_core_set_variable(name, val); - } - } - } - -} - -void kz_event_decode(switch_event_t *event) -{ - switch_event_header_t *hp; - int i; - for (hp = event->headers; hp; hp = hp->next) { - if (strncmp(hp->name, "_json_", 6)) { - if (hp->idx) { - for(i = 0; i < hp->idx; i++) { - switch_url_decode(hp->array[i]); - } - } else { - switch_url_decode(hp->value); - } - } - } -} - -void kz_expand_headers(switch_event_t *resolver, switch_event_t *event) { - switch_event_t *clone = NULL; - switch_event_header_t *header = NULL; - switch_event_create_plain(&clone, event->event_id); - - for(header = event->headers; header; header = header->next) { - char *expanded = kz_event_expand_headers(resolver, header->value); - if (expanded != header->value) { - switch_event_add_header_string(clone, SWITCH_STACK_BOTTOM, header->name, expanded); - switch_safe_free(expanded); - } - } - - /* we don't want to force unique headers - * so we delete and then merge - */ - for(header = clone->headers; header; header = header->next) { - switch_event_del_header(event, header->name); - } - - switch_event_merge(event, clone); - - switch_event_destroy(&clone); -} - -void kz_expand_headers_self(switch_event_t *event) { - kz_expand_headers(event, event); -} - -char * kz_expand_vars(char *xml_str) { - return kz_expand_vars_pool(xml_str, NULL); -} - -char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool) { - char *var, *val; - char *rp = xml_str; /* read pointer */ - char *ep, *wp, *buff; /* end pointer, write pointer, write buffer */ - - if (!(strstr(xml_str, "$${"))) { - return xml_str; - } - - switch_zmalloc(buff, strlen(xml_str) * 2); - wp = buff; - ep = buff + (strlen(xml_str) * 2) - 1; - - while (*rp && wp < ep) { - if (*rp == '$' && *(rp + 1) == '$' && *(rp + 2) == '{') { - char *e = switch_find_end_paren(rp + 2, '{', '}'); - - if (e) { - rp += 3; - var = rp; - *e++ = '\0'; - rp = e; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "trying to expand %s \n", var); - if ((val = switch_core_get_variable_dup(var))) { - char *p; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "expanded %s to %s\n", var, val); - for (p = val; p && *p && wp <= ep; p++) { - *wp++ = *p; - } - switch_safe_free(val); - } - continue; - } - } - - *wp++ = *rp++; - } - - *wp++ = '\0'; - - if(pool) { - char * ret = switch_core_strdup(pool, buff); - switch_safe_free(buff); - return ret; - } else { - switch_safe_free(xml_str); - return buff; - } - -} - -switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - cJSON *req = cJSON_CreateObject(); - cJSON_AddItemToObject(req, "command", cJSON_CreateString(command)); - cJSON_AddItemToObject(req, "data", args ? args : cJSON_CreateObject()); - status = switch_json_api_execute(req, NULL, res); - cJSON_Delete(req); - return status; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.h b/src/mod/event_handlers/mod_kazoo/kazoo_utils.h deleted file mode 100644 index cb5549c760..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -#define KZ_BEGIN_EXTERN_C extern "C" { -#define KZ_END_EXTERN_C } -#else -#define KZ_BEGIN_EXTERN_C -#define KZ_END_EXTERN_C -#endif - -KZ_BEGIN_EXTERN_C - -void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val); - -SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event); - -SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event); - -SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream); - -SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur); - -SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in); - -SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool, switch_event_t *event, char *val); - -SWITCH_DECLARE(char *) kz_expand(const char *in, const char *uuid); - -SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in); - -char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]); - -SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...); - -SWITCH_DECLARE(switch_xml_t) kz_xml_child(switch_xml_t xml, const char *name); - -void kz_xml_process(switch_xml_t cfg); -void kz_event_decode(switch_event_t *event); - -char * kz_expand_vars(char *xml_str); -void kz_expand_headers(switch_event_t *resolver, switch_event_t *event); -void kz_expand_headers_self(switch_event_t *event); - -char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool); -switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res); - -SWITCH_DECLARE(switch_status_t) kz_expand_json_to_event(cJSON *json, switch_event_t *event, char * prefix); - -KZ_END_EXTERN_C diff --git a/src/mod/event_handlers/mod_kazoo/kz_node.c b/src/mod/event_handlers/mod_kazoo/kz_node.c deleted file mode 100644 index 1c50d0586e..0000000000 --- a/src/mod/event_handlers/mod_kazoo/kz_node.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "mod_kazoo.h" - -static int kz_nodes_module_names_array_callback(void *pArg, const char *module_name) -{ - cJSON *json = (cJSON *) pArg; - if(!strstr(module_name, "CORE")) { - cJSON_AddItemToArray(json, cJSON_CreateString(module_name)); - } - return 0; -} - -void kz_nodes_collect_media_role(cJSON *container) -{ - cJSON *retval = NULL; - if(kz_json_api("sofia.status.info", NULL, &retval) == SWITCH_STATUS_SUCCESS) { - if(retval != NULL && (!(retval->type & cJSON_NULL))) { - cJSON_AddItemToObject(container, "Media", cJSON_Duplicate(retval, 1)); - } - } - if(retval) { - cJSON_Delete(retval); - } -} - -void kz_nodes_collect_modules(cJSON *container) -{ - cJSON *modules = cJSON_CreateObject(); - cJSON *loaded = cJSON_CreateArray(); - cJSON *available = cJSON_CreateArray(); - switch_loadable_module_enumerate_available(SWITCH_GLOBAL_dirs.mod_dir, kz_nodes_module_names_array_callback, available); - switch_loadable_module_enumerate_loaded(kz_nodes_module_names_array_callback, loaded); - cJSON_AddItemToObject(modules, "available", available); - cJSON_AddItemToObject(modules, "loaded", loaded); - cJSON_AddItemToObject(container, "Modules", modules); -} - -void kz_nodes_collect_runtime(cJSON *container) -{ - cJSON *retval = NULL; - if(kz_json_api("status", NULL, &retval) == SWITCH_STATUS_SUCCESS) { - if(retval != NULL && (!(retval->type & cJSON_NULL))) { - cJSON *val = cJSON_Duplicate(retval, 1); - cJSON_AddItemToObject(val, "Core-UUID", cJSON_CreateString(switch_core_get_uuid())); - cJSON_AddItemToObject(container, "Runtime-Info", val); - } - } - if(retval) { - cJSON_Delete(retval); - } -} - -void kz_nodes_collect_apps(cJSON *container) -{ - cJSON *apps = cJSON_CreateObject(); - cJSON *app = cJSON_CreateObject(); - cJSON_AddItemToObject(app, "Uptime", cJSON_CreateNumber(switch_core_uptime())); - cJSON_AddItemToObject(apps, "freeswitch", app); - cJSON_AddItemToObject(container, "WhApps", apps); -} - -void kz_nodes_collect_roles(cJSON *container) -{ - cJSON *roles = cJSON_CreateObject(); - cJSON_AddItemToObject(container, "Roles", roles); - kz_nodes_collect_media_role(roles); -} - -cJSON * kz_node_create() -{ - cJSON *node = cJSON_CreateObject(); - - kz_nodes_collect_apps(node); - kz_nodes_collect_runtime(node); - kz_nodes_collect_modules(node); - kz_nodes_collect_roles(node); - - return node; -} - -SWITCH_STANDARD_JSON_API(kz_node_info_json_function) -{ - cJSON * ret = kz_node_create(); - *json_reply = ret; - return SWITCH_STATUS_SUCCESS; -} - -void add_kz_node(switch_loadable_module_interface_t **module_interface) -{ - switch_json_api_interface_t *json_api_interface = NULL; - SWITCH_ADD_JSON_API(json_api_interface, "node.info", "JSON node API", kz_node_info_json_function, ""); -} diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c deleted file mode 100644 index 15b8fb469c..0000000000 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * mod_kazoo.c -- Socket Controlled Event Handler - * - */ -#include "mod_kazoo.h" - -kz_globals_t kazoo_globals = {0}; - - - -SWITCH_MODULE_DEFINITION(mod_kazoo, mod_kazoo_load, mod_kazoo_shutdown, mod_kazoo_runtime); - -SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) -{ - kz_erl_init(); - - memset(&kazoo_globals, 0, sizeof(kazoo_globals)); - kazoo_globals.pool = pool; - kz_set_hostname(); - if(kazoo_load_config() != SWITCH_STATUS_SUCCESS) { - // TODO: what would we need to clean up here? - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improper configuration!\n"); - return SWITCH_STATUS_TERM; - } - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - switch_thread_rwlock_create(&kazoo_globals.ei_nodes_lock, pool); - - switch_set_flag(&kazoo_globals, LFLAG_RUNNING); - - /* create all XML fetch agents */ - bind_fetch_agents(); - - /* create an api for cli debug commands */ - add_cli_api(module_interface); - - /* add our modified commands */ - add_kz_commands(module_interface); - - /* add our modified dptools */ - add_kz_dptools(module_interface); - - /* add our endpoints */ - add_kz_endpoints(module_interface); - - /* add our kz_node api */ - add_kz_node(module_interface); - - /* add tweaks */ - kz_tweaks_start(); - - /* add our cdr */ - kz_cdr_start(); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) { - int sanity = 0; - - remove_cli_api(); - - kz_cdr_stop(); - - kz_tweaks_stop(); - - /* stop taking new requests and start shuting down the threads */ - switch_clear_flag(&kazoo_globals, LFLAG_RUNNING); - - /* give everyone time to cleanly shutdown */ - while (switch_atomic_read(&kazoo_globals.threads)) { - switch_yield(100000); - if (++sanity >= 200) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to kill all threads, continuing. This probably wont end well.....good luck!\n"); - break; - } - } - - /* close the connection to epmd and the acceptor */ - close_socketfd(&kazoo_globals.epmdfd); - close_socket(&kazoo_globals.acceptor); - - /* remove all XML fetch agents */ - unbind_fetch_agents(); - - if (kazoo_globals.event_filter) { - switch_core_hash_destroy(&kazoo_globals.event_filter); - } - - switch_thread_rwlock_wrlock(kazoo_globals.ei_nodes_lock); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - switch_thread_rwlock_destroy(kazoo_globals.ei_nodes_lock); - - /* Close the port we reserved for uPnP/Switch behind firewall, if necessary */ - if (kazoo_globals.nat_map && switch_nat_get_type()) { - switch_nat_del_mapping(kazoo_globals.port, SWITCH_NAT_TCP); - } - - kazoo_destroy_config(); - - /* clean up our allocated preferences */ - switch_safe_free(kazoo_globals.ip); - switch_safe_free(kazoo_globals.ei_cookie); - switch_safe_free(kazoo_globals.ei_nodename); - - kz_erl_shutdown(); - - return SWITCH_STATUS_SUCCESS; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h deleted file mode 100644 index 37fdd861e7..0000000000 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_ACL 100 -#define CMD_BUFLEN 1024 * 1000 -#define MAX_QUEUE_LEN 25000 -#define MAX_MISSED 500 -#define MAX_PID_CHARS 255 - -extern const char kz_default_config[]; -extern const int kz_default_config_size; - -#include "kazoo_defs.h" -#include "kazoo_tweaks.h" -#include "kazoo_ei.h" -#include "kazoo_message.h" -#include "kazoo_utils.h" - -typedef enum { - LFLAG_RUNNING = (1 << 0) -} event_flag_t; - - -/* kazoo_commands.c */ -void add_kz_commands(switch_loadable_module_interface_t **module_interface); - -/* kazoo_dptools.c */ -void add_kz_dptools(switch_loadable_module_interface_t **module_interface); - -/* kazoo_api.c */ -void add_cli_api(switch_loadable_module_interface_t **module_interface); -void remove_cli_api(); - -/* kazoo_utils.c */ -/* -SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event); -SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event); -void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val); -char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]); -SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...); -void kz_xml_process(switch_xml_t cfg); -void kz_event_decode(switch_event_t *event); -char * kz_expand_vars(char *xml_str); -char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool); -SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in); -SWITCH_DECLARE(char *) kz_expand(const char *in); -SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in); -switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res); -*/ - -/* kazoo_endpoints.c */ -void add_kz_endpoints(switch_loadable_module_interface_t **module_interface); - -/* kazoo_cdr.c */ -void kz_cdr_start(); -void kz_cdr_stop(); - -/* kazoo_tweaks.c */ -void kz_tweaks_start(); -void kz_tweaks_stop(); -SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak); -SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type); - -/* kazoo_node.c */ -void add_kz_node(switch_loadable_module_interface_t **module_interface); - -SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown); - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ From 49029c8575891b4f3a637d43214d5df323760171 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Wed, 21 Feb 2024 01:47:45 +0000 Subject: [PATCH 110/205] [mod_sofia] Set missing CF_3PCC flag --- src/mod/endpoints/mod_sofia/sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 311052a619..43bd68b923 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7992,6 +7992,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING); } else { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP"); + switch_channel_set_flag(channel, CF_3PCC); switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); switch_channel_set_state(channel, CS_HIBERNATE); From d5ad504723a6bf80fbf80b3c35a2e14ab4111582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Had=C5=BEem=20Had=C5=BEi=C4=87?= Date: Thu, 18 Apr 2024 11:06:40 +0200 Subject: [PATCH 111/205] [mod_vlc] Resolve double mutex lock --- src/mod/formats/mod_vlc/mod_vlc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index af83330d07..6b725515f4 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -1096,7 +1096,8 @@ static switch_status_t vlc_file_read(switch_file_handle_t *handle, void *data, s switch_thread_cond_wait(context->cond, context->cond_mutex); status = libvlc_media_get_state(context->m); } - switch_mutex_lock(context->cond_mutex); + + switch_mutex_unlock(context->cond_mutex); if (context->err == 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VLC error\n"); From ef32d90e91001c39ed261518db423868844a32fd Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 26 Apr 2024 12:41:07 +0000 Subject: [PATCH 112/205] [mod_av] Fix scan-build 14 --- src/mod/applications/mod_av/avcodec.c | 1 - src/mod/applications/mod_av/avformat.c | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 16d268273b..4f0057264e 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -1581,7 +1581,6 @@ GCC_DIAG_ON(deprecated-declarations) } else if (ret == AVERROR(EAGAIN)) { /* we fully drain all the output in each encode call, so this should not ever happen */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder - BUG, should never happen\n"); - ret = AVERROR_BUG; goto error; } else if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending frame to encoder\n"); diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 69475c169f..c1e0052530 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1170,7 +1170,6 @@ GCC_DIAG_ON(deprecated-declarations) } else if (ret == AVERROR(EAGAIN)) { /* we fully drain all the output in each encode call, so this should not ever happen */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder on draining AVERROR_BUG - should never happen\n"); - ret = AVERROR_BUG; goto do_break; } else if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder on draining\n"); @@ -1426,7 +1425,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h av_dump_format(context->fc, 0, filename, 0); - for (i = 0; i< context->fc->nb_streams; i++) { + for (i = 0; i < context->fc->nb_streams; i++) { enum AVMediaType codec_type = av_get_codec_type(context->fc->streams[i]); if (codec_type == AVMEDIA_TYPE_AUDIO && context->has_audio < 2 && idx < 2) { @@ -1554,7 +1553,9 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h if (context->has_audio) { AVCodecContext *c[2] = { NULL }; - c[0] = av_get_codec_context(&context->audio_st[0]); + if (!(c[0] = av_get_codec_context(&context->audio_st[0]))) { + switch_goto_status(SWITCH_STATUS_FALSE, err); + } if ((cc = av_get_codec_context(&context->audio_st[1]))) { c[1] = cc; @@ -1568,9 +1569,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h if (c[1]) { context->audio_st[1].frame = av_frame_alloc(); switch_assert(context->audio_st[1].frame); - } - if (c[0] && c[1]) { context->audio_st[0].channels = 1; context->audio_st[1].channels = 1; } else { @@ -2016,7 +2015,6 @@ GCC_DIAG_ON(deprecated-declarations) } else if (dret == AVERROR(EAGAIN)) { /* we fully drain all the output in each decode call, so this should not ever happen */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending audio packet to decoder - BUG, should never happen\n"); - dret = AVERROR_BUG; goto do_continue; } else if (dret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending audio packet to decoder\n"); From 597ee613de378c69abfdf4fe5133f29061d8ade7 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 26 Apr 2024 12:58:44 +0000 Subject: [PATCH 113/205] [mod_avmd] Fix scan-build 14 --- src/mod/applications/mod_avmd/mod_avmd.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index e5076c1500..713f9158cd 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -2130,9 +2130,7 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff sma_buffer_t *sqa_amp_b = &buffer->sqa_amp_b; if (sample_to_skip_n > 0) { - sample_to_skip_n--; - valid_amplitude = 0; - valid_omega = 0; + return AVMD_DETECT_NONE; } @@ -2145,14 +2143,14 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff RESET_SMA_BUFFER(sma_amp_b); RESET_SMA_BUFFER(sqa_amp_b); buffer->samples_streak_amp = s->settings.sample_n_continuous_streak_amp; - sample_to_skip_n = s->settings.sample_n_to_skip; } } else { if (ISINF(amplitude)) { amplitude = buffer->amplitude_max; } + if (valid_amplitude == 1) { - APPEND_SMA_VAL(sma_amp_b, amplitude); /* append amplitude */ + APPEND_SMA_VAL(sma_amp_b, amplitude); /* append amplitude */ APPEND_SMA_VAL(sqa_amp_b, amplitude * amplitude); if (s->settings.require_continuous_streak_amp == 1) { if (buffer->samples_streak_amp > 0) { @@ -2161,6 +2159,7 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff } } } + if (sma_amp_b->sma > buffer->amplitude_max) { buffer->amplitude_max = sma_amp_b->sma; } @@ -2176,9 +2175,7 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff RESET_SMA_BUFFER(sma_b_fir); RESET_SMA_BUFFER(sqa_b_fir); buffer->samples_streak = s->settings.sample_n_continuous_streak; - sample_to_skip_n = s->settings.sample_n_to_skip; } - sample_to_skip_n = s->settings.sample_n_to_skip; } else if (omega < -0.99999 || omega > 0.99999) { valid_omega = 0; if (s->settings.require_continuous_streak == 1) { @@ -2187,7 +2184,6 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff RESET_SMA_BUFFER(sma_b_fir); RESET_SMA_BUFFER(sqa_b_fir); buffer->samples_streak = s->settings.sample_n_continuous_streak; - sample_to_skip_n = s->settings.sample_n_to_skip; } } else { if (valid_omega) { @@ -2216,20 +2212,26 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff if (((mode == AVMD_DETECT_AMP) || (mode == AVMD_DETECT_BOTH)) && (valid_amplitude == 1)) { v_amp = sqa_amp_b->sma - (sma_amp_b->sma * sma_amp_b->sma); /* calculate variance of amplitude (biased estimator) */ if ((mode == AVMD_DETECT_AMP) && (avmd_decision_amplitude(s, buffer, v_amp, AVMD_AMPLITUDE_RSD_THRESHOLD) == 1)) { + return AVMD_DETECT_AMP; } } + if (((mode == AVMD_DETECT_FREQ) || (mode == AVMD_DETECT_BOTH)) && (valid_omega == 1)) { v_fir = sqa_b_fir->sma - (sma_b_fir->sma * sma_b_fir->sma); /* calculate variance of filtered samples */ if ((mode == AVMD_DETECT_FREQ) && (avmd_decision_freq(s, buffer, v_fir, AVMD_VARIANCE_RSD_THRESHOLD) == 1)) { + return AVMD_DETECT_FREQ; } + if (mode == AVMD_DETECT_BOTH) { - if ((avmd_decision_amplitude(s, buffer, v_amp, AVMD_AMPLITUDE_RSD_THRESHOLD) == 1) && (avmd_decision_freq(s, buffer, v_fir, AVMD_VARIANCE_RSD_THRESHOLD) == 1)) { + if ((avmd_decision_amplitude(s, buffer, v_amp, AVMD_AMPLITUDE_RSD_THRESHOLD) == 1) && (avmd_decision_freq(s, buffer, v_fir, AVMD_VARIANCE_RSD_THRESHOLD) == 1)) { + return AVMD_DETECT_BOTH; } } } + return AVMD_DETECT_NONE; } From 84ab90895ab53cbbf60f0f214f4ca2c025d085e7 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 26 Apr 2024 13:11:54 +0000 Subject: [PATCH 114/205] [mod_amrwb] Fix scan-build 14 --- src/mod/codecs/mod_amrwb/amrwb_be.c | 6 +++--- src/mod/codecs/mod_amrwb/mod_amrwb.c | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mod/codecs/mod_amrwb/amrwb_be.c b/src/mod/codecs/mod_amrwb/amrwb_be.c index 7b43b2b583..e8f45cf7d7 100644 --- a/src/mod/codecs/mod_amrwb/amrwb_be.c +++ b/src/mod/codecs/mod_amrwb/amrwb_be.c @@ -95,23 +95,23 @@ extern switch_bool_t switch_amrwb_pack_be(unsigned char *shift_buf, int n) extern switch_bool_t switch_amrwb_unpack_be(unsigned char *encoded_buf, uint8_t *tmp, int encoded_len) { - int framesz, index, ft; + int framesz, index; uint8_t shift_tocs[2] = {0x00, 0x00}; uint8_t *shift_buf; memcpy(shift_tocs, encoded_buf, 2); /* shift for BE */ switch_amr_array_lshift(4, shift_tocs, 2); - ft = shift_tocs[0] >> 3; - ft &= ~(1 << 5); /* Frame Type*/ shift_buf = encoded_buf + 1; /* skip CMR */ /* shift for BE */ switch_amr_array_lshift(2, shift_buf, encoded_len - 1); /* get frame size */ index = ((shift_tocs[0] >> 3) & 0x0f); if (index > 10 && index != 0xe && index != 0xf) { + return SWITCH_FALSE; } + framesz = switch_amrwb_frame_sizes[index]; tmp[0] = shift_tocs[0]; /* save TOC */ memcpy(&tmp[1], shift_buf, framesz); diff --git a/src/mod/codecs/mod_amrwb/mod_amrwb.c b/src/mod/codecs/mod_amrwb/mod_amrwb.c index 4ac3f25f37..d89ec5d62b 100644 --- a/src/mod/codecs/mod_amrwb/mod_amrwb.c +++ b/src/mod/codecs/mod_amrwb/mod_amrwb.c @@ -191,6 +191,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla if (codec->fmtp_in) { codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); } + return SWITCH_STATUS_SUCCESS; #else struct amrwb_context *context = NULL; @@ -204,6 +205,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla decoding = (flags & SWITCH_CODEC_FLAG_DECODE); if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(struct amrwb_context))))) { + return SWITCH_STATUS_FALSE; } else { @@ -296,6 +298,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla /* re-create mode-set */ fmtptmp_pos = switch_snprintf(fmtptmp, sizeof(fmtptmp), "mode-set="); + for (i = 0; SWITCH_AMRWB_MODES-1 > i; ++i) { if (context->enc_modes & (1 << i)) { fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, fmtptmp_pos > strlen("mode-set=") ? ",%d" : "%d", i); @@ -312,12 +315,13 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } if (!globals.volte) { - fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d", + switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0); } else { - fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d;max-red=0;mode-change-capability=2", + switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d;max-red=0;mode-change-capability=2", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0); } + codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp); context->encoder_state = NULL; From 91cc40d17038c4f9d5df6fbaa6f155f8b652258e Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 7 May 2024 10:24:07 +0300 Subject: [PATCH 115/205] [support-d] Add deadlock.py to tree. --- support-d/gdb/README.md | 76 ++++++ support-d/gdb/deadlock.py | 474 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 550 insertions(+) create mode 100644 support-d/gdb/README.md create mode 100644 support-d/gdb/deadlock.py diff --git a/support-d/gdb/README.md b/support-d/gdb/README.md new file mode 100644 index 0000000000..d3d198c5b5 --- /dev/null +++ b/support-d/gdb/README.md @@ -0,0 +1,76 @@ +`gdb` scripts +----------- + +Originally from: https://github.com/facebook/folly/tree/593b6e76881042031b7f21d898c8e0874ea79fe0/folly/experimental/gdb + +This directory contains a collection of `gdb` scripts that we have found helpful. +These scripts use the [gdb extension Python API](https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html#Python). + +### How to run the scripts + +To run the scripts, fire up `gdb` and load a script with `source -v`. Example: + +```lang=bash +$ gdb -p 123456 +(gdb) source -v ./folly/experimental/gdb/deadlock.py +Type "deadlock" to detect deadlocks. +# At this point, any new commands defined in `deadlock.py` are available. +(gdb) deadlock +Found deadlock! +... +``` + +### What does each script do? + +#### `deadlock.py` - Detect deadlocks + +Consider the following program that always deadlocks: + +```lang=cpp +void deadlock3() { + std::mutex m1, m2, m3; + folly::Baton<> b1, b2, b3; + + auto t1 = std::thread([&m1, &m2, &b1, &b2] { + std::lock_guard g1(m1); + b1.post(); + b2.wait(); + std::lock_guard g2(m2); + }); + + auto t2 = std::thread([&m3, &m2, &b3, &b2] { + std::lock_guard g2(m2); + b2.post(); + b3.wait(); + std::lock_guard g3(m3); + }); + + auto t3 = std::thread([&m3, &m1, &b3, &b1] { + std::lock_guard g3(m3); + b3.post(); + b1.wait(); + std::lock_guard g1(m1); + }); + + t1.join(); + t2.join(); + t3.join(); +} +``` + +The `deadlock.py` script introduces a new `deadlock` command that can help +us identify the threads and mutexes involved with the deadlock. + +```lang=bash +$ gdb -p 2174496 +(gdb) source -v ./folly/experimental/gdb/deadlock.py +Type "deadlock" to detect deadlocks. +(gdb) deadlock +Found deadlock! +Thread 2 (LWP 2174497) is waiting on mutex (0x00007ffcff42a4c0) held by Thread 3 (LWP 2174498) +Thread 3 (LWP 2174498) is waiting on mutex (0x00007ffcff42a4f0) held by Thread 4 (LWP 2174499) +Thread 4 (LWP 2174499) is waiting on mutex (0x00007ffcff42a490) held by Thread 2 (LWP 2174497) +``` + +NOTE: This script only works on Linux and requires debug symbols to be installed +for the `pthread` library. diff --git a/support-d/gdb/deadlock.py b/support-d/gdb/deadlock.py new file mode 100644 index 0000000000..feeae0713f --- /dev/null +++ b/support-d/gdb/deadlock.py @@ -0,0 +1,474 @@ +#!/usr/bin/env python3 +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +from collections import defaultdict +from enum import Enum + +import gdb + + +class DiGraph: + """ + Adapted from networkx: http://networkx.github.io/ + Represents a directed graph. Edges can store (key, value) attributes. + """ + + def __init__(self): + # Map of node -> set of nodes + self.adjacency_map = {} + # Map of (node1, node2) -> map string -> arbitrary attribute + # This will not be copied in subgraph() + self.attributes_map = {} + + def neighbors(self, node): + return self.adjacency_map.get(node, set()) + + def edges(self): + edges = [] + for node, neighbors in self.adjacency_map.items(): + for neighbor in neighbors: + edges.append((node, neighbor)) + return edges + + def nodes(self): + return self.adjacency_map.keys() + + def attributes(self, node1, node2): + return self.attributes_map[(node1, node2)] + + def add_edge(self, node1, node2, **kwargs): + if node1 not in self.adjacency_map: + self.adjacency_map[node1] = set() + if node2 not in self.adjacency_map: + self.adjacency_map[node2] = set() + self.adjacency_map[node1].add(node2) + self.attributes_map[(node1, node2)] = kwargs + + def remove_node(self, node): + self.adjacency_map.pop(node, None) + for _, neighbors in self.adjacency_map.items(): + neighbors.discard(node) + + def subgraph(self, nodes): + graph = DiGraph() + for node in nodes: + for neighbor in self.neighbors(node): + if neighbor in nodes: + graph.add_edge(node, neighbor) + return graph + + def node_link_data(self): + """ + Returns the graph as a dictionary in a format that can be + serialized. + """ + data = { + "directed": True, + "multigraph": False, + "graph": {}, + "links": [], + "nodes": [], + } + + # Do one pass to build a map of node -> position in nodes + node_to_number = {} + for node in self.adjacency_map.keys(): + node_to_number[node] = len(data["nodes"]) + data["nodes"].append({"id": node}) + + # Do another pass to build the link information + for node, neighbors in self.adjacency_map.items(): + for neighbor in neighbors: + link = self.attributes_map[(node, neighbor)].copy() + link["source"] = node_to_number[node] + link["target"] = node_to_number[neighbor] + data["links"].append(link) + return data + + +def strongly_connected_components(G): # noqa: C901 + """ + Adapted from networkx: http://networkx.github.io/ + Parameters + ---------- + G : DiGraph + Returns + ------- + comp : generator of sets + A generator of sets of nodes, one for each strongly connected + component of G. + """ + preorder = {} + lowlink = {} + scc_found = {} + scc_queue = [] + i = 0 # Preorder counter + for source in G.nodes(): + if source not in scc_found: + queue = [source] + while queue: + v = queue[-1] + if v not in preorder: + i = i + 1 + preorder[v] = i + done = 1 + v_nbrs = G.neighbors(v) + for w in v_nbrs: + if w not in preorder: + queue.append(w) + done = 0 + break + if done == 1: + lowlink[v] = preorder[v] + for w in v_nbrs: + if w not in scc_found: + if preorder[w] > preorder[v]: + lowlink[v] = min([lowlink[v], lowlink[w]]) + else: + lowlink[v] = min([lowlink[v], preorder[w]]) + queue.pop() + if lowlink[v] == preorder[v]: + scc_found[v] = True + scc = {v} + while scc_queue and preorder[scc_queue[-1]] > preorder[v]: + k = scc_queue.pop() + scc_found[k] = True + scc.add(k) + yield scc + else: + scc_queue.append(v) + + +def simple_cycles(G): # noqa: C901 + """ + Adapted from networkx: http://networkx.github.io/ + Parameters + ---------- + G : DiGraph + Returns + ------- + cycle_generator: generator + A generator that produces elementary cycles of the graph. + Each cycle is represented by a list of nodes along the cycle. + """ + + def _unblock(thisnode, blocked, B): + stack = {thisnode} + while stack: + node = stack.pop() + if node in blocked: + blocked.remove(node) + stack.update(B[node]) + B[node].clear() + + # Johnson's algorithm requires some ordering of the nodes. + # We assign the arbitrary ordering given by the strongly connected comps + # There is no need to track the ordering as each node removed as processed. + # save the actual graph so we can mutate it here + # We only take the edges because we do not want to + # copy edge and node attributes here. + subG = G.subgraph(G.nodes()) + sccs = list(strongly_connected_components(subG)) + while sccs: + scc = sccs.pop() + # order of scc determines ordering of nodes + startnode = scc.pop() + # Processing node runs 'circuit' routine from recursive version + path = [startnode] + blocked = set() # vertex: blocked from search? + closed = set() # nodes involved in a cycle + blocked.add(startnode) + B = defaultdict(set) # graph portions that yield no elementary circuit + stack = [(startnode, list(subG.neighbors(startnode)))] + while stack: + thisnode, nbrs = stack[-1] + if nbrs: + nextnode = nbrs.pop() + if nextnode == startnode: + yield path[:] + closed.update(path) + elif nextnode not in blocked: + path.append(nextnode) + stack.append((nextnode, list(subG.neighbors(nextnode)))) + closed.discard(nextnode) + blocked.add(nextnode) + continue + # done with nextnode... look for more neighbors + if not nbrs: # no more nbrs + if thisnode in closed: + _unblock(thisnode, blocked, B) + else: + for nbr in subG.neighbors(thisnode): + if thisnode not in B[nbr]: + B[nbr].add(thisnode) + stack.pop() + path.pop() + # done processing this node + subG.remove_node(startnode) + H = subG.subgraph(scc) # make smaller to avoid work in SCC routine + sccs.extend(list(strongly_connected_components(H))) + + +def find_cycle(graph): + """ + Looks for a cycle in the graph. If found, returns the first cycle. + If nodes a1, a2, ..., an are in a cycle, then this returns: + [(a1,a2), (a2,a3), ... (an-1,an), (an, a1)] + Otherwise returns an empty list. + """ + cycles = list(simple_cycles(graph)) + if cycles: + nodes = cycles[0] + nodes.append(nodes[0]) + edges = [] + prev = nodes[0] + for node in nodes[1:]: + edges.append((prev, node)) + prev = node + return edges + else: + return [] + + +def get_stacktrace(thread_id): + """ + Returns the stack trace for the thread id as a list of strings. + """ + gdb.execute("thread %d" % thread_id, from_tty=False, to_string=True) + output = gdb.execute("bt", from_tty=False, to_string=True) + stacktrace_lines = output.strip().split("\n") + return stacktrace_lines + + +def is_thread_blocked_with_frame( + thread_id, top_line, expected_top_lines, expected_frame +): + """ + Returns True if we found expected_top_line in top_line, and + we found the expected_frame in the thread's stack trace. + """ + if all(expected not in top_line for expected in expected_top_lines): + return False + stacktrace_lines = get_stacktrace(thread_id) + return any(expected_frame in line for line in stacktrace_lines) + + +class MutexType(Enum): + """Types of mutexes that we can detect deadlocks.""" + + PTHREAD_MUTEX_T = "pthread_mutex_t" + PTHREAD_RWLOCK_T = "pthread_rwlock_t" + + @staticmethod + def get_mutex_type(thread_id, top_line): + """ + Returns the probable mutex type, based on the first line + of the thread's stack. Returns None if not found. + """ + + WAITLIST = [ + "__lll_lock_wait", + "futex_abstimed_wait", + "futex_abstimed_wait_cancelable", + "futex_reltimed_wait", + "futex_reltimed_wait_cancelable", + "futex_wait", + "futex_wait_cancelable", + ] + + if is_thread_blocked_with_frame(thread_id, top_line, WAITLIST, "pthread_mutex"): + return MutexType.PTHREAD_MUTEX_T + if is_thread_blocked_with_frame( + thread_id, top_line, WAITLIST, "pthread_rwlock" + ): + return MutexType.PTHREAD_RWLOCK_T + return None + + @staticmethod + def get_mutex_owner_and_address_func_for_type(mutex_type): + """ + Returns a function to resolve the mutex owner and address for + the given type. The returned function f has the following + signature: + + f: args: (map of thread lwp -> thread id), blocked thread lwp + returns: (lwp of thread owning mutex, mutex address) + or (None, None) if not found. + + Returns None if there is no function for this mutex_type. + """ + if mutex_type == MutexType.PTHREAD_MUTEX_T: + return get_pthread_mutex_t_owner_and_address + if mutex_type == MutexType.PTHREAD_RWLOCK_T: + return get_pthread_rwlock_t_owner_and_address + return None + + +def print_cycle(graph, lwp_to_thread_id, cycle): + """Prints the threads and mutexes involved in the deadlock.""" + for m, n in cycle: + print( + "Thread %d (LWP %d) is waiting on %s (0x%016x) held by " + "Thread %d (LWP %d)" + % ( + lwp_to_thread_id[m], + m, + graph.attributes(m, n)["mutex_type"].value, + graph.attributes(m, n)["mutex"], + lwp_to_thread_id[n], + n, + ) + ) + + +def get_thread_info(): + """ + Returns a pair of: + - map of LWP -> thread ID + - map of blocked threads LWP -> potential mutex type + """ + # LWP -> thread ID + lwp_to_thread_id = {} + + # LWP -> potential mutex type it is blocked on + blocked_threads = {} + + output = gdb.execute("info threads", from_tty=False, to_string=True) + lines = output.strip().split("\n")[1:] + regex = re.compile(r"[\s\*]*(\d+).*Thread.*\(LWP (\d+)\).*") + for line in lines: + try: + thread_id = int(regex.match(line).group(1)) + thread_lwp = int(regex.match(line).group(2)) + lwp_to_thread_id[thread_lwp] = thread_id + mutex_type = MutexType.get_mutex_type(thread_id, line) + if mutex_type: + blocked_threads[thread_lwp] = mutex_type + except Exception: + continue + + return (lwp_to_thread_id, blocked_threads) + + +def get_pthread_mutex_t_owner_and_address(lwp_to_thread_id, thread_lwp): + """ + Finds the thread holding the mutex that this thread is blocked on. + Returns a pair of (lwp of thread owning mutex, mutex address), + or (None, None) if not found. + """ + # Go up the stack to the pthread_mutex_lock frame + gdb.execute( + "thread %d" % lwp_to_thread_id[thread_lwp], from_tty=False, to_string=True + ) + gdb.execute("frame 1", from_tty=False, to_string=True) + + # Get the owner of the mutex by inspecting the internal + # fields of the mutex. + try: + mutex_info = gdb.parse_and_eval("mutex").dereference() + mutex_owner_lwp = int(mutex_info["__data"]["__owner"]) + return (mutex_owner_lwp, int(mutex_info.address)) + except gdb.error: + return (None, None) + + +def get_pthread_rwlock_t_owner_and_address(lwp_to_thread_id, thread_lwp): + """ + If the thread is waiting on a write-locked pthread_rwlock_t, this will + return the pair of: + (lwp of thread that is write-owning the mutex, mutex address) + or (None, None) if not found, or if the mutex is read-locked. + """ + # Go up the stack to the pthread_rwlock_{rd|wr}lock frame + gdb.execute( + "thread %d" % lwp_to_thread_id[thread_lwp], from_tty=False, to_string=True + ) + gdb.execute("frame 2", from_tty=False, to_string=True) + + # Get the owner of the mutex by inspecting the internal + # fields of the mutex. + try: + rwlock_info = gdb.parse_and_eval("rwlock").dereference() + rwlock_data = rwlock_info["__data"] + field_names = ["__cur_writer", "__writer"] + fields = rwlock_data.type.fields() + field = [f for f in fields if f.name in field_names][0] + rwlock_owner_lwp = int(rwlock_data[field]) + # We can only track the owner if it is currently write-locked. + # If it is not write-locked or if it is currently read-locked, + # possibly by multiple threads, we cannot find the owner. + if rwlock_owner_lwp != 0: + return (rwlock_owner_lwp, int(rwlock_info.address)) + else: + return (None, None) + except gdb.error: + return (None, None) + + +class Deadlock(gdb.Command): + """Detects deadlocks""" + + def __init__(self): + super(Deadlock, self).__init__("deadlock", gdb.COMMAND_NONE) + + def invoke(self, arg, from_tty): + """Prints the threads and mutexes in a deadlock, if it exists.""" + lwp_to_thread_id, blocked_threads = get_thread_info() + + # Nodes represent threads. Edge (A,B) exists if thread A + # is waiting on a mutex held by thread B. + graph = DiGraph() + + # Go through all the blocked threads and see which threads + # they are blocked on, and build the thread wait graph. + for thread_lwp, mutex_type in blocked_threads.items(): + get_owner_and_address_func = ( + MutexType.get_mutex_owner_and_address_func_for_type(mutex_type) + ) + if not get_owner_and_address_func: + continue + mutex_owner_lwp, mutex_address = get_owner_and_address_func( + lwp_to_thread_id, thread_lwp + ) + if mutex_owner_lwp and mutex_address: + graph.add_edge( + thread_lwp, + mutex_owner_lwp, + mutex=mutex_address, + mutex_type=mutex_type, + ) + + # A deadlock exists if there is a cycle in the graph. + cycle = find_cycle(graph) + if cycle: + print("Found deadlock!") + print_cycle(graph, lwp_to_thread_id, cycle) + else: + print("No deadlock detected. " "Do you have debug symbols installed?") + + +def load(): + # instantiate the Deadlock command + Deadlock() + print('Type "deadlock" to detect deadlocks.') + + +def info(): + return "Detect deadlocks" + + +if __name__ == "__main__": + load() From 5b1c2688da6ffcddad4b54bb97408d8325ffa7b9 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 30 Apr 2024 21:14:29 +0300 Subject: [PATCH 116/205] [Core, mod_sofia] Add switch_uint31_t type. Fix CSeq bigger than 2^31-1. --- src/include/switch_types.h | 4 ++++ src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia_presence.c | 19 +++++++++---------- tests/unit/switch_core.c | 20 ++++++++++++++++++++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index d315e46fc8..f8ae00790d 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -255,6 +255,10 @@ SWITCH_BEGIN_EXTERN_C typedef uint8_t switch_byte_t; +typedef struct { + unsigned int value : 31; +} switch_uint31_t; + typedef enum { SWITCH_PVT_PRIMARY = 0, SWITCH_PVT_SECONDARY diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index bfd682c1f1..8e2b1b483c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -776,7 +776,7 @@ struct sofia_profile { int watchdog_enabled; switch_mutex_t *gw_mutex; uint32_t queued_events; - uint32_t last_cseq; + switch_uint31_t last_cseq; int tls_only; int tls_verify_date; enum tport_tls_verify_policy tls_verify_policy; diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 579cea83e2..48ad579411 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2112,12 +2112,12 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char * #define SOFIA_PRESENCE_COLLISION_DELTA 50 #define SOFIA_PRESENCE_ROLLOVER_YEAR (86400 * 365 * SOFIA_PRESENCE_COLLISION_DELTA) -static uint32_t check_presence_epoch(void) +static switch_uint31_t check_presence_epoch(void) { time_t now = switch_epoch_time_now(NULL); - uint32_t callsequence = (uint32_t)((now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA); + switch_uint31_t callsequence = { .value = (uint32_t)((now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA) }; - if (!mod_sofia_globals.presence_year || callsequence >= SOFIA_PRESENCE_ROLLOVER_YEAR) { + if (!mod_sofia_globals.presence_year || callsequence.value >= SOFIA_PRESENCE_ROLLOVER_YEAR) { struct tm tm; switch_mutex_lock(mod_sofia_globals.mutex); tm = *(localtime(&now)); @@ -2125,7 +2125,7 @@ static uint32_t check_presence_epoch(void) if (tm.tm_year != mod_sofia_globals.presence_year) { mod_sofia_globals.presence_epoch = (uint32_t)now - (tm.tm_yday * 86400) - (tm.tm_hour * 60 * 60) - (tm.tm_min * 60) - tm.tm_sec; mod_sofia_globals.presence_year = tm.tm_year; - callsequence = (uint32_t)(((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA); + callsequence.value = (uint32_t)(((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA); } switch_mutex_unlock(mod_sofia_globals.mutex); @@ -2136,17 +2136,17 @@ static uint32_t check_presence_epoch(void) uint32_t sofia_presence_get_cseq(sofia_profile_t *profile) { - uint32_t callsequence; + switch_uint31_t callsequence; int diff = 0; switch_mutex_lock(profile->ireg_mutex); callsequence = check_presence_epoch(); - if (profile->last_cseq) { - diff = callsequence - profile->last_cseq; + if (profile->last_cseq.value) { + diff = (int)callsequence.value - (int)profile->last_cseq.value; if (diff <= 0 && diff > -100000) { - callsequence = ++profile->last_cseq; + callsequence.value = ++profile->last_cseq.value; } } @@ -2154,8 +2154,7 @@ uint32_t sofia_presence_get_cseq(sofia_profile_t *profile) switch_mutex_unlock(profile->ireg_mutex); - return callsequence; - + return (uint32_t)callsequence.value; } diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index 1159017571..2f06966582 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -53,6 +53,26 @@ FST_CORE_BEGIN("./conf") } FST_TEARDOWN_END() + FST_TEST_BEGIN(test_switch_uint31_t_overflow) + { + switch_uint31_t x; + uint32_t overflow; + + x.value = 0x7fffffff; + x.value++; + + fst_check_int_equals(x.value, 0); + x.value++; + fst_check_int_equals(x.value, 1); + x.value -= 2; + fst_check_int_equals(x.value, 0x7fffffff); + + overflow = (uint32_t)0x7fffffff + 1; + x.value = overflow; + fst_check_int_equals(x.value, 0); + } + FST_TEST_END() + FST_TEST_BEGIN(test_switch_parse_cidr_v6) { ip_t ip, mask; From 681c61ad3203d3a560f85f548feb136cb93c57e1 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Sun, 19 May 2024 16:18:53 +0100 Subject: [PATCH 117/205] [libvpx] Fix scan-build 14 --- libs/libvpx/vp9/encoder/vp9_subexp.c | 3 +++ libs/libvpx/vpx_scale/generic/vpx_scale.c | 2 ++ libs/libvpx/vpx_scale/vpx_scale.h | 2 ++ 3 files changed, 7 insertions(+) diff --git a/libs/libvpx/vp9/encoder/vp9_subexp.c b/libs/libvpx/vp9/encoder/vp9_subexp.c index cf17fcdfce..b5a2390662 100644 --- a/libs/libvpx/vp9/encoder/vp9_subexp.c +++ b/libs/libvpx/vp9/encoder/vp9_subexp.c @@ -64,6 +64,9 @@ static int remap_prob(int v, int m) { 228, 229, 17, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 18, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19, }; + + assert(m > 0); + v--; m--; if ((m << 1) <= MAX_PROB) diff --git a/libs/libvpx/vpx_scale/generic/vpx_scale.c b/libs/libvpx/vpx_scale/generic/vpx_scale.c index 958bb320fc..e20905e9ce 100644 --- a/libs/libvpx/vpx_scale/generic/vpx_scale.c +++ b/libs/libvpx/vpx_scale/generic/vpx_scale.c @@ -167,6 +167,8 @@ static void scale1d_c(const unsigned char *source, int source_step, (void)source_length; + assert(dest_scale); + /* These asserts are needed if there are boundary issues... */ /*assert ( dest_scale > source_scale );*/ /*assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale diff --git a/libs/libvpx/vpx_scale/vpx_scale.h b/libs/libvpx/vpx_scale/vpx_scale.h index fd5ba7ccdc..96edb7af20 100644 --- a/libs/libvpx/vpx_scale/vpx_scale.h +++ b/libs/libvpx/vpx_scale/vpx_scale.h @@ -11,6 +11,8 @@ #ifndef VPX_VPX_SCALE_VPX_SCALE_H_ #define VPX_VPX_SCALE_VPX_SCALE_H_ +#include + #include "vpx_scale/yv12config.h" extern void vpx_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, From 85400015b7eed420f49bfde85cd08acc44f48b28 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 1 Jun 2022 00:09:48 +0300 Subject: [PATCH 118/205] [Core] VAD: Add a math sanity check to the switch_vad_process --- src/switch_vad.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/switch_vad.c b/src/switch_vad.c index 6118c0237e..74d131331b 100644 --- a/src/switch_vad.c +++ b/src/switch_vad.c @@ -206,7 +206,9 @@ SWITCH_DECLARE(switch_vad_state_t) switch_vad_process(switch_vad_t *vad, int16_t j += vad->channels; } - score = (uint32_t) (energy / (samples / vad->divisor)); + if (samples && vad->divisor && samples >= vad->divisor) { + score = (uint32_t)(energy / (samples / vad->divisor)); + } #ifdef SWITCH_HAVE_FVAD } #endif From 41bc763d800a9fef127d238e88a797470b1256f9 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Mon, 13 May 2024 12:25:47 +0100 Subject: [PATCH 119/205] [core] Fix scan-build 14 in port allocator --- src/switch_core_port_allocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_port_allocator.c b/src/switch_core_port_allocator.c index 3bbed2a351..074ce5f5ea 100644 --- a/src/switch_core_port_allocator.c +++ b/src/switch_core_port_allocator.c @@ -150,7 +150,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c switch_mutex_lock(alloc->mutex); srand((unsigned) ((unsigned) (intptr_t) port_ptr + (unsigned) (intptr_t) switch_thread_self() + switch_micro_time_now())); - while (alloc->track_used < alloc->track_len) { + while (alloc->track_len && alloc->track_used < alloc->track_len) { uint32_t index; uint32_t tries = 0; From 72eef5681fc03a4405eab26545ff09953a999094 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 14 Aug 2023 18:14:28 +0300 Subject: [PATCH 120/205] [CI] Enable scan build 14 on Drone CI --- .drone.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.drone.yml b/.drone.yml index 07ccb34f27..63838cfb73 100644 --- a/.drone.yml +++ b/.drone.yml @@ -97,13 +97,14 @@ name: scan-build steps: - name: bootstrap - image: signalwire/freeswitch-public-base:bullseye + image: signalwire/freeswitch-public-base:bookworm pull: always commands: + - apt-get update && apt-get -yq install autoconf - ./bootstrap.sh -j - name: configure - image: signalwire/freeswitch-public-base:bullseye + image: signalwire/freeswitch-public-base:bookworm pull: always environment: REPOTOKEN: @@ -140,7 +141,7 @@ steps: - ./configure - name: scan-build - image: signalwire/freeswitch-public-base:bullseye + image: signalwire/freeswitch-public-base:bookworm pull: always environment: REPOTOKEN: @@ -152,7 +153,7 @@ steps: - export REPOTOKEN='' - rm -rf /etc/apt/auth.conf - mkdir -p scan-build - - echo '#!/bin/bash\nscan-build-11 -o ./scan-build/ make -j`nproc --all` |& tee ./scan-build-result.txt\nexitstatus=$${PIPESTATUS[0]}\necho $$exitstatus > ./scan-build-status.txt\n' > scan.sh + - echo '#!/bin/bash\nscan-build-14 --force-analyze-debug-code -o ./scan-build/ make -j`nproc --all` |& tee ./scan-build-result.txt\nexitstatus=$${PIPESTATUS[0]}\necho $$exitstatus > ./scan-build-status.txt\n' > scan.sh - chmod +x scan.sh - ./scan.sh - exitstatus=`cat ./scan-build-status.txt` @@ -178,6 +179,6 @@ trigger: --- kind: signature -hmac: 780e4aaee61e3683ea4a8d6fe5131f7c9e62ebad727546013f18df0fca80d705 +hmac: 7e5f6cafc88da0be59243daf47a2a5607ff00b45f441ce4c1041d4b690e8a853 ... From a92c1e4c4739cd9b0f7a456c5baf045df3dc4066 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 7 Mar 2024 21:41:54 +0300 Subject: [PATCH 121/205] [Build-System] Fix crashing MSI packaging on Windows when Visual Studio 2022 is used. --- .gitignore | 2 +- w32/Setup/Setup.2017.wixproj | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0461c273de..135473c8df 100644 --- a/.gitignore +++ b/.gitignore @@ -187,7 +187,7 @@ ipch/ /w32/Setup/obj *dSYM* -/UpgradeLog.* +/UpgradeLog*.* /_UpgradeReport_Files/ *.aps /w32/Library/switch_version.inc diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index dd745e8438..bf0aae0498 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -1032,6 +1032,7 @@ SuppressRegistry="true" SuppressCom="true" SuppressFragments="true" + RunAsSeparateProcess="true" PreprocessorVariable="var.FreeSWITCHConfFilesDir"> From c7e793c345218158df4feda7326f5925da6cccab Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 21:05:33 +0300 Subject: [PATCH 122/205] [Core] Add new switch_rand() a compliant random number generator API. Add a unit-test. * [Core] Add new switch_rand() a compliant random number generator API. Add a unit-test. * Fall back to rand() on unsupported platforms compile time. --- src/include/switch_utils.h | 5 ++++ src/switch_utils.c | 57 ++++++++++++++++++++++++++++++++++++++ tests/unit/switch_core.c | 21 ++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 1d33939f4c..a0c91e6384 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -1514,6 +1514,11 @@ SWITCH_DECLARE(switch_status_t) switch_digest_string(const char *digest_name, ch SWITCH_DECLARE(char *) switch_must_strdup(const char *_s); SWITCH_DECLARE(const char *) switch_memory_usage_stream(switch_stream_handle_t *stream); +/** +/ Compliant random number generator. Returns the value between 0 and 0x7fff (RAND_MAX). +**/ +SWITCH_DECLARE(int) switch_rand(void); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/switch_utils.c b/src/switch_utils.c index faffc1cc04..25d0bf76ee 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4811,6 +4811,63 @@ done: return status; } +SWITCH_DECLARE(int) switch_rand(void) +{ + uint32_t random_number = 0; +#ifdef WIN32 + BCRYPT_ALG_HANDLE hAlgorithm = NULL; + NTSTATUS status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); + + if (!BCRYPT_SUCCESS(status)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptOpenAlgorithmProvider failed with status %d\n", status); + + return 1; + } + + status = BCryptGenRandom(hAlgorithm, (PUCHAR)&random_number, sizeof(random_number), 0); + if (!BCRYPT_SUCCESS(status)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptGenRandom failed with status %d\n", status); + + return 1; + } + + BCryptCloseAlgorithmProvider(hAlgorithm, 0); + + /* Make sure we return from 0 to RAND_MAX */ + return (random_number & 0x7FFF); +#elif defined(__unix__) || defined(__APPLE__) + int random_fd = open("/dev/urandom", O_RDONLY); + ssize_t result; + char error_msg[100]; + + if (random_fd == -1) { + strncpy(error_msg, strerror(errno), sizeof(error_msg) - 1); + error_msg[sizeof(error_msg) - 1] = '\0'; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open failed: %s\n", error_msg); + + return 1; + } + + result = read(random_fd, &random_number, sizeof(random_number)); + if (result < 0) { + strncpy(error_msg, strerror(errno), sizeof(error_msg) - 1); + error_msg[sizeof(error_msg) - 1] = '\0'; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read failed: %s\n", error_msg); + + return 1; + } + + close(random_fd); + + /* Make sure we return from 0 to RAND_MAX */ + return (random_number & 0x7FFF); +#else + return rand(); +#endif +} + /* For Emacs: * Local Variables: * mode:c diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index 2f06966582..295e4e0ff1 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -53,6 +53,27 @@ FST_CORE_BEGIN("./conf") } FST_TEARDOWN_END() + FST_TEST_BEGIN(test_switch_rand) + { + int i, c = 0; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "\nLet's generate a few random numbers.\n"); + + for (i = 0; i < 10; i++) { + uint32_t rnd = switch_rand(); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Random number %d\n", rnd); + + if (rnd == 1) { + c++; + } + } + + /* We do not expect all random numbers to be 1 all 10 times. That would mean we have an error OR we are lucky to have 10 random ones! */ + fst_check(c < 10); + } + FST_TEST_END() + FST_TEST_BEGIN(test_switch_uint31_t_overflow) { switch_uint31_t x; From 3b65e271164006affd327d2f42e39d76ac97c32d Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 16 May 2024 23:48:28 +0300 Subject: [PATCH 123/205] [mod_av] Fix use of switch_size_t in fs_rtp_parse_h263_rfc2190(). --- src/mod/applications/mod_av/avcodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 4f0057264e..0293b83446 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -906,7 +906,7 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p #if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size); #else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%ld\n", mb_info_pos, mb_info_count, mb_info_size); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, mb_info_size); #endif } } From 0c8b5987f04ac3753ebb0d8680f30512d3593776 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 17 May 2024 16:44:51 +0300 Subject: [PATCH 124/205] [mod_fsv] Fix use of 2gb of memory. Fix compiler warnings preventing builds on Bookworm. --- src/mod/applications/mod_fsv/mod_fsv.c | 32 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/mod/applications/mod_fsv/mod_fsv.c b/src/mod/applications/mod_fsv/mod_fsv.c index 90d64972ad..37f413d6b2 100644 --- a/src/mod/applications/mod_fsv/mod_fsv.c +++ b/src/mod/applications/mod_fsv/mod_fsv.c @@ -40,6 +40,11 @@ SWITCH_MODULE_DEFINITION(mod_fsv, mod_fsv_load, NULL, NULL); #define VID_BIT (1 << 31) #define VERSION 4202 +typedef struct fsv_video_data_s { + uint32_t size; + uint8_t data[]; +} fsv_video_data_t; + struct file_header { int32_t version; char video_codec_name[32]; @@ -983,15 +988,16 @@ again: } if (size & VID_BIT) { /* video */ - uint8_t *video_data = malloc(sizeof(size) + size); + fsv_video_data_t *video_data; switch_size_t read_size; - switch_assert(video_data); size &= ~VID_BIT; + video_data = malloc(sizeof(fsv_video_data_t) + size); + switch_assert(video_data); read_size = size; - *(uint32_t *)video_data = size; + video_data->size = size; - status = switch_file_read(context->fd, video_data + sizeof(size), &read_size); + status = switch_file_read(context->fd, video_data->data, &read_size); if (status != SWITCH_STATUS_SUCCESS || read_size != size) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, @@ -1033,7 +1039,7 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ fsv_file_context *context = handle->private_info; switch_image_t *dup = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; - void *video_packet = NULL; + fsv_video_data_t *video_packet = NULL; switch_time_t start = switch_time_now(); switch_status_t decode_status = SWITCH_STATUS_MORE_DATA; int new_img = 0; @@ -1047,8 +1053,9 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ switch_rtp_hdr_t *rtp; while (1) { + video_packet = NULL; switch_mutex_lock(context->mutex); - status = switch_queue_trypop(context->video_queue, &video_packet); + status = switch_queue_trypop(context->video_queue, (void**)&video_packet); switch_mutex_unlock(context->mutex); if (status != SWITCH_STATUS_SUCCESS || !video_packet) { @@ -1065,13 +1072,13 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ break; } - size = *(uint32_t *)video_packet; + size = video_packet->size; if (size > sizeof(context->video_packet_buffer)) { free(video_packet); return SWITCH_STATUS_BREAK; } - memcpy(context->video_packet_buffer, (uint8_t *)video_packet + sizeof(uint32_t), size); + memcpy(context->video_packet_buffer, video_packet->data, size); free(video_packet); video_packet = NULL; @@ -1093,14 +1100,15 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ uint32_t size; switch_rtp_hdr_t *rtp; - switch_mutex_lock(context->mutex); - status = switch_queue_trypop(context->video_queue, &video_packet); + video_packet = NULL; + switch_mutex_lock(context->mutex); + status = switch_queue_trypop(context->video_queue, (void**)&video_packet); switch_mutex_unlock(context->mutex); if (status != SWITCH_STATUS_SUCCESS || !video_packet) break; - size = *(uint32_t *)video_packet; - rtp = (switch_rtp_hdr_t *)((uint8_t *)video_packet + sizeof(uint32_t)); + size = video_packet->size; + rtp = (switch_rtp_hdr_t *)(video_packet->data); rtp_frame.packet = rtp; rtp_frame.packetlen = size; From 9f362ea3154501b93b276b82c7a3aa44d7111cfb Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 16:07:15 +0300 Subject: [PATCH 125/205] [Core] Better handle error cases in switch_rand(). --- src/switch_utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_utils.c b/src/switch_utils.c index 25d0bf76ee..64577d3997 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4828,6 +4828,8 @@ SWITCH_DECLARE(int) switch_rand(void) if (!BCRYPT_SUCCESS(status)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptGenRandom failed with status %d\n", status); + BCryptCloseAlgorithmProvider(hAlgorithm, 0); + return 1; } @@ -4856,6 +4858,8 @@ SWITCH_DECLARE(int) switch_rand(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read failed: %s\n", error_msg); + close(random_fd); + return 1; } From 74f386bf94a3b793c466a14c71f267daa7fd96d2 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 10 Jun 2024 15:48:30 +0000 Subject: [PATCH 126/205] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 50 ++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 78 +++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index bba26c8f9b..7cec120fbe 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -2129,6 +2129,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_LOST_BURST_CAPTURE_get___() } +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_uint31_t_value_set___(void * jarg1, unsigned int jarg2) { + switch_uint31_t *arg1 = (switch_uint31_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_uint31_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->value = arg2; +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_uint31_t_value_get___(void * jarg1) { + unsigned int jresult ; + switch_uint31_t *arg1 = (switch_uint31_t *) 0 ; + unsigned int result; + + arg1 = (switch_uint31_t *)jarg1; + result = (unsigned int) ((arg1)->value); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_FreeSWITCHfNative_new_switch_uint31_t___() { + void * jresult ; + switch_uint31_t *result = 0 ; + + result = (switch_uint31_t *)new switch_uint31_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_delete_switch_uint31_t___(void * jarg1) { + switch_uint31_t *arg1 = (switch_uint31_t *) 0 ; + + arg1 = (switch_uint31_t *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_dtmf_t_digit_set___(void * jarg1, char jarg2) { switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; char arg2 ; @@ -23521,6 +23561,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_memory_usage_strea } +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_rand___() { + int jresult ; + int result; + + result = (int)switch_rand(); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_profile_node_t_var_set___(void * jarg1, char * jarg2) { profile_node_s *arg1 = (profile_node_s *) 0 ; char *arg2 = (char *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index dc3926cbbb..6ca27764cf 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -11585,6 +11585,11 @@ else return ret; } + public static int switch_rand() { + int ret = freeswitchPINVOKE.switch_rand(); + return ret; + } + public static switch_caller_extension switch_caller_extension_new(SWIGTYPE_p_switch_core_session session, string extension_name, string extension_number) { global::System.IntPtr cPtr = freeswitchPINVOKE.switch_caller_extension_new(SWIGTYPE_p_switch_core_session.getCPtr(session), extension_name, extension_number); switch_caller_extension ret = (cPtr == global::System.IntPtr.Zero) ? null : new switch_caller_extension(cPtr, false); @@ -15975,6 +15980,18 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_LOST_BURST_CAPTURE_get___")] public static extern int LOST_BURST_CAPTURE_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_uint31_t_value_set___")] + public static extern void switch_uint31_t_value_set(global::System.Runtime.InteropServices.HandleRef jarg1, uint jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_uint31_t_value_get___")] + public static extern uint switch_uint31_t_value_get(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_new_switch_uint31_t___")] + public static extern global::System.IntPtr new_switch_uint31_t(); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_delete_switch_uint31_t___")] + public static extern void delete_switch_uint31_t(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_dtmf_t_digit_set___")] public static extern void switch_dtmf_t_digit_set(global::System.Runtime.InteropServices.HandleRef jarg1, char jarg2); @@ -21099,6 +21116,9 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_memory_usage_stream___")] public static extern string switch_memory_usage_stream(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_rand___")] + public static extern int switch_rand(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_profile_node_t_var_set___")] public static extern void profile_node_t_var_set(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2); @@ -47333,6 +47353,64 @@ public class switch_timer_interface : global::System.IDisposable { namespace FreeSWITCH.Native { +public class switch_uint31_t : global::System.IDisposable { + private global::System.Runtime.InteropServices.HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_uint31_t(global::System.IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr); + } + + internal static global::System.Runtime.InteropServices.HandleRef getCPtr(switch_uint31_t obj) { + return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_uint31_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != global::System.IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_uint31_t(swigCPtr); + } + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); + } + global::System.GC.SuppressFinalize(this); + } + } + + public uint value { + set { + freeswitchPINVOKE.switch_uint31_t_value_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_uint31_t_value_get(swigCPtr); + return ret; + } + } + + public switch_uint31_t() : this(freeswitchPINVOKE.new_switch_uint31_t(), true) { + } + +} + +} +//------------------------------------------------------------------------------ +// +// +// This file was automatically generated by SWIG (http://www.swig.org). +// Version 3.0.12 +// +// Do not make changes to this file unless you know what you are doing--modify +// the SWIG interface file instead. +//------------------------------------------------------------------------------ + +namespace FreeSWITCH.Native { + public class switch_unicast_conninfo : global::System.IDisposable { private global::System.Runtime.InteropServices.HandleRef swigCPtr; protected bool swigCMemOwn; From 8224bb8e65bd876ead46b21db57ccf09a7478404 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 11 May 2024 12:37:32 +0300 Subject: [PATCH 127/205] [Build-System] Add ARM64 support, extend Debian helper scripts. Co-authored-by: s3rj1k --- debian/bootstrap.sh | 63 +++++++++++++++++---------------- debian/util.sh | 48 ++++++++++++++++++------- debian/version-omit_revision.pl | 22 ++++++++++++ 3 files changed, 91 insertions(+), 42 deletions(-) create mode 100755 debian/version-omit_revision.pl diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index aba9e38bf7..fa40702938 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -65,6 +65,9 @@ avoid_mods=( avoid_mods_armhf=( languages/mod_v8 ) +avoid_mods_arm64=( + languages/mod_v8 +) avoid_mods_sid=( directories/mod_ldap ) @@ -352,7 +355,7 @@ EOF print_core_control () { cat <= 1.13.17) Recommends: Suggests: libfreeswitch1-dbg @@ -385,7 +388,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: python-esl Section: python -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${shlibs:Depends}, \${misc:Depends}, \${python:Depends} Description: Cross-Platform Scalable Multi-Protocol Soft Switch $(debian_wrap "${fs_description}") @@ -394,7 +397,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: libesl-perl Section: perl -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${shlibs:Depends}, \${misc:Depends}, \${perl:Depends} Description: Cross-Platform Scalable Multi-Protocol Soft Switch $(debian_wrap "${fs_description}") @@ -402,7 +405,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch This package contains the Perl binding for FreeSWITCH Event Socket Library (ESL). Package: freeswitch-meta-bare -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}) Recommends: freeswitch-doc (= \${binary:Version}), @@ -420,7 +423,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch bare FreeSWITCH install. Package: freeswitch-meta-default -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-commands (= \${binary:Version}), freeswitch-mod-conference (= \${binary:Version}), @@ -462,7 +465,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch reasonably basic FreeSWITCH install. Package: freeswitch-meta-vanilla -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-init, freeswitch-mod-console (= \${binary:Version}), @@ -511,7 +514,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch running the FreeSWITCH vanilla example configuration. Package: freeswitch-meta-sorbet -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), Recommends: freeswitch-init, @@ -594,7 +597,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch modules except a few which aren't recommended. Package: freeswitch-meta-all -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-init, freeswitch-lang (= \${binary:Version}), @@ -705,7 +708,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH modules. Package: freeswitch-meta-codecs -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-amr (= \${binary:Version}), freeswitch-mod-amrwb (= \${binary:Version}), @@ -732,7 +735,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch most FreeSWITCH codecs. Package: freeswitch-meta-codecs-dbg -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-amr-dbg (= \${binary:Version}), freeswitch-mod-amrwb-dbg (= \${binary:Version}), @@ -759,7 +762,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch most FreeSWITCH codecs. Package: freeswitch-meta-conf -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-conf-curl (= \${binary:Version}), freeswitch-conf-insideout (= \${binary:Version}), @@ -773,7 +776,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch examples for FreeSWITCH. Package: freeswitch-meta-lang -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-lang-de (= \${binary:Version}), freeswitch-lang-en (= \${binary:Version}), @@ -789,7 +792,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH. Package: freeswitch-meta-mod-say -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-mod-say-de (= \${binary:Version}), freeswitch-mod-say-en (= \${binary:Version}), @@ -814,7 +817,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH. Package: freeswitch-meta-mod-say-dbg -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-mod-say-de-dbg (= \${binary:Version}), freeswitch-mod-say-en-dbg (= \${binary:Version}), @@ -839,7 +842,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH. Package: freeswitch-meta-all-dbg -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-meta-codecs-dbg (= \${binary:Version}), freeswitch-meta-mod-say (= \${binary:Version}), @@ -943,7 +946,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: freeswitch-all-dbg Section: debug Priority: optional -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-meta-all (= \${binary:Version}), freeswitch-meta-all-dbg (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") @@ -953,7 +956,7 @@ Description: debugging symbols for FreeSWITCH Package: freeswitch-dbg Section: debug Priority: optional -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") @@ -963,7 +966,7 @@ Description: debugging symbols for FreeSWITCH Package: libfreeswitch1-dbg Section: debug Priority: optional -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, libfreeswitch1 (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") @@ -972,7 +975,7 @@ Description: debugging symbols for FreeSWITCH Package: libfreeswitch-dev Section: libdevel -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch Description: development libraries and header files for FreeSWITCH $(debian_wrap "${fs_description}") @@ -981,7 +984,7 @@ Description: development libraries and header files for FreeSWITCH Package: freeswitch-doc Section: doc -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends} Description: documentation for FreeSWITCH $(debian_wrap "${fs_description}") @@ -994,7 +997,7 @@ Description: documentation for FreeSWITCH ## languages Package: freeswitch-lang -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-lang-en (= \${binary:Version}) Description: Language files for FreeSWITCH @@ -1006,7 +1009,7 @@ Description: Language files for FreeSWITCH ## timezones Package: freeswitch-timezones -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends} Description: Timezone files for FreeSWITCH $(debian_wrap "${fs_description}") @@ -1020,7 +1023,7 @@ EOF if [ ${use_sysvinit} = "true" ]; then cat <= 3.0-6), sysvinit | sysvinit-utils Conflicts: freeswitch-init Provides: freeswitch-init @@ -1033,7 +1036,7 @@ EOF else cat <&2 echo $orig } @@ -292,9 +308,9 @@ create_dsc () { prep_create_dsc "$@" - local OPTIND OPTARG suite_postfix="" suite_postfix_p=false zl=9 + local OPTIND OPTARG suite_postfix="" suite_postfix_p=false soft_reset=false zl=9 - while getopts 'a:f:m:p:s:u:z:' o "$@"; do + while getopts 'a:f:m:p:s:u:xz:' o "$@"; do case "$o" in a) ;; f) ;; @@ -302,6 +318,7 @@ create_dsc () { p) ;; s) ;; u) suite_postfix="$OPTARG"; suite_postfix_p=true;; + x) soft_reset=true;; z) zl="$OPTARG";; esac done @@ -328,7 +345,11 @@ create_dsc () { local dsc="../$(dsc_base).dsc" - git reset --hard HEAD^ && git clean -fdx + if $soft_reset; then + git reset --soft HEAD^ + else + git reset --hard HEAD^ && git clean -fdx + fi } 1>&2 echo $dsc } @@ -686,6 +707,7 @@ commands: Set FS bootstrap/build -j flags -u Specify a custom suite postfix + -x Use git soft reset instead of hard reset -z Set compression level create-orig (same for 'prep_create_orig') @@ -694,6 +716,8 @@ commands: Choose custom list of modules to build -n Nightly build -v Set version + -V Set version (without replacing every '-' to '~') + -x Use git soft reset instead of hard reset -z Set compression level EOF diff --git a/debian/version-omit_revision.pl b/debian/version-omit_revision.pl new file mode 100755 index 0000000000..c6f5767a29 --- /dev/null +++ b/debian/version-omit_revision.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Dpkg::Version; + +my $version; + +open(my $fh, '-|', 'dpkg-parsechangelog -S version') or die "Failed to execute dpkg-parsechangelog: $!"; +{ + local $/; + $version = <$fh>; +} +close $fh; + +$version =~ s/\s+$//; + +die "No version found or empty output from dpkg-parsechangelog" unless defined $version and $version ne ''; + +my $v = Dpkg::Version->new($version); +my $vs = $v->as_string(omit_epoch => 1, omit_revision => 1); + +print "$vs\n"; From 72d17ccf5c559947de2e2c08b0778f677e3e5051 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 6 Jun 2024 23:59:10 +0200 Subject: [PATCH 128/205] [GHA] Add build workflow. --- .../docker/debian/bookworm/amd64/Dockerfile | 97 ++++++++++++++++ .../docker/debian/bookworm/arm32v7/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bookworm/arm64v8/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bullseye/amd64/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bullseye/arm32v7/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bullseye/arm64v8/Dockerfile | 96 ++++++++++++++++ .github/docker/debian/buster/amd64/Dockerfile | 97 ++++++++++++++++ .../docker/debian/buster/arm32v7/Dockerfile | 96 ++++++++++++++++ .../docker/debian/buster/arm64v8/Dockerfile | 96 ++++++++++++++++ .github/workflows/build.yml | 107 ++++++++++++++++++ 10 files changed, 973 insertions(+) create mode 100644 .github/docker/debian/bookworm/amd64/Dockerfile create mode 100644 .github/docker/debian/bookworm/arm32v7/Dockerfile create mode 100644 .github/docker/debian/bookworm/arm64v8/Dockerfile create mode 100644 .github/docker/debian/bullseye/amd64/Dockerfile create mode 100644 .github/docker/debian/bullseye/arm32v7/Dockerfile create mode 100644 .github/docker/debian/bullseye/arm64v8/Dockerfile create mode 100644 .github/docker/debian/buster/amd64/Dockerfile create mode 100644 .github/docker/debian/buster/arm32v7/Dockerfile create mode 100644 .github/docker/debian/buster/arm64v8/Dockerfile create mode 100644 .github/workflows/build.yml diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile new file mode 100644 index 0000000000..b500830148 --- /dev/null +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -0,0 +1,97 @@ +ARG BUILDER_IMAGE=debian:bookworm-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" + +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile new file mode 100644 index 0000000000..43b4778b3e --- /dev/null +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm32v7/debian:bookworm-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile new file mode 100644 index 0000000000..50c24957f1 --- /dev/null +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm64v8/debian:bookworm-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile new file mode 100644 index 0000000000..aefbd38224 --- /dev/null +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=debian:bullseye-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile new file mode 100644 index 0000000000..b3a6f00c36 --- /dev/null +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm32v7/debian:bullseye-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile new file mode 100644 index 0000000000..dfa899540e --- /dev/null +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm64v8/debian:bullseye-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile new file mode 100644 index 0000000000..119a18076e --- /dev/null +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -0,0 +1,97 @@ +ARG BUILDER_IMAGE=debian:buster-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=buster +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} + +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile new file mode 100644 index 0000000000..2113f55bd8 --- /dev/null +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm32v7/debian:buster-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=buster +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile new file mode 100644 index 0000000000..150a77fec2 --- /dev/null +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm64v8/debian:buster-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=buster +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..e16da9a364 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,107 @@ +name: Build and Distribute + +on: + pull_request: + push: + branches: + - master + paths: + - "**" + workflow_dispatch: + +concurrency: + group: ${{ github.head_ref || github.ref }} + +jobs: + excludes: + runs-on: ubuntu-latest + outputs: + deb: ${{ steps.deb.outputs.excludes }} + steps: + - id: deb + name: Generate Matrix excludes for DEB + run: | + JSON="[]" + + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + JSON=$(jq -n '[ + { + "version": "bookworm", + "platform": { + "name": "amd64" + } + }, + { + "version": "bookworm", + "platform": { + "name": "arm64v8" + } + }, + { + "version": "bullseye" + } + ]') + fi + + echo "excludes=$(echo $JSON | jq -c .)" | tee -a $GITHUB_OUTPUT + + deb: + name: 'DEB' + permissions: + id-token: write + contents: read + needs: + - excludes + uses: signalwire/actions-template/.github/workflows/cicd-docker-build-and-distribute.yml@main + strategy: + # max-parallel: 1 + fail-fast: false + matrix: + os: + - debian + version: + - bookworm + - bullseye + - buster + platform: + - name: amd64 + runner: ubuntu-latest + - name: arm32v7 + runner: linux-arm64-4-core-public + - name: arm64v8 + runner: linux-arm64-4-core-public + exclude: ${{ fromJson(needs.excludes.outputs.deb) }} + with: + RUNNER: ${{ matrix.platform.runner }} + ARTIFACTS_PATTERN: '.*\.(deb|dsc|changes|tar.bz2|tar.gz|tar.lzma|tar.xz)$' + DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile + MAINTAINER: 'Andrey Volk ' + META_FILE_PATH_PREFIX: /var/www/freeswitch/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }} + PLATFORM: ${{ matrix.platform.name }} + REPO_DOMAIN: freeswitch.signalwire.com + TARGET_ARTIFACT_NAME: ${{ matrix.os }}-${{ matrix.version }}-${{ matrix.platform.name }}-artifact + UPLOAD_BUILD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':upload-artifacts') }} + secrets: + GH_BOT_DEPLOY_TOKEN: ${{ secrets.PAT }} + HOSTNAME: ${{ secrets.HOSTNAME }} + PROXY_URL: ${{ secrets.PROXY_URL }} + USERNAME: ${{ secrets.USERNAME }} + TELEPORT_TOKEN: ${{ secrets.TELEPORT_TOKEN }} + REPO_USERNAME: 'signalwire' + REPO_PASSWORD: ${{ secrets.REPOTOKEN }} + + meta: + name: 'Publish build data to meta-repo' + if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':upload-artifacts') }} + needs: + - deb + permissions: + id-token: write + contents: read + uses: signalwire/actions-template/.github/workflows/meta-repo-content.yml@main + with: + META_CONTENT: '/var/www/freeswitch/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }}' + META_REPO: signalwire/bamboo_gha_trigger + META_REPO_BRANCH: trigger/freeswitch/${{ github.ref_name }} + secrets: + GH_BOT_DEPLOY_TOKEN: ${{ secrets.PAT }} From a0e7fb8e7112cfaf413c6f26c7fa7709279ebc21 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 7 Mar 2024 21:45:13 +0300 Subject: [PATCH 129/205] [Build-System] Update expired Certificate Thumbprint on Windows. --- w32/Setup/Setup.2017.wixproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index bf0aae0498..ef66d7c2e8 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -13,7 +13,7 @@ 2.0 FreeSWITCH Package - bf386393c880967b00adbc438aee534de6211774 + 076ce3c57198fc39443bd87f4aab86dac0aab62d http://timestamp.comodoca.com $(WindowsSDK80Path)bin\x86\signtool.exe $(WindowsSDK80Path)bin\x64\signtool.exe From 453b18d893e01a4351aac0cf9517439ca077eca8 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Sat, 22 Jun 2024 16:26:28 +0200 Subject: [PATCH 130/205] [GHA] Rework how secrets are used inside Dockerfiles. --- .../docker/debian/bookworm/amd64/Dockerfile | 31 ++++++++++++------- .../docker/debian/bookworm/arm32v7/Dockerfile | 31 ++++++++++++------- .../docker/debian/bookworm/arm64v8/Dockerfile | 31 ++++++++++++------- .../docker/debian/bullseye/amd64/Dockerfile | 31 ++++++++++++------- .../docker/debian/bullseye/arm32v7/Dockerfile | 31 ++++++++++++------- .../docker/debian/bullseye/arm64v8/Dockerfile | 31 ++++++++++++------- .github/docker/debian/buster/amd64/Dockerfile | 31 ++++++++++++------- .../docker/debian/buster/arm32v7/Dockerfile | 31 ++++++++++++------- .../docker/debian/buster/arm64v8/Dockerfile | 31 ++++++++++++------- 9 files changed, 171 insertions(+), 108 deletions(-) diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile index b500830148..844d9494a4 100644 --- a/.github/docker/debian/bookworm/amd64/Dockerfile +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile index 43b4778b3e..164e602356 100644 --- a/.github/docker/debian/bookworm/arm32v7/Dockerfile +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODE deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile index 50c24957f1..0e30f8504e 100644 --- a/.github/docker/debian/bookworm/arm64v8/Dockerfile +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile index aefbd38224..e4557f1ed6 100644 --- a/.github/docker/debian/bullseye/amd64/Dockerfile +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile index b3a6f00c36..03eb59b40f 100644 --- a/.github/docker/debian/bullseye/arm32v7/Dockerfile +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODE deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile index dfa899540e..ca216a82d7 100644 --- a/.github/docker/debian/bullseye/arm64v8/Dockerfile +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile index 119a18076e..a0da4dbe7c 100644 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -73,9 +64,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile index 2113f55bd8..c283d9c6ce 100644 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODE deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile index 150a77fec2..ac1f77959f 100644 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ From 1c7163e2ce5bc404551bcc15224d3a1c37b7ab68 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Sat, 22 Jun 2024 18:49:55 +0200 Subject: [PATCH 131/205] [GHA] Fail early when required secret not set. --- .github/docker/debian/bookworm/amd64/Dockerfile | 3 +-- .github/docker/debian/bookworm/arm32v7/Dockerfile | 3 +-- .github/docker/debian/bookworm/arm64v8/Dockerfile | 3 +-- .github/docker/debian/bullseye/amd64/Dockerfile | 3 +-- .github/docker/debian/bullseye/arm32v7/Dockerfile | 3 +-- .github/docker/debian/bullseye/arm64v8/Dockerfile | 3 +-- .github/docker/debian/buster/amd64/Dockerfile | 3 +-- .github/docker/debian/buster/arm32v7/Dockerfile | 3 +-- .github/docker/debian/buster/arm64v8/Dockerfile | 3 +-- .github/workflows/build.yml | 8 +++++++- 10 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile index 844d9494a4..7b1dc8bf38 100644 --- a/.github/docker/debian/bookworm/amd64/Dockerfile +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile index 164e602356..08608032a4 100644 --- a/.github/docker/debian/bookworm/arm32v7/Dockerfile +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile index 0e30f8504e..e509a587e6 100644 --- a/.github/docker/debian/bookworm/arm64v8/Dockerfile +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile index e4557f1ed6..0d11c84dec 100644 --- a/.github/docker/debian/bullseye/amd64/Dockerfile +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile index 03eb59b40f..7ea36d1bcc 100644 --- a/.github/docker/debian/bullseye/arm32v7/Dockerfile +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile index ca216a82d7..ae3429cff7 100644 --- a/.github/docker/debian/bullseye/arm64v8/Dockerfile +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile index a0da4dbe7c..9f3d03f14c 100644 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -64,7 +64,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -73,7 +73,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile index c283d9c6ce..362c2a6602 100644 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile index ac1f77959f..ed678405a9 100644 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e16da9a364..ec183137b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,12 @@ name: Build and Distribute on: + pull_request_target: + types: + - ready_for_review + paths: + - '**' + - '!.github/' pull_request: push: branches: @@ -23,7 +29,7 @@ jobs: run: | JSON="[]" - if [[ "${{ github.event_name }}" == "pull_request" ]]; then + if [[ "${{ github.event_name }}" == "pull_request" || "${{ github.event_name }}" == "pull_request_target" ]]; then JSON=$(jq -n '[ { "version": "bookworm", From 89a2db91c823086237600cfa3ce6bddfe92006e5 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 17:00:45 +0200 Subject: [PATCH 132/205] [GHA] Increase verbosity for `mount=type=secret`. --- .github/docker/debian/bookworm/amd64/Dockerfile | 2 +- .github/docker/debian/bookworm/arm32v7/Dockerfile | 2 +- .github/docker/debian/bookworm/arm64v8/Dockerfile | 2 +- .github/docker/debian/bullseye/amd64/Dockerfile | 2 +- .github/docker/debian/bullseye/arm32v7/Dockerfile | 2 +- .github/docker/debian/bullseye/arm64v8/Dockerfile | 2 +- .github/docker/debian/buster/amd64/Dockerfile | 2 +- .github/docker/debian/buster/arm32v7/Dockerfile | 2 +- .github/docker/debian/buster/arm64v8/Dockerfile | 2 +- .github/workflows/build.yml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile index 7b1dc8bf38..3ef7b38b38 100644 --- a/.github/docker/debian/bookworm/amd64/Dockerfile +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile index 08608032a4..6259c7e8e9 100644 --- a/.github/docker/debian/bookworm/arm32v7/Dockerfile +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile index e509a587e6..0df5a178fe 100644 --- a/.github/docker/debian/bookworm/arm64v8/Dockerfile +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile index 0d11c84dec..56586d338e 100644 --- a/.github/docker/debian/bullseye/amd64/Dockerfile +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile index 7ea36d1bcc..24c5804b68 100644 --- a/.github/docker/debian/bullseye/arm32v7/Dockerfile +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile index ae3429cff7..f5a6a906c4 100644 --- a/.github/docker/debian/bullseye/arm64v8/Dockerfile +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile index 9f3d03f14c..8e88ce56e6 100644 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -69,6 +68,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile index 362c2a6602..9326979622 100644 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile index ed678405a9..71aca46052 100644 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec183137b4..a3be4b2c2c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,7 +93,7 @@ jobs: PROXY_URL: ${{ secrets.PROXY_URL }} USERNAME: ${{ secrets.USERNAME }} TELEPORT_TOKEN: ${{ secrets.TELEPORT_TOKEN }} - REPO_USERNAME: 'signalwire' + REPO_USERNAME: 'SWUSERNAME' REPO_PASSWORD: ${{ secrets.REPOTOKEN }} meta: From c8b8f0d9614987fef2b07b48ba4d5ac9ddbf9e44 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 20:35:43 +0200 Subject: [PATCH 133/205] [GHA] Rework `pull_request_target` workflow. --- .github/workflows/build-from-fork.yml | 75 +++++++++++++++++++++++++++ .github/workflows/build.yml | 8 +-- 2 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/build-from-fork.yml diff --git a/.github/workflows/build-from-fork.yml b/.github/workflows/build-from-fork.yml new file mode 100644 index 0000000000..0fe53c239a --- /dev/null +++ b/.github/workflows/build-from-fork.yml @@ -0,0 +1,75 @@ +name: Build from fork + +on: + pull_request_target: + types: + - ready_for_review + paths: + - '**' + - '!.github/' + workflow_dispatch: + +concurrency: + group: ${{ github.head_ref || github.ref }} + +jobs: + deb: + name: 'DEB' + strategy: + max-parallel: 1 + fail-fast: true + matrix: + os: + - debian + version: + - bookworm + - bullseye + - buster + platform: + - name: amd64 + runner: ubuntu-latest + - name: arm32v7 + runner: linux-arm64-4-core-public + - name: arm64v8 + runner: linux-arm64-4-core-public + exclude: + - version: bookworm + platform: + name: amd64 + - version: bookworm + platform: + name: arm64v8 + - version: bullseye + + runs-on: ${{ matrix.platform.runner }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + path: code + + - name: Checkout reusable actions + uses: actions/checkout@v4 + with: + repository: signalwire/actions-template + ref: main + fetch-depth: 1 + path: actions + sparse-checkout: | + .github/actions/docker-build-artifacts/action.yml + sparse-checkout-cone-mode: false + + - name: Build artifacts via Docker + uses: ./actions/.github/actions/docker-build-artifacts + with: + REPO_DOMAIN: freeswitch.signalwire.com + PLATFORM: ${{ matrix.platform.name }} + DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile + MAINTAINER: 'Andrey Volk ' + WORKING_DIRECTORY: code + env: + REPO_USERNAME: 'SWUSERNAME' + REPO_PASSWORD: ${{ secrets.REPO_PASSWORD }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a3be4b2c2c..df3baa4992 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,6 @@ name: Build and Distribute on: - pull_request_target: - types: - - ready_for_review - paths: - - '**' - - '!.github/' pull_request: push: branches: @@ -29,7 +23,7 @@ jobs: run: | JSON="[]" - if [[ "${{ github.event_name }}" == "pull_request" || "${{ github.event_name }}" == "pull_request_target" ]]; then + if [[ "${{ github.event_name }}" == "pull_request" ]]; then JSON=$(jq -n '[ { "version": "bookworm", From 4a15dc1a6252a53ba18c76d595509c083de7d197 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 21:38:29 +0200 Subject: [PATCH 134/205] [GHA] Pin workflow to repository. --- .github/workflows/build-from-fork.yml | 1 - .github/workflows/build.yml | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-from-fork.yml b/.github/workflows/build-from-fork.yml index 0fe53c239a..b98cadb134 100644 --- a/.github/workflows/build-from-fork.yml +++ b/.github/workflows/build-from-fork.yml @@ -7,7 +7,6 @@ on: paths: - '**' - '!.github/' - workflow_dispatch: concurrency: group: ${{ github.head_ref || github.ref }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df3baa4992..5b7cfb3665 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,8 @@ concurrency: jobs: excludes: + name: 'Excludes' + if: github.repository == 'signalwire/freeswitch' runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} @@ -47,6 +49,7 @@ jobs: deb: name: 'DEB' + if: github.repository == 'signalwire/freeswitch' permissions: id-token: write contents: read From 318953d078c1b109120cac24af231eaf8e7b63f1 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 22:15:53 +0200 Subject: [PATCH 135/205] [GHA] Pin workflow to repository. --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b7cfb3665..59958dfc0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ concurrency: jobs: excludes: name: 'Excludes' - if: github.repository == 'signalwire/freeswitch' + if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} @@ -49,7 +49,7 @@ jobs: deb: name: 'DEB' - if: github.repository == 'signalwire/freeswitch' + if: github.event.pull_request.head.repo.full_name == github.repository permissions: id-token: write contents: read From 460d1c19cfb191e73396650727b93ee8936d744d Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 27 Jun 2024 13:25:53 +0200 Subject: [PATCH 136/205] [GHA] Remove `build-from-fork.yml`. --- .github/workflows/build-from-fork.yml | 74 --------------------------- 1 file changed, 74 deletions(-) delete mode 100644 .github/workflows/build-from-fork.yml diff --git a/.github/workflows/build-from-fork.yml b/.github/workflows/build-from-fork.yml deleted file mode 100644 index b98cadb134..0000000000 --- a/.github/workflows/build-from-fork.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Build from fork - -on: - pull_request_target: - types: - - ready_for_review - paths: - - '**' - - '!.github/' - -concurrency: - group: ${{ github.head_ref || github.ref }} - -jobs: - deb: - name: 'DEB' - strategy: - max-parallel: 1 - fail-fast: true - matrix: - os: - - debian - version: - - bookworm - - bullseye - - buster - platform: - - name: amd64 - runner: ubuntu-latest - - name: arm32v7 - runner: linux-arm64-4-core-public - - name: arm64v8 - runner: linux-arm64-4-core-public - exclude: - - version: bookworm - platform: - name: amd64 - - version: bookworm - platform: - name: arm64v8 - - version: bullseye - - runs-on: ${{ matrix.platform.runner }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - path: code - - - name: Checkout reusable actions - uses: actions/checkout@v4 - with: - repository: signalwire/actions-template - ref: main - fetch-depth: 1 - path: actions - sparse-checkout: | - .github/actions/docker-build-artifacts/action.yml - sparse-checkout-cone-mode: false - - - name: Build artifacts via Docker - uses: ./actions/.github/actions/docker-build-artifacts - with: - REPO_DOMAIN: freeswitch.signalwire.com - PLATFORM: ${{ matrix.platform.name }} - DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile - MAINTAINER: 'Andrey Volk ' - WORKING_DIRECTORY: code - env: - REPO_USERNAME: 'SWUSERNAME' - REPO_PASSWORD: ${{ secrets.REPO_PASSWORD }} From 5f4036eaac7ca52b3b511ac4eeecd267f8d4d454 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Mon, 22 Jul 2024 16:39:05 +0200 Subject: [PATCH 137/205] [GHA] Disable repo name check. --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59958dfc0a..2d1ddf07fc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,7 @@ on: push: branches: - master + - v1.10 paths: - "**" workflow_dispatch: @@ -15,7 +16,7 @@ concurrency: jobs: excludes: name: 'Excludes' - if: github.event.pull_request.head.repo.full_name == github.repository + # if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} @@ -49,7 +50,7 @@ jobs: deb: name: 'DEB' - if: github.event.pull_request.head.repo.full_name == github.repository + # if: github.event.pull_request.head.repo.full_name == github.repository permissions: id-token: write contents: read From 19270516bf9bf8b2854aa9788b8cba7de55c9314 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Mon, 22 Jul 2024 16:57:32 +0200 Subject: [PATCH 138/205] [UTIL] Generate reproducible source archive. --- debian/util.sh | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/debian/util.sh b/debian/util.sh index 46c1f95346..dab53b1d47 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -203,11 +203,16 @@ create_orig () { done shift $(($OPTIND-1)) - local orig + local commit_epoch=$(git log -1 --format=%ct) + local source_date=$(date -u -d @$commit_epoch +'%Y-%m-%d %H:%M:%S') + + local orig git_archive_prefix if $auto_orig; then orig="../freeswitch_$(debian/version-omit_revision.pl).orig.tar.xz" + git_archive_prefix="freeswitch/" else orig="../freeswitch_$(mk_dver "$uver")~$(lsb_release -sc).orig.tar.xz" + git_archive_prefix="freeswitch-$uver/" fi mv .gitattributes .gitattributes.orig @@ -226,12 +231,32 @@ create_orig () { git add -f configure.ac .version git commit --allow-empty -m "nightly v$uver" + local tmpsrcdir="$(mktemp -d)" git archive -v \ --worktree-attributes \ --format=tar \ - --prefix=freeswitch-$uver/ \ - HEAD \ - | xz -c -${zl}v > $orig + --prefix=$git_archive_prefix \ + HEAD | tar --extract --directory="$tmpsrcdir" + + # https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html + tar \ + --sort=name \ + --format=posix \ + --pax-option='exthdr.name=%d/PaxHeaders/%f' \ + --pax-option='delete=atime,delete=ctime' \ + --clamp-mtime \ + --mtime="$source_date" \ + --numeric-owner \ + --owner=0 \ + --group=0 \ + --mode='go+u,go-w' \ + --create \ + --directory="$tmpsrcdir" \ + . | xz -v -c -${zl} > "$orig" && \ + rm -rf "$tmpsrcdir" + + echo "Source archive checksum:" + sha256sum $orig mv .gitattributes.orig .gitattributes From 93072c9503ed737303d0995ddeb7db330f17bdde Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 25 Jul 2024 21:46:40 +0300 Subject: [PATCH 139/205] [core] check_rtcp_and_ice() - stringop-overflow: Fix build on Debian Bookworm. --- src/switch_rtp.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 1125e2f59b..3d9e2ae624 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -185,6 +185,10 @@ typedef struct { char body[SWITCH_RTCP_MAX_BUF_LEN]; } rtcp_msg_t; +typedef struct { + switch_rtcp_hdr_t header; + uint32_t ssrc; +} sdes_ssrc_t; typedef enum { VAD_FIRE_TALK = (1 << 0), @@ -2228,9 +2232,9 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) struct switch_rtcp_report_block *rtcp_report_block = NULL; switch_size_t rtcp_bytes = sizeof(struct switch_rtcp_hdr_s)+sizeof(uint32_t); /* add size of the packet header and the ssrc */ switch_rtcp_hdr_t *sdes; + sdes_ssrc_t *sdes_ssrc; uint8_t *p; switch_size_t sdes_bytes = sizeof(struct switch_rtcp_hdr_s); - uint32_t *ssrc; switch_rtcp_sdes_unit_t *unit; switch_bool_t is_only_receiver = FALSE; @@ -2426,14 +2430,13 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) //SDES + CNAME p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes; - sdes = (switch_rtcp_hdr_t *) p; + sdes_ssrc = (sdes_ssrc_t *) p; + sdes = &sdes_ssrc->header; sdes->version = 2; sdes->type = _RTCP_PT_SDES; sdes->count = 1; sdes->p = 0; - p = (uint8_t *) (sdes) + sdes_bytes; - ssrc = (uint32_t *) p; - *ssrc = htonl(rtp_session->ssrc); + sdes_ssrc->ssrc = htonl(rtp_session->ssrc); sdes_bytes += sizeof(uint32_t); From b38d87941351b509382d6d83afbbcc1a7f150a44 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:50:56 +0300 Subject: [PATCH 140/205] [Core] rtp_common_write: Coverity 1227609 Calling risky function --- src/switch_rtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 3d9e2ae624..a27703f449 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -8267,11 +8267,11 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { int external = (flags && *flags & SFF_EXTERNAL); /* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base - so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough* + so if the timestamps and ssrc of the source change, it will not break the other end's jitter buffer / decoder etc *cough* CHROME *cough* */ if (!rtp_session->ts_norm.ts) { - rtp_session->ts_norm.ts = (uint32_t) rand() % 1000000 + 1; + rtp_session->ts_norm.ts = (uint32_t) switch_rand() % 1000000 + 1; } if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc || rtp_session->ts_norm.last_external != external) { From a99ed5c46f03094703befa056e1c95e84cbf9a14 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 29 Jul 2024 21:50:13 +0300 Subject: [PATCH 141/205] [Core] Introduce SWITCH_RAND_MAX to switch_rand() --- src/include/switch_types.h | 7 +++++++ src/switch_utils.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index f8ae00790d..c4c9131bd6 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -599,6 +599,13 @@ SWITCH_DECLARE_DATA extern switch_filenames SWITCH_GLOBAL_filenames; #define SWITCH_ACCEPTABLE_INTERVAL(_i) (_i && _i <= SWITCH_MAX_INTERVAL && (_i % 10) == 0) +/* Check if RAND_MAX is a power of 2 minus 1 or in other words all bits set */ +#if ((RAND_MAX) & ((RAND_MAX) + 1)) == 0 && (RAND_MAX) != 0 +#define SWITCH_RAND_MAX RAND_MAX +#else +#define SWITCH_RAND_MAX 0x7fff +#endif + typedef enum { SWITCH_RW_READ, SWITCH_RW_WRITE diff --git a/src/switch_utils.c b/src/switch_utils.c index 64577d3997..90c5de059a 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4835,8 +4835,8 @@ SWITCH_DECLARE(int) switch_rand(void) BCryptCloseAlgorithmProvider(hAlgorithm, 0); - /* Make sure we return from 0 to RAND_MAX */ - return (random_number & 0x7FFF); + /* Make sure we return from 0 to SWITCH_RAND_MAX */ + return (random_number & (SWITCH_RAND_MAX)); #elif defined(__unix__) || defined(__APPLE__) int random_fd = open("/dev/urandom", O_RDONLY); ssize_t result; @@ -4865,8 +4865,8 @@ SWITCH_DECLARE(int) switch_rand(void) close(random_fd); - /* Make sure we return from 0 to RAND_MAX */ - return (random_number & 0x7FFF); + /* Make sure we return from 0 to SWITCH_RAND_MAX */ + return (random_number & (SWITCH_RAND_MAX)); #else return rand(); #endif From b43ae84564a971fe446759e3c9fce49be65b2bee Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:53:44 +0300 Subject: [PATCH 142/205] [Core] switch_rtp_create: Coverity 1227620 Calling risky function --- src/switch_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index a27703f449..6f33b47992 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4517,7 +4517,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session switch_sockaddr_create(&rtp_session->rtcp_from_addr, pool); } - rtp_session->seq = (uint16_t) rand(); + rtp_session->seq = (uint16_t) switch_rand(); rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (switch_time_t) switch_epoch_time_now(NULL)); #ifdef DEBUG_TS_ROLLOVER rtp_session->last_write_ts = TS_ROLLOVER_START; From 1ff5a6593cedc8c14855d314f614f9460fdcf7ad Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 12:16:42 +0300 Subject: [PATCH 143/205] [Core] switch_rtp.c: Coverity 1500271, 1500287: Out-of-bounds access (OVERRUN) --- src/switch_rtp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 6f33b47992..46e13253b7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -8520,9 +8520,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } if (!rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_MKI]) { - stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &send_msg->header, &sbytes); + stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], send_msg, &sbytes); } else { - stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &send_msg->header, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); + stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], send_msg, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); } if (stat) { @@ -9044,9 +9044,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_write_raw(switch_rtp_t *rtp_session, } if (!rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_MKI]) { - stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg.header, &sbytes); + stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg, &sbytes); } else { - stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg.header, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); + stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); } if (stat) { From 11e3cff7cb9097c347663fe3092947648eadef91 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 12:58:57 +0300 Subject: [PATCH 144/205] [Core] switch_find_local_ip: Coverity 1024290 Resource leak. --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index 90c5de059a..1af2011dbd 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2015,7 +2015,7 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma } doh: - if (tmp_socket > 0) { + if (tmp_socket >= 0) { close(tmp_socket); } #endif From 9f7c64b6fafa1afb53c6ce4c3d944767382f4544 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 12:47:07 +0300 Subject: [PATCH 145/205] [Core] switch_stun.c: Coverity 1468480: Out-of-bounds access (OVERRUN) --- src/include/switch_stun.h | 7 +++++++ src/switch_stun.c | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index 54b03088e8..ca612c06aa 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -141,6 +141,13 @@ typedef struct { uint32_t address; } switch_stun_ip_t; +typedef struct { + uint8_t wasted; + uint8_t family; + uint16_t port; + uint8_t address[16]; +} switch_stun_ipv6_t; + #if SWITCH_BYTE_ORDER == __BIG_ENDIAN typedef struct { diff --git a/src/switch_stun.c b/src/switch_stun.c index d4a2c96503..2ab1f41d5a 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -401,13 +401,17 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_s SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, switch_stun_packet_header_t *header, char *ipstr, switch_size_t iplen, uint16_t *port) { switch_stun_ip_t *ip; + switch_stun_ipv6_t *ipv6; uint8_t x, *i; char *p = ipstr; ip = (switch_stun_ip_t *) attribute->value; if (ip->family == 2) { - uint8_t *v6addr = (uint8_t *) &ip->address; + uint8_t *v6addr; + + ipv6 = (switch_stun_ipv6_t *)attribute->value; + v6addr = (uint8_t *) &ipv6->address; v6_xor(v6addr, (uint8_t *)header->id); inet_ntop(AF_INET6, v6addr, ipstr, iplen); } else { From 6fbb49d66cdd6a630b30ad0b731707fc1f8c2903 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 9 Jun 2024 13:12:11 +0300 Subject: [PATCH 146/205] [mod_mariadb] mariadb_dsn: Coverity 1546237 COPY_INSTEAD_OF_MOVE --- src/mod/databases/mod_mariadb/mariadb_dsn.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp index eb7bfeedbd..06091eb469 100644 --- a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp +++ b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp @@ -83,11 +83,11 @@ public: if ("server" == key || "host" == key) { _host = value; } else if ("uid" == key || "user" == key || "username" == key) { - _user = value; + _user = std::move(value); } else if ("pwd" == key || "passwd" == key || "password" == key) { - _passwd = value; + _passwd = std::move(value); } else if ("database" == key || "db" == key) { - _db = value; + _db = std::move(value); } else if ("port" == key) { _port = std::stoi(value); } else if ("option" == key || "options" == key) { From 3c47eadd28505640113a76c3b82e2216be22dbbe Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 9 Jun 2024 13:13:43 +0300 Subject: [PATCH 147/205] [mod_v8] SayPhrase: Coverity 1546153 COPY_INSTEAD_OF_MOVE --- src/mod/languages/mod_v8/src/fssession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/languages/mod_v8/src/fssession.cpp b/src/mod/languages/mod_v8/src/fssession.cpp index d3bc77ae13..2510457175 100644 --- a/src/mod/languages/mod_v8/src/fssession.cpp +++ b/src/mod/languages/mod_v8/src/fssession.cpp @@ -671,7 +671,7 @@ JS_SESSION_FUNCTION_IMPL(SayPhrase) String::Utf8Value str(info[2]); tmp = js_safe_str(*str); if (!zstr(tmp.c_str())) { - phrase_lang = tmp; + phrase_lang = std::move(tmp); } } From 0974bd112cb0489040386c68889ebf2964e8029c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:52:27 +0300 Subject: [PATCH 148/205] [Core] switch_simple_email: Coverity 1227612 Calling risky function --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index 1af2011dbd..aa3fc74cae 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1160,7 +1160,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, switch_safe_free(dupfile); } - switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int)(switch_time_t) switch_epoch_time_now(NULL), rand() & 0xffff); + switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int)(switch_time_t) switch_epoch_time_now(NULL), switch_rand() & 0xffff); if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) > -1) { if (file) { From 844cce8595a9221e2620e1d61a4171a6a6f85524 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 13:07:43 +0300 Subject: [PATCH 149/205] [mod_mariadb] Coverity 1546237 COPY_INSTEAD_OF_MOVE --- src/mod/databases/mod_mariadb/mariadb_dsn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp index 06091eb469..aa7fb89412 100644 --- a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp +++ b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp @@ -81,7 +81,7 @@ public: std::string value = pair[1]; if ("server" == key || "host" == key) { - _host = value; + _host = std::move(value); } else if ("uid" == key || "user" == key || "username" == key) { _user = std::move(value); } else if ("pwd" == key || "passwd" == key || "password" == key) { From 9d379b707171b212dcc7d4b0f9db860719eeefa4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:55:10 +0300 Subject: [PATCH 150/205] [Core] switch_core_port_allocator_request_port: Coverity 1227622 Calling risky function --- src/switch_core_port_allocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_port_allocator.c b/src/switch_core_port_allocator.c index 074ce5f5ea..2ed956c6fb 100644 --- a/src/switch_core_port_allocator.c +++ b/src/switch_core_port_allocator.c @@ -155,7 +155,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c uint32_t tries = 0; /* randomly pick a port */ - index = rand() % alloc->track_len; + index = switch_rand() % alloc->track_len; /* if it is used walk up the list to find a free one */ while (alloc->track[index] && tries < alloc->track_len) { From c736458a21368fba462957ba98aa3f948facc313 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:56:56 +0300 Subject: [PATCH 151/205] [Core] switch_stun_random_string: Coverity 1227623 Calling risky function --- src/switch_stun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_stun.c b/src/switch_stun.c index 2ab1f41d5a..d58dd6fd93 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -135,7 +135,7 @@ SWITCH_DECLARE(void) switch_stun_random_string(char *buf, uint16_t len, char *se max = (int) strlen(set); for (x = 0; x < len; x++) { - int j = (int) (max * 1.0 * rand() / (RAND_MAX + 1.0)); + int j = (int) (max * 1.0 * switch_rand() / (SWITCH_RAND_MAX + 1.0)); buf[x] = set[j]; } } From 251da2f905ed4585cea1e263f585a5dd9e42be05 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:57:53 +0300 Subject: [PATCH 152/205] [mod_mariadb] mariadb_send_query: Coverity 1518917 Calling risky function --- src/mod/databases/mod_mariadb/mod_mariadb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/databases/mod_mariadb/mod_mariadb.c b/src/mod/databases/mod_mariadb/mod_mariadb.c index 09b67468bb..c39c2ce818 100644 --- a/src/mod/databases/mod_mariadb/mod_mariadb.c +++ b/src/mod/databases/mod_mariadb/mod_mariadb.c @@ -641,7 +641,7 @@ switch_status_t mariadb_send_query(mariadb_handle_t *handle, const char* sql) switch_safe_free(err_str); /* We are waiting for 500 ms and random time is not more than 500 ms. This is necessary so that the delay on the primary and secondary servers does not coincide and deadlock does not occur again. */ - switch_yield(500 + (rand() & 511)); + switch_yield(500 + (switch_rand() & 511)); goto again; } From b39f14679f6e030ce6a9da0fb754b5cb03bd0bd5 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Fri, 2 Aug 2024 18:54:28 +0200 Subject: [PATCH 153/205] [GHA] Remove Debian `Buster`. --- .github/docker/debian/buster/amd64/Dockerfile | 103 ------------------ .../docker/debian/buster/arm32v7/Dockerfile | 102 ----------------- .../docker/debian/buster/arm64v8/Dockerfile | 102 ----------------- .github/workflows/build.yml | 18 +-- 4 files changed, 10 insertions(+), 315 deletions(-) delete mode 100644 .github/docker/debian/buster/amd64/Dockerfile delete mode 100644 .github/docker/debian/buster/arm32v7/Dockerfile delete mode 100644 .github/docker/debian/buster/arm64v8/Dockerfile diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile deleted file mode 100644 index 8e88ce56e6..0000000000 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ /dev/null @@ -1,103 +0,0 @@ -ARG BUILDER_IMAGE=debian:buster-20240513 - -FROM ${BUILDER_IMAGE} AS builder - -ARG MAINTAINER_NAME="Andrey Volk" -ARG MAINTAINER_EMAIL="andrey@signalwire.com" - -# Credentials -ARG REPO_DOMAIN=freeswitch.signalwire.com -ARG REPO_USERNAME=user - -ARG BUILD_NUMBER=42 -ARG GIT_SHA=0000000000 - -ARG DATA_DIR=/data -ARG CODENAME=buster -ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" - -MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" - -SHELL ["/bin/bash", "-c"] - -RUN apt-get -q update && \ - DEBIAN_FRONTEND=noninteractive apt-get -yq install \ - apt-transport-https \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - debhelper \ - devscripts \ - dh-autoreconf \ - dos2unix \ - doxygen \ - git \ - graphviz \ - libglib2.0-dev \ - libssl-dev \ - lsb-release \ - pkg-config \ - wget - -RUN update-ca-certificates --fresh - -RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ - chmod +x ~/.env - -RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list -deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -EOF - -RUN git config --global --add safe.directory '*' \ - && git config --global user.name "${MAINTAINER_NAME}" \ - && git config --global user.email "${MAINTAINER_EMAIL}" - -# Bootstrap and Build -COPY . ${DATA_DIR} -WORKDIR ${DATA_DIR} - -RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env - -RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x -RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} - -RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ - printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ - printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ - printf "password " >> /etc/apt/auth.conf && \ - cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ - sha512sum /run/secrets/REPO_PASSWORD && \ - curl \ - --fail \ - --netrc-file /etc/apt/auth.conf \ - --output ${GPG_KEY} \ - https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ - file ${GPG_KEY} && \ - apt-get --quiet update && \ - mk-build-deps \ - --install \ - --remove debian/control \ - --tool "apt-get --yes --no-install-recommends" && \ - apt-get --yes --fix-broken install && \ - rm -f /etc/apt/auth.conf - -ENV DEB_BUILD_OPTIONS="parallel=1" -RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ - --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" -RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x - -RUN dpkg-source \ - --diff-ignore=.* \ - --compression=xz \ - --compression-level=9 \ - --build \ - . \ - && debuild -b -us -uc \ - && mkdir OUT \ - && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. - -# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) -FROM scratch -COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile deleted file mode 100644 index 9326979622..0000000000 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -ARG BUILDER_IMAGE=arm32v7/debian:buster-20240513 - -FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder - -ARG MAINTAINER_NAME="Andrey Volk" -ARG MAINTAINER_EMAIL="andrey@signalwire.com" - -# Credentials -ARG REPO_DOMAIN=freeswitch.signalwire.com -ARG REPO_USERNAME=user - -ARG BUILD_NUMBER=42 -ARG GIT_SHA=0000000000 - -ARG DATA_DIR=/data -ARG CODENAME=buster -ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" - -MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" - -SHELL ["/bin/bash", "-c"] - -RUN apt-get -q update && \ - DEBIAN_FRONTEND=noninteractive apt-get -yq install \ - apt-transport-https \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - debhelper \ - devscripts \ - dh-autoreconf \ - dos2unix \ - doxygen \ - git \ - graphviz \ - libglib2.0-dev \ - libssl-dev \ - lsb-release \ - pkg-config \ - wget - -RUN update-ca-certificates --fresh - -RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ - chmod +x ~/.env - -RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list -deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main -deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main -EOF - -RUN git config --global --add safe.directory '*' \ - && git config --global user.name "${MAINTAINER_NAME}" \ - && git config --global user.email "${MAINTAINER_EMAIL}" - -# Bootstrap and Build -COPY . ${DATA_DIR} -WORKDIR ${DATA_DIR} -RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env - -RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x -RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} - -RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ - printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ - printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ - printf "password " >> /etc/apt/auth.conf && \ - cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ - sha512sum /run/secrets/REPO_PASSWORD && \ - curl \ - --fail \ - --netrc-file /etc/apt/auth.conf \ - --output ${GPG_KEY} \ - https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ - file ${GPG_KEY} && \ - apt-get --quiet update && \ - mk-build-deps \ - --install \ - --remove debian/control \ - --tool "apt-get --yes --no-install-recommends" && \ - apt-get --yes --fix-broken install && \ - rm -f /etc/apt/auth.conf - -ENV DEB_BUILD_OPTIONS="parallel=1" -RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ - --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" -RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x - -RUN dpkg-source \ - --diff-ignore=.* \ - --compression=xz \ - --compression-level=9 \ - --build \ - . \ - && debuild -b -us -uc \ - && mkdir OUT \ - && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. - -# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) -FROM scratch -COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile deleted file mode 100644 index 71aca46052..0000000000 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -ARG BUILDER_IMAGE=arm64v8/debian:buster-20240513 - -FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder - -ARG MAINTAINER_NAME="Andrey Volk" -ARG MAINTAINER_EMAIL="andrey@signalwire.com" - -# Credentials -ARG REPO_DOMAIN=freeswitch.signalwire.com -ARG REPO_USERNAME=user - -ARG BUILD_NUMBER=42 -ARG GIT_SHA=0000000000 - -ARG DATA_DIR=/data -ARG CODENAME=buster -ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" - -MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" - -SHELL ["/bin/bash", "-c"] - -RUN apt-get -q update && \ - DEBIAN_FRONTEND=noninteractive apt-get -yq install \ - apt-transport-https \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - debhelper \ - devscripts \ - dh-autoreconf \ - dos2unix \ - doxygen \ - git \ - graphviz \ - libglib2.0-dev \ - libssl-dev \ - lsb-release \ - pkg-config \ - wget - -RUN update-ca-certificates --fresh - -RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ - chmod +x ~/.env - -RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list -deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -EOF - -RUN git config --global --add safe.directory '*' \ - && git config --global user.name "${MAINTAINER_NAME}" \ - && git config --global user.email "${MAINTAINER_EMAIL}" - -# Bootstrap and Build -COPY . ${DATA_DIR} -WORKDIR ${DATA_DIR} -RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env - -RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x -RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} - -RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ - printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ - printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ - printf "password " >> /etc/apt/auth.conf && \ - cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ - sha512sum /run/secrets/REPO_PASSWORD && \ - curl \ - --fail \ - --netrc-file /etc/apt/auth.conf \ - --output ${GPG_KEY} \ - https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ - file ${GPG_KEY} && \ - apt-get --quiet update && \ - mk-build-deps \ - --install \ - --remove debian/control \ - --tool "apt-get --yes --no-install-recommends" && \ - apt-get --yes --fix-broken install && \ - rm -f /etc/apt/auth.conf - -ENV DEB_BUILD_OPTIONS="parallel=1" -RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ - --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" -RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x - -RUN dpkg-source \ - --diff-ignore=.* \ - --compression=xz \ - --compression-level=9 \ - --build \ - . \ - && debuild -b -us -uc \ - && mkdir OUT \ - && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. - -# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) -FROM scratch -COPY --from=builder /data/OUT/ / diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d1ddf07fc..37e29568a8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,12 +28,6 @@ jobs: if [[ "${{ github.event_name }}" == "pull_request" ]]; then JSON=$(jq -n '[ - { - "version": "bookworm", - "platform": { - "name": "amd64" - } - }, { "version": "bookworm", "platform": { @@ -41,7 +35,16 @@ jobs: } }, { - "version": "bullseye" + "version": "bullseye", + "platform": { + "name": "amd64" + } + }, + { + "version": "bullseye", + "platform": { + "name": "arm32v7" + } } ]') fi @@ -66,7 +69,6 @@ jobs: version: - bookworm - bullseye - - buster platform: - name: amd64 runner: ubuntu-latest From 6e8f30ea8b75033c7d5d56b957b142e5f53ec17b Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 2 Aug 2024 19:39:59 +0000 Subject: [PATCH 154/205] swigall --- src/mod/languages/mod_managed/freeswitch_wrap.cxx | 10 ++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 7cec120fbe..c09f650f5a 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -3401,6 +3401,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_SWITCH_MAX_MANAGEMENT_BUFFER } +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_SWITCH_RAND_MAX_get___() { + int jresult ; + int result; + + result = (int)(0x7fff); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_error_period_t_start_set___(void * jarg1, long long jarg2) { error_period *arg1 = (error_period *) 0 ; int64_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 6ca27764cf..20bcbf4273 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -15184,6 +15184,7 @@ else public static readonly int SWITCH_MAX_STATE_HANDLERS = freeswitchPINVOKE.SWITCH_MAX_STATE_HANDLERS_get(); public static readonly int SWITCH_CORE_QUEUE_LEN = freeswitchPINVOKE.SWITCH_CORE_QUEUE_LEN_get(); public static readonly int SWITCH_MAX_MANAGEMENT_BUFFER_LEN = freeswitchPINVOKE.SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get(); + public static readonly int SWITCH_RAND_MAX = freeswitchPINVOKE.SWITCH_RAND_MAX_get(); public static readonly int SWITCH_RTP_CNG_PAYLOAD = freeswitchPINVOKE.SWITCH_RTP_CNG_PAYLOAD_get(); public static readonly int SWITCH_MEDIA_TYPE_TOTAL = freeswitchPINVOKE.SWITCH_MEDIA_TYPE_TOTAL_get(); public static readonly int SWITCH_SOCK_INVALID = freeswitchPINVOKE.SWITCH_SOCK_INVALID_get(); @@ -16292,6 +16293,9 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get___")] public static extern int SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_SWITCH_RAND_MAX_get___")] + public static extern int SWITCH_RAND_MAX_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_error_period_t_start_set___")] public static extern void switch_error_period_t_start_set(global::System.Runtime.InteropServices.HandleRef jarg1, long jarg2); From ed4a242931051d30fdcbd6554665f9730ba79c82 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 3 Aug 2024 18:24:55 +0300 Subject: [PATCH 155/205] version bump --- build/next-release.txt | 2 +- configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/next-release.txt b/build/next-release.txt index a3426275e7..27cbef8a6e 100644 --- a/build/next-release.txt +++ b/build/next-release.txt @@ -1 +1 @@ -1.10.12-dev +1.10.13-dev diff --git a/configure.ac b/configure.ac index 348103f8db..6991398ae7 100644 --- a/configure.ac +++ b/configure.ac @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.10.12-dev], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.10.13-dev], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [10]) -AC_SUBST(SWITCH_VERSION_MICRO, [12-dev]) +AC_SUBST(SWITCH_VERSION_MICRO, [13-dev]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 94b8ebaea7b03b3b23c2ffbe51ff3ea6589944f5 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 22 Aug 2024 14:00:25 -0700 Subject: [PATCH 156/205] Delete .drone.yml (#2580) --- .drone.yml | 184 ----------------------------------------------------- 1 file changed, 184 deletions(-) delete mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 63838cfb73..0000000000 --- a/.drone.yml +++ /dev/null @@ -1,184 +0,0 @@ ---- -kind: pipeline -name: unit-tests - -steps: - - name: bootstrap - image: signalwire/freeswitch-public-base:bullseye - pull: always - commands: - - cat /proc/sys/kernel/core_pattern - - ./bootstrap.sh -j - - - name: configure - image: signalwire/freeswitch-public-base:bullseye - pull: always - environment: - REPOTOKEN: - from_secret: repotoken - commands: - - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf - - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq remove libsofia-sip-ua0 libspandsp-dev - - DEBIAN_FRONTEND=noninteractive apt-get -yq install libspandsp3-dev - - export REPOTOKEN='' - - rm -rf /etc/apt/auth.conf - - git clone https://github.com/freeswitch/sofia-sip.git - - cd sofia-sip && ./autogen.sh && ./configure.gnu && make -j`nproc` && make install && cd .. - - echo 'codecs/mod_openh264' >> modules.conf - - sed -i '/applications\\/mod_http_cache/s/^#//g' modules.conf - - sed -i '/event_handlers\\/mod_rayo/s/^#//g' modules.conf - - sed -i '/formats\\/mod_opusfile/s/^#//g' modules.conf - - sed -i '/languages\\/mod_lua/s/^#//g' modules.conf - - export ASAN_OPTIONS=log_path=stdout:disable_coredump=0:unmap_shadow_on_exit=1:fast_unwind_on_malloc=0 - - ./configure --enable-address-sanitizer --enable-fake-dlclose - - - name: build - image: signalwire/freeswitch-public-base:bullseye - pull: always - environment: - REPOTOKEN: - from_secret: repotoken - commands: - - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf - - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq remove libsofia-sip-ua0 libspandsp-dev - - DEBIAN_FRONTEND=noninteractive apt-get -yq install libspandsp3-dev - - export REPOTOKEN='' - - rm -rf /etc/apt/auth.conf - - cd sofia-sip && make install && cd .. - - echo '#!/bin/bash\nmake -j`nproc --all` |& tee ./unit-tests-build-result.txt\nexitstatus=$${PIPESTATUS[0]}\necho $$exitstatus > ./build-status.txt\n' > build.sh - - chmod +x build.sh - - ./build.sh - - - name: run-tests - image: signalwire/freeswitch-public-base:bullseye - pull: always - environment: - REPOTOKEN: - from_secret: repotoken - commands: - - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf - - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq remove libsofia-sip-ua0 libspandsp-dev - - DEBIAN_FRONTEND=noninteractive apt-get -yq install libspandsp3-dev - - export REPOTOKEN='' - - rm -rf /etc/apt/auth.conf - - cd sofia-sip && make install && cd .. - - make install || true - - cd tests/unit - - export ASAN_OPTIONS=log_path=stdout:disable_coredump=0:unmap_shadow_on_exit=1:fast_unwind_on_malloc=0 - - ./run-tests.sh - - ls -la /cores - - mkdir logs && (mv log_run-tests_*.html logs || true) && (mv backtrace_*.txt logs || true) - - echo 0 > run-tests-status.txt - - ./collect-test-logs.sh && exit 0 || echo 'Some tests failed' - - echo 1 > run-tests-status.txt - - cd logs && ls -la - - - name: notify - image: signalwire/drone-notify - pull: always - environment: - SLACK_WEBHOOK_URL: - from_secret: slack_webhook_url - ENV_FILE: - from_secret: notify_env - commands: - - /root/unit-tests-notify.sh - -trigger: - branch: - - master - event: - - pull_request - - push - ---- -kind: pipeline -name: scan-build - -steps: - - name: bootstrap - image: signalwire/freeswitch-public-base:bookworm - pull: always - commands: - - apt-get update && apt-get -yq install autoconf - - ./bootstrap.sh -j - - - name: configure - image: signalwire/freeswitch-public-base:bookworm - pull: always - environment: - REPOTOKEN: - from_secret: repotoken - commands: - - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf - - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq remove libspandsp-dev - - DEBIAN_FRONTEND=noninteractive apt-get -yq install libsofia-sip-ua-dev libspandsp3-dev - - export REPOTOKEN='' - - rm -rf /etc/apt/auth.conf - - cp build/modules.conf.most modules.conf - #Enable/Uncomment mods - - echo 'codecs/mod_openh264' >> modules.conf - - sed -i "/mod_mariadb/s/^#//g" modules.conf - - sed -i "/mod_v8/s/^#//g" modules.conf - #Disable/Comment out mods - - sed -i '/mod_ilbc/s/^/#/g' modules.conf - - sed -i '/mod_isac/s/^/#/g' modules.conf - - sed -i '/mod_mp4/s/^/#/g' modules.conf - - sed -i '/mod_mongo/s/^/#/g' modules.conf - - sed -i '/mod_pocketsphinx/s/^/#/g' modules.conf - - sed -i '/mod_sangoma_codec/s/^/#/g' modules.conf - - sed -i '/mod_siren/s/^/#/g' modules.conf - #Comment out mods for a while - - sed -i '/mod_avmd/s/^/#/g' modules.conf - - sed -i '/mod_basic/s/^/#/g' modules.conf - - sed -i '/mod_cdr_mongodb/s/^/#/g' modules.conf - - sed -i '/mod_cv/s/^/#/g' modules.conf - - sed -i '/mod_erlang_event/s/^/#/g' modules.conf - - sed -i '/mod_perl/s/^/#/g' modules.conf - - sed -i '/mod_rtmp/s/^/#/g' modules.conf - - sed -i '/mod_unimrcp/s/^/#/g' modules.conf - - sed -i '/mod_xml_rpc/s/^/#/g' modules.conf - - ./configure - - - name: scan-build - image: signalwire/freeswitch-public-base:bookworm - pull: always - environment: - REPOTOKEN: - from_secret: repotoken - commands: - - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf - - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq remove libspandsp-dev - - DEBIAN_FRONTEND=noninteractive apt-get -yq install libsofia-sip-ua-dev libspandsp3-dev - - export REPOTOKEN='' - - rm -rf /etc/apt/auth.conf - - mkdir -p scan-build - - echo '#!/bin/bash\nscan-build-14 --force-analyze-debug-code -o ./scan-build/ make -j`nproc --all` |& tee ./scan-build-result.txt\nexitstatus=$${PIPESTATUS[0]}\necho $$exitstatus > ./scan-build-status.txt\n' > scan.sh - - chmod +x scan.sh - - ./scan.sh - - exitstatus=`cat ./scan-build-status.txt` - - echo "*** Exit status is $exitstatus" - - - name: notify - image: signalwire/drone-notify - pull: always - environment: - SLACK_WEBHOOK_URL: - from_secret: slack_webhook_url - ENV_FILE: - from_secret: notify_env - commands: - - /root/scan-build-notify.sh - -trigger: - branch: - - master - event: - - pull_request - - push - ---- -kind: signature -hmac: 7e5f6cafc88da0be59243daf47a2a5607ff00b45f441ce4c1041d4b690e8a853 - -... From 628938fcc8ae68ac57b2b8a97f8ee2a73050a731 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Sat, 21 Sep 2024 13:19:22 +0200 Subject: [PATCH 157/205] [GHA] Migrate to new project layout. --- .../bookworm/amd64/public.release.Dockerfile | 103 ++++++++++++++++++ ...{Dockerfile => public.unstable.Dockerfile} | 0 .../arm32v7/public.release.Dockerfile | 102 +++++++++++++++++ ...{Dockerfile => public.unstable.Dockerfile} | 0 .../arm64v8/public.release.Dockerfile | 102 +++++++++++++++++ ...{Dockerfile => public.unstable.Dockerfile} | 0 .../bullseye/amd64/public.release.Dockerfile | 102 +++++++++++++++++ ...{Dockerfile => public.unstable.Dockerfile} | 0 .../arm32v7/public.release.Dockerfile | 102 +++++++++++++++++ ...{Dockerfile => public.unstable.Dockerfile} | 0 .../arm64v8/public.release.Dockerfile | 102 +++++++++++++++++ ...{Dockerfile => public.unstable.Dockerfile} | 0 .github/workflows/build.yml | 49 ++++++--- 13 files changed, 646 insertions(+), 16 deletions(-) create mode 100644 .github/docker/debian/bookworm/amd64/public.release.Dockerfile rename .github/docker/debian/bookworm/amd64/{Dockerfile => public.unstable.Dockerfile} (100%) create mode 100644 .github/docker/debian/bookworm/arm32v7/public.release.Dockerfile rename .github/docker/debian/bookworm/arm32v7/{Dockerfile => public.unstable.Dockerfile} (100%) create mode 100644 .github/docker/debian/bookworm/arm64v8/public.release.Dockerfile rename .github/docker/debian/bookworm/arm64v8/{Dockerfile => public.unstable.Dockerfile} (100%) create mode 100644 .github/docker/debian/bullseye/amd64/public.release.Dockerfile rename .github/docker/debian/bullseye/amd64/{Dockerfile => public.unstable.Dockerfile} (100%) create mode 100644 .github/docker/debian/bullseye/arm32v7/public.release.Dockerfile rename .github/docker/debian/bullseye/arm32v7/{Dockerfile => public.unstable.Dockerfile} (100%) create mode 100644 .github/docker/debian/bullseye/arm64v8/public.release.Dockerfile rename .github/docker/debian/bullseye/arm64v8/{Dockerfile => public.unstable.Dockerfile} (100%) diff --git a/.github/docker/debian/bookworm/amd64/public.release.Dockerfile b/.github/docker/debian/bookworm/amd64/public.release.Dockerfile new file mode 100644 index 0000000000..e6ec64661e --- /dev/null +++ b/.github/docker/debian/bookworm/amd64/public.release.Dockerfile @@ -0,0 +1,103 @@ +ARG BUILDER_IMAGE=debian:bookworm-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +EOF + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + https://${REPO_DOMAIN}/repo/deb/debian-release/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" + +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/public.unstable.Dockerfile similarity index 100% rename from .github/docker/debian/bookworm/amd64/Dockerfile rename to .github/docker/debian/bookworm/amd64/public.unstable.Dockerfile diff --git a/.github/docker/debian/bookworm/arm32v7/public.release.Dockerfile b/.github/docker/debian/bookworm/arm32v7/public.release.Dockerfile new file mode 100644 index 0000000000..d636a0c6ea --- /dev/null +++ b/.github/docker/debian/bookworm/arm32v7/public.release.Dockerfile @@ -0,0 +1,102 @@ +ARG BUILDER_IMAGE=arm32v7/debian:bookworm-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-release ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-release ${CODENAME} main +EOF + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-release/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/public.unstable.Dockerfile similarity index 100% rename from .github/docker/debian/bookworm/arm32v7/Dockerfile rename to .github/docker/debian/bookworm/arm32v7/public.unstable.Dockerfile diff --git a/.github/docker/debian/bookworm/arm64v8/public.release.Dockerfile b/.github/docker/debian/bookworm/arm64v8/public.release.Dockerfile new file mode 100644 index 0000000000..5c34022d29 --- /dev/null +++ b/.github/docker/debian/bookworm/arm64v8/public.release.Dockerfile @@ -0,0 +1,102 @@ +ARG BUILDER_IMAGE=arm64v8/debian:bookworm-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +EOF + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + https://${REPO_DOMAIN}/repo/deb/debian-release/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/public.unstable.Dockerfile similarity index 100% rename from .github/docker/debian/bookworm/arm64v8/Dockerfile rename to .github/docker/debian/bookworm/arm64v8/public.unstable.Dockerfile diff --git a/.github/docker/debian/bullseye/amd64/public.release.Dockerfile b/.github/docker/debian/bullseye/amd64/public.release.Dockerfile new file mode 100644 index 0000000000..94c5e335b2 --- /dev/null +++ b/.github/docker/debian/bullseye/amd64/public.release.Dockerfile @@ -0,0 +1,102 @@ +ARG BUILDER_IMAGE=debian:bullseye-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +EOF + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + https://${REPO_DOMAIN}/repo/deb/debian-release/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/public.unstable.Dockerfile similarity index 100% rename from .github/docker/debian/bullseye/amd64/Dockerfile rename to .github/docker/debian/bullseye/amd64/public.unstable.Dockerfile diff --git a/.github/docker/debian/bullseye/arm32v7/public.release.Dockerfile b/.github/docker/debian/bullseye/arm32v7/public.release.Dockerfile new file mode 100644 index 0000000000..200b8dca1a --- /dev/null +++ b/.github/docker/debian/bullseye/arm32v7/public.release.Dockerfile @@ -0,0 +1,102 @@ +ARG BUILDER_IMAGE=arm32v7/debian:bullseye-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-release ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-release ${CODENAME} main +EOF + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-release/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/public.unstable.Dockerfile similarity index 100% rename from .github/docker/debian/bullseye/arm32v7/Dockerfile rename to .github/docker/debian/bullseye/arm32v7/public.unstable.Dockerfile diff --git a/.github/docker/debian/bullseye/arm64v8/public.release.Dockerfile b/.github/docker/debian/bullseye/arm64v8/public.release.Dockerfile new file mode 100644 index 0000000000..5476c22192 --- /dev/null +++ b/.github/docker/debian/bullseye/arm64v8/public.release.Dockerfile @@ -0,0 +1,102 @@ +ARG BUILDER_IMAGE=arm64v8/debian:bullseye-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-release ${CODENAME} main +EOF + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + https://${REPO_DOMAIN}/repo/deb/debian-release/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/public.unstable.Dockerfile similarity index 100% rename from .github/docker/debian/bullseye/arm64v8/Dockerfile rename to .github/docker/debian/bullseye/arm64v8/public.unstable.Dockerfile diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 37e29568a8..49e99e8b48 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,15 +14,14 @@ concurrency: group: ${{ github.head_ref || github.ref }} jobs: - excludes: - name: 'Excludes' - # if: github.event.pull_request.head.repo.full_name == github.repository + preconfig: runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} + release: ${{ steps.release.outputs.release }} steps: - - id: deb - name: Generate Matrix excludes for DEB + - name: Generate Matrix excludes for DEB + id: deb run: | JSON="[]" @@ -51,14 +50,30 @@ jobs: echo "excludes=$(echo $JSON | jq -c .)" | tee -a $GITHUB_OUTPUT - deb: - name: 'DEB' - # if: github.event.pull_request.head.repo.full_name == github.repository + - name: Get release type based on branch + id: release + run: | + if [[ '${{ github.event_name }}' == 'pull_request' ]]; then + if [[ '${{ github.base_ref }}' == 'master' ]]; then + echo 'release=unstable' | tee -a $GITHUB_OUTPUT + elif [[ '${{ github.base_ref }}' == 'v1.10' ]]; then + echo 'release=release' | tee -a $GITHUB_OUTPUT + fi + elif [[ '${{ github.ref }}' == 'refs/heads/master' ]]; then + echo 'release=unstable' | tee -a $GITHUB_OUTPUT + elif [[ '${{ github.ref }}' == 'refs/heads/v1.10' ]]; then + echo 'release=release' | tee -a $GITHUB_OUTPUT + else + exit 1 + fi + + deb-public: + name: 'DEB-PUBLIC' permissions: id-token: write contents: read needs: - - excludes + - preconfig uses: signalwire/actions-template/.github/workflows/cicd-docker-build-and-distribute.yml@main strategy: # max-parallel: 1 @@ -76,16 +91,18 @@ jobs: runner: linux-arm64-4-core-public - name: arm64v8 runner: linux-arm64-4-core-public - exclude: ${{ fromJson(needs.excludes.outputs.deb) }} + release: + - ${{ needs.preconfig.outputs.release }} + exclude: ${{ fromJson(needs.preconfig.outputs.deb) }} with: RUNNER: ${{ matrix.platform.runner }} ARTIFACTS_PATTERN: '.*\.(deb|dsc|changes|tar.bz2|tar.gz|tar.lzma|tar.xz)$' - DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile + DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/public.${{ matrix.release }}.Dockerfile MAINTAINER: 'Andrey Volk ' - META_FILE_PATH_PREFIX: /var/www/freeswitch/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }} + META_FILE_PATH_PREFIX: /var/www/freeswitch/public/${{ matrix.release }}/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }} PLATFORM: ${{ matrix.platform.name }} - REPO_DOMAIN: freeswitch.signalwire.com - TARGET_ARTIFACT_NAME: ${{ matrix.os }}-${{ matrix.version }}-${{ matrix.platform.name }}-artifact + REPO_DOMAIN: 'freeswitch.signalwire.com' + TARGET_ARTIFACT_NAME: ${{ matrix.os }}-${{ matrix.version }}-${{ matrix.platform.name }}-public-${{ matrix.release }}-artifact UPLOAD_BUILD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':upload-artifacts') }} secrets: GH_BOT_DEPLOY_TOKEN: ${{ secrets.PAT }} @@ -100,13 +117,13 @@ jobs: name: 'Publish build data to meta-repo' if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':upload-artifacts') }} needs: - - deb + - deb-public permissions: id-token: write contents: read uses: signalwire/actions-template/.github/workflows/meta-repo-content.yml@main with: - META_CONTENT: '/var/www/freeswitch/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }}' + META_CONTENT: '/var/www/freeswitch/public/{release,unstable}/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }}' META_REPO: signalwire/bamboo_gha_trigger META_REPO_BRANCH: trigger/freeswitch/${{ github.ref_name }} secrets: From ef3bd2d8c30f0fab0220a88629b4e3be761542e0 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Wed, 9 Oct 2024 00:34:22 +0800 Subject: [PATCH 158/205] [core] fix base64 decoded size when encoded string contains padding = --- src/switch_utils.c | 2 +- tests/unit/switch_utils.c | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index aa3fc74cae..1293ca3fbd 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1076,7 +1076,7 @@ SWITCH_DECLARE(switch_size_t) switch_b64_decode(const char *in, char *out, switc l64[(int) switch_b64_table[i]] = (char) i; } - for (ip = in; ip && *ip; ip++) { + for (ip = in; ip && *ip && (*ip != '='); ip++) { c = l64[(int) *ip]; if (c == -1) { continue; diff --git a/tests/unit/switch_utils.c b/tests/unit/switch_utils.c index 1fc291ea96..391ec6e8e6 100644 --- a/tests/unit/switch_utils.c +++ b/tests/unit/switch_utils.c @@ -80,6 +80,49 @@ FST_TEST_BEGIN(b64) } FST_TEST_END() +FST_TEST_BEGIN(b64_pad2) +{ + switch_size_t size; + char str[] = {0, 0, 0, 0}; + unsigned char b64_str[128]; + char decoded_str[128]; + int i; + switch_status_t status = switch_b64_encode((unsigned char *)str, sizeof(str), b64_str, sizeof(b64_str)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "b64_str: %s\n", b64_str); + fst_check(status == SWITCH_STATUS_SUCCESS); + fst_check_string_equals((const char *)b64_str, "AAAAAA=="); + + size = switch_b64_decode((const char *)b64_str, decoded_str, sizeof(decoded_str)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "decoded_str: %s\n", decoded_str); + fst_check_string_equals(decoded_str, str); + fst_check(size == sizeof(str) + 1); + for (i = 0; i < sizeof(str); i++) { + fst_check(decoded_str[i] == str[i]); + } +} +FST_TEST_END() + +FST_TEST_BEGIN(b64_pad1) +{ + switch_size_t size; + char str[] = {0, 0, 0, 0, 0}; + unsigned char b64_str[128]; + char decoded_str[128]; + int i; + switch_status_t status = switch_b64_encode((unsigned char *)str, sizeof(str), b64_str, sizeof(b64_str)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "b64_str: %s\n", b64_str); + fst_check(status == SWITCH_STATUS_SUCCESS); + fst_check_string_equals((const char *)b64_str, "AAAAAAA="); + + size = switch_b64_decode((const char *)b64_str, decoded_str, sizeof(decoded_str)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "decoded_str: %s\n", decoded_str); + fst_check_string_equals(decoded_str, str); + fst_check(size == sizeof(str) + 1); + for (i = 0; i < sizeof(str); i++) { + fst_check(decoded_str[i] == str[i]); + } +} +FST_TEST_END() FST_SUITE_END() From b4ebd0936c756f32a5e65ec181429a431dff4505 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 11 Oct 2024 14:16:02 +0100 Subject: [PATCH 159/205] [core, mod_sofia] Fix codec set deadlock --- src/include/switch_core.h | 11 +++++++++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 13 ++++++++++++- src/switch_core_codec.c | 21 +++++++++++++++++++++ src/switch_core_media.c | 6 ++---- src/switch_core_session.c | 4 ++++ 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index e4c615941d..ff04fa0954 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1822,6 +1822,17 @@ SWITCH_DECLARE(void) switch_core_session_unlock_codec_write(_In_ switch_core_ses SWITCH_DECLARE(void) switch_core_session_lock_codec_read(_In_ switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_unlock_codec_read(_In_ switch_core_session_t *session); +/*! + \brief Lock codec read mutex and codec write mutex using trylock in an infinite loop + \param session session to lock the codec in +*/ +SWITCH_DECLARE(void) switch_core_codec_lock_full(switch_core_session_t *session); + +/*! + \brief Unlock codec read mutex and codec write mutex + \param session session to unlock the codec in +*/ +SWITCH_DECLARE(void) switch_core_codec_unlock_full(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp); SWITCH_DECLARE(switch_status_t) switch_core_session_get_real_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index c5ce6e3855..c41ed9b2e3 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1339,6 +1339,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (msg->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) msg->pointer_arg; + + switch_core_session_lock_codec_write(session); switch_mutex_lock(tech_pvt->sofia_mutex); if (switch_core_session_in_thread(session)) { de->session = session; @@ -1346,8 +1348,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi sofia_process_dispatch_event(&de); - switch_mutex_unlock(tech_pvt->sofia_mutex); + switch_core_session_unlock_codec_write(session); goto end; } @@ -1363,6 +1365,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi /* ones that do not need to lock sofia mutex */ switch (msg->message_id) { + case SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY: + case SWITCH_MESSAGE_RESAMPLE_EVENT: + goto end; case SWITCH_MESSAGE_INDICATE_KEEPALIVE: { if (msg->numeric_arg) { @@ -1523,6 +1528,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } /* ones that do need to lock sofia mutex */ + switch_core_session_lock_codec_write(session); switch_mutex_lock(tech_pvt->sofia_mutex); if (switch_channel_down(channel) || sofia_test_flag(tech_pvt, TFLAG_BYE)) { @@ -1557,7 +1563,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi tech_pvt->proxy_refer_uuid = (char *)msg->string_array_arg[0]; } else if (!switch_channel_var_true(tech_pvt->channel, "sip_refer_continue_after_reply")) { switch_mutex_unlock(tech_pvt->sofia_mutex); + switch_core_session_unlock_codec_write(session); sofia_wait_for_reply(tech_pvt, 9999, 10); + switch_core_session_lock_codec_write(session); switch_mutex_lock(tech_pvt->sofia_mutex); if ((var = switch_channel_get_variable(tech_pvt->channel, "sip_refer_reply"))) { @@ -2391,6 +2399,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi /* Unlock the session signal to allow the ack to make it in */ // Maybe we should timeout? switch_mutex_unlock(tech_pvt->sofia_mutex); + switch_core_session_unlock_codec_write(session); while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) { switch_ivr_parse_all_events(session); @@ -2398,6 +2407,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } /* Regain lock on sofia */ + switch_core_session_lock_codec_write(session); switch_mutex_lock(tech_pvt->sofia_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n"); @@ -2706,6 +2716,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi //} switch_mutex_unlock(tech_pvt->sofia_mutex); + switch_core_session_unlock_codec_write(session); end: diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index e5c22cd610..5cedbed6e0 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -59,6 +59,27 @@ SWITCH_DECLARE(void) switch_core_session_unset_read_codec(switch_core_session_t switch_mutex_unlock(session->codec_read_mutex); } +SWITCH_DECLARE(void) switch_core_codec_lock_full(switch_core_session_t *session) +{ + do { + if (switch_mutex_trylock(session->codec_write_mutex) == SWITCH_STATUS_SUCCESS) { + if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) { + return; + } + + switch_mutex_unlock(session->codec_write_mutex); + } + + switch_cond_next(); + } while (1); +} + +SWITCH_DECLARE(void) switch_core_codec_unlock_full(switch_core_session_t *session) +{ + switch_mutex_unlock(session->codec_read_mutex); + switch_mutex_unlock(session->codec_write_mutex); +} + SWITCH_DECLARE(void) switch_core_session_lock_codec_write(switch_core_session_t *session) { switch_mutex_lock(session->codec_write_mutex); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 58ef94a53e..de5d0eff74 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3601,8 +3601,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ switch_assert(session); - switch_core_session_lock_codec_write(session); - switch_core_session_lock_codec_read(session); + switch_core_codec_lock_full(session); switch_mutex_lock(session->codec_init_mutex); @@ -3756,8 +3755,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ switch_mutex_unlock(session->codec_init_mutex); - switch_core_session_unlock_codec_read(session); - switch_core_session_unlock_codec_write(session); + switch_core_codec_unlock_full(session); return status; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 61aa500070..94944faa2f 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1392,6 +1392,8 @@ SWITCH_DECLARE(void) switch_core_session_reset(switch_core_session_t *session, s { switch_channel_t *channel = switch_core_session_get_channel(session); + switch_core_codec_lock_full(session); + if (reset_read_codec) { switch_core_session_set_read_codec(session, NULL); if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) { @@ -1425,6 +1427,8 @@ SWITCH_DECLARE(void) switch_core_session_reset(switch_core_session_t *session, s switch_clear_flag(session, SSF_WARN_TRANSCODE); switch_ivr_deactivate_unicast(session); switch_channel_clear_flag(channel, CF_BREAK); + + switch_core_codec_unlock_full(session); } From 07283ac104e4d43fd6cdadb10c95f9df9e249408 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 25 Jul 2024 19:47:30 +0200 Subject: [PATCH 160/205] [GHA] Add tests. --- .github/workflows/ci.yml | 94 ++++++++++++++++++++ .github/workflows/unit-test.yml | 111 ++++++++++++++++++++++++ scan_build.sh | 28 ++++++ src/mod/endpoints/mod_sofia/Makefile.am | 3 +- tests/unit/run-tests.mk | 5 ++ tests/unit/run-tests.sh | 37 ++++---- tests/unit/test.sh | 12 ++- 7 files changed, 269 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/unit-test.yml create mode 100755 scan_build.sh create mode 100644 tests/unit/run-tests.mk diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..d16f1a987a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,94 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + types: + - opened + - synchronize + +jobs: + unit-tests_1: + name: "unit-tests (group 1)" + uses: ./.github/workflows/unit-test.yml + with: + total-groups: 2 + current-group: 1 + secrets: inherit + + unit-tests_2: + name: "unit-tests (group 2)" + uses: ./.github/workflows/unit-test.yml + with: + total-groups: 2 + current-group: 2 + secrets: inherit + + scan-build: + runs-on: ubuntu-latest + container: + image: signalwire/freeswitch-public-base:bookworm + credentials: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + options: --privileged + env: + REPOTOKEN: ${{ secrets.REPOTOKEN }} + DEBIAN_FRONTEND: noninteractive + + steps: + - name: Install dependencies + shell: bash + run: | + echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf && \ + apt-get update && \ + apt-get -y remove \ + libsofia-sip-ua0 \ + libspandsp-dev && \ + apt-get -y install \ + autoconf \ + libsofia-sip-ua-dev \ + libspandsp3-dev && \ + rm -rf /etc/apt/auth.conf + + - name: Checkout code + uses: actions/checkout@v4 + with: + path: /__w/freeswitch/freeswitch + + - name: Bootstrap + shell: bash + working-directory: /__w/freeswitch/freeswitch + run: | + ./bootstrap.sh -j || exit 1 + + - name: Scan-build FreeSwitch + shell: bash + working-directory: /__w/freeswitch/freeswitch + run: | + cp build/modules.conf.most modules.conf && \ + echo 'codecs/mod_openh264' >> modules.conf && \ + sed -i \ + -e '/mod_mariadb/s/^#//g' \ + -e '/mod_v8/s/^#//g' \ + -e '/mod_ilbc/s/^/#/g' \ + -e '/mod_isac/s/^/#/g' \ + -e '/mod_mp4/s/^/#/g' \ + -e '/mod_mongo/s/^/#/g' \ + -e '/mod_pocketsphinx/s/^/#/g' \ + -e '/mod_sangoma_codec/s/^/#/g' \ + -e '/mod_siren/s/^/#/g' \ + -e '/mod_avmd/s/^/#/g' \ + -e '/mod_basic/s/^/#/g' \ + -e '/mod_cdr_mongodb/s/^/#/g' \ + -e '/mod_cv/s/^/#/g' \ + -e '/mod_erlang_event/s/^/#/g' \ + -e '/mod_perl/s/^/#/g' \ + -e '/mod_rtmp/s/^/#/g' \ + -e '/mod_unimrcp/s/^/#/g' \ + -e '/mod_xml_rpc/s/^/#/g' \ + modules.conf && \ + ./configure && \ + ./scan_build.sh diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml new file mode 100644 index 0000000000..8ff0d832a7 --- /dev/null +++ b/.github/workflows/unit-test.yml @@ -0,0 +1,111 @@ +name: Unit tests + +on: + workflow_call: + inputs: + total-groups: + description: 'Total number of test groups' + required: true + type: number + current-group: + description: 'Current test group number' + required: true + type: number + +jobs: + unit-tests: + runs-on: ubuntu-latest + container: + image: signalwire/freeswitch-public-base:bookworm + credentials: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + options: --privileged + env: + DEBIAN_FRONTEND: noninteractive + ASAN_OPTIONS: log_path=stdout:disable_coredump=0:unmap_shadow_on_exit=1:fast_unwind_on_malloc=0 + + steps: + - name: Override core_pattern + shell: bash + run: | + cat /proc/sys/kernel/core_pattern + echo '/cores/core.%s.%E.%e.%p.%t' > /proc/sys/kernel/core_pattern + cat /proc/sys/kernel/core_pattern + + - name: Install dependencies + shell: bash + env: + REPOTOKEN: ${{ secrets.REPOTOKEN }} + run: | + echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf && \ + apt-get update && \ + apt-get -y remove \ + libsofia-sip-ua0 \ + libspandsp-dev && \ + apt-get -y install \ + libspandsp3-dev && \ + rm -rf /etc/apt/auth.conf + + - name: Checkout code + uses: actions/checkout@v4 + with: + path: /__w/freeswitch/freeswitch + + - name: Bootstrap + shell: bash + working-directory: /__w/freeswitch/freeswitch + run: | + ./bootstrap.sh -j || exit 1 + + - name: Checkout Sofia-Sip + uses: actions/checkout@v4 + with: + repository: freeswitch/sofia-sip + path: /__w/freeswitch/freeswitch/sofia-sip + + - name: Build sofia-sip + shell: bash + working-directory: /__w/freeswitch/freeswitch/sofia-sip + run: | + ./autogen.sh && \ + ./configure.gnu && \ + make -j$(nproc --all) install + + - name: Build FreeSwitch + shell: bash + working-directory: /__w/freeswitch/freeswitch + run: | + echo 'codecs/mod_openh264' >> modules.conf && \ + sed -i \ + -e '/applications\/mod_http_cache/s/^#//g' \ + -e '/event_handlers\/mod_rayo/s/^#//g' \ + -e '/formats\/mod_opusfile/s/^#//g' \ + -e '/languages\/mod_lua/s/^#//g' \ + modules.conf && \ + ./configure \ + --enable-address-sanitizer \ + --enable-fake-dlclose && \ + make -j$(nproc --all) |& tee ./unit-tests-build-result.txt + + echo ${PIPESTATUS[0]} > ./build-status.txt + if ! test "$(cat ./build-status.txt | tr -d '[:space:]')" -eq 0; then + exit "$(cat ./build-status.txt | tr -d '[:space:]')" + fi + make install + + - name: Run tests + shell: bash + working-directory: /__w/freeswitch/freeswitch/tests/unit + run: | + ./run-tests.sh ${{ inputs.total-groups }} ${{ inputs.current-group }} + mkdir logs && (mv log_run-tests_*.html logs || true) && (mv backtrace_*.txt logs || true) + ./collect-test-logs.sh + + - name: Notify result + if: failure() + uses: signalwire/actions-template/.github/actions/notify-ci-result@main + with: + for: "run_tests" + test_logs_path: /__w/freeswitch/freeswitch/tests/unit + test_artifacts_suffix: "-${{ inputs.current-group }}" diff --git a/scan_build.sh b/scan_build.sh new file mode 100755 index 0000000000..200cc2d2df --- /dev/null +++ b/scan_build.sh @@ -0,0 +1,28 @@ +#!/bin/bash +mkdir -p scan-build +scan-build-14 --force-analyze-debug-code -o ./scan-build/ make -j`nproc --all` |& tee ./scan-build-result.txt +exitstatus=${PIPESTATUS[0]} +echo "*** Exit status is $exitstatus" +export SubString="scan-build: No bugs found" +export COMPILATION_FAILED="false" +export BUGS_FOUND="false" +if [[ "0" != "$exitstatus" ]] ; then + export COMPILATION_FAILED="true" + echo MESSAGE="compilation failed" >> $GITHUB_OUTPUT +fi +export RESULTFILE="$PWD/scan-build-result.txt" +# cat $RESULTFILE +if ! grep -sq "$SubString" $RESULTFILE; then + export BUGS_FOUND="true" + echo MESSAGE="found bugs" >> $GITHUB_OUTPUT +fi +export REPORT=$PWD/`find scan-build* -mindepth 1 -type d` +echo "COMPILATION_FAILED: $COMPILATION_FAILED" +echo "BUGS_FOUND: $BUGS_FOUND" +echo "COMPILATION_FAILED=$COMPILATION_FAILED" >> $GITHUB_OUTPUT +echo "BUGS_FOUND=$BUGS_FOUND" >> $GITHUB_OUTPUT +echo "REPORT=$REPORT" >> $GITHUB_OUTPUT +if [[ "0" != "$exitstatus" ]] || ! grep -sq "$SubString" $RESULTFILE; then + exit 1 +fi +exit 0 diff --git a/src/mod/endpoints/mod_sofia/Makefile.am b/src/mod/endpoints/mod_sofia/Makefile.am index c813f9f597..3a5d295ddb 100644 --- a/src/mod/endpoints/mod_sofia/Makefile.am +++ b/src/mod/endpoints/mod_sofia/Makefile.am @@ -38,7 +38,8 @@ test_sipp_based_tests_CFLAGS = $(AM_CFLAGS) $(SOFIA_SIP_CFLAGS) -DSWITCH_TEST_BA test_sipp_based_tests_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) test_sipp_based_tests_LDADD = libsofiamod.la $(SOFIA_SIP_LIBS) -TESTS = test/test_sofia_funcs.sh test/test_nuafail test/test_run_sipp.sh +TESTS = test/test_sofia_funcs.sh test/test_nuafail +#TESTS += test/test_run_sipp.sh if ISMAC mod_sofia_la_LDFLAGS += -framework CoreFoundation -framework SystemConfiguration diff --git a/tests/unit/run-tests.mk b/tests/unit/run-tests.mk new file mode 100644 index 0000000000..8c260cfa2a --- /dev/null +++ b/tests/unit/run-tests.mk @@ -0,0 +1,5 @@ +.DEFAULT: + ./test.sh "$@" + +all: $(TEST_LIST) + diff --git a/tests/unit/run-tests.sh b/tests/unit/run-tests.sh index bda6a32571..559dec4a8f 100755 --- a/tests/unit/run-tests.sh +++ b/tests/unit/run-tests.sh @@ -3,26 +3,27 @@ # "print_tests" returns relative paths to all the tests TESTS=$(make -s -C ../.. print_tests) +chunks=${1:-1} +chunk_number=${2:-1} + +IFS=$'\n' read -d '' -r -a lines <<< "$TESTS" + +result="" +for ((i=chunk_number-1; i<${#lines[@]}; i+=chunks)) +do + result+="${lines[$i]}"$'\n' +done + +TESTS=$result + echo "-----------------------------------------------------------------"; -echo "Starting tests"; +echo "Starting tests on $(nproc --all) processors"; echo "Tests found: ${TESTS}"; echo "-----------------------------------------------------------------"; -echo "Starting" > pids.txt -for i in $TESTS -do - echo "Testing $i" ; - ./test.sh "$i" & - pid=($!) - pids+=($pid) - echo "$pid $i" >> pids.txt - echo "----------------" ; -done -for pid in "${pids[@]}" -do - echo "$pid waiting" >> pids.txt - wait "$pid" - echo "$pid finished" >> pids.txt -done +make -f run-tests.mk TEST_LIST=$TESTS -echo "Done running tests!" \ No newline at end of file +echo "Timing results:" +cat test_times.log + +echo "Done running tests!" diff --git a/tests/unit/test.sh b/tests/unit/test.sh index 89711ca99b..08de6ccd99 100755 --- a/tests/unit/test.sh +++ b/tests/unit/test.sh @@ -1,11 +1,16 @@ #!/bin/bash +start_time=$(date +%s) + # All output will be collected here TESTSUNITPATH=$PWD # All relative paths are based on the tree's root FSBASEDIR=$(realpath "$PWD/../../") +ulimit -c unlimited +ulimit -a + i=$1 echo "----------------------------------" ; @@ -28,20 +33,23 @@ echo "Start executing $currenttestpath" $currenttestpath 2>&1 | tee >(ansi2html > $log) ; exitstatus=${PIPESTATUS[0]} ; echo "End executing $currenttestpath" +end_time=$(date +%s) +duration=$((end_time - start_time)) +echo "Test $1 took $duration seconds" >> test_times.log echo "Exit status is $exitstatus" if [ "0" -eq $exitstatus ] ; then rm $log ; else echo "*** ./$i exit status is $exitstatus" ; - corefilesearch=/cores/core.*.!drone!src!${relativedir//\//!}!.libs!$file.* ; + corefilesearch=/cores/core.*.!__w!freeswitch!freeswitch!${relativedir//\//!}!.libs!$file.* ; echo $corefilesearch ; if ls $corefilesearch 1> /dev/null 2>&1; then echo "coredump found"; coredump=$(ls $corefilesearch) ; echo $coredump; echo "set logging file $TESTSUNITPATH/backtrace_${i//\//!}.txt" ; - gdb -ex "set logging file $TESTSUNITPATH/backtrace_${i//\//!}.txt" -ex "set logging on" -ex "set pagination off" -ex "bt full" -ex "bt" -ex "info threads" -ex "thread apply all bt" -ex "thread apply all bt full" -ex "quit" /drone/src/$relativedir/.libs/$file $coredump ; + gdb -ex "set logging file $TESTSUNITPATH/backtrace_${i//\//!}.txt" -ex "set logging on" -ex "set pagination off" -ex "bt full" -ex "bt" -ex "info threads" -ex "thread apply all bt" -ex "thread apply all bt full" -ex "quit" /__w/freeswitch/freeswitch/$relativedir/.libs/$file $coredump ; fi ; echo "*** $log was saved" ; fi ; From b662cc73fb5eb18967e5dd40e38982e00e4604df Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Sat, 12 Oct 2024 19:02:23 +0200 Subject: [PATCH 161/205] [GHA] Use autogenerated matrix for grouping unit-tests. --- .github/workflows/ci.yml | 33 ++++++++++++++++++++++----------- .github/workflows/unit-test.yml | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d16f1a987a..51586fabfe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,20 +10,31 @@ on: - synchronize jobs: - unit-tests_1: - name: "unit-tests (group 1)" - uses: ./.github/workflows/unit-test.yml - with: - total-groups: 2 - current-group: 1 - secrets: inherit + unit-tests-pre-config: + runs-on: ubuntu-latest + env: + TOTAL_GROUPS: 2 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - id: set-matrix + shell: bash + run: | + MATRIX=$(jq -c -n --argjson groups "${{ env.TOTAL_GROUPS }}" \ + '{ + include: [range(1; $groups + 1) | {group: ., total: $groups}] + }') + echo "matrix=$MATRIX" | tee -a $GITHUB_OUTPUT - unit-tests_2: - name: "unit-tests (group 2)" + unit-tests: + needs: unit-tests-pre-config + strategy: + matrix: ${{ fromJson(needs.unit-tests-pre-config.outputs.matrix) }} + name: "unit-tests (group ${{ matrix.group }})" uses: ./.github/workflows/unit-test.yml with: - total-groups: 2 - current-group: 2 + total-groups: ${{ matrix.total }} + current-group: ${{ matrix.group }} secrets: inherit scan-build: diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 8ff0d832a7..5db97620a4 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -13,7 +13,7 @@ on: type: number jobs: - unit-tests: + unit-test: runs-on: ubuntu-latest container: image: signalwire/freeswitch-public-base:bookworm From 1a7090fc66d5d1ccada478abc633ba57c1da5603 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 5 Nov 2024 17:40:30 +0000 Subject: [PATCH 162/205] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 16 ++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index c09f650f5a..51de531a35 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -15548,6 +15548,22 @@ SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_core_session_unlock_ } +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_core_codec_lock_full___(void * jarg1) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + + arg1 = (switch_core_session_t *)jarg1; + switch_core_codec_lock_full(arg1); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_core_codec_unlock_full___(void * jarg1) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + + arg1 = (switch_core_session_t *)jarg1; + switch_core_codec_unlock_full(arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_core_session_get_read_impl___(void * jarg1, void * jarg2) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 20bcbf4273..bfcee9310e 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -9283,6 +9283,14 @@ else freeswitchPINVOKE.switch_core_session_unlock_codec_read(SWIGTYPE_p_switch_core_session.getCPtr(session)); } + public static void switch_core_codec_lock_full(SWIGTYPE_p_switch_core_session session) { + freeswitchPINVOKE.switch_core_codec_lock_full(SWIGTYPE_p_switch_core_session.getCPtr(session)); + } + + public static void switch_core_codec_unlock_full(SWIGTYPE_p_switch_core_session session) { + freeswitchPINVOKE.switch_core_codec_unlock_full(SWIGTYPE_p_switch_core_session.getCPtr(session)); + } + public static switch_status_t switch_core_session_get_read_impl(SWIGTYPE_p_switch_core_session session, switch_codec_implementation impp) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_get_read_impl(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_codec_implementation.getCPtr(impp)); return ret; @@ -19314,6 +19322,12 @@ class freeswitchPINVOKE { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_core_session_unlock_codec_read___")] public static extern void switch_core_session_unlock_codec_read(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_core_codec_lock_full___")] + public static extern void switch_core_codec_lock_full(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_core_codec_unlock_full___")] + public static extern void switch_core_codec_unlock_full(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_core_session_get_read_impl___")] public static extern int switch_core_session_get_read_impl(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); From 4658192547e9b36baeaf90511e14d9bcd80a0402 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 13 Nov 2024 22:56:15 +0300 Subject: [PATCH 163/205] [Core] switch_channel_clear_state_handler(), switch_channel_get_state_handler(): Coverity 1546120 Data race condition * [Core] switch_channel_clear_state_handler: Coverity 1546120 Data race condition * [Core] Fix race in switch_channel_get_state_handler() --- src/switch_channel.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 9c7b8e433d..66e18a323c 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -3072,12 +3072,12 @@ SWITCH_DECLARE(const switch_state_handler_table_t *) switch_channel_get_state_ha switch_assert(channel != NULL); - if (index >= SWITCH_MAX_STATE_HANDLERS || index > channel->state_handler_index) { - return NULL; + switch_mutex_lock(channel->state_mutex); + + if (index < SWITCH_MAX_STATE_HANDLERS && index <= channel->state_handler_index) { + h = channel->state_handlers[index]; } - switch_mutex_lock(channel->state_mutex); - h = channel->state_handlers[index]; switch_mutex_unlock(channel->state_mutex); return h; @@ -3085,12 +3085,13 @@ SWITCH_DECLARE(const switch_state_handler_table_t *) switch_channel_get_state_ha SWITCH_DECLARE(void) switch_channel_clear_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler) { - int index, i = channel->state_handler_index; + int index, i; const switch_state_handler_table_t *new_handlers[SWITCH_MAX_STATE_HANDLERS] = { 0 }; switch_assert(channel != NULL); switch_mutex_lock(channel->state_mutex); + i = channel->state_handler_index; channel->state_handler_index = 0; if (state_handler) { From 8e694fe10be23feae1c9a0785789c8daa8bd4f70 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 2 Mar 2024 03:20:06 +0300 Subject: [PATCH 164/205] [Build-System] Upgrade legacy Windows SDK to 10.0 in Visual Studio projects. --- libs/esl/managed/esl.2017.vcxproj | 2 +- libs/win32/civetweb/duktape_lib.vcxproj | 2 +- libs/win32/civetweb/lua_lib.vcxproj | 2 +- libs/win32/ffmpeg/ffmpeg.2017.vcxproj | 2 +- libs/win32/libav/libav.2017.vcxproj | 2 +- libs/win32/libyuv/libyuv.2017.vcxproj | 2 +- libs/win32/speex/libspeexdsp.2017.vcxproj | 2 +- src/mod/applications/mod_av/test/test_mod_av.2017.vcxproj | 2 +- tests/unit/test_switch_core.2017.vcxproj | 2 +- tests/unit/test_switch_core_codec.2017.vcxproj | 2 +- tests/unit/test_switch_core_db.2017.vcxproj | 2 +- tests/unit/test_switch_ivr_originate.2017.vcxproj | 2 +- w32/Library/FreeSwitchCore.2017.vcxproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libs/esl/managed/esl.2017.vcxproj b/libs/esl/managed/esl.2017.vcxproj index f004381411..a140d2d296 100644 --- a/libs/esl/managed/esl.2017.vcxproj +++ b/libs/esl/managed/esl.2017.vcxproj @@ -23,7 +23,7 @@ {FEA2D0AE-6713-4E41-A473-A143849BC7FF} ESL ManagedCProj - 8.1 + 10.0 diff --git a/libs/win32/civetweb/duktape_lib.vcxproj b/libs/win32/civetweb/duktape_lib.vcxproj index c5ada61614..5a157971a0 100644 --- a/libs/win32/civetweb/duktape_lib.vcxproj +++ b/libs/win32/civetweb/duktape_lib.vcxproj @@ -22,7 +22,7 @@ {0A11689C-DB6A-4BF6-97B2-AD32DB863FBD} Win32Proj duktape_lib - 8.1 + 10.0 diff --git a/libs/win32/civetweb/lua_lib.vcxproj b/libs/win32/civetweb/lua_lib.vcxproj index 35b9f448b8..d2b5d7503e 100644 --- a/libs/win32/civetweb/lua_lib.vcxproj +++ b/libs/win32/civetweb/lua_lib.vcxproj @@ -22,7 +22,7 @@ {8F5E5D77-D269-4665-9E27-1045DA6CF0D8} Win32Proj lua_lib - 8.1 + 10.0 diff --git a/libs/win32/ffmpeg/ffmpeg.2017.vcxproj b/libs/win32/ffmpeg/ffmpeg.2017.vcxproj index b985670dbe..4c70bf6c71 100644 --- a/libs/win32/ffmpeg/ffmpeg.2017.vcxproj +++ b/libs/win32/ffmpeg/ffmpeg.2017.vcxproj @@ -21,7 +21,7 @@ ffmpeg ffmpeg - 10.0.17134.0 + 10.0 {BC1FD72E-1CD5-4525-A7F5-17C5740BFDED} diff --git a/libs/win32/libav/libav.2017.vcxproj b/libs/win32/libav/libav.2017.vcxproj index df547c3a7c..1b4ed945b7 100644 --- a/libs/win32/libav/libav.2017.vcxproj +++ b/libs/win32/libav/libav.2017.vcxproj @@ -21,7 +21,7 @@ libav libav - 8.1 + 10.0 {841C345F-FCC7-4F64-8F54-0281CEABEB01} diff --git a/libs/win32/libyuv/libyuv.2017.vcxproj b/libs/win32/libyuv/libyuv.2017.vcxproj index 136ac5119b..f74f7e1203 100644 --- a/libs/win32/libyuv/libyuv.2017.vcxproj +++ b/libs/win32/libyuv/libyuv.2017.vcxproj @@ -23,7 +23,7 @@ {B6E22500-3DB6-4E6E-8CD5-591B781D7D99} libyuv Win32Proj - 8.1 + 10.0 diff --git a/libs/win32/speex/libspeexdsp.2017.vcxproj b/libs/win32/speex/libspeexdsp.2017.vcxproj index 3c50103da9..4e2ba30453 100644 --- a/libs/win32/speex/libspeexdsp.2017.vcxproj +++ b/libs/win32/speex/libspeexdsp.2017.vcxproj @@ -38,7 +38,7 @@ {03207781-0D1C-4DB3-A71D-45C608F28DBD} Win32Proj libspeexdsp - 8.1 + 10.0 diff --git a/src/mod/applications/mod_av/test/test_mod_av.2017.vcxproj b/src/mod/applications/mod_av/test/test_mod_av.2017.vcxproj index 11dd386ff1..da6fdb97c3 100644 --- a/src/mod/applications/mod_av/test/test_mod_av.2017.vcxproj +++ b/src/mod/applications/mod_av/test/test_mod_av.2017.vcxproj @@ -22,7 +22,7 @@ test_mod_av test_mod_av Win32Proj - 10.0.17134.0 + 10.0 {7926CB0D-62CE-4A09-AE94-1DA2BC92D625} diff --git a/tests/unit/test_switch_core.2017.vcxproj b/tests/unit/test_switch_core.2017.vcxproj index c9e1cd5423..453e4a6bb8 100644 --- a/tests/unit/test_switch_core.2017.vcxproj +++ b/tests/unit/test_switch_core.2017.vcxproj @@ -22,7 +22,7 @@ test_switch_core test_switch_core Win32Proj - 10.0.17134.0 + 10.0 {EF62B845-A0CE-44FD-B8E6-475FE87D06C3} diff --git a/tests/unit/test_switch_core_codec.2017.vcxproj b/tests/unit/test_switch_core_codec.2017.vcxproj index 1434d80475..9c30374327 100644 --- a/tests/unit/test_switch_core_codec.2017.vcxproj +++ b/tests/unit/test_switch_core_codec.2017.vcxproj @@ -22,7 +22,7 @@ test_switch_core_codec test_switch_core_codec Win32Proj - 10.0.17134.0 + 10.0 {589A07E7-5DE5-49FD-A62C-27795B806AFB} diff --git a/tests/unit/test_switch_core_db.2017.vcxproj b/tests/unit/test_switch_core_db.2017.vcxproj index 9a419d556d..956e708977 100644 --- a/tests/unit/test_switch_core_db.2017.vcxproj +++ b/tests/unit/test_switch_core_db.2017.vcxproj @@ -22,7 +22,7 @@ test_switch_core_db test_switch_core_db Win32Proj - 10.0.17134.0 + 10.0 {580675D7-C1C9-4197-AAC5-00F64FAFDE78} diff --git a/tests/unit/test_switch_ivr_originate.2017.vcxproj b/tests/unit/test_switch_ivr_originate.2017.vcxproj index 78769a0b36..6ca24a11bb 100644 --- a/tests/unit/test_switch_ivr_originate.2017.vcxproj +++ b/tests/unit/test_switch_ivr_originate.2017.vcxproj @@ -22,7 +22,7 @@ test_switch_ivr_originate test_switch_ivr_originate Win32Proj - 10.0.17134.0 + 10.0 {69A7464A-9B0D-4804-A108-835229DACF58} diff --git a/w32/Library/FreeSwitchCore.2017.vcxproj b/w32/Library/FreeSwitchCore.2017.vcxproj index 2f7a3239bd..dbb0d5b7d1 100644 --- a/w32/Library/FreeSwitchCore.2017.vcxproj +++ b/w32/Library/FreeSwitchCore.2017.vcxproj @@ -23,7 +23,7 @@ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} FreeSwitchCoreLib Win32Proj - 8.1 + 10.0 From 556702ce9fd0a4391559f9f036a4f4906bfdb7e8 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Mon, 2 Dec 2024 02:16:21 +0100 Subject: [PATCH 165/205] [GHA] Refactor workflows --- .../debian/bookworm/amd64/CI/Dockerfile | 24 ++ .github/workflows/ci.yml | 132 +++++---- .github/workflows/scan-build.yml | 100 +++++++ .github/workflows/unit-test-dind.yml | 101 +++++++ .github/workflows/unit-test.yml | 178 +++++++----- .github/workflows/windows.yml | 28 ++ build/modmake.rulesam | 3 +- ci.sh | 259 ++++++++++++++++++ scan_build.sh | 28 -- tests/unit/collect-test-logs.sh | 119 ++++++-- tests/unit/run-tests-docker.sh | 165 +++++++++++ tests/unit/run-tests.sh | 211 ++++++++++++-- tests/unit/test.sh | 77 ++++-- 13 files changed, 1184 insertions(+), 241 deletions(-) create mode 100644 .github/docker/debian/bookworm/amd64/CI/Dockerfile create mode 100644 .github/workflows/scan-build.yml create mode 100644 .github/workflows/unit-test-dind.yml create mode 100644 .github/workflows/windows.yml create mode 100755 ci.sh delete mode 100755 scan_build.sh create mode 100755 tests/unit/run-tests-docker.sh diff --git a/.github/docker/debian/bookworm/amd64/CI/Dockerfile b/.github/docker/debian/bookworm/amd64/CI/Dockerfile new file mode 100644 index 0000000000..0fd3cec5f4 --- /dev/null +++ b/.github/docker/debian/bookworm/amd64/CI/Dockerfile @@ -0,0 +1,24 @@ +ARG BUILDER_IMAGE=signalwire/freeswitch-public-ci-base:bookworm-amd64 + +FROM ${BUILDER_IMAGE} + +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +LABEL org.opencontainers.image.authors="${MAINTAINER_EMAIL}" + +SHELL ["/bin/bash", "-c"] + +COPY --from=sofia-sip / /usr/src/sofia-sip +COPY --from=freeswitch / /usr/src/freeswitch + +RUN cd /usr/src/freeswitch && \ + ./ci.sh -t unit-test -a configure -c sofia-sip -p "/usr/src/sofia-sip" && \ + ./ci.sh -t unit-test -a build -c sofia-sip -p "/usr/src/sofia-sip" && \ + ./ci.sh -t unit-test -a install -c sofia-sip -p "/usr/src/sofia-sip" && \ + ./ci.sh -t unit-test -a configure -c freeswitch -p "/usr/src/freeswitch" && \ + ./ci.sh -t unit-test -a build -c freeswitch -p "/usr/src/freeswitch" && \ + ./ci.sh -t unit-test -a install -c freeswitch -p "/usr/src/freeswitch" + +WORKDIR /usr/src/freeswitch/tests/unit + +ENTRYPOINT ["/usr/src/freeswitch/tests/unit/run-tests.sh"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51586fabfe..0a774108e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,18 +4,45 @@ on: push: branches: - master + - v1.10 pull_request: types: - opened - synchronize + workflow_dispatch: + inputs: + freeswitch_ref: + description: 'FreeSWITCH repository ref' + required: false + type: string + sofia-sip_ref: + description: 'Sofia-Sip repository ref' + required: false + type: string + dind: + description: 'Run tests using Docker-in-Docker' + required: false + type: boolean + default: false + +env: + CI_BASE_STATIC_IMAGE: signalwire/freeswitch-public-ci-base:bookworm-amd64 + DOCKER_BUILD_SUMMARY: false + DOCKER_BUILD_CHECKS_ANNOTATIONS: false + DOCKER_BUILD_RECORD_UPLOAD: false jobs: unit-tests-pre-config: + if: ${{ !inputs.dind }} + name: "Unit-tests pre-config" runs-on: ubuntu-latest env: TOTAL_GROUPS: 2 outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} + container-image: ${{ steps.set-vars.outputs.container-image }} + working-directory: ${{ steps.set-vars.outputs.working-directory }} + tests-only: ${{ steps.set-vars.outputs.tests-only }} steps: - id: set-matrix shell: bash @@ -25,81 +52,52 @@ jobs: include: [range(1; $groups + 1) | {group: ., total: $groups}] }') echo "matrix=$MATRIX" | tee -a $GITHUB_OUTPUT + - id: set-vars + shell: bash + run: | + echo "tests-only=false" >> $GITHUB_OUTPUT + echo "working-directory=freeswitch/tests/unit" >> $GITHUB_OUTPUT + echo "container-image=$CI_BASE_STATIC_IMAGE" >> $GITHUB_OUTPUT unit-tests: - needs: unit-tests-pre-config + if: ${{ !inputs.dind }} + name: "Unit-tests (group ${{ matrix.group }})" + needs: + - unit-tests-pre-config strategy: + fail-fast: false matrix: ${{ fromJson(needs.unit-tests-pre-config.outputs.matrix) }} - name: "unit-tests (group ${{ matrix.group }})" uses: ./.github/workflows/unit-test.yml with: total-groups: ${{ matrix.total }} current-group: ${{ matrix.group }} + container-image: ${{ needs.unit-tests-pre-config.outputs.container-image }} + working-directory: ${{ needs.unit-tests-pre-config.outputs.working-directory }} + tests-only: ${{ fromJson(needs.unit-tests-pre-config.outputs.tests-only) }} + secrets: inherit + + validate-unit-tests: + if: ${{ always() && !inputs.dind }} + name: "Validate Unit-tests" + needs: unit-tests + runs-on: ubuntu-latest + steps: + - name: Check unit tests status + run: | + if [ "${{ needs.unit-tests.result }}" != "success" ]; then + exit 1 + fi + + unit-tests-dind: + if: ${{ inputs.dind }} + name: "Unit-tests D-in-D" + uses: ./.github/workflows/unit-test-dind.yml + with: + freeswitch_ref: ${{ inputs.freeswitch_ref }} + sofia-sip_ref: ${{ inputs.sofia-sip_ref }} secrets: inherit scan-build: - runs-on: ubuntu-latest - container: - image: signalwire/freeswitch-public-base:bookworm - credentials: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - options: --privileged - env: - REPOTOKEN: ${{ secrets.REPOTOKEN }} - DEBIAN_FRONTEND: noninteractive - - steps: - - name: Install dependencies - shell: bash - run: | - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf && \ - apt-get update && \ - apt-get -y remove \ - libsofia-sip-ua0 \ - libspandsp-dev && \ - apt-get -y install \ - autoconf \ - libsofia-sip-ua-dev \ - libspandsp3-dev && \ - rm -rf /etc/apt/auth.conf - - - name: Checkout code - uses: actions/checkout@v4 - with: - path: /__w/freeswitch/freeswitch - - - name: Bootstrap - shell: bash - working-directory: /__w/freeswitch/freeswitch - run: | - ./bootstrap.sh -j || exit 1 - - - name: Scan-build FreeSwitch - shell: bash - working-directory: /__w/freeswitch/freeswitch - run: | - cp build/modules.conf.most modules.conf && \ - echo 'codecs/mod_openh264' >> modules.conf && \ - sed -i \ - -e '/mod_mariadb/s/^#//g' \ - -e '/mod_v8/s/^#//g' \ - -e '/mod_ilbc/s/^/#/g' \ - -e '/mod_isac/s/^/#/g' \ - -e '/mod_mp4/s/^/#/g' \ - -e '/mod_mongo/s/^/#/g' \ - -e '/mod_pocketsphinx/s/^/#/g' \ - -e '/mod_sangoma_codec/s/^/#/g' \ - -e '/mod_siren/s/^/#/g' \ - -e '/mod_avmd/s/^/#/g' \ - -e '/mod_basic/s/^/#/g' \ - -e '/mod_cdr_mongodb/s/^/#/g' \ - -e '/mod_cv/s/^/#/g' \ - -e '/mod_erlang_event/s/^/#/g' \ - -e '/mod_perl/s/^/#/g' \ - -e '/mod_rtmp/s/^/#/g' \ - -e '/mod_unimrcp/s/^/#/g' \ - -e '/mod_xml_rpc/s/^/#/g' \ - modules.conf && \ - ./configure && \ - ./scan_build.sh + name: "Scan Build" + uses: ./.github/workflows/scan-build.yml + secrets: inherit diff --git a/.github/workflows/scan-build.yml b/.github/workflows/scan-build.yml new file mode 100644 index 0000000000..5d90f2b3da --- /dev/null +++ b/.github/workflows/scan-build.yml @@ -0,0 +1,100 @@ +name: Scan build (Static Analysis) + +on: + workflow_call: + inputs: + freeswitch_ref: + description: 'FreeSWITCH repository ref' + required: false + type: string + sofia-sip_ref: + description: 'Sofia-Sip repository ref' + required: false + type: string + +jobs: + scan-build: + runs-on: ubuntu-latest + container: + image: signalwire/freeswitch-public-ci-base:bookworm-amd64 + options: --privileged + env: + DEBIAN_FRONTEND: noninteractive + + steps: + - name: Checkout Sofia-Sip + if: inputs.sofia-sip_ref == '' + uses: actions/checkout@v4 + with: + repository: freeswitch/sofia-sip + path: sofia-sip + + - name: Checkout Sofia-Sip (via ref) + if: inputs.sofia-sip_ref != '' + uses: actions/checkout@v4 + with: + repository: freeswitch/sofia-sip + ref: ${{ inputs.sofia-sip_ref }} + path: sofia-sip + + - name: Checkout FreeSWITCH (via ref) + if: inputs.freeswitch_ref != '' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.freeswitch_ref }} + path: freeswitch + + - name: Checkout FreeSWITCH + if: inputs.freeswitch_ref == '' + uses: actions/checkout@v4 + with: + path: freeswitch + + - name: Configure, Build and Install Sofia-Sip + shell: bash + working-directory: freeswitch + run: | + ./ci.sh -t scan-build -a configure -c sofia-sip -p "$GITHUB_WORKSPACE/sofia-sip" + ./ci.sh -t scan-build -a build -c sofia-sip -p "$GITHUB_WORKSPACE/sofia-sip" + ./ci.sh -t scan-build -a install -c sofia-sip -p "$GITHUB_WORKSPACE/sofia-sip" + + - name: Configure FreeSWITCH + shell: bash + working-directory: freeswitch + run: | + ./ci.sh -t scan-build -a configure -c freeswitch -p "$GITHUB_WORKSPACE/freeswitch" + + - name: Run scan-build analysis + shell: bash + working-directory: freeswitch + run: | + ./ci.sh -t scan-build -a build -c freeswitch -p "$GITHUB_WORKSPACE/freeswitch" + + - name: Check analysis results + if: always() + shell: bash + working-directory: freeswitch + run: | + ./ci.sh -t scan-build -a validate -c freeswitch -p "$GITHUB_WORKSPACE/freeswitch" + + - name: Upload Scan-Build logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: scan-build-logs + path: freeswitch/scan-build + retention-days: 3 + if-no-files-found: ignore + compression-level: 9 + + - name: Notify run tests result to slack + if: | + failure() && + github.event_name == 'push' && + (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v1.10') + uses: signalwire/actions-template/.github/actions/slack@main + with: + CHANNEL: ${{ secrets.SLACK_DEVOPS_CI_CHANNEL }} + MESSAGE: Scan-Build ${{ github.repository }} > <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ github.run_id }}>. Static analysis failed. + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/unit-test-dind.yml b/.github/workflows/unit-test-dind.yml new file mode 100644 index 0000000000..40a51a101d --- /dev/null +++ b/.github/workflows/unit-test-dind.yml @@ -0,0 +1,101 @@ +name: Unit-tests D-in-D + +on: + workflow_call: + inputs: + freeswitch_ref: + description: 'FreeSWITCH repository ref' + required: false + type: string + sofia-sip_ref: + description: 'Sofia-Sip repository ref' + required: false + type: string + +env: + MAX_CONTAINERS: 8 + NUM_CPU_PER_CONTAINER: 1 + DOCKER_BUILD_SUMMARY: false + DOCKER_BUILD_CHECKS_ANNOTATIONS: false + DOCKER_BUILD_RECORD_UPLOAD: false + +jobs: + unit-tests: + runs-on: ubuntu-latest + container: + image: signalwire/freeswitch-public-ci-base:bookworm-amd64 + options: --privileged + env: + DEBIAN_FRONTEND: noninteractive + ASAN_OPTIONS: log_path=stdout:disable_coredump=0:unmap_shadow_on_exit=1:fast_unwind_on_malloc=0 + + steps: + - name: Checkout Sofia-Sip (via ref) + if: inputs.sofia-sip_ref != '' + uses: actions/checkout@v4 + with: + repository: freeswitch/sofia-sip + ref: ${{ inputs.sofia-sip_ref }} + path: sofia-sip + + - name: Checkout Sofia-Sip + if: inputs.sofia-sip_ref == '' + uses: actions/checkout@v4 + with: + repository: freeswitch/sofia-sip + path: sofia-sip + + - name: Checkout FreeSWITCH (via ref) + if: inputs.freeswitch_ref != '' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.freeswitch_ref }} + path: freeswitch + + - name: Checkout FreeSWITCH + if: inputs.freeswitch_ref == '' + uses: actions/checkout@v4 + with: + path: freeswitch + + - name: Run Unit-Test containers and collect artifacts + id: unit_tests + shell: bash + run: | + echo "logs_path=${GITHUB_WORKSPACE}/freeswitch/tests/unit/logs" >> $GITHUB_OUTPUT + + "${GITHUB_WORKSPACE}/freeswitch/tests/unit/run-tests-docker.sh" \ + --base-image signalwire/freeswitch-public-ci-base:bookworm-amd64 \ + --cpus ${{ env.NUM_CPU_PER_CONTAINER }} \ + --image-tag ci.local \ + --max-containers ${{ env.MAX_CONTAINERS }} \ + --output-dir "${GITHUB_WORKSPACE}/freeswitch/tests/unit/logs" \ + --sofia-sip-path "${GITHUB_WORKSPACE}/sofia-sip" \ + --freeswitch-path "${GITHUB_WORKSPACE}/freeswitch" + + test -d "/cores" && ls -lah /cores + + cd "${GITHUB_WORKSPACE}/freeswitch/tests/unit/" && \ + ./collect-test-logs.sh --dir logs --print + + - name: Upload Unit-Test logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ github.sha }}-${{ github.run_number }} + path: ${{ steps.unit_tests.outputs.logs_path }} + retention-days: 3 + if-no-files-found: ignore + compression-level: 9 + + - name: Notify run tests result to slack + if: | + failure() && + github.event_name == 'push' && + (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v1.10') + uses: signalwire/actions-template/.github/actions/slack@main + with: + CHANNEL: ${{ secrets.SLACK_DEVOPS_CI_CHANNEL }} + MESSAGE: Unit-Tests ${{ github.repository }} > <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ github.run_id }}>. Some tests are failing. + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 5db97620a4..e89a1f6799 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -7,19 +7,41 @@ on: description: 'Total number of test groups' required: true type: number + default: 1 current-group: description: 'Current test group number' required: true type: number + default: 1 + freeswitch_ref: + description: 'FreeSWITCH repository ref' + required: false + type: string + sofia-sip_ref: + description: 'Sofia-Sip repository ref' + required: false + type: string + container-image: + description: 'Container image to use for running tests' + required: false + type: string + default: 'signalwire/freeswitch-public-ci-base:bookworm-amd64' + working-directory: + description: 'Working directory for running tests' + required: false + type: string + default: 'freeswitch/tests/unit' + tests-only: + description: 'Run only tests, skip other tasks' + required: false + type: boolean + default: false jobs: unit-test: runs-on: ubuntu-latest container: - image: signalwire/freeswitch-public-base:bookworm - credentials: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + image: ${{ inputs.container-image }} options: --privileged env: DEBIAN_FRONTEND: noninteractive @@ -29,83 +51,87 @@ jobs: - name: Override core_pattern shell: bash run: | - cat /proc/sys/kernel/core_pattern echo '/cores/core.%s.%E.%e.%p.%t' > /proc/sys/kernel/core_pattern cat /proc/sys/kernel/core_pattern - - name: Install dependencies - shell: bash - env: - REPOTOKEN: ${{ secrets.REPOTOKEN }} - run: | - echo "machine freeswitch.signalwire.com password $REPOTOKEN" > /etc/apt/auth.conf && \ - apt-get update && \ - apt-get -y remove \ - libsofia-sip-ua0 \ - libspandsp-dev && \ - apt-get -y install \ - libspandsp3-dev && \ - rm -rf /etc/apt/auth.conf - - - name: Checkout code - uses: actions/checkout@v4 - with: - path: /__w/freeswitch/freeswitch - - - name: Bootstrap - shell: bash - working-directory: /__w/freeswitch/freeswitch - run: | - ./bootstrap.sh -j || exit 1 - - - name: Checkout Sofia-Sip + - name: Checkout Sofia-Sip (via ref) + if: ${{ !inputs.tests-only && inputs.sofia-sip_ref != '' }} uses: actions/checkout@v4 with: repository: freeswitch/sofia-sip - path: /__w/freeswitch/freeswitch/sofia-sip + ref: ${{ inputs.sofia-sip_ref }} + path: sofia-sip - - name: Build sofia-sip - shell: bash - working-directory: /__w/freeswitch/freeswitch/sofia-sip - run: | - ./autogen.sh && \ - ./configure.gnu && \ - make -j$(nproc --all) install - - - name: Build FreeSwitch - shell: bash - working-directory: /__w/freeswitch/freeswitch - run: | - echo 'codecs/mod_openh264' >> modules.conf && \ - sed -i \ - -e '/applications\/mod_http_cache/s/^#//g' \ - -e '/event_handlers\/mod_rayo/s/^#//g' \ - -e '/formats\/mod_opusfile/s/^#//g' \ - -e '/languages\/mod_lua/s/^#//g' \ - modules.conf && \ - ./configure \ - --enable-address-sanitizer \ - --enable-fake-dlclose && \ - make -j$(nproc --all) |& tee ./unit-tests-build-result.txt - - echo ${PIPESTATUS[0]} > ./build-status.txt - if ! test "$(cat ./build-status.txt | tr -d '[:space:]')" -eq 0; then - exit "$(cat ./build-status.txt | tr -d '[:space:]')" - fi - make install - - - name: Run tests - shell: bash - working-directory: /__w/freeswitch/freeswitch/tests/unit - run: | - ./run-tests.sh ${{ inputs.total-groups }} ${{ inputs.current-group }} - mkdir logs && (mv log_run-tests_*.html logs || true) && (mv backtrace_*.txt logs || true) - ./collect-test-logs.sh - - - name: Notify result - if: failure() - uses: signalwire/actions-template/.github/actions/notify-ci-result@main + - name: Checkout Sofia-Sip + if: ${{ !inputs.tests-only && inputs.sofia-sip_ref == '' }} + uses: actions/checkout@v4 with: - for: "run_tests" - test_logs_path: /__w/freeswitch/freeswitch/tests/unit - test_artifacts_suffix: "-${{ inputs.current-group }}" + repository: freeswitch/sofia-sip + path: sofia-sip + + - name: Checkout FreeSWITCH (via ref) + if: ${{ !inputs.tests-only && inputs.freeswitch_ref != '' }} + uses: actions/checkout@v4 + with: + ref: ${{ inputs.freeswitch_ref }} + path: freeswitch + + - name: Checkout FreeSWITCH + if: ${{ !inputs.tests-only && inputs.freeswitch_ref == '' }} + uses: actions/checkout@v4 + with: + path: freeswitch + + - name: Configure, Build and Install Sofia-Sip + if: ${{ !inputs.tests-only }} + shell: bash + working-directory: freeswitch + run: | + ./ci.sh -t unit-test -a configure -c sofia-sip -p "$GITHUB_WORKSPACE/sofia-sip" + ./ci.sh -t unit-test -a build -c sofia-sip -p "$GITHUB_WORKSPACE/sofia-sip" + ./ci.sh -t unit-test -a install -c sofia-sip -p "$GITHUB_WORKSPACE/sofia-sip" + + - name: Configure, Build and Install FreeSWITCH + if: ${{ !inputs.tests-only }} + shell: bash + working-directory: freeswitch + run: | + ./ci.sh -t unit-test -a configure -c freeswitch -p "$GITHUB_WORKSPACE/freeswitch" + ./ci.sh -t unit-test -a build -c freeswitch -p "$GITHUB_WORKSPACE/freeswitch" + ./ci.sh -t unit-test -a install -c freeswitch -p "$GITHUB_WORKSPACE/freeswitch" + + - name: Run unit tests + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + ./run-tests.sh ${{ inputs.total-groups }} ${{ inputs.current-group }} --output-dir logs || exit 1 + + - name: Collect unit test logs + if: always() + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + test -d "/cores" && ls -lah /cores + ./collect-test-logs.sh --dir logs --print + + - name: Upload Unit-Test logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ github.sha }}-${{ github.run_number }}-${{ inputs.current-group }}-of-${{ inputs.total-groups }} + path: ${{ inputs.working-directory }}/logs + retention-days: 3 + if-no-files-found: ignore + compression-level: 9 + + - name: Notify run tests result to slack + if: | + failure() && + github.event_name == 'push' && + (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v1.10') + uses: signalwire/actions-template/.github/actions/slack@main + with: + CHANNEL: ${{ secrets.SLACK_DEVOPS_CI_CHANNEL }} + MESSAGE: Unit-Tests ${{ github.repository }} > <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ github.run_id }}>. Some tests are failing. + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000000..5d59fba2a1 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,28 @@ +name: Windows + +on: + pull_request: + types: [opened, synchronize] + push: + branches: [master, release] +jobs: + x64: + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: Build + run: msbuild Freeswitch.2017.sln -t:build -verbosity:minimal -property:Configuration=Release -property:Platform=x64 + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: MSI Package + path: D:\a\freeswitch\freeswitch\x64\*.msi + if: contains(github.event.pull_request.title, ':upload-artifacts') || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v1.10' diff --git a/build/modmake.rulesam b/build/modmake.rulesam index 5ccdf8b5c2..9e4eb56f97 100644 --- a/build/modmake.rulesam +++ b/build/modmake.rulesam @@ -17,5 +17,4 @@ extraclean-modules: extraclean print_tests: @set +e; \ - test -z "$(TESTS)" || for i in $(TESTS); do echo $(subdir)/$$i; done; - \ No newline at end of file + test -z "$(TESTS)" || for i in $(TESTS); do echo $(subdir)/$$i; done; echo; diff --git a/ci.sh b/ci.sh new file mode 100755 index 0000000000..c8d9e848cc --- /dev/null +++ b/ci.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env bash + +### shfmt -w -s -ci -sr -kp -fn ci.sh + +#------------------------------------------------------------------------------ +# CI Script +# Helper script for running CI jobs +#------------------------------------------------------------------------------ + +# Function to display usage information +display_usage() +{ + echo "Usage: $0 -t -a -c -p " + echo "Options:" + echo " -t Type (unit-test, scan-build)" + echo " -a Action (configure, build, install, validate)" + echo " -c Code (sofia-sip, freeswitch)" + echo " -p Path to code" + exit 1 +} + +# Parse command line arguments +while getopts "t:p:a:c:h" opt; do + case $opt in + t) TYPE="$OPTARG" ;; + a) ACTION="$OPTARG" ;; + c) CODE="$OPTARG" ;; + p) PATH_TO_CODE="$OPTARG" ;; + h) display_usage ;; + ?) display_usage ;; + esac +done + +# Function to handle sofia-sip configuration +configure_sofia_sip() +{ + ./autogen.sh && ./configure.gnu || exit 1 +} + +# Function to handle sofia-sip build +build_sofia_sip() +{ + make -j$(nproc) || exit 1 +} + +# Function to handle sofia-sip installation +install_sofia_sip() +{ + make install || exit 1 +} + +# Function to handle sofia-sip validation +validate_sofia_sip() +{ + exit 0 +} + +# Function to handle freeswitch configuration +configure_freeswitch() +{ + local type="$1" + + ./bootstrap.sh -j || exit 1 + + case "$type" in + "unit-test") + echo 'codecs/mod_openh264' >> modules.conf + sed -i \ + -e '/applications\/mod_http_cache/s/^#//g' \ + -e '/event_handlers\/mod_rayo/s/^#//g' \ + -e '/formats\/mod_opusfile/s/^#//g' \ + -e '/languages\/mod_lua/s/^#//g' \ + modules.conf + + export ASAN_OPTIONS=log_path=stdout:disable_coredump=0:unmap_shadow_on_exit=1:fast_unwind_on_malloc=0 + + ./configure \ + --enable-address-sanitizer \ + --enable-fake-dlclose || + exit 1 + + ;; + "scan-build") + cp build/modules.conf.most modules.conf + + # "Enable"/"Uncomment" mods + echo 'codecs/mod_openh264' >> modules.conf + sed -i \ + -e '/mod_mariadb/s/^#//g' \ + -e '/mod_v8/s/^#//g' \ + modules.conf + + # "Disable"/"Comment out" mods + sed -i \ + -e '/mod_ilbc/s/^/#/g' \ + -e '/mod_isac/s/^/#/g' \ + -e '/mod_mp4/s/^/#/g' \ + -e '/mod_mongo/s/^/#/g' \ + -e '/mod_pocketsphinx/s/^/#/g' \ + -e '/mod_sangoma_codec/s/^/#/g' \ + -e '/mod_siren/s/^/#/g' \ + -e '/mod_avmd/s/^/#/g' \ + -e '/mod_basic/s/^/#/g' \ + -e '/mod_cdr_mongodb/s/^/#/g' \ + -e '/mod_cv/s/^/#/g' \ + -e '/mod_erlang_event/s/^/#/g' \ + -e '/mod_perl/s/^/#/g' \ + -e '/mod_rtmp/s/^/#/g' \ + -e '/mod_unimrcp/s/^/#/g' \ + -e '/mod_xml_rpc/s/^/#/g' \ + modules.conf + + ./configure || exit 1 + + ;; + *) + exit 1 + ;; + esac +} + +# Function to handle freeswitch build +build_freeswitch() +{ + local type="$1" + + set -o pipefail + + case "$type" in + "unit-test") + make --no-keep-going -j$(nproc --all) |& tee ./unit-tests-build-result.txt + build_status=${PIPESTATUS[0]} + if [[ $build_status != "0" ]]; then + exit $build_status + fi + + ;; + "scan-build") + if ! command -v scan-build-14 > /dev/null 2>&1; then + echo "Error: scan-build-14 command not found. Please ensure clang static analyzer is installed." >&2 + exit 1 + fi + + mkdir -p scan-build + + scan-build-14 \ + --force-analyze-debug-code \ + --status-bugs \ + -o ./scan-build/ \ + make --no-keep-going -j$(nproc --all) |& tee ./scan-build-result.txt + build_status=${PIPESTATUS[0]} + + if ! grep -siq "scan-build: No bugs found" ./scan-build-result.txt; then + echo "scan-build: bugs found!" + exit 1 + fi + + if [[ $build_status != "0" ]]; then + echo "scan-build: compilation failed!" + exit $build_status + fi + + ;; + *) + exit 1 + ;; + esac +} + +# Function to handle freeswitch installation +install_freeswitch() +{ + make install || exit 1 +} + +# Function to handle freeswitch validation +validate_freeswitch() +{ + local type="$1" + + case "$type" in + "unit-test") + exit 0 + ;; + "scan-build") + REPORT_PATH=$(find scan-build* -mindepth 1 -type d) + if [ -n "$REPORT_PATH" ]; then + echo "Found analysis report at: $REPORT_PATH" + + if command -v html2text > /dev/null 2>&1; then + echo "Report contents:" + html2text "$REPORT_PATH"/*.html || true + fi + + echo "Number of issues found:" + grep -c " - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/cdr_csv.conf.xml b/conf/rayo/autoload_configs/cdr_csv.conf.xml deleted file mode 100644 index 8d796c68f0..0000000000 --- a/conf/rayo/autoload_configs/cdr_csv.conf.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/conference.conf.xml b/conf/rayo/autoload_configs/conference.conf.xml deleted file mode 100644 index 0641df764e..0000000000 --- a/conf/rayo/autoload_configs/conference.conf.xml +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/console.conf.xml b/conf/rayo/autoload_configs/console.conf.xml deleted file mode 100644 index 44a7e6cb1d..0000000000 --- a/conf/rayo/autoload_configs/console.conf.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/event_socket.conf.xml b/conf/rayo/autoload_configs/event_socket.conf.xml deleted file mode 100644 index 5ea2e09788..0000000000 --- a/conf/rayo/autoload_configs/event_socket.conf.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/conf/rayo/autoload_configs/http_cache.conf.xml b/conf/rayo/autoload_configs/http_cache.conf.xml deleted file mode 100644 index 5d70ec6a3a..0000000000 --- a/conf/rayo/autoload_configs/http_cache.conf.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/local_stream.conf.xml b/conf/rayo/autoload_configs/local_stream.conf.xml deleted file mode 100644 index 94a5665392..0000000000 --- a/conf/rayo/autoload_configs/local_stream.conf.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/logfile.conf.xml b/conf/rayo/autoload_configs/logfile.conf.xml deleted file mode 100644 index 38a1d39a4c..0000000000 --- a/conf/rayo/autoload_configs/logfile.conf.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/modules.conf.xml b/conf/rayo/autoload_configs/modules.conf.xml deleted file mode 100644 index ee44e06c57..0000000000 --- a/conf/rayo/autoload_configs/modules.conf.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/pocketsphinx.conf.xml b/conf/rayo/autoload_configs/pocketsphinx.conf.xml deleted file mode 100644 index 3bf7d5e575..0000000000 --- a/conf/rayo/autoload_configs/pocketsphinx.conf.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/post_load_modules.conf.xml b/conf/rayo/autoload_configs/post_load_modules.conf.xml deleted file mode 100644 index 8f4e132fa4..0000000000 --- a/conf/rayo/autoload_configs/post_load_modules.conf.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/conf/rayo/autoload_configs/pre_load_modules.conf.xml b/conf/rayo/autoload_configs/pre_load_modules.conf.xml deleted file mode 100644 index 620a6c1cd9..0000000000 --- a/conf/rayo/autoload_configs/pre_load_modules.conf.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/conf/rayo/autoload_configs/presence_map.conf.xml b/conf/rayo/autoload_configs/presence_map.conf.xml deleted file mode 100644 index 8a9d1dde5a..0000000000 --- a/conf/rayo/autoload_configs/presence_map.conf.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml deleted file mode 100644 index 9f525c597c..0000000000 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - 0123456789]]]]> - - - ]]> - - - - - - yesno - ]]]]> - - - ]]> - - - - - - yesno - ]]]]> - - - ]]> - - -
- -
diff --git a/conf/rayo/autoload_configs/shout.conf.xml b/conf/rayo/autoload_configs/shout.conf.xml deleted file mode 100644 index c3d1334b68..0000000000 --- a/conf/rayo/autoload_configs/shout.conf.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/conf/rayo/autoload_configs/sofia.conf.xml b/conf/rayo/autoload_configs/sofia.conf.xml deleted file mode 100644 index a5e8614322..0000000000 --- a/conf/rayo/autoload_configs/sofia.conf.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/spandsp.conf.xml b/conf/rayo/autoload_configs/spandsp.conf.xml deleted file mode 100644 index f9556d3c78..0000000000 --- a/conf/rayo/autoload_configs/spandsp.conf.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/ssml.conf.xml b/conf/rayo/autoload_configs/ssml.conf.xml deleted file mode 100644 index d4e27bf184..0000000000 --- a/conf/rayo/autoload_configs/ssml.conf.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/switch.conf.xml b/conf/rayo/autoload_configs/switch.conf.xml deleted file mode 100644 index 02aa434f9b..0000000000 --- a/conf/rayo/autoload_configs/switch.conf.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/timezones.conf.xml b/conf/rayo/autoload_configs/timezones.conf.xml deleted file mode 100644 index 9ddded792c..0000000000 --- a/conf/rayo/autoload_configs/timezones.conf.xml +++ /dev/null @@ -1,661 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/cacert.pem b/conf/rayo/cacert.pem deleted file mode 100644 index 72e14177c9..0000000000 --- a/conf/rayo/cacert.pem +++ /dev/null @@ -1,3366 +0,0 @@ -## -## ca-bundle.crt -- Bundle of CA Root Certificates -## -## Certificate data from Mozilla as of: Sun Feb 19 04:03:37 2012 -## -## This is a bundle of X.509 certificates of public Certificate Authorities -## (CA). These were automatically extracted from Mozilla's root certificates -## file (certdata.txt). This file can be found in the mozilla source tree: -## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 -## -## It contains the certificates in PEM format and therefore -## can be directly used with curl / libcurl / php_curl, or with -## an Apache+mod_ssl webserver for SSL client authentication. -## Just configure this file as the SSLCACertificateFile. -## - -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.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. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** -# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.82 $ $Date: 2012/02/18 21:41:46 $ - -GTE CyberTrust Global Root -========================== ------BEGIN CERTIFICATE----- -MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg -Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG -A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz -MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL -Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 -IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u -sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql -HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID -AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW -M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF -NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ ------END CERTIFICATE----- - -Thawte Server CA -================ ------BEGIN CERTIFICATE----- -MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE -AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j -b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV -BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u -c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG -A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 -ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl -/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 -1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J -GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ -GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= ------END CERTIFICATE----- - -Thawte Premium Server CA -======================== ------BEGIN CERTIFICATE----- -MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE -AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl -ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT -AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU -VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 -aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ -cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 -aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh -Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ -qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm -SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf -8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t -UCemDaYj+bvLpgcUQg== ------END CERTIFICATE----- - -Equifax Secure CA -================= ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE -ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT -B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR -fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW -8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG -A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE -CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG -A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS -spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB -Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 -zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB -BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 -70+sB3c4 ------END CERTIFICATE----- - -Digital Signature Trust Co. Global CA 1 -======================================= ------BEGIN CERTIFICATE----- -MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE -ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy -MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs -IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE -NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i -o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo -BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 -dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw -IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY -MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM -BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB -ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq -kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4 -RbyhkwS7hp86W0N6w4pl ------END CERTIFICATE----- - -Digital Signature Trust Co. Global CA 3 -======================================= ------BEGIN CERTIFICATE----- -MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE -ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy -MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs -IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD -VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS -xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo -BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 -dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw -IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY -MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM -BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB -AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi -up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1 -mPnHfxsb1gYgAlihw6ID ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA -TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah -WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf -Tqj/ZA1k ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO -FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 -lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB -MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT -1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD -Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 ------END CERTIFICATE----- - -GlobalSign Root CA -================== ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx -GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds -b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD -VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa -DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc -THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb -Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP -c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX -gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF -AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj -Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG -j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH -hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC -X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -GlobalSign Root CA - R2 -======================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 -ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp -s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN -S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL -TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C -ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i -YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN -BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp -9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu -01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 -9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -ValiCert Class 1 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy -MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi -GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm -DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG -lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX -icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP -Orf1LXLI ------END CERTIFICATE----- - -ValiCert Class 2 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC -CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf -ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ -SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV -UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 -W9ViH0Pd ------END CERTIFICATE----- - -RSA Root Certificate 1 -====================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td -3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H -BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs -3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF -V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r -on+jjBXu ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 -EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc -cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw -EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj -055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f -j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 -xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa -t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - -Verisign Class 4 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS -tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM -8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW -Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX -Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt -mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd -RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG -UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - -Entrust.net Secure Server CA -============================ ------BEGIN CERTIFICATE----- -MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg -cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl -ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG -A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi -eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p -dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ -aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 -gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw -ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw -CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l -dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF -bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu -dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw -NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow -HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA -BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN -Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 -n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= ------END CERTIFICATE----- - -Entrust.net Premium 2048 Secure Server CA -========================================= ------BEGIN CERTIFICATE----- -MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u -ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp -bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV -BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx -NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 -d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl -MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u -ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL -Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr -hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW -nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi -VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC -AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER -gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B -AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo -oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS -o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z -2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX -OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ== ------END CERTIFICATE----- - -Baltimore CyberTrust Root -========================= ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE -ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li -ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC -SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs -dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME -uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB -UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C -G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 -XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr -l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI -VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB -BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh -cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 -hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa -Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H -RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -Equifax Secure Global eBusiness CA -================================== ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp -bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx -HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds -b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV -PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN -qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn -hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs -MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN -I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY -NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 1 -============================= ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB -LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE -ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz -IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ -1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a -IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk -MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW -Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF -AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 -lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ -KpYrtWKmpj29f5JZzVoqgrI3eQ== ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 2 -============================= ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE -ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y -MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT -DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn -2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 -BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG -A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx -JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG -A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e -uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB -Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 -jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia -78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm -V+GRMOrN ------END CERTIFICATE----- - -AddTrust Low-Value Services Root -================================ ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU -cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw -CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO -ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 -54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr -oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 -Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui -GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w -HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT -RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw -HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt -ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph -iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr -mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj -ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- - -AddTrust External Root -====================== ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD -VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw -NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU -cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg -Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 -+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw -Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo -aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy -2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 -7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL -VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk -VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl -j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 -e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u -G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - -AddTrust Public Services Root -============================= ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU -cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ -BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l -dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu -nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i -d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG -Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw -HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G -A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G -A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 -JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL -+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao -GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 -Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H -EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= ------END CERTIFICATE----- - -AddTrust Qualified Certificates Root -==================================== ------BEGIN CERTIFICATE----- -MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU -cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx -CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ -IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx -64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 -KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o -L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR -wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU -MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE -BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y -azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG -GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X -dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze -RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB -iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= ------END CERTIFICATE----- - -Entrust Root Certification Authority -==================================== ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw -b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG -A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 -MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu -MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu -Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v -dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz -A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww -Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 -j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN -rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 -MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH -hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM -Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa -v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS -W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 -tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -RSA Security 2048 v3 -==================== ------BEGIN CERTIFICATE----- -MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK -ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy -MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb -BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 -Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb -WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH -KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP -+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E -FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY -v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj -0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj -VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 -nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA -pKnXwiJPZ9d37CAFYd4= ------END CERTIFICATE----- - -GeoTrust Global CA -================== ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw -MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo -BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet -8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc -T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU -vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q -zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 -d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 -mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p -XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm -Mw== ------END CERTIFICATE----- - -GeoTrust Global CA 2 -==================== ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw -MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ -NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k -LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA -Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b -HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH -K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 -srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh -ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL -OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC -x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF -H4z1Ir+rzoPz4iIprn2DQKi6bA== ------END CERTIFICATE----- - -GeoTrust Universal CA -===================== ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 -MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu -Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t -JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e -RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs -7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d -8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V -qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga -Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB -Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu -KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 -ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 -XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB -hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 -qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL -oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK -xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF -KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 -DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK -xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU -p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI -P/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -GeoTrust Universal CA 2 -======================= ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 -MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg -SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 -DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 -j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q -JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a -QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 -WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP -20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn -ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC -SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG -8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 -+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E -BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ -4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ -mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq -A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg -Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP -pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d -FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp -gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm -X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - -America Online Root Certification Authority 1 -============================================= ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG -v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z -DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh -sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP -8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z -o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf -GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF -VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft -3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g -Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds -sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 ------END CERTIFICATE----- - -America Online Root Certification Authority 2 -============================================= ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en -fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 -f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO -qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN -RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 -gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn -6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid -FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 -Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj -B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op -aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY -T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p -+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg -JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy -zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO -ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh -1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf -GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff -Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP -cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= ------END CERTIFICATE----- - -Visa eCommerce Root -=================== ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG -EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug -QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 -WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm -VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL -F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b -RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 -TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI -/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs -GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG -MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc -CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW -YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz -zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu -YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- - -Certum Root CA -============== ------BEGIN CERTIFICATE----- -MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK -ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla -Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u -by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x -wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL -kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ -89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K -Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P -NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ -GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg -GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ -0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS -qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== ------END CERTIFICATE----- - -Comodo AAA Services root -======================== ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw -MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl -c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV -BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG -C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs -i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW -Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH -Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK -Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f -BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl -cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz -LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm -7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z -8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C -12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -Comodo Secure Services root -=========================== ------BEGIN CERTIFICATE----- -MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw -MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu -Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi -BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP -9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc -rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC -oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V -p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E -FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w -gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj -YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm -aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm -4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj -Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL -DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw -pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H -RR3B7Hzs/Sk= ------END CERTIFICATE----- - -Comodo Trusted Services root -============================ ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw -MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h -bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw -IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 -3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y -/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 -juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS -ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud -DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp -ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl -cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw -uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 -pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA -BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l -R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O -9y5Xt5hwXsjEeLBi ------END CERTIFICATE----- - -QuoVadis Root CA -================ ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE -ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz -MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp -cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD -EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk -J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL -F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL -YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen -AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w -PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y -ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 -MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj -YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs -ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW -Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu -BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw -FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 -tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo -fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul -LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x -gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi -5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi -5nrQNiOKSnQ2+Q== ------END CERTIFICATE----- - -QuoVadis Root CA 2 -================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -QuoVadis Root CA 3 -================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - -Sonera Class 2 Root CA -====================== ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG -U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw -NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh -IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 -/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT -dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG -f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P -tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH -nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT -XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt -0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI -cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph -Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx -EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH -llpwrN9M ------END CERTIFICATE----- - -Staat der Nederlanden Root CA -============================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE -ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w -HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh -bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt -vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P -jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca -C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth -vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 -22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV -HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v -dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN -BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR -EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw -MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y -nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- - -TDC Internet Root CA -==================== ------BEGIN CERTIFICATE----- -MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE -ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx -NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu -ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j -xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL -znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc -5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 -otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI -AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM -VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM -MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC -AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe -UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G -CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m -gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ -2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb -O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU -Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l ------END CERTIFICATE----- - -TDC OCES Root CA -================ ------BEGIN CERTIFICATE----- -MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE -ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5 -MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH -nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0 -zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV -iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde -dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO -3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB -5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k -ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm -cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp -Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x -LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM -MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm -aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy -MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647 -+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6 -NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4 -A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc -A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9 -AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1 -AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw== ------END CERTIFICATE----- - -UTN DATACorp SGC Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ -BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa -MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w -HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy -dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys -raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo -wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA -9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv -33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud -DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 -BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD -LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 -DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 -I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx -EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP -DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- - -UTN USERFirst Hardware Root CA -============================== ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd -BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx -OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 -eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz -ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI -wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd -tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 -i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf -Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw -gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF -lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF -UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF -BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW -XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 -lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn -iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 -nfhmqA== ------END CERTIFICATE----- - -Camerfirma Chambers of Commerce Root -==================================== ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe -QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i -ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx -NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp -cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn -MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC -AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU -xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH -NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW -DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV -d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud -EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v -cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P -AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh -bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD -VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz -aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi -fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD -L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN -UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n -ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 -erfutGWaIZDgqtCYvDi1czyL+Nw= ------END CERTIFICATE----- - -Camerfirma Global Chambersign Root -================================== ------BEGIN CERTIFICATE----- -MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe -QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i -ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx -NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt -YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg -MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw -ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J -1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O -by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl -6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c -8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ -BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j -aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B -Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj -aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y -ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh -bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA -PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y -gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ -PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 -IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes -t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== ------END CERTIFICATE----- - -NetLock Notary (Class A) Root -============================= ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI -EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j -ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX -DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH -EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD -VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz -cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM -D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ -z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC -/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 -tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 -4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG -A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC -Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv -bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn -LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 -ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz -IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh -IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu -b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh -bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg -Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp -bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 -ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP -ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB -CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr -KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM -8CgHrTwXZoi1/baI ------END CERTIFICATE----- - -NetLock Business (Class B) Root -=============================== ------BEGIN CERTIFICATE----- -MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg -VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD -VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv -bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg -VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S -o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr -1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV -HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ -RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh -dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 -ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv -c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg -YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh -c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz -Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA -bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl -IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 -YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj -cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM -43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR -stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI ------END CERTIFICATE----- - -NetLock Express (Class C) Root -============================== ------BEGIN CERTIFICATE----- -MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ -BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j -ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB -jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z -W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 -euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw -DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN -RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn -YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB -IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i -aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 -ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs -ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo -dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y -emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k -IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ -UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg -YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 -xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW -gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== ------END CERTIFICATE----- - -XRamp Global CA Root -==================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE -BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj -dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx -HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg -U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu -IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx -foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE -zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs -AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry -xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap -oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC -AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc -/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n -nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz -8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -Go Daddy Class 2 CA -=================== ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY -VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG -A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g -RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD -ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv -2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 -qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j -YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY -vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O -BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o -atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu -MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG -A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim -PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt -I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI -Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b -vZ8= ------END CERTIFICATE----- - -Starfield Class 2 CA -==================== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc -U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo -MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG -A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG -SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY -bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ -JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm -epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN -F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF -MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f -hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo -bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g -QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs -afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM -PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD -KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 -QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -StartCom Certification Authority -================================ ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu -ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 -NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk -LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg -U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y -o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ -Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d -eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt -2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z -6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ -osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ -untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc -UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT -37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj -YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH -AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw -Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg -U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 -LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh -cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT -dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC -AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh -3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm -vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk -fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 -fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ -EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl -1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ -lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro -g14= ------END CERTIFICATE----- - -Taiwan GRCA -=========== ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG -EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X -DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv -dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN -w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 -BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O -1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO -htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov -J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 -Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t -B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB -O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 -lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV -HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 -09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj -Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 -Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU -D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz -DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk -Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk -7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ -CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy -+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS ------END CERTIFICATE----- - -Firmaprofesional Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT -GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp -Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA -ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL -MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT -OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2 -ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V -j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH -lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf -3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8 -NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww -KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG -AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD -ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq -u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf -wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm -7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG -VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA= ------END CERTIFICATE----- - -Wells Fargo Root CA -=================== ------BEGIN CERTIFICATE----- -MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl -bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv -MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX -x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3 -E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5 -OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j -sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj -YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF -BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD -ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv -m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R -OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx -x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023 -tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= ------END CERTIFICATE----- - -Swisscom Root CA 1 -================== ------BEGIN CERTIFICATE----- -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 -NY6E0F/6MBr1mmz0DlP5OlvRHA== ------END CERTIFICATE----- - -DigiCert Assured ID Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx -MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO -9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy -UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW -/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy -oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf -GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF -66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq -hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc -EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn -SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i -8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -DigiCert Global Root CA -======================= ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -DigiCert High Assurance EV Root CA -================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw -KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw -MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ -MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu -Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t -Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS -OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 -MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ -NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe -h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY -JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ -V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp -myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK -mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K ------END CERTIFICATE----- - -Certplus Class 2 Primary CA -=========================== ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE -BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN -OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy -dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR -5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ -Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO -YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e -e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME -CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ -YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t -L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD -P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R -TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ -7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW -//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - -DST Root CA X3 -============== ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK -ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X -DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 -cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT -rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 -UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy -xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d -utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ -MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug -dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE -GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw -RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS -fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - -DST ACES CA X6 -============== ------BEGIN CERTIFICATE----- -MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT -MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha -MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE -CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI -DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa -pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow -GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy -MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu -Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy -dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU -CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 -5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t -Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq -nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs -vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 -oKfN5XozNmr6mis= ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 1 -============================================== ------BEGIN CERTIFICATE----- -MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP -MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 -acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx -MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB -TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC -aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX -yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i -Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ -8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 -W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME -BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 -sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE -q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy -B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY -nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 2 -============================================== ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP -MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg -QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN -MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr -dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G -A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls -acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe -LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI -x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g -QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr -5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB -AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt -Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 -Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ -hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P -9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 -UrbnBEI= ------END CERTIFICATE----- - -SwissSign Gold CA - G2 -====================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -SwissSign Silver CA - G2 -======================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority -======================================== ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx -CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ -cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN -b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 -nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge -RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt -tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI -hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K -Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN -NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa -Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG -1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -thawte Primary Root CA -====================== ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 -MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg -SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv -KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT -FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs -oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ -1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc -q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K -aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p -afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF -AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE -uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 -jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH -z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G5 -============================================================ ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln -biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh -dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz -j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD -Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r -fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ -BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv -Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG -SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ -X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE -KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC -Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE -ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - -SecureTrust CA -============== ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy -dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe -BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX -OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t -DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH -GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b -01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH -ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj -aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu -SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf -mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ -nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -Secure Global CA -================ ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH -bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg -MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg -Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx -YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ -bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g -8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV -HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi -0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn -oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA -MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ -OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn -CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 -3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -COMODO Certification Authority -============================== ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE -BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG -A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb -MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD -T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH -+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww -xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV -4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA -1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI -rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k -b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC -AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP -OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc -IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN -+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== ------END CERTIFICATE----- - -Network Solutions Certificate Authority -======================================= ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG -EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr -IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx -MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx -jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT -aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT -crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc -/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB -AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv -bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA -A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q -4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ -GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD -ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - -WellsSecure Public Root Certificate Authority -============================================= ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM -F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw -NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl -bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD -VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 -iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 -i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 -bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB -K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB -AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu -cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm -lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB -i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww -GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI -K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 -bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj -qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es -E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ -tylv2G0xffX8oRAHh84vWdw+WNs= ------END CERTIFICATE----- - -COMODO ECC Certification Authority -================================== ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC -R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE -ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix -GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X -4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni -wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG -FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA -U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -IGC/A -===== ------BEGIN CERTIFICATE----- -MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD -VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE -Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy -MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI -EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT -STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 -TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW -So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy -HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd -frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ -tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB -egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC -iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK -q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q -MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg -Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI -lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF -0mBWWg== ------END CERTIFICATE----- - -Security Communication EV RootCA1 -================================= ------BEGIN CERTIFICATE----- -MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE -BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl -Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO -/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX -WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z -ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 -bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK -9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm -iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG -Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW -mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW -T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 ------END CERTIFICATE----- - -OISTE WISeKey Global Root GA CA -=============================== ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE -BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG -A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH -bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD -VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw -IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 -IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 -Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg -Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD -d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ -/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R -LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm -MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 -+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY -okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= ------END CERTIFICATE----- - -Microsec e-Szigno Root CA -========================= ------BEGIN CERTIFICATE----- -MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE -BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL -EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 -MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz -dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT -GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG -d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N -oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc -QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ -PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb -MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG -IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD -VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 -LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A -dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn -AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA -4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg -AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA -egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 -Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO -PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv -c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h -cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw -IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT -WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV -MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER -MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp -Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal -HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT -nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE -aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a -86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK -yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB -S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= ------END CERTIFICATE----- - -Certigna -======== ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw -EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 -MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI -Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q -XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH -GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p -ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg -DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf -Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ -tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ -BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J -SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA -hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ -ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu -PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY -1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. -====================================== ------BEGIN CERTIFICATE----- -MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT -AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg -LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w -HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ -U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh -IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN -yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU -2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 -4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP -2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm -8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf -HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa -Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK -5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b -czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g -ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF -BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug -cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf -AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX -EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v -/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 -MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 -3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk -eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f -/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h -RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU -Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== ------END CERTIFICATE----- - -TC TrustCenter Class 2 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw -MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw -IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 -xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ -Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u -SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G -dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ -KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj -TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP -JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk -vQ== ------END CERTIFICATE----- - -TC TrustCenter Class 3 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw -MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W -yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo -6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ -uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk -2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE -O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 -yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 -IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal -092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc -5A== ------END CERTIFICATE----- - -TC TrustCenter Universal CA I -============================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN -MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg -VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw -JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC -qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv -xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw -ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O -gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j -BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG -1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy -vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 -ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a -7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- - -Deutsche Telekom Root CA 2 -========================== ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT -RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG -A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 -MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G -A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS -b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 -bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI -KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY -AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK -Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV -jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV -HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr -E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy -zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 -rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G -dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - -ComSign Secured CA -================== ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE -AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w -NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD -QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs -49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH -7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB -kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 -9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw -AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t -U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA -j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC -AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a -BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp -FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP -51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- - -Cybertrust Global Root -====================== ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li -ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 -MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD -ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW -0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL -AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin -89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT -8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 -MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G -A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO -lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi -5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 -hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T -X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - -ePKI Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx -MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq -MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs -IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi -lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv -qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX -12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O -WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ -ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao -lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ -vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi -Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi -MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 -1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq -KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV -xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP -NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r -GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE -xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx -gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy -sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD -BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 -============================================================================================================================= ------BEGIN CERTIFICATE----- -MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH -DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q -aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry -b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV -BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg -S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 -MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl -IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF -n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl -IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft -dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl -cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO -Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 -xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR -6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL -hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd -BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 -N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT -y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh -LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M -dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= ------END CERTIFICATE----- - -Buypass Class 2 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 -MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M -cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 -0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 -0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R -uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV -1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt -7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 -fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w -wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho ------END CERTIFICATE----- - -Buypass Class 3 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 -MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx -ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 -n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia -AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c -1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 -pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA -EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 -htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj -el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------END CERTIFICATE----- - -EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 -========================================================================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -certSIGN ROOT CA -================ ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD -VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa -Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE -CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I -JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH -rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 -ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD -0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 -AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B -Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB -AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 -SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 -x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt -vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz -TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -CNNIC ROOT -========== ------BEGIN CERTIFICATE----- -MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE -ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw -OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD -o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz -VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT -VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or -czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK -y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC -wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S -lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 -Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM -O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 -BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 -G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m -mxE= ------END CERTIFICATE----- - -ApplicationCA - Japanese Government -=================================== ------BEGIN CERTIFICATE----- -MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT -SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw -MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl -cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 -fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN -wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE -jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu -nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU -WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV -BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD -vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs -o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g -/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD -io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW -dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL -rosot4LKGAfmt1t06SAZf7IbiVQ= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G3 -============================================= ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 -IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz -NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo -YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT -LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j -K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE -c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C -IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu -dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr -2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 -cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE -Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s -t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -thawte Primary Root CA - G2 -=========================== ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC -VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu -IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg -Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV -MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG -b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt -IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS -LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 -8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU -mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN -G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K -rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -thawte Primary Root CA - G3 -=========================== ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w -ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD -VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG -A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At -P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC -+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY -7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW -vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ -KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK -A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC -8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm -er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G2 -============================================= ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu -Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 -OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl -b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG -BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc -KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ -EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m -ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 -npaqBA+K ------END CERTIFICATE----- - -VeriSign Universal Root Certification Authority -=============================================== ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj -1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP -MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 -9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I -AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR -tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G -CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O -a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 -Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx -Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx -P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P -wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 -mJO37M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G4 -============================================================ ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC -VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 -b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz -ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU -cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo -b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 -Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz -rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw -HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u -Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD -A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx -AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - -NetLock Arany (Class Gold) Főtanúsítvány -============================================ ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G -A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 -dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB -cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx -MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO -ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 -c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu -0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw -/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk -H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw -fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 -neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW -qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta -YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna -NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu -dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -Staat der Nederlanden Root CA - G2 -================================== ------BEGIN CERTIFICATE----- -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 -66+KAQ== ------END CERTIFICATE----- - -CA Disig -======== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK -QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw -MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz -bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm -GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD -Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo -hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt -ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w -gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P -AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz -aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff -ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa -BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t -WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 -mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K -ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA -4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- - -Juur-SK -======= ------BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA -c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw -DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG -SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy -aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf -TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC -+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw -UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa -Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF -MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD -HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh -AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA -cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr -AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw -cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE -FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G -A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo -ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL -abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 -IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh -Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 -yyqcjg== ------END CERTIFICATE----- - -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - -SecureSign RootCA11 -=================== ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi -SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS -b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw -KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 -cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL -TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO -wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq -g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP -O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA -bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX -t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh -OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r -bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ -Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 -y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 -lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - -ACEDICOM Root -============= ------BEGIN CERTIFICATE----- -MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD -T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 -MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG -A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk -WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD -YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew -MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb -m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk -HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT -xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 -3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 -2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq -TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz -4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU -9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv -bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg -aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP -eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk -zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 -ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI -KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq -nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE -I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp -MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o -tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky -CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX -bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ -D/xwzoiQ ------END CERTIFICATE----- - -Microsec e-Szigno Root CA 2009 -============================== ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER -MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv -c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE -BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt -U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA -fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG -0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA -pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm -1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC -AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf -QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE -FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o -lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX -I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 -yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi -LXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi -=================================================== ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz -ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 -MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 -cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u -aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY -8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y -jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI -JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk -9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG -SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d -F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq -D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 -Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- - -GlobalSign Root CA - R3 -======================= ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt -iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ -0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 -rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl -OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 -xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 -lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 -EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E -bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 -YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r -kpeDMdmztcpHWD9f ------END CERTIFICATE----- - -TC TrustCenter Universal CA III -=============================== ------BEGIN CERTIFICATE----- -MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe -Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU -QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex -KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt -QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO -juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut -CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1 -M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G -A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA -g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+ -KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK -BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV -CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq -woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== ------END CERTIFICATE----- - -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - -Izenpe.com -========== ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG -EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz -MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu -QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ -03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK -ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU -+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC -PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT -OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK -F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK -0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ -0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB -leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID -AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ -SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG -NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O -BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l -Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga -kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q -hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs -g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 -aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 -nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC -ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo -Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z -WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- - -Chambers of Commerce Root - 2008 -================================ ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy -Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl -ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF -EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl -cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA -XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj -h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ -ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk -NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g -D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 -lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ -0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 -EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI -G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ -BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh -bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh -bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC -CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH -AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 -wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH -3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU -RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 -M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 -YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF -9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK -zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG -nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ ------END CERTIFICATE----- - -Global Chambersign Root - 2008 -============================== ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx -NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg -Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ -QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf -VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf -XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 -ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB -/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA -TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M -H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe -Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF -HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB -AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT -BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE -BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm -aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm -aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp -1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 -dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG -/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 -ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s -dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg -9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH -foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du -qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr -P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq -c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- - -Go Daddy Root Certificate Authority - G2 -======================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu -MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G -A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq -9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD -+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd -fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl -NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 -BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac -vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r -5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV -N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 ------END CERTIFICATE----- - -Starfield Root Certificate Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw -DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg -VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB -dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv -W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs -bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk -N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf -ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU -JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol -TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx -4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw -F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ -c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -Starfield Services Root Certificate Authority - G2 -================================================== ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl -IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT -dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 -h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa -hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP -LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB -rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG -SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP -E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy -xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza -YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 ------END CERTIFICATE----- - -AffirmTrust Commercial -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw -MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb -DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV -C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 -BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww -MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV -HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG -hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi -qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv -0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh -sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -AffirmTrust Networking -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw -MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE -Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI -dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 -/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb -h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV -HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu -UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 -12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 -WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 -/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -AffirmTrust Premium -=================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy -OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy -dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn -BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV -5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs -+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd -GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R -p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI -S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 -6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 -/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo -+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv -MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC -6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S -L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK -+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV -BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg -IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 -g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb -zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== ------END CERTIFICATE----- - -AffirmTrust Premium ECC -======================= ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV -BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx -MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U -cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ -N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW -BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK -BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X -57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM -eQ== ------END CERTIFICATE----- - -Certum Trusted Network CA -========================= ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK -ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy -MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU -ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC -l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J -J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 -fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 -cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB -Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw -DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj -jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 -mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj -Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -Certinomis - Autorité Racine -============================= ------BEGIN CERTIFICATE----- -MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK -Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg -LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG -A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw -JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa -wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly -Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw -2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N -jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q -c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC -lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb -xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g -530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna -4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ -KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x -WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva -R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 -nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B -CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv -JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE -qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b -WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE -wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ -vgt2Fl43N+bYdJeimUV5 ------END CERTIFICATE----- - -Root CA Generalitat Valenciana -============================== ------BEGIN CERTIFICATE----- -MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE -ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 -IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 -WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE -CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 -F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B -ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ -D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte -JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB -AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n -dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB -ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl -AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA -YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy -AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA -aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt -AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA -YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu -AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA -OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 -dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV -BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G -A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S -b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh -TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz -Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 -NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH -iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt -+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= ------END CERTIFICATE----- - -A-Trust-nQual-03 -================ ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE -Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy -a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R -dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw -RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 -ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 -c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA -zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n -yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE -SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 -iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V -cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV -eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 -ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr -sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd -JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS -mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 -ahq97BvIxYSazQ== ------END CERTIFICATE----- - -TWCA Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ -VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG -EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB -IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx -QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC -oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP -4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r -y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG -9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC -mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW -QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY -T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny -Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -Security Communication RootCA2 -============================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC -SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy -aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ -+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R -3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV -spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K -EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 -QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj -u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk -3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q -tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 -mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -EC-ACC -====== ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE -BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w -ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD -VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE -CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT -BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 -MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt -SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl -Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh -cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK -w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT -ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 -HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a -E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw -0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD -VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 -Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l -dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ -lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa -Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe -l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 -E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D -5EI= ------END CERTIFICATE----- diff --git a/conf/rayo/dialplan/public.xml b/conf/rayo/dialplan/public.xml deleted file mode 100644 index 76c4ea280b..0000000000 --- a/conf/rayo/dialplan/public.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/directory/default.xml b/conf/rayo/directory/default.xml deleted file mode 100644 index 11c2e633de..0000000000 --- a/conf/rayo/directory/default.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/directory/default/usera.xml b/conf/rayo/directory/default/usera.xml deleted file mode 100644 index 1e9c412be2..0000000000 --- a/conf/rayo/directory/default/usera.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/directory/default/userb.xml b/conf/rayo/directory/default/userb.xml deleted file mode 100644 index 9775d8371c..0000000000 --- a/conf/rayo/directory/default/userb.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/directory/default/userc.xml b/conf/rayo/directory/default/userc.xml deleted file mode 100644 index d870a051f8..0000000000 --- a/conf/rayo/directory/default/userc.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/directory/default/userd.xml b/conf/rayo/directory/default/userd.xml deleted file mode 100644 index e0a63ec76a..0000000000 --- a/conf/rayo/directory/default/userd.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/freeswitch.xml b/conf/rayo/freeswitch.xml deleted file mode 100644 index f38983ebcb..0000000000 --- a/conf/rayo/freeswitch.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - -
- -
- -
- -
- - - -
- -
- - -
- - - - - - - - - - -
- -
diff --git a/conf/rayo/lang/de/de.xml b/conf/rayo/lang/de/de.xml deleted file mode 100644 index a7dbab0c0c..0000000000 --- a/conf/rayo/lang/de/de.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - diff --git a/conf/rayo/lang/de/demo/demo.xml b/conf/rayo/lang/de/demo/demo.xml deleted file mode 100644 index fa77948b65..0000000000 --- a/conf/rayo/lang/de/demo/demo.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/de/vm/sounds.xml b/conf/rayo/lang/de/vm/sounds.xml deleted file mode 100644 index 657e611c20..0000000000 --- a/conf/rayo/lang/de/vm/sounds.xml +++ /dev/null @@ -1,413 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/de/vm/tts.xml b/conf/rayo/lang/de/vm/tts.xml deleted file mode 100644 index f91cae1b99..0000000000 --- a/conf/rayo/lang/de/vm/tts.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/demo/demo-ivr.xml b/conf/rayo/lang/en/demo/demo-ivr.xml deleted file mode 100644 index 98f155a265..0000000000 --- a/conf/rayo/lang/en/demo/demo-ivr.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/demo/demo.xml b/conf/rayo/lang/en/demo/demo.xml deleted file mode 100644 index bcfe6a8227..0000000000 --- a/conf/rayo/lang/en/demo/demo.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/demo/funnies.xml b/conf/rayo/lang/en/demo/funnies.xml deleted file mode 100644 index e901c5ad9c..0000000000 --- a/conf/rayo/lang/en/demo/funnies.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/conf/rayo/lang/en/demo/new-demo-ivr.xml b/conf/rayo/lang/en/demo/new-demo-ivr.xml deleted file mode 100644 index 619d9921e9..0000000000 --- a/conf/rayo/lang/en/demo/new-demo-ivr.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/dir/sounds.xml b/conf/rayo/lang/en/dir/sounds.xml deleted file mode 100644 index b715a7f825..0000000000 --- a/conf/rayo/lang/en/dir/sounds.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/dir/tts.xml b/conf/rayo/lang/en/dir/tts.xml deleted file mode 100644 index d5f112dcda..0000000000 --- a/conf/rayo/lang/en/dir/tts.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/en.xml b/conf/rayo/lang/en/en.xml deleted file mode 100644 index 24bee311c9..0000000000 --- a/conf/rayo/lang/en/en.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/ivr/sounds.xml b/conf/rayo/lang/en/ivr/sounds.xml deleted file mode 100644 index 0c4f0b9c70..0000000000 --- a/conf/rayo/lang/en/ivr/sounds.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/vm/sounds.xml b/conf/rayo/lang/en/vm/sounds.xml deleted file mode 100644 index fdef472a5b..0000000000 --- a/conf/rayo/lang/en/vm/sounds.xml +++ /dev/null @@ -1,441 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/vm/tts.xml b/conf/rayo/lang/en/vm/tts.xml deleted file mode 100644 index 2de4b3781e..0000000000 --- a/conf/rayo/lang/en/vm/tts.xml +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/en/vm/voicemail_ivr.xml b/conf/rayo/lang/en/vm/voicemail_ivr.xml deleted file mode 100644 index 1c48299430..0000000000 --- a/conf/rayo/lang/en/vm/voicemail_ivr.xml +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/demo/demo-es-ES.xml b/conf/rayo/lang/es/demo/demo-es-ES.xml deleted file mode 100644 index 4c6919dd0e..0000000000 --- a/conf/rayo/lang/es/demo/demo-es-ES.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/demo/demo-es-MX.xml b/conf/rayo/lang/es/demo/demo-es-MX.xml deleted file mode 100644 index 4c6919dd0e..0000000000 --- a/conf/rayo/lang/es/demo/demo-es-MX.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/demo/demo-ivr-es-ES.xml b/conf/rayo/lang/es/demo/demo-ivr-es-ES.xml deleted file mode 100644 index ec7d7bccd2..0000000000 --- a/conf/rayo/lang/es/demo/demo-ivr-es-ES.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/demo/demo-ivr-es-MX.xml b/conf/rayo/lang/es/demo/demo-ivr-es-MX.xml deleted file mode 100644 index ec7d7bccd2..0000000000 --- a/conf/rayo/lang/es/demo/demo-ivr-es-MX.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/dir/sounds-es-ES.xml b/conf/rayo/lang/es/dir/sounds-es-ES.xml deleted file mode 100644 index 2bdc1492ec..0000000000 --- a/conf/rayo/lang/es/dir/sounds-es-ES.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/dir/sounds-es-MX.xml b/conf/rayo/lang/es/dir/sounds-es-MX.xml deleted file mode 100644 index 2bdc1492ec..0000000000 --- a/conf/rayo/lang/es/dir/sounds-es-MX.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/dir/tts-es-ES.xml b/conf/rayo/lang/es/dir/tts-es-ES.xml deleted file mode 100644 index fbdeca703c..0000000000 --- a/conf/rayo/lang/es/dir/tts-es-ES.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/dir/tts-es-MX.xml b/conf/rayo/lang/es/dir/tts-es-MX.xml deleted file mode 100644 index ddf15d0a50..0000000000 --- a/conf/rayo/lang/es/dir/tts-es-MX.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/es_ES.xml b/conf/rayo/lang/es/es_ES.xml deleted file mode 100644 index f8de6858ea..0000000000 --- a/conf/rayo/lang/es/es_ES.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/conf/rayo/lang/es/es_MX.xml b/conf/rayo/lang/es/es_MX.xml deleted file mode 100644 index 936abcf16f..0000000000 --- a/conf/rayo/lang/es/es_MX.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/conf/rayo/lang/es/vm/sounds-es-ES.xml b/conf/rayo/lang/es/vm/sounds-es-ES.xml deleted file mode 100644 index dcc9d9f76f..0000000000 --- a/conf/rayo/lang/es/vm/sounds-es-ES.xml +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/vm/sounds-es-MX.xml b/conf/rayo/lang/es/vm/sounds-es-MX.xml deleted file mode 100644 index 1f22c43bdc..0000000000 --- a/conf/rayo/lang/es/vm/sounds-es-MX.xml +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/vm/tts-es-ES.xml b/conf/rayo/lang/es/vm/tts-es-ES.xml deleted file mode 100644 index 6dab48ca60..0000000000 --- a/conf/rayo/lang/es/vm/tts-es-ES.xml +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/es/vm/tts-es-MX.xml b/conf/rayo/lang/es/vm/tts-es-MX.xml deleted file mode 100644 index ce5722e934..0000000000 --- a/conf/rayo/lang/es/vm/tts-es-MX.xml +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/fr/demo/demo.xml b/conf/rayo/lang/fr/demo/demo.xml deleted file mode 100644 index 0d0de592ac..0000000000 --- a/conf/rayo/lang/fr/demo/demo.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/fr/dir/sounds.xml b/conf/rayo/lang/fr/dir/sounds.xml deleted file mode 100644 index a0dcb2c0e9..0000000000 --- a/conf/rayo/lang/fr/dir/sounds.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/fr/dir/tts.xml b/conf/rayo/lang/fr/dir/tts.xml deleted file mode 100644 index 7d3e5e3090..0000000000 --- a/conf/rayo/lang/fr/dir/tts.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/fr/fr.xml b/conf/rayo/lang/fr/fr.xml deleted file mode 100644 index 124ca02415..0000000000 --- a/conf/rayo/lang/fr/fr.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - diff --git a/conf/rayo/lang/fr/vm/sounds.xml b/conf/rayo/lang/fr/vm/sounds.xml deleted file mode 100644 index 9cd209eab1..0000000000 --- a/conf/rayo/lang/fr/vm/sounds.xml +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/he/demo/demo-ivr.xml b/conf/rayo/lang/he/demo/demo-ivr.xml deleted file mode 100644 index df8d24b751..0000000000 --- a/conf/rayo/lang/he/demo/demo-ivr.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/he/demo/demo.xml b/conf/rayo/lang/he/demo/demo.xml deleted file mode 100644 index bcfe6a8227..0000000000 --- a/conf/rayo/lang/he/demo/demo.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/he/dir/sounds.xml b/conf/rayo/lang/he/dir/sounds.xml deleted file mode 100644 index 5fd13fffc5..0000000000 --- a/conf/rayo/lang/he/dir/sounds.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/he/he.xml b/conf/rayo/lang/he/he.xml deleted file mode 100644 index 7cca73c1e8..0000000000 --- a/conf/rayo/lang/he/he.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - diff --git a/conf/rayo/lang/he/vm/sounds.xml b/conf/rayo/lang/he/vm/sounds.xml deleted file mode 100644 index 917c84b038..0000000000 --- a/conf/rayo/lang/he/vm/sounds.xml +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/demo/demo-ivr-pt-BR.xml b/conf/rayo/lang/pt/demo/demo-ivr-pt-BR.xml deleted file mode 100644 index ec7d7bccd2..0000000000 --- a/conf/rayo/lang/pt/demo/demo-ivr-pt-BR.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/demo/demo-ivr-pt-PT.xml b/conf/rayo/lang/pt/demo/demo-ivr-pt-PT.xml deleted file mode 100644 index ec7d7bccd2..0000000000 --- a/conf/rayo/lang/pt/demo/demo-ivr-pt-PT.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/demo/demo-pt-BR.xml b/conf/rayo/lang/pt/demo/demo-pt-BR.xml deleted file mode 100644 index 846561a541..0000000000 --- a/conf/rayo/lang/pt/demo/demo-pt-BR.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/demo/demo-pt-PT.xml b/conf/rayo/lang/pt/demo/demo-pt-PT.xml deleted file mode 100644 index 34464f7a6d..0000000000 --- a/conf/rayo/lang/pt/demo/demo-pt-PT.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/dir/sounds-pt-BR.xml b/conf/rayo/lang/pt/dir/sounds-pt-BR.xml deleted file mode 100644 index 2bdc1492ec..0000000000 --- a/conf/rayo/lang/pt/dir/sounds-pt-BR.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/dir/sounds-pt-PT.xml b/conf/rayo/lang/pt/dir/sounds-pt-PT.xml deleted file mode 100644 index 2bdc1492ec..0000000000 --- a/conf/rayo/lang/pt/dir/sounds-pt-PT.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/dir/tts-pt-BR.xml b/conf/rayo/lang/pt/dir/tts-pt-BR.xml deleted file mode 100644 index 71b79c60a8..0000000000 --- a/conf/rayo/lang/pt/dir/tts-pt-BR.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/dir/tts-pt-PT.xml b/conf/rayo/lang/pt/dir/tts-pt-PT.xml deleted file mode 100644 index 4f03c5abdb..0000000000 --- a/conf/rayo/lang/pt/dir/tts-pt-PT.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/pt_BR.xml b/conf/rayo/lang/pt/pt_BR.xml deleted file mode 100644 index 690ee6974c..0000000000 --- a/conf/rayo/lang/pt/pt_BR.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/conf/rayo/lang/pt/pt_PT.xml b/conf/rayo/lang/pt/pt_PT.xml deleted file mode 100644 index c30b3612f1..0000000000 --- a/conf/rayo/lang/pt/pt_PT.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/conf/rayo/lang/pt/vm/sounds-pt-BR.xml b/conf/rayo/lang/pt/vm/sounds-pt-BR.xml deleted file mode 100644 index 1ab472a71e..0000000000 --- a/conf/rayo/lang/pt/vm/sounds-pt-BR.xml +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/vm/sounds-pt-PT.xml b/conf/rayo/lang/pt/vm/sounds-pt-PT.xml deleted file mode 100644 index 587d3fe5bd..0000000000 --- a/conf/rayo/lang/pt/vm/sounds-pt-PT.xml +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/vm/tts-pt-BR.xml b/conf/rayo/lang/pt/vm/tts-pt-BR.xml deleted file mode 100644 index 4f770457e5..0000000000 --- a/conf/rayo/lang/pt/vm/tts-pt-BR.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/pt/vm/tts-pt-PT.xml b/conf/rayo/lang/pt/vm/tts-pt-PT.xml deleted file mode 100644 index c3dfc3a066..0000000000 --- a/conf/rayo/lang/pt/vm/tts-pt-PT.xml +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/demo/demo-ivr.xml b/conf/rayo/lang/ru/demo/demo-ivr.xml deleted file mode 100644 index 7de0d7fd0d..0000000000 --- a/conf/rayo/lang/ru/demo/demo-ivr.xml +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/demo/demo.xml b/conf/rayo/lang/ru/demo/demo.xml deleted file mode 100644 index 10c9dbc552..0000000000 --- a/conf/rayo/lang/ru/demo/demo.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/dir/sounds.xml b/conf/rayo/lang/ru/dir/sounds.xml deleted file mode 100644 index a0dcb2c0e9..0000000000 --- a/conf/rayo/lang/ru/dir/sounds.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/dir/tts.xml b/conf/rayo/lang/ru/dir/tts.xml deleted file mode 100644 index f0aafa267d..0000000000 --- a/conf/rayo/lang/ru/dir/tts.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/ru.xml b/conf/rayo/lang/ru/ru.xml deleted file mode 100644 index 5f52e768a4..0000000000 --- a/conf/rayo/lang/ru/ru.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/vm/sounds.xml b/conf/rayo/lang/ru/vm/sounds.xml deleted file mode 100644 index 2ee9e6ec58..0000000000 --- a/conf/rayo/lang/ru/vm/sounds.xml +++ /dev/null @@ -1,374 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/ru/vm/tts.xml b/conf/rayo/lang/ru/vm/tts.xml deleted file mode 100644 index 2de4b3781e..0000000000 --- a/conf/rayo/lang/ru/vm/tts.xml +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/lang/sv/sv.xml b/conf/rayo/lang/sv/sv.xml deleted file mode 100644 index f77e0221f6..0000000000 --- a/conf/rayo/lang/sv/sv.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/conf/rayo/lang/sv/vm/sounds.xml b/conf/rayo/lang/sv/vm/sounds.xml deleted file mode 100644 index aaee3c0b6b..0000000000 --- a/conf/rayo/lang/sv/vm/sounds.xml +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/mime.types b/conf/rayo/mime.types deleted file mode 100644 index b680b3327d..0000000000 --- a/conf/rayo/mime.types +++ /dev/null @@ -1,1609 +0,0 @@ -# -# MIME type configs overriden by the FreeSWITCH project. -# -audio/mpeg mp3 mpga mp2 mp2a m2a m3a -image/jpeg jpg jpeg jpe -# -# Additional MIME types added by the FreeSWITCH project. Any duplicate file extensions listed here will only be -# used to map from MIME -> extension and not extension -> MIME -audio/x-mpeg mp3 -audio/mp3 mp3 -audio/x-mp3 mp3 -audio/mpeg3 mp3 -audio/x-mpeg3 mp3 -audio/mpg mp3 -audio/x-mpegaudio mp3 -audio/x-wave wav -audio/wave wav -# -# The section below was taken from Apache httpd Project at -# -# -# This file maps Internet media types to unique file extension(s). -# Although created for httpd, this file is used by many software systems -# and has been placed in the public domain for unlimited redisribution. -# -# The table below contains both registered and (common) unregistered types. -# A type that has no unique extension can be ignored -- they are listed -# here to guide configurations toward known types and to make it easier to -# identify "new" types. File extensions are also commonly used to indicate -# content languages and encodings, so choose them carefully. -# -# Internet media types should be registered as described in RFC 4288. -# The registry is at . -# -# MIME type (lowercased) Extensions -# ============================================ ========== -# application/1d-interleaved-parityfec -# application/3gpp-ims+xml -# application/activemessage -application/andrew-inset ez -# application/applefile -application/applixware aw -application/atom+xml atom -application/atomcat+xml atomcat -# application/atomicmail -application/atomsvc+xml atomsvc -# application/auth-policy+xml -# application/batch-smtp -# application/beep+xml -# application/calendar+xml -# application/cals-1840 -# application/ccmp+xml -application/ccxml+xml ccxml -application/cdmi-capability cdmia -application/cdmi-container cdmic -application/cdmi-domain cdmid -application/cdmi-object cdmio -application/cdmi-queue cdmiq -# application/cea-2018+xml -# application/cellml+xml -# application/cfw -# application/cnrp+xml -# application/commonground -# application/conference-info+xml -# application/cpl+xml -# application/csta+xml -# application/cstadata+xml -application/cu-seeme cu -# application/cybercash -application/davmount+xml davmount -# application/dca-rft -# application/dec-dx -# application/dialog-info+xml -# application/dicom -# application/dns -application/docbook+xml dbk -# application/dskpp+xml -application/dssc+der dssc -application/dssc+xml xdssc -# application/dvcs -application/ecmascript ecma -# application/edi-consent -# application/edi-x12 -# application/edifact -application/emma+xml emma -# application/epp+xml -application/epub+zip epub -# application/eshop -# application/example -application/exi exi -# application/fastinfoset -# application/fastsoap -# application/fits -application/font-tdpfr pfr -# application/framework-attributes+xml -application/gml+xml gml -application/gpx+xml gpx -application/gxf gxf -# application/h224 -# application/held+xml -# application/http -application/hyperstudio stk -# application/ibe-key-request+xml -# application/ibe-pkg-reply+xml -# application/ibe-pp-data -# application/iges -# application/im-iscomposing+xml -# application/index -# application/index.cmd -# application/index.obj -# application/index.response -# application/index.vnd -application/inkml+xml ink inkml -# application/iotp -application/ipfix ipfix -# application/ipp -# application/isup -application/java-archive jar -application/java-serialized-object ser -application/java-vm class -application/javascript js -application/json json -application/jsonml+json jsonml -# application/kpml-request+xml -# application/kpml-response+xml -application/lost+xml lostxml -application/mac-binhex40 hqx -application/mac-compactpro cpt -# application/macwriteii -application/mads+xml mads -application/marc mrc -application/marcxml+xml mrcx -application/mathematica ma nb mb -# application/mathml-content+xml -# application/mathml-presentation+xml -application/mathml+xml mathml -# application/mbms-associated-procedure-description+xml -# application/mbms-deregister+xml -# application/mbms-envelope+xml -# application/mbms-msk+xml -# application/mbms-msk-response+xml -# application/mbms-protection-description+xml -# application/mbms-reception-report+xml -# application/mbms-register+xml -# application/mbms-register-response+xml -# application/mbms-user-service-description+xml -application/mbox mbox -# application/media_control+xml -application/mediaservercontrol+xml mscml -application/metalink+xml metalink -application/metalink4+xml meta4 -application/mets+xml mets -# application/mikey -application/mods+xml mods -# application/moss-keys -# application/moss-signature -# application/mosskey-data -# application/mosskey-request -application/mp21 m21 mp21 -application/mp4 mp4s -# application/mpeg4-generic -# application/mpeg4-iod -# application/mpeg4-iod-xmt -# application/msc-ivr+xml -# application/msc-mixer+xml -application/msword doc dot -application/mxf mxf -# application/nasdata -# application/news-checkgroups -# application/news-groupinfo -# application/news-transmission -# application/nss -# application/ocsp-request -# application/ocsp-response -application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy -application/oda oda -application/oebps-package+xml opf -application/ogg ogx -application/omdoc+xml omdoc -application/onenote onetoc onetoc2 onetmp onepkg -application/oxps oxps -# application/parityfec -application/patch-ops-error+xml xer -application/pdf pdf -application/pgp-encrypted pgp -# application/pgp-keys -application/pgp-signature asc sig -application/pics-rules prf -# application/pidf+xml -# application/pidf-diff+xml -application/pkcs10 p10 -application/pkcs7-mime p7m p7c -application/pkcs7-signature p7s -application/pkcs8 p8 -application/pkix-attr-cert ac -application/pkix-cert cer -application/pkix-crl crl -application/pkix-pkipath pkipath -application/pkixcmp pki -application/pls+xml pls -# application/poc-settings+xml -application/postscript ai eps ps -# application/prs.alvestrand.titrax-sheet -application/prs.cww cww -# application/prs.nprend -# application/prs.plucker -# application/prs.rdf-xml-crypt -# application/prs.xsf+xml -application/pskc+xml pskcxml -# application/qsig -application/rdf+xml rdf -application/reginfo+xml rif -application/relax-ng-compact-syntax rnc -# application/remote-printing -application/resource-lists+xml rl -application/resource-lists-diff+xml rld -# application/riscos -# application/rlmi+xml -application/rls-services+xml rs -application/rpki-ghostbusters gbr -application/rpki-manifest mft -application/rpki-roa roa -# application/rpki-updown -application/rsd+xml rsd -application/rss+xml rss -application/rtf rtf -# application/rtx -# application/samlassertion+xml -# application/samlmetadata+xml -application/sbml+xml sbml -application/scvp-cv-request scq -application/scvp-cv-response scs -application/scvp-vp-request spq -application/scvp-vp-response spp -application/sdp sdp -# application/set-payment -application/set-payment-initiation setpay -# application/set-registration -application/set-registration-initiation setreg -# application/sgml -# application/sgml-open-catalog -application/shf+xml shf -# application/sieve -# application/simple-filter+xml -# application/simple-message-summary -# application/simplesymbolcontainer -# application/slate -# application/smil -application/smil+xml smi smil -# application/soap+fastinfoset -# application/soap+xml -application/sparql-query rq -application/sparql-results+xml srx -# application/spirits-event+xml -application/srgs gram -application/srgs+xml grxml -application/sru+xml sru -application/ssdl+xml ssdl -application/ssml+xml ssml -# application/tamp-apex-update -# application/tamp-apex-update-confirm -# application/tamp-community-update -# application/tamp-community-update-confirm -# application/tamp-error -# application/tamp-sequence-adjust -# application/tamp-sequence-adjust-confirm -# application/tamp-status-query -# application/tamp-status-response -# application/tamp-update -# application/tamp-update-confirm -application/tei+xml tei teicorpus -application/thraud+xml tfi -# application/timestamp-query -# application/timestamp-reply -application/timestamped-data tsd -# application/tve-trigger -# application/ulpfec -# application/vcard+xml -# application/vemmi -# application/vividence.scriptfile -# application/vnd.3gpp.bsf+xml -application/vnd.3gpp.pic-bw-large plb -application/vnd.3gpp.pic-bw-small psb -application/vnd.3gpp.pic-bw-var pvb -# application/vnd.3gpp.sms -# application/vnd.3gpp2.bcmcsinfo+xml -# application/vnd.3gpp2.sms -application/vnd.3gpp2.tcap tcap -application/vnd.3m.post-it-notes pwn -application/vnd.accpac.simply.aso aso -application/vnd.accpac.simply.imp imp -application/vnd.acucobol acu -application/vnd.acucorp atc acutc -application/vnd.adobe.air-application-installer-package+zip air -application/vnd.adobe.formscentral.fcdt fcdt -application/vnd.adobe.fxp fxp fxpl -# application/vnd.adobe.partial-upload -application/vnd.adobe.xdp+xml xdp -application/vnd.adobe.xfdf xfdf -# application/vnd.aether.imp -# application/vnd.ah-barcode -application/vnd.ahead.space ahead -application/vnd.airzip.filesecure.azf azf -application/vnd.airzip.filesecure.azs azs -application/vnd.amazon.ebook azw -application/vnd.americandynamics.acc acc -application/vnd.amiga.ami ami -# application/vnd.amundsen.maze+xml -application/vnd.android.package-archive apk -application/vnd.anser-web-certificate-issue-initiation cii -application/vnd.anser-web-funds-transfer-initiation fti -application/vnd.antix.game-component atx -application/vnd.apple.installer+xml mpkg -application/vnd.apple.mpegurl m3u8 -# application/vnd.arastra.swi -application/vnd.aristanetworks.swi swi -application/vnd.astraea-software.iota iota -application/vnd.audiograph aep -# application/vnd.autopackage -# application/vnd.avistar+xml -application/vnd.blueice.multipass mpm -# application/vnd.bluetooth.ep.oob -application/vnd.bmi bmi -application/vnd.businessobjects rep -# application/vnd.cab-jscript -# application/vnd.canon-cpdl -# application/vnd.canon-lips -# application/vnd.cendio.thinlinc.clientconf -application/vnd.chemdraw+xml cdxml -application/vnd.chipnuts.karaoke-mmd mmd -application/vnd.cinderella cdy -# application/vnd.cirpack.isdn-ext -application/vnd.claymore cla -application/vnd.cloanto.rp9 rp9 -application/vnd.clonk.c4group c4g c4d c4f c4p c4u -application/vnd.cluetrust.cartomobile-config c11amc -application/vnd.cluetrust.cartomobile-config-pkg c11amz -# application/vnd.collection+json -# application/vnd.commerce-battelle -application/vnd.commonspace csp -application/vnd.contact.cmsg cdbcmsg -application/vnd.cosmocaller cmc -application/vnd.crick.clicker clkx -application/vnd.crick.clicker.keyboard clkk -application/vnd.crick.clicker.palette clkp -application/vnd.crick.clicker.template clkt -application/vnd.crick.clicker.wordbank clkw -application/vnd.criticaltools.wbs+xml wbs -application/vnd.ctc-posml pml -# application/vnd.ctct.ws+xml -# application/vnd.cups-pdf -# application/vnd.cups-postscript -application/vnd.cups-ppd ppd -# application/vnd.cups-raster -# application/vnd.cups-raw -# application/vnd.curl -application/vnd.curl.car car -application/vnd.curl.pcurl pcurl -# application/vnd.cybank -application/vnd.dart dart -application/vnd.data-vision.rdz rdz -application/vnd.dece.data uvf uvvf uvd uvvd -application/vnd.dece.ttml+xml uvt uvvt -application/vnd.dece.unspecified uvx uvvx -application/vnd.dece.zip uvz uvvz -application/vnd.denovo.fcselayout-link fe_launch -# application/vnd.dir-bi.plate-dl-nosuffix -application/vnd.dna dna -application/vnd.dolby.mlp mlp -# application/vnd.dolby.mobile.1 -# application/vnd.dolby.mobile.2 -application/vnd.dpgraph dpg -application/vnd.dreamfactory dfac -application/vnd.ds-keypoint kpxx -application/vnd.dvb.ait ait -# application/vnd.dvb.dvbj -# application/vnd.dvb.esgcontainer -# application/vnd.dvb.ipdcdftnotifaccess -# application/vnd.dvb.ipdcesgaccess -# application/vnd.dvb.ipdcesgaccess2 -# application/vnd.dvb.ipdcesgpdd -# application/vnd.dvb.ipdcroaming -# application/vnd.dvb.iptv.alfec-base -# application/vnd.dvb.iptv.alfec-enhancement -# application/vnd.dvb.notif-aggregate-root+xml -# application/vnd.dvb.notif-container+xml -# application/vnd.dvb.notif-generic+xml -# application/vnd.dvb.notif-ia-msglist+xml -# application/vnd.dvb.notif-ia-registration-request+xml -# application/vnd.dvb.notif-ia-registration-response+xml -# application/vnd.dvb.notif-init+xml -# application/vnd.dvb.pfr -application/vnd.dvb.service svc -# application/vnd.dxr -application/vnd.dynageo geo -# application/vnd.easykaraoke.cdgdownload -# application/vnd.ecdis-update -application/vnd.ecowin.chart mag -# application/vnd.ecowin.filerequest -# application/vnd.ecowin.fileupdate -# application/vnd.ecowin.series -# application/vnd.ecowin.seriesrequest -# application/vnd.ecowin.seriesupdate -# application/vnd.emclient.accessrequest+xml -application/vnd.enliven nml -# application/vnd.eprints.data+xml -application/vnd.epson.esf esf -application/vnd.epson.msf msf -application/vnd.epson.quickanime qam -application/vnd.epson.salt slt -application/vnd.epson.ssf ssf -# application/vnd.ericsson.quickcall -application/vnd.eszigno3+xml es3 et3 -# application/vnd.etsi.aoc+xml -# application/vnd.etsi.cug+xml -# application/vnd.etsi.iptvcommand+xml -# application/vnd.etsi.iptvdiscovery+xml -# application/vnd.etsi.iptvprofile+xml -# application/vnd.etsi.iptvsad-bc+xml -# application/vnd.etsi.iptvsad-cod+xml -# application/vnd.etsi.iptvsad-npvr+xml -# application/vnd.etsi.iptvservice+xml -# application/vnd.etsi.iptvsync+xml -# application/vnd.etsi.iptvueprofile+xml -# application/vnd.etsi.mcid+xml -# application/vnd.etsi.overload-control-policy-dataset+xml -# application/vnd.etsi.sci+xml -# application/vnd.etsi.simservs+xml -# application/vnd.etsi.tsl+xml -# application/vnd.etsi.tsl.der -# application/vnd.eudora.data -application/vnd.ezpix-album ez2 -application/vnd.ezpix-package ez3 -# application/vnd.f-secure.mobile -application/vnd.fdf fdf -application/vnd.fdsn.mseed mseed -application/vnd.fdsn.seed seed dataless -# application/vnd.ffsns -# application/vnd.fints -application/vnd.flographit gph -application/vnd.fluxtime.clip ftc -# application/vnd.font-fontforge-sfd -application/vnd.framemaker fm frame maker book -application/vnd.frogans.fnc fnc -application/vnd.frogans.ltf ltf -application/vnd.fsc.weblaunch fsc -application/vnd.fujitsu.oasys oas -application/vnd.fujitsu.oasys2 oa2 -application/vnd.fujitsu.oasys3 oa3 -application/vnd.fujitsu.oasysgp fg5 -application/vnd.fujitsu.oasysprs bh2 -# application/vnd.fujixerox.art-ex -# application/vnd.fujixerox.art4 -# application/vnd.fujixerox.hbpl -application/vnd.fujixerox.ddd ddd -application/vnd.fujixerox.docuworks xdw -application/vnd.fujixerox.docuworks.binder xbd -# application/vnd.fut-misnet -application/vnd.fuzzysheet fzs -application/vnd.genomatix.tuxedo txd -# application/vnd.geocube+xml -application/vnd.geogebra.file ggb -application/vnd.geogebra.tool ggt -application/vnd.geometry-explorer gex gre -application/vnd.geonext gxt -application/vnd.geoplan g2w -application/vnd.geospace g3w -# application/vnd.globalplatform.card-content-mgt -# application/vnd.globalplatform.card-content-mgt-response -application/vnd.gmx gmx -application/vnd.google-earth.kml+xml kml -application/vnd.google-earth.kmz kmz -application/vnd.grafeq gqf gqs -# application/vnd.gridmp -application/vnd.groove-account gac -application/vnd.groove-help ghf -application/vnd.groove-identity-message gim -application/vnd.groove-injector grv -application/vnd.groove-tool-message gtm -application/vnd.groove-tool-template tpl -application/vnd.groove-vcard vcg -# application/vnd.hal+json -application/vnd.hal+xml hal -application/vnd.handheld-entertainment+xml zmm -application/vnd.hbci hbci -# application/vnd.hcl-bireports -application/vnd.hhe.lesson-player les -application/vnd.hp-hpgl hpgl -application/vnd.hp-hpid hpid -application/vnd.hp-hps hps -application/vnd.hp-jlyt jlt -application/vnd.hp-pcl pcl -application/vnd.hp-pclxl pclxl -# application/vnd.httphone -application/vnd.hydrostatix.sof-data sfd-hdstx -# application/vnd.hzn-3d-crossword -# application/vnd.ibm.afplinedata -# application/vnd.ibm.electronic-media -application/vnd.ibm.minipay mpy -application/vnd.ibm.modcap afp listafp list3820 -application/vnd.ibm.rights-management irm -application/vnd.ibm.secure-container sc -application/vnd.iccprofile icc icm -application/vnd.igloader igl -application/vnd.immervision-ivp ivp -application/vnd.immervision-ivu ivu -# application/vnd.informedcontrol.rms+xml -# application/vnd.informix-visionary -# application/vnd.infotech.project -# application/vnd.infotech.project+xml -# application/vnd.innopath.wamp.notification -application/vnd.insors.igm igm -application/vnd.intercon.formnet xpw xpx -application/vnd.intergeo i2g -# application/vnd.intertrust.digibox -# application/vnd.intertrust.nncp -application/vnd.intu.qbo qbo -application/vnd.intu.qfx qfx -# application/vnd.iptc.g2.conceptitem+xml -# application/vnd.iptc.g2.knowledgeitem+xml -# application/vnd.iptc.g2.newsitem+xml -# application/vnd.iptc.g2.newsmessage+xml -# application/vnd.iptc.g2.packageitem+xml -# application/vnd.iptc.g2.planningitem+xml -application/vnd.ipunplugged.rcprofile rcprofile -application/vnd.irepository.package+xml irp -application/vnd.is-xpr xpr -application/vnd.isac.fcs fcs -application/vnd.jam jam -# application/vnd.japannet-directory-service -# application/vnd.japannet-jpnstore-wakeup -# application/vnd.japannet-payment-wakeup -# application/vnd.japannet-registration -# application/vnd.japannet-registration-wakeup -# application/vnd.japannet-setstore-wakeup -# application/vnd.japannet-verification -# application/vnd.japannet-verification-wakeup -application/vnd.jcp.javame.midlet-rms rms -application/vnd.jisp jisp -application/vnd.joost.joda-archive joda -application/vnd.kahootz ktz ktr -application/vnd.kde.karbon karbon -application/vnd.kde.kchart chrt -application/vnd.kde.kformula kfo -application/vnd.kde.kivio flw -application/vnd.kde.kontour kon -application/vnd.kde.kpresenter kpr kpt -application/vnd.kde.kspread ksp -application/vnd.kde.kword kwd kwt -application/vnd.kenameaapp htke -application/vnd.kidspiration kia -application/vnd.kinar kne knp -application/vnd.koan skp skd skt skm -application/vnd.kodak-descriptor sse -application/vnd.las.las+xml lasxml -# application/vnd.liberty-request+xml -application/vnd.llamagraphics.life-balance.desktop lbd -application/vnd.llamagraphics.life-balance.exchange+xml lbe -application/vnd.lotus-1-2-3 123 -application/vnd.lotus-approach apr -application/vnd.lotus-freelance pre -application/vnd.lotus-notes nsf -application/vnd.lotus-organizer org -application/vnd.lotus-screencam scm -application/vnd.lotus-wordpro lwp -application/vnd.macports.portpkg portpkg -# application/vnd.marlin.drm.actiontoken+xml -# application/vnd.marlin.drm.conftoken+xml -# application/vnd.marlin.drm.license+xml -# application/vnd.marlin.drm.mdcf -application/vnd.mcd mcd -application/vnd.medcalcdata mc1 -application/vnd.mediastation.cdkey cdkey -# application/vnd.meridian-slingshot -application/vnd.mfer mwf -application/vnd.mfmp mfm -application/vnd.micrografx.flo flo -application/vnd.micrografx.igx igx -application/vnd.mif mif -# application/vnd.minisoft-hp3000-save -# application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.mobius.daf daf -application/vnd.mobius.dis dis -application/vnd.mobius.mbk mbk -application/vnd.mobius.mqy mqy -application/vnd.mobius.msl msl -application/vnd.mobius.plc plc -application/vnd.mobius.txf txf -application/vnd.mophun.application mpn -application/vnd.mophun.certificate mpc -# application/vnd.motorola.flexsuite -# application/vnd.motorola.flexsuite.adsi -# application/vnd.motorola.flexsuite.fis -# application/vnd.motorola.flexsuite.gotap -# application/vnd.motorola.flexsuite.kmr -# application/vnd.motorola.flexsuite.ttc -# application/vnd.motorola.flexsuite.wem -# application/vnd.motorola.iprm -application/vnd.mozilla.xul+xml xul -application/vnd.ms-artgalry cil -# application/vnd.ms-asf -application/vnd.ms-cab-compressed cab -# application/vnd.ms-color.iccprofile -application/vnd.ms-excel xls xlm xla xlc xlt xlw -application/vnd.ms-excel.addin.macroenabled.12 xlam -application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb -application/vnd.ms-excel.sheet.macroenabled.12 xlsm -application/vnd.ms-excel.template.macroenabled.12 xltm -application/vnd.ms-fontobject eot -application/vnd.ms-htmlhelp chm -application/vnd.ms-ims ims -application/vnd.ms-lrm lrm -# application/vnd.ms-office.activex+xml -application/vnd.ms-officetheme thmx -# application/vnd.ms-opentype -# application/vnd.ms-package.obfuscated-opentype -application/vnd.ms-pki.seccat cat -application/vnd.ms-pki.stl stl -# application/vnd.ms-playready.initiator+xml -application/vnd.ms-powerpoint ppt pps pot -application/vnd.ms-powerpoint.addin.macroenabled.12 ppam -application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm -application/vnd.ms-powerpoint.slide.macroenabled.12 sldm -application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm -application/vnd.ms-powerpoint.template.macroenabled.12 potm -# application/vnd.ms-printing.printticket+xml -application/vnd.ms-project mpp mpt -# application/vnd.ms-tnef -# application/vnd.ms-wmdrm.lic-chlg-req -# application/vnd.ms-wmdrm.lic-resp -# application/vnd.ms-wmdrm.meter-chlg-req -# application/vnd.ms-wmdrm.meter-resp -application/vnd.ms-word.document.macroenabled.12 docm -application/vnd.ms-word.template.macroenabled.12 dotm -application/vnd.ms-works wps wks wcm wdb -application/vnd.ms-wpl wpl -application/vnd.ms-xpsdocument xps -application/vnd.mseq mseq -# application/vnd.msign -# application/vnd.multiad.creator -# application/vnd.multiad.creator.cif -# application/vnd.music-niff -application/vnd.musician mus -application/vnd.muvee.style msty -application/vnd.mynfc taglet -# application/vnd.ncd.control -# application/vnd.ncd.reference -# application/vnd.nervana -# application/vnd.netfpx -application/vnd.neurolanguage.nlu nlu -application/vnd.nitf ntf nitf -application/vnd.noblenet-directory nnd -application/vnd.noblenet-sealer nns -application/vnd.noblenet-web nnw -# application/vnd.nokia.catalogs -# application/vnd.nokia.conml+wbxml -# application/vnd.nokia.conml+xml -# application/vnd.nokia.isds-radio-presets -# application/vnd.nokia.iptv.config+xml -# application/vnd.nokia.landmark+wbxml -# application/vnd.nokia.landmark+xml -# application/vnd.nokia.landmarkcollection+xml -# application/vnd.nokia.n-gage.ac+xml -application/vnd.nokia.n-gage.data ngdat -application/vnd.nokia.n-gage.symbian.install n-gage -# application/vnd.nokia.ncd -# application/vnd.nokia.pcd+wbxml -# application/vnd.nokia.pcd+xml -application/vnd.nokia.radio-preset rpst -application/vnd.nokia.radio-presets rpss -application/vnd.novadigm.edm edm -application/vnd.novadigm.edx edx -application/vnd.novadigm.ext ext -# application/vnd.ntt-local.file-transfer -# application/vnd.ntt-local.sip-ta_remote -# application/vnd.ntt-local.sip-ta_tcp_stream -application/vnd.oasis.opendocument.chart odc -application/vnd.oasis.opendocument.chart-template otc -application/vnd.oasis.opendocument.database odb -application/vnd.oasis.opendocument.formula odf -application/vnd.oasis.opendocument.formula-template odft -application/vnd.oasis.opendocument.graphics odg -application/vnd.oasis.opendocument.graphics-template otg -application/vnd.oasis.opendocument.image odi -application/vnd.oasis.opendocument.image-template oti -application/vnd.oasis.opendocument.presentation odp -application/vnd.oasis.opendocument.presentation-template otp -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.spreadsheet-template ots -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.text-master odm -application/vnd.oasis.opendocument.text-template ott -application/vnd.oasis.opendocument.text-web oth -# application/vnd.obn -# application/vnd.oftn.l10n+json -# application/vnd.oipf.contentaccessdownload+xml -# application/vnd.oipf.contentaccessstreaming+xml -# application/vnd.oipf.cspg-hexbinary -# application/vnd.oipf.dae.svg+xml -# application/vnd.oipf.dae.xhtml+xml -# application/vnd.oipf.mippvcontrolmessage+xml -# application/vnd.oipf.pae.gem -# application/vnd.oipf.spdiscovery+xml -# application/vnd.oipf.spdlist+xml -# application/vnd.oipf.ueprofile+xml -# application/vnd.oipf.userprofile+xml -application/vnd.olpc-sugar xo -# application/vnd.oma-scws-config -# application/vnd.oma-scws-http-request -# application/vnd.oma-scws-http-response -# application/vnd.oma.bcast.associated-procedure-parameter+xml -# application/vnd.oma.bcast.drm-trigger+xml -# application/vnd.oma.bcast.imd+xml -# application/vnd.oma.bcast.ltkm -# application/vnd.oma.bcast.notification+xml -# application/vnd.oma.bcast.provisioningtrigger -# application/vnd.oma.bcast.sgboot -# application/vnd.oma.bcast.sgdd+xml -# application/vnd.oma.bcast.sgdu -# application/vnd.oma.bcast.simple-symbol-container -# application/vnd.oma.bcast.smartcard-trigger+xml -# application/vnd.oma.bcast.sprov+xml -# application/vnd.oma.bcast.stkm -# application/vnd.oma.cab-address-book+xml -# application/vnd.oma.cab-feature-handler+xml -# application/vnd.oma.cab-pcc+xml -# application/vnd.oma.cab-user-prefs+xml -# application/vnd.oma.dcd -# application/vnd.oma.dcdc -application/vnd.oma.dd2+xml dd2 -# application/vnd.oma.drm.risd+xml -# application/vnd.oma.group-usage-list+xml -# application/vnd.oma.pal+xml -# application/vnd.oma.poc.detailed-progress-report+xml -# application/vnd.oma.poc.final-report+xml -# application/vnd.oma.poc.groups+xml -# application/vnd.oma.poc.invocation-descriptor+xml -# application/vnd.oma.poc.optimized-progress-report+xml -# application/vnd.oma.push -# application/vnd.oma.scidm.messages+xml -# application/vnd.oma.xcap-directory+xml -# application/vnd.omads-email+xml -# application/vnd.omads-file+xml -# application/vnd.omads-folder+xml -# application/vnd.omaloc-supl-init -application/vnd.openofficeorg.extension oxt -# application/vnd.openxmlformats-officedocument.custom-properties+xml -# application/vnd.openxmlformats-officedocument.customxmlproperties+xml -# application/vnd.openxmlformats-officedocument.drawing+xml -# application/vnd.openxmlformats-officedocument.drawingml.chart+xml -# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml -# application/vnd.openxmlformats-officedocument.extended-properties+xml -# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml -# application/vnd.openxmlformats-officedocument.presentationml.comments+xml -# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml -application/vnd.openxmlformats-officedocument.presentationml.slide sldx -# application/vnd.openxmlformats-officedocument.presentationml.slide+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml -application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx -# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml -# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml -# application/vnd.openxmlformats-officedocument.presentationml.tags+xml -application/vnd.openxmlformats-officedocument.presentationml.template potx -# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx -# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml -# application/vnd.openxmlformats-officedocument.theme+xml -# application/vnd.openxmlformats-officedocument.themeoverride+xml -# application/vnd.openxmlformats-officedocument.vmldrawing -# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx -# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml -# application/vnd.openxmlformats-package.core-properties+xml -# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml -# application/vnd.openxmlformats-package.relationships+xml -# application/vnd.quobject-quoxdocument -# application/vnd.osa.netdeploy -application/vnd.osgeo.mapguide.package mgp -# application/vnd.osgi.bundle -application/vnd.osgi.dp dp -application/vnd.osgi.subsystem esa -# application/vnd.otps.ct-kip+xml -application/vnd.palm pdb pqa oprc -# application/vnd.paos.xml -application/vnd.pawaafile paw -application/vnd.pg.format str -application/vnd.pg.osasli ei6 -# application/vnd.piaccess.application-licence -application/vnd.picsel efif -application/vnd.pmi.widget wg -# application/vnd.poc.group-advertisement+xml -application/vnd.pocketlearn plf -application/vnd.powerbuilder6 pbd -# application/vnd.powerbuilder6-s -# application/vnd.powerbuilder7 -# application/vnd.powerbuilder7-s -# application/vnd.powerbuilder75 -# application/vnd.powerbuilder75-s -# application/vnd.preminet -application/vnd.previewsystems.box box -application/vnd.proteus.magazine mgz -application/vnd.publishare-delta-tree qps -application/vnd.pvi.ptid1 ptid -# application/vnd.pwg-multiplexed -# application/vnd.pwg-xhtml-print+xml -# application/vnd.qualcomm.brew-app-res -application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb -# application/vnd.radisys.moml+xml -# application/vnd.radisys.msml+xml -# application/vnd.radisys.msml-audit+xml -# application/vnd.radisys.msml-audit-conf+xml -# application/vnd.radisys.msml-audit-conn+xml -# application/vnd.radisys.msml-audit-dialog+xml -# application/vnd.radisys.msml-audit-stream+xml -# application/vnd.radisys.msml-conf+xml -# application/vnd.radisys.msml-dialog+xml -# application/vnd.radisys.msml-dialog-base+xml -# application/vnd.radisys.msml-dialog-fax-detect+xml -# application/vnd.radisys.msml-dialog-fax-sendrecv+xml -# application/vnd.radisys.msml-dialog-group+xml -# application/vnd.radisys.msml-dialog-speech+xml -# application/vnd.radisys.msml-dialog-transform+xml -# application/vnd.rainstor.data -# application/vnd.rapid -application/vnd.realvnc.bed bed -application/vnd.recordare.musicxml mxl -application/vnd.recordare.musicxml+xml musicxml -# application/vnd.renlearn.rlprint -application/vnd.rig.cryptonote cryptonote -application/vnd.rim.cod cod -application/vnd.rn-realmedia rm -application/vnd.rn-realmedia-vbr rmvb -application/vnd.route66.link66+xml link66 -# application/vnd.rs-274x -# application/vnd.ruckus.download -# application/vnd.s3sms -application/vnd.sailingtracker.track st -# application/vnd.sbm.cid -# application/vnd.sbm.mid2 -# application/vnd.scribus -# application/vnd.sealed.3df -# application/vnd.sealed.csf -# application/vnd.sealed.doc -# application/vnd.sealed.eml -# application/vnd.sealed.mht -# application/vnd.sealed.net -# application/vnd.sealed.ppt -# application/vnd.sealed.tiff -# application/vnd.sealed.xls -# application/vnd.sealedmedia.softseal.html -# application/vnd.sealedmedia.softseal.pdf -application/vnd.seemail see -application/vnd.sema sema -application/vnd.semd semd -application/vnd.semf semf -application/vnd.shana.informed.formdata ifm -application/vnd.shana.informed.formtemplate itp -application/vnd.shana.informed.interchange iif -application/vnd.shana.informed.package ipk -application/vnd.simtech-mindmapper twd twds -application/vnd.smaf mmf -# application/vnd.smart.notebook -application/vnd.smart.teacher teacher -# application/vnd.software602.filler.form+xml -# application/vnd.software602.filler.form-xml-zip -application/vnd.solent.sdkm+xml sdkm sdkd -application/vnd.spotfire.dxp dxp -application/vnd.spotfire.sfs sfs -# application/vnd.sss-cod -# application/vnd.sss-dtf -# application/vnd.sss-ntf -application/vnd.stardivision.calc sdc -application/vnd.stardivision.draw sda -application/vnd.stardivision.impress sdd -application/vnd.stardivision.math smf -application/vnd.stardivision.writer sdw vor -application/vnd.stardivision.writer-global sgl -application/vnd.stepmania.package smzip -application/vnd.stepmania.stepchart sm -# application/vnd.street-stream -application/vnd.sun.xml.calc sxc -application/vnd.sun.xml.calc.template stc -application/vnd.sun.xml.draw sxd -application/vnd.sun.xml.draw.template std -application/vnd.sun.xml.impress sxi -application/vnd.sun.xml.impress.template sti -application/vnd.sun.xml.math sxm -application/vnd.sun.xml.writer sxw -application/vnd.sun.xml.writer.global sxg -application/vnd.sun.xml.writer.template stw -# application/vnd.sun.wadl+xml -application/vnd.sus-calendar sus susp -application/vnd.svd svd -# application/vnd.swiftview-ics -application/vnd.symbian.install sis sisx -application/vnd.syncml+xml xsm -application/vnd.syncml.dm+wbxml bdm -application/vnd.syncml.dm+xml xdm -# application/vnd.syncml.dm.notification -# application/vnd.syncml.ds.notification -application/vnd.tao.intent-module-archive tao -application/vnd.tcpdump.pcap pcap cap dmp -application/vnd.tmobile-livetv tmo -application/vnd.trid.tpt tpt -application/vnd.triscape.mxs mxs -application/vnd.trueapp tra -# application/vnd.truedoc -# application/vnd.ubisoft.webplayer -application/vnd.ufdl ufd ufdl -application/vnd.uiq.theme utz -application/vnd.umajin umj -application/vnd.unity unityweb -application/vnd.uoml+xml uoml -# application/vnd.uplanet.alert -# application/vnd.uplanet.alert-wbxml -# application/vnd.uplanet.bearer-choice -# application/vnd.uplanet.bearer-choice-wbxml -# application/vnd.uplanet.cacheop -# application/vnd.uplanet.cacheop-wbxml -# application/vnd.uplanet.channel -# application/vnd.uplanet.channel-wbxml -# application/vnd.uplanet.list -# application/vnd.uplanet.list-wbxml -# application/vnd.uplanet.listcmd -# application/vnd.uplanet.listcmd-wbxml -# application/vnd.uplanet.signal -application/vnd.vcx vcx -# application/vnd.vd-study -# application/vnd.vectorworks -# application/vnd.verimatrix.vcas -# application/vnd.vidsoft.vidconference -application/vnd.visio vsd vst vss vsw -application/vnd.visionary vis -# application/vnd.vividence.scriptfile -application/vnd.vsf vsf -# application/vnd.wap.sic -# application/vnd.wap.slc -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/vnd.webturbo wtb -# application/vnd.wfa.wsc -# application/vnd.wmc -# application/vnd.wmf.bootstrap -# application/vnd.wolfram.mathematica -# application/vnd.wolfram.mathematica.package -application/vnd.wolfram.player nbp -application/vnd.wordperfect wpd -application/vnd.wqd wqd -# application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf stf -# application/vnd.wv.csp+wbxml -# application/vnd.wv.csp+xml -# application/vnd.wv.ssp+xml -application/vnd.xara xar -application/vnd.xfdl xfdl -# application/vnd.xfdl.webform -# application/vnd.xmi+xml -# application/vnd.xmpie.cpkg -# application/vnd.xmpie.dpkg -# application/vnd.xmpie.plan -# application/vnd.xmpie.ppkg -# application/vnd.xmpie.xlim -application/vnd.yamaha.hv-dic hvd -application/vnd.yamaha.hv-script hvs -application/vnd.yamaha.hv-voice hvp -application/vnd.yamaha.openscoreformat osf -application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg -# application/vnd.yamaha.remote-setup -application/vnd.yamaha.smaf-audio saf -application/vnd.yamaha.smaf-phrase spf -# application/vnd.yamaha.through-ngn -# application/vnd.yamaha.tunnel-udpencap -application/vnd.yellowriver-custom-menu cmp -application/vnd.zul zir zirz -application/vnd.zzazz.deck+xml zaz -application/voicexml+xml vxml -# application/vq-rtcpxr -# application/watcherinfo+xml -# application/whoispp-query -# application/whoispp-response -application/widget wgt -application/winhlp hlp -# application/wita -# application/wordperfect5.1 -application/wsdl+xml wsdl -application/wspolicy+xml wspolicy -application/x-7z-compressed 7z -application/x-abiword abw -application/x-ace-compressed ace -# application/x-amf -application/x-apple-diskimage dmg -application/x-authorware-bin aab x32 u32 vox -application/x-authorware-map aam -application/x-authorware-seg aas -application/x-bcpio bcpio -application/x-bittorrent torrent -application/x-blorb blb blorb -application/x-bzip bz -application/x-bzip2 bz2 boz -application/x-cbr cbr cba cbt cbz cb7 -application/x-cdlink vcd -application/x-cfs-compressed cfs -application/x-chat chat -application/x-chess-pgn pgn -application/x-conference nsc -# application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-debian-package deb udeb -application/x-dgc-compressed dgc -application/x-director dir dcr dxr cst cct cxt w3d fgd swa -application/x-doom wad -application/x-dtbncx+xml ncx -application/x-dtbook+xml dtb -application/x-dtbresource+xml res -application/x-dvi dvi -application/x-envoy evy -application/x-eva eva -application/x-font-bdf bdf -# application/x-font-dos -# application/x-font-framemaker -application/x-font-ghostscript gsf -# application/x-font-libgrx -application/x-font-linux-psf psf -application/x-font-otf otf -application/x-font-pcf pcf -application/x-font-snf snf -# application/x-font-speedo -# application/x-font-sunos-news -application/x-font-ttf ttf ttc -application/x-font-type1 pfa pfb pfm afm -application/font-woff woff -# application/x-font-vfont -application/x-freearc arc -application/x-futuresplash spl -application/x-gca-compressed gca -application/x-glulx ulx -application/x-gnumeric gnumeric -application/x-gramps-xml gramps -application/x-gtar gtar -# application/x-gzip -application/x-hdf hdf -application/x-install-instructions install -application/x-iso9660-image iso -application/x-java-jnlp-file jnlp -application/x-latex latex -application/x-lzh-compressed lzh lha -application/x-mie mie -application/x-mobipocket-ebook prc mobi -application/x-ms-application application -application/x-ms-shortcut lnk -application/x-ms-wmd wmd -application/x-ms-wmz wmz -application/x-ms-xbap xbap -application/x-msaccess mdb -application/x-msbinder obd -application/x-mscardfile crd -application/x-msclip clp -application/x-msdownload exe dll com bat msi -application/x-msmediaview mvb m13 m14 -application/x-msmetafile wmf wmz emf emz -application/x-msmoney mny -application/x-mspublisher pub -application/x-msschedule scd -application/x-msterminal trm -application/x-mswrite wri -application/x-netcdf nc cdf -application/x-nzb nzb -application/x-pkcs12 p12 pfx -application/x-pkcs7-certificates p7b spc -application/x-pkcs7-certreqresp p7r -application/x-rar-compressed rar -application/x-research-info-systems ris -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-silverlight-app xap -application/x-sql sql -application/x-stuffit sit -application/x-stuffitx sitx -application/x-subrip srt -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-t3vm-image t3 -application/x-tads gam -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-tex-tfm tfm -application/x-texinfo texinfo texi -application/x-tgif obj -application/x-ustar ustar -application/x-wais-source src -application/x-x509-ca-cert der crt -application/x-xfig fig -application/x-xliff+xml xlf -application/x-xpinstall xpi -application/x-xz xz -application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 -# application/x400-bp -application/xaml+xml xaml -# application/xcap-att+xml -# application/xcap-caps+xml -application/xcap-diff+xml xdf -# application/xcap-el+xml -# application/xcap-error+xml -# application/xcap-ns+xml -# application/xcon-conference-info-diff+xml -# application/xcon-conference-info+xml -application/xenc+xml xenc -application/xhtml+xml xhtml xht -# application/xhtml-voice+xml -application/xml xml xsl -application/xml-dtd dtd -# application/xml-external-parsed-entity -# application/xmpp+xml -application/xop+xml xop -application/xproc+xml xpl -application/xslt+xml xslt -application/xspf+xml xspf -application/xv+xml mxml xhvml xvml xvm -application/yang yang -application/yin+xml yin -application/zip zip -# audio/1d-interleaved-parityfec -# audio/32kadpcm -# audio/3gpp -# audio/3gpp2 -# audio/ac3 -audio/adpcm adp -# audio/amr -# audio/amr-wb -# audio/amr-wb+ -# audio/asc -# audio/atrac-advanced-lossless -# audio/atrac-x -# audio/atrac3 -audio/basic au snd -# audio/bv16 -# audio/bv32 -# audio/clearmode -# audio/cn -# audio/dat12 -# audio/dls -# audio/dsr-es201108 -# audio/dsr-es202050 -# audio/dsr-es202211 -# audio/dsr-es202212 -# audio/dv -# audio/dvi4 -# audio/eac3 -# audio/evrc -# audio/evrc-qcp -# audio/evrc0 -# audio/evrc1 -# audio/evrcb -# audio/evrcb0 -# audio/evrcb1 -# audio/evrcwb -# audio/evrcwb0 -# audio/evrcwb1 -# audio/example -# audio/fwdred -# audio/g719 -# audio/g722 -# audio/g7221 -# audio/g723 -# audio/g726-16 -# audio/g726-24 -# audio/g726-32 -# audio/g726-40 -# audio/g728 -# audio/g729 -# audio/g7291 -# audio/g729d -# audio/g729e -# audio/gsm -# audio/gsm-efr -# audio/gsm-hr-08 -# audio/ilbc -# audio/ip-mr_v2.5 -# audio/isac -# audio/l16 -# audio/l20 -# audio/l24 -# audio/l8 -# audio/lpc -audio/midi mid midi kar rmi -# audio/mobile-xmf -audio/mp4 mp4a -# audio/mp4a-latm -# audio/mpa -# audio/mpa-robust -audio/mpeg mpga mp2 mp2a mp3 m2a m3a -# audio/mpeg4-generic -# audio/musepack -audio/ogg oga ogg spx -# audio/opus -# audio/parityfec -# audio/pcma -# audio/pcma-wb -# audio/pcmu-wb -# audio/pcmu -# audio/prs.sid -# audio/qcelp -# audio/red -# audio/rtp-enc-aescm128 -# audio/rtp-midi -# audio/rtx -audio/s3m s3m -audio/silk sil -# audio/smv -# audio/smv0 -# audio/smv-qcp -# audio/sp-midi -# audio/speex -# audio/t140c -# audio/t38 -# audio/telephone-event -# audio/tone -# audio/uemclip -# audio/ulpfec -# audio/vdvi -# audio/vmr-wb -# audio/vnd.3gpp.iufp -# audio/vnd.4sb -# audio/vnd.audiokoz -# audio/vnd.celp -# audio/vnd.cisco.nse -# audio/vnd.cmles.radio-events -# audio/vnd.cns.anp1 -# audio/vnd.cns.inf1 -audio/vnd.dece.audio uva uvva -audio/vnd.digital-winds eol -# audio/vnd.dlna.adts -# audio/vnd.dolby.heaac.1 -# audio/vnd.dolby.heaac.2 -# audio/vnd.dolby.mlp -# audio/vnd.dolby.mps -# audio/vnd.dolby.pl2 -# audio/vnd.dolby.pl2x -# audio/vnd.dolby.pl2z -# audio/vnd.dolby.pulse.1 -audio/vnd.dra dra -audio/vnd.dts dts -audio/vnd.dts.hd dtshd -# audio/vnd.dvb.file -# audio/vnd.everad.plj -# audio/vnd.hns.audio -audio/vnd.lucent.voice lvp -audio/vnd.ms-playready.media.pya pya -# audio/vnd.nokia.mobile-xmf -# audio/vnd.nortel.vbk -audio/vnd.nuera.ecelp4800 ecelp4800 -audio/vnd.nuera.ecelp7470 ecelp7470 -audio/vnd.nuera.ecelp9600 ecelp9600 -# audio/vnd.octel.sbc -# audio/vnd.qcelp -# audio/vnd.rhetorex.32kadpcm -audio/vnd.rip rip -# audio/vnd.sealedmedia.softseal.mpeg -# audio/vnd.vmx.cvsd -# audio/vorbis -# audio/vorbis-config -audio/webm weba -audio/x-aac aac -audio/x-aiff aif aiff aifc -audio/x-caf caf -audio/x-flac flac -audio/x-matroska mka -audio/x-mpegurl m3u -audio/x-ms-wax wax -audio/x-ms-wma wma -audio/x-pn-realaudio ram ra -audio/x-pn-realaudio-plugin rmp -# audio/x-tta -audio/x-wav wav -audio/xm xm -chemical/x-cdx cdx -chemical/x-cif cif -chemical/x-cmdf cmdf -chemical/x-cml cml -chemical/x-csml csml -# chemical/x-pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -# image/example -# image/fits -image/g3fax g3 -image/gif gif -image/ief ief -# image/jp2 -image/jpeg jpeg jpg jpe -# image/jpm -# image/jpx -image/ktx ktx -# image/naplps -image/png png -image/prs.btif btif -# image/prs.pti -image/sgi sgi -image/svg+xml svg svgz -# image/t38 -image/tiff tiff tif -# image/tiff-fx -image/vnd.adobe.photoshop psd -# image/vnd.cns.inf2 -image/vnd.dece.graphic uvi uvvi uvg uvvg -image/vnd.dvb.subtitle sub -image/vnd.djvu djvu djv -image/vnd.dwg dwg -image/vnd.dxf dxf -image/vnd.fastbidsheet fbs -image/vnd.fpx fpx -image/vnd.fst fst -image/vnd.fujixerox.edmics-mmr mmr -image/vnd.fujixerox.edmics-rlc rlc -# image/vnd.globalgraphics.pgb -# image/vnd.microsoft.icon -# image/vnd.mix -image/vnd.ms-modi mdi -image/vnd.ms-photo wdp -image/vnd.net-fpx npx -# image/vnd.radiance -# image/vnd.sealed.png -# image/vnd.sealedmedia.softseal.gif -# image/vnd.sealedmedia.softseal.jpg -# image/vnd.svf -image/vnd.wap.wbmp wbmp -image/vnd.xiff xif -image/webp webp -image/x-3ds 3ds -image/x-cmu-raster ras -image/x-cmx cmx -image/x-freehand fh fhc fh4 fh5 fh7 -image/x-icon ico -image/x-mrsid-image sid -image/x-pcx pcx -image/x-pict pic pct -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-tga tga -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -# message/cpim -# message/delivery-status -# message/disposition-notification -# message/example -# message/external-body -# message/feedback-report -# message/global -# message/global-delivery-status -# message/global-disposition-notification -# message/global-headers -# message/http -# message/imdn+xml -# message/news -# message/partial -message/rfc822 eml mime -# message/s-http -# message/sip -# message/sipfrag -# message/tracking-status -# message/vnd.si.simp -# model/example -model/iges igs iges -model/mesh msh mesh silo -model/vnd.collada+xml dae -model/vnd.dwf dwf -# model/vnd.flatland.3dml -model/vnd.gdl gdl -# model/vnd.gs-gdl -# model/vnd.gs.gdl -model/vnd.gtw gtw -# model/vnd.moml+xml -model/vnd.mts mts -# model/vnd.parasolid.transmit.binary -# model/vnd.parasolid.transmit.text -model/vnd.vtu vtu -model/vrml wrl vrml -model/x3d+binary x3db x3dbz -model/x3d+vrml x3dv x3dvz -model/x3d+xml x3d x3dz -# multipart/alternative -# multipart/appledouble -# multipart/byteranges -# multipart/digest -# multipart/encrypted -# multipart/example -# multipart/form-data -# multipart/header-set -# multipart/mixed -# multipart/parallel -# multipart/related -# multipart/report -# multipart/signed -# multipart/voice-message -# text/1d-interleaved-parityfec -text/cache-manifest appcache -text/calendar ics ifb -text/css css -text/csv csv -# text/directory -# text/dns -# text/ecmascript -# text/enriched -# text/example -# text/fwdred -text/html html htm -# text/javascript -text/n3 n3 -# text/parityfec -text/plain txt text conf def list log in -# text/prs.fallenstein.rst -text/prs.lines.tag dsc -# text/vnd.radisys.msml-basic-layout -# text/red -# text/rfc822-headers -text/richtext rtx -# text/rtf -# text/rtp-enc-aescm128 -# text/rtx -text/sgml sgml sgm -# text/t140 -text/tab-separated-values tsv -text/troff t tr roff man me ms -text/turtle ttl -# text/ulpfec -text/uri-list uri uris urls -text/vcard vcard -# text/vnd.abc -text/vnd.curl curl -text/vnd.curl.dcurl dcurl -text/vnd.curl.scurl scurl -text/vnd.curl.mcurl mcurl -# text/vnd.dmclientscript -text/vnd.dvb.subtitle sub -# text/vnd.esmertec.theme-descriptor -text/vnd.fly fly -text/vnd.fmi.flexstor flx -text/vnd.graphviz gv -text/vnd.in3d.3dml 3dml -text/vnd.in3d.spot spot -# text/vnd.iptc.newsml -# text/vnd.iptc.nitf -# text/vnd.latex-z -# text/vnd.motorola.reflex -# text/vnd.ms-mediapackage -# text/vnd.net2phone.commcenter.command -# text/vnd.si.uricatalogue -text/vnd.sun.j2me.app-descriptor jad -# text/vnd.trolltech.linguist -# text/vnd.wap.si -# text/vnd.wap.sl -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-asm s asm -text/x-c c cc cxx cpp h hh dic -text/x-fortran f for f77 f90 -text/x-java-source java -text/x-opml opml -text/x-pascal p pas -text/x-nfo nfo -text/x-setext etx -text/x-sfv sfv -text/x-uuencode uu -text/x-vcalendar vcs -text/x-vcard vcf -# text/xml -# text/xml-external-parsed-entity -# video/1d-interleaved-parityfec -video/3gpp 3gp -# video/3gpp-tt -video/3gpp2 3g2 -# video/bmpeg -# video/bt656 -# video/celb -# video/dv -# video/example -video/h261 h261 -video/h263 h263 -# video/h263-1998 -# video/h263-2000 -video/h264 h264 -# video/h264-rcdo -# video/h264-svc -video/jpeg jpgv -# video/jpeg2000 -video/jpm jpm jpgm -video/mj2 mj2 mjp2 -# video/mp1s -# video/mp2p -# video/mp2t -video/mp4 mp4 mp4v mpg4 -# video/mp4v-es -video/mpeg mpeg mpg mpe m1v m2v -# video/mpeg4-generic -# video/mpv -# video/nv -video/ogg ogv -# video/parityfec -# video/pointer -video/quicktime qt mov -# video/raw -# video/rtp-enc-aescm128 -# video/rtx -# video/smpte292m -# video/ulpfec -# video/vc1 -# video/vnd.cctv -video/vnd.dece.hd uvh uvvh -video/vnd.dece.mobile uvm uvvm -# video/vnd.dece.mp4 -video/vnd.dece.pd uvp uvvp -video/vnd.dece.sd uvs uvvs -video/vnd.dece.video uvv uvvv -# video/vnd.directv.mpeg -# video/vnd.directv.mpeg-tts -# video/vnd.dlna.mpeg-tts -video/vnd.dvb.file dvb -video/vnd.fvt fvt -# video/vnd.hns.video -# video/vnd.iptvforum.1dparityfec-1010 -# video/vnd.iptvforum.1dparityfec-2005 -# video/vnd.iptvforum.2dparityfec-1010 -# video/vnd.iptvforum.2dparityfec-2005 -# video/vnd.iptvforum.ttsavc -# video/vnd.iptvforum.ttsmpeg2 -# video/vnd.motorola.video -# video/vnd.motorola.videop -video/vnd.mpegurl mxu m4u -video/vnd.ms-playready.media.pyv pyv -# video/vnd.nokia.interleaved-multimedia -# video/vnd.nokia.videovoip -# video/vnd.objectvideo -# video/vnd.sealed.mpeg1 -# video/vnd.sealed.mpeg4 -# video/vnd.sealed.swf -# video/vnd.sealedmedia.softseal.mov -video/vnd.uvvu.mp4 uvu uvvu -video/vnd.vivo viv -video/webm webm -video/x-f4v f4v -video/x-fli fli -video/x-flv flv -video/x-m4v m4v -video/x-matroska mkv mk3d mks -video/x-mng mng -video/x-ms-asf asf asx -video/x-ms-vob vob -video/x-ms-wm wm -video/x-ms-wmv wmv -video/x-ms-wmx wmx -video/x-ms-wvx wvx -video/x-msvideo avi -video/x-sgi-movie movie -video/x-smv smv -x-conference/x-cooltalk ice diff --git a/conf/rayo/sip_profiles/external.xml b/conf/rayo/sip_profiles/external.xml deleted file mode 100644 index 2b601fbb38..0000000000 --- a/conf/rayo/sip_profiles/external.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/sip_profiles/external/example.xml b/conf/rayo/sip_profiles/external/example.xml deleted file mode 100644 index 0497bcd1e1..0000000000 --- a/conf/rayo/sip_profiles/external/example.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/vars.xml b/conf/rayo/vars.xml deleted file mode 100644 index af602cad34..0000000000 --- a/conf/rayo/vars.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/configure.ac b/configure.ac index 6991398ae7..0d9c2efc1a 100644 --- a/configure.ac +++ b/configure.ac @@ -2210,7 +2210,6 @@ AC_CONFIG_FILES([Makefile src/mod/event_handlers/mod_json_cdr/Makefile src/mod/event_handlers/mod_radius_cdr/Makefile src/mod/event_handlers/mod_odbc_cdr/Makefile - src/mod/event_handlers/mod_rayo/Makefile src/mod/event_handlers/mod_smpp/Makefile src/mod/event_handlers/mod_snmp/Makefile src/mod/event_handlers/mod_event_zmq/Makefile @@ -2222,7 +2221,6 @@ AC_CONFIG_FILES([Makefile src/mod/formats/mod_shell_stream/Makefile src/mod/formats/mod_shout/Makefile src/mod/formats/mod_sndfile/Makefile - src/mod/formats/mod_ssml/Makefile src/mod/formats/mod_tone_stream/Makefile src/mod/formats/mod_vlc/Makefile src/mod/formats/mod_portaudio_stream/Makefile @@ -2339,7 +2337,6 @@ AC_CONFIG_SUBDIRS([libs/srtp]) if test "$use_system_apr" != "yes"; then AC_CONFIG_SUBDIRS([libs/apr]) fi -AC_CONFIG_SUBDIRS([libs/iksemel]) case $host in *-openbsd*|*-netbsd*) diff --git a/debian/control-modules b/debian/control-modules index 0f0784d3f5..7d6182d790 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -550,11 +550,6 @@ Module: event_handlers/mod_radius_cdr Description: mod_radius_cdr Adds mod_radius_cdr. -Module: event_handlers/mod_rayo -Description: mod_rayo - Adds mod_rayo. -Depends: freeswitch-mod-ssml (= ${binary:Version}) - Module: event_handlers/mod_smpp Description: mod_snmp Adds mod_snmp. @@ -604,10 +599,6 @@ Description: mod_sndfile Build-Depends: libsndfile1-dev, libflac-dev, libogg-dev, libvorbis-dev -Module: formats/mod_ssml -Description: mod_ssml - Adds mod_ssml. - Module: formats/mod_tone_stream Description: mod_tone_stream Adds mod_tone_stream. diff --git a/debian/copyright b/debian/copyright index 5a76744817..2270e4a9d5 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1202,10 +1202,6 @@ Files: src/include/switch_cpp.h Copyright: 2007 Yossi Neiman License: MPL-1.1 (well, maybe -- it refers to a COPYING file, so probably docs/COPYING, in which case MPL-1.1) -Files: libs/iksemel/* -Copyright: 2000-2007 Gurer Ozen -License: LGPL-2.1 - Files: libs/apr*/* Copyright: 2000-2005 The Apache Software Foundation or its licensors 1991-1992, RSA Data Security, Inc. @@ -1519,7 +1515,6 @@ License: MPL-1.1 Files: src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/* src/mod/languages/mod_lua/lua-mode.el - libs/iksemel/ltmain.sh Copyright: 1995-2007 Free Software Foundation, Inc. License: GPL-2+ diff --git a/debian/rules b/debian/rules index 88aaee3f71..8b5d9ebe5e 100755 --- a/debian/rules +++ b/debian/rules @@ -82,7 +82,6 @@ override_dh_auto_configure: .stamp-configure .stamp-build: .stamp-configure @$(call show_vars) make -j$(NJOBS) core - make iksemel-dep make -j$(NJOBS) make -C libs/esl pymod make -C libs/esl py3mod diff --git a/docs/Doxygen.conf b/docs/Doxygen.conf index 9e62b08232..e9394d18bb 100644 --- a/docs/Doxygen.conf +++ b/docs/Doxygen.conf @@ -1240,7 +1240,7 @@ SEARCH_INCLUDES = YES # contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH =../libs/apr ../libs/apr-util ../libs/iksemel ../libs/libnatpmp \ +INCLUDE_PATH =../libs/apr ../libs/apr-util ../libs/libnatpmp \ ../libs/miniupnpc ../libs/sofia-sip ../libs/spandsp \ ../libs/srtp ../libs/win32 ../libs/xmlrpc-c diff --git a/freeswitch-config-rayo.spec b/freeswitch-config-rayo.spec deleted file mode 100644 index d022978834..0000000000 --- a/freeswitch-config-rayo.spec +++ /dev/null @@ -1,177 +0,0 @@ -###################################################################################################################### -# -# freeswitch-config-rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -# Copyright (C) 2013-2015, Grasshopper -# -# 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. -# -# The Original Code is freeswitch-config-rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -# -# The Initial Developer of the Original Code is Grasshopper -# Portions created by the Initial Developer are Copyright (C) -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Chris Rienzo -# -# freeswitch-rayo-config -- RPM packaging for Rayo Server configuration -# -###################################################################################################################### - -%define nonparsedversion 1.7.0 -%define version %(echo '%{nonparsedversion}' | sed 's/-//g') -%define release 1 - -%define fsname freeswitch - -%define PREFIX %{_prefix} -%define EXECPREFIX %{_exec_prefix} -%define BINDIR %{_bindir} -%define SBINDIR %{_sbindir} -%define LIBEXECDIR %{_libexecdir}/%fsname -%define SYSCONFDIR %{_sysconfdir}/%fsname -%define SHARESTATEDIR %{_sharedstatedir}/%fsname -%define LOCALSTATEDIR %{_localstatedir}/lib/%fsname -%define LIBDIR %{_libdir} -%define INCLUDEDIR %{_includedir} -%define _datarootdir %{_prefix}/share -%define DATAROOTDIR %{_datarootdir} -%define DATADIR %{_datadir} -%define INFODIR %{_infodir} -%define LOCALEDIR %{_datarootdir}/locale -%define MANDIR %{_mandir} -%define DOCDIR %{_defaultdocdir}/%fsname -%define HTMLDIR %{_defaultdocdir}/%fsname/html -%define DVIDIR %{_defaultdocdir}/%fsname/dvi -%define PDFDIR %{_defaultdocdir}/%fsname/pdf -%define PSDIR %{_defaultdocdir}/%fsname/ps -%define LOGFILEDIR /var/log/%fsname -%define MODINSTDIR %{_libdir}/%fsname/mod -%define RUNDIR %{_localstatedir}/run/%fsname -%define DBDIR %{LOCALSTATEDIR}/db -%define HTDOCSDIR %{_datarootdir}/%fsname/htdocs -%define SOUNDSDIR %{_datarootdir}/%fsname/sounds -%define GRAMMARDIR %{_datarootdir}/%fsname/grammar -%define SCRIPTDIR %{_datarootdir}/%fsname/scripts -%define RECORDINGSDIR %{LOCALSTATEDIR}/recordings -%define PKGCONFIGDIR %{_datarootdir}/%fsname/pkgconfig -%define HOMEDIR %{LOCALSTATEDIR} - -Name: freeswitch-config-rayo -Version: %{version} -Release: %{release}%{?dist} -License: MPL1.1 -Summary: Rayo configuration for the FreeSWITCH Open Source telephone platform. -Group: System/Libraries -Packager: Chris Rienzo -URL: http://www.freeswitch.org/ -Source0: freeswitch-%{nonparsedversion}.tar.bz2 -Requires: freeswitch -Requires: freeswitch-application-conference -Requires: freeswitch-application-esf -Requires: freeswitch-application-expr -Requires: freeswitch-application-fsv -Requires: freeswitch-application-http-cache -Requires: freeswitch-asrtts-flite -Requires: freeswitch-asrtts-pocketsphinx -Requires: freeswitch-codec-h26x -Requires: freeswitch-codec-ilbc -Requires: freeswitch-codec-opus -Requires: freeswitch-codec-vp8 -Requires: freeswitch-event-rayo -Requires: freeswitch-format-local-stream -Requires: freeswitch-format-mod-shout -Requires: freeswitch-format-shell-stream -Requires: freeswitch-format-ssml -Requires: freeswitch-sounds-music-8000 -Requires: freeswitch-lang-en -Requires: freeswitch-sounds-en-us-callie-8000 -BuildRequires: bash -BuildArch: noarch -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -%description -FreeSWITCH rayo server implementation. - -%prep -%setup -b0 -q -n freeswitch-%{nonparsedversion} - -%build - -%install -%{__rm} -rf %{buildroot} -%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR} -%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/autoload_configs -%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/dialplan -%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/sip_profiles -%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/directory -%{__cp} -prv ./conf/rayo/*.{xml,types,pem} %{buildroot}/%{SYSCONFDIR}/ -%{__cp} -prv ./conf/rayo/{autoload_configs,dialplan} %{buildroot}/%{SYSCONFDIR}/ -%{__cp} -prv ./conf/rayo/sip_profiles/external.xml %{buildroot}/%{SYSCONFDIR}/sip_profiles -%{__cp} -prv ./conf/rayo/sip_profiles/external %{buildroot}/%{SYSCONFDIR}/sip_profiles -%{__cp} -prv ./conf/rayo/directory %{buildroot}/%{SYSCONFDIR}/ - -%postun - -%clean -%{__rm} -rf %{buildroot} - -%files -%defattr(-,freeswitch,daemon) -%dir %attr(0750, freeswitch, daemon) %{SYSCONFDIR} -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/cacert.pem -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/*.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/mime.types -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/acl.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/cdr_csv.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/conference.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/console.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/event_socket.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/http_cache.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/local_stream.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/logfile.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/modules.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/pocketsphinx.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/post_load_modules.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/presence_map.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/rayo.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/shout.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/sofia.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/spandsp.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/ssml.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/switch.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/timezones.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/dialplan/public.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/directory/default.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/directory/default/*.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/sip_profiles/*.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/sip_profiles/external/*.xml - -### END OF config-rayo - -###################################################################################################################### -# -# Changelog -# -###################################################################################################################### -%changelog -* Tue Apr 23 2019 - Andrey Volk -- Fix build for Stack 20.x -* Tue Jun 10 2014 crienzo@grasshopper.com -- Remove dependency to high resolution music and sounds files -- Remove dependency to specific FreeSWITCH package version -* Mon Jun 03 2013 - crienzo@grasshopper.com -- Added users and internal profile for softphone testing -* Wed May 08 2013 - crienzo@grasshopper.com -- Initial revision - diff --git a/freeswitch.spec b/freeswitch.spec index 98ce36cb90..6d7ad663d4 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -35,8 +35,6 @@ %define build_py26_esl 0 %define build_timerfd 0 %define build_mod_esl 0 -%define build_mod_rayo 1 -%define build_mod_ssml 1 %define build_mod_v8 0 %{?with_sang_tc:%define build_sng_tc 1 } @@ -984,17 +982,6 @@ Requires: %{name} = %{version}-%{release} %description event-radius-cdr RADIUS Logger for the FreeSWITCH open source telephony platform -%if %{build_mod_rayo} -%package event-rayo -Summary: Rayo (XMPP 3PCC) server for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description event-rayo -Rayo 3PCC for FreeSWITCH. http://rayo.org http://xmpp.org/extensions/xep-0327.html -Rayo is an XMPP protocol extension for third-party control of telephone calls. -%endif - %package event-snmp Summary: SNMP stats reporter for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1087,16 +1074,6 @@ BuildRequires: opusfile-devel >= 0.5 %description format-opusfile Mod Opusfile is a FreeSWITCH module to allow you to play Opus encoded files -%if %{build_mod_ssml} -%package format-ssml -Summary: Adds Speech Synthesis Markup Language (SSML) parser format for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description format-ssml -mod_ssml is a FreeSWITCH module that renders SSML into audio. This module requires a text-to-speech module for speech synthesis. -%endif - %package format-tone-stream Summary: Implements TGML Tone Generation for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1472,9 +1449,6 @@ EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_mongodb event_handlers/mod_format_cdr event_handlers/mod_erlang_event event_handlers/mod_event_multicast \ event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_radius_cdr \ event_handlers/mod_snmp" -%if %{build_mod_rayo} -EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo" -%endif #### BUILD ISSUES NET RESOLVED FOR RELEASE event_handlers/mod_event_zmq ###################################################################################################################### @@ -1484,9 +1458,6 @@ EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo" ###################################################################################################################### FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_opusfile formats/mod_portaudio_stream \ formats/mod_shell_stream formats/mod_shout formats/mod_sndfile formats/mod_tone_stream" -%if %{build_mod_ssml} -FORMATS_MODULES+=" formats/mod_ssml" -%endif ###################################################################################################################### # @@ -2278,11 +2249,6 @@ fi %files event-radius-cdr %{MODINSTDIR}/mod_radius_cdr.so* -%if %{build_mod_rayo} -%files event-rayo -%{MODINSTDIR}/mod_rayo.so* -%endif - %files event-snmp %{MODINSTDIR}/mod_snmp.so* @@ -2310,11 +2276,6 @@ fi %files format-mod-shout %{MODINSTDIR}/mod_shout.so* -%if %{build_mod_ssml} -%files format-ssml -%{MODINSTDIR}/mod_ssml.so* -%endif - %files format-tone-stream %{MODINSTDIR}/mod_tone_stream.so* diff --git a/libs/.gitignore b/libs/.gitignore index 87da2671c6..77e312f88b 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -58,32 +58,6 @@ opal /esl/Release/ /flite-*/ /freeradius-client-*/ -/iksemel/build/compile -/iksemel/doc/Makefile -/iksemel/doc/Makefile.in -/iksemel/include/config.h -/iksemel/include/Makefile -/iksemel/include/Makefile.in -/iksemel/include/stamp-h1 -/iksemel/Makefile -/iksemel/Makefile.in -/iksemel/src/Makefile -/iksemel/src/Makefile.in -/iksemel/test/Makefile -/iksemel/test/Makefile.in -/iksemel/test/tst-dom -/iksemel/test/tst-filter -/iksemel/test/tst-iks -/iksemel/test/tst-ikstack -/iksemel/test/tst-jid -/iksemel/test/tst-md5 -/iksemel/test/tst-sax -/iksemel/test/tst-sha -/iksemel/tools/ikslint -/iksemel/tools/iksperf -/iksemel/tools/iksroster -/iksemel/tools/Makefile -/iksemel/tools/Makefile.in /ilbc/config-h.in /ilbc/doc/Makefile /ilbc/doc/Makefile.in @@ -600,7 +574,6 @@ opal /v8-*.zip # build products we should remove -!/iksemel/ltmain.sh !/libg722_1/config/depcomp !/libg722_1/config/missing !/tiff-*/config/depcomp @@ -622,7 +595,6 @@ srtp/build/compile /portaudio/ portaudio.*.log apr/configure -iksemel/configure libyuv/Makefile libyuv/convert srtp/configure diff --git a/libs/iksemel/.update b/libs/iksemel/.update deleted file mode 100644 index a3a56a0ec9..0000000000 --- a/libs/iksemel/.update +++ /dev/null @@ -1 +0,0 @@ -Mon Jul 15 16:57:11 CDT 2013 diff --git a/libs/iksemel/AUTHORS b/libs/iksemel/AUTHORS deleted file mode 100644 index 2ba1196f3e..0000000000 --- a/libs/iksemel/AUTHORS +++ /dev/null @@ -1,17 +0,0 @@ - -Author -====== - -Gurer Ozen - - -Contributions -============= - -Bernhard R. Link (code) -Fabien Ninoles (code) -Evan Prodromou (jabberx improvements, project maintenance) -David Yitzchak Cohen (countless bug reports) -Benoit Laniel (mingw port) -Darrell Karbott (ikstransport) -Rafal Piotrowski (SASL auth) diff --git a/libs/iksemel/COPYING b/libs/iksemel/COPYING deleted file mode 100644 index c4792dd27a..0000000000 --- a/libs/iksemel/COPYING +++ /dev/null @@ -1,515 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. -^L - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. -^L - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. -^L - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. -^L - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. -^L - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. -^L - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. -^L - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS -^L - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper -mail. - -You should also get your employer (if you work as a programmer) or -your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James -Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/libs/iksemel/ChangeLog b/libs/iksemel/ChangeLog deleted file mode 100644 index 789652105f..0000000000 --- a/libs/iksemel/ChangeLog +++ /dev/null @@ -1,648 +0,0 @@ -2007-08-02 Gurer - * tst-iks.c: test for new append/prepend functions added. - -2007-08-01 Gurer - * Patch from Benjamin Bennett: - base64.c: fix padding - * sha.c: 64bit fix (long -> int) - * iks.c: new funcs: iks_append, iks_prepend - iks_append_cdata, iks_prepend_cdata - * stream.c: iks_sasl_challenge split into smaller functions - This change also fixes some possible leaks which are detected - by Coverity Inc's excellent Prevent product. - -2006-05-19 Gurer - * dom.c: fixed (size % FILE_IO_BUFFER_SIZE) problem in iks_load() - -2005-08-29 Gurer - * Patch from Jakob Schroter: - iksemel.texi: small documentation update - * Patch from Darrell Karbott: - sax.c: use fixed instead of floating point (for arm) - mark static const data properly - explicit char* uchar* casts - -2004-08-14 Gurer - * version bump to 1.3 - * patch from Roland Hedberg - io-posix.c: io_connect now tries all addrinfo values. - -2004-08-05 Gurer - * iksemel.h: ikstransport cosmetic cleanup. - * iksemel.texi: mingw notice added. - -2004-07-30 Gurer - * iksemel.h: get_fd and connect_fd is removed from ikstransport api. - ikstransport structure now has an abi_version field. - new IKS_TRANSPORT_V1 macro defined for using in abi_version. - * io-posix.c: modified for new ikstransport scheme. - * stream.c: iks_connect_fd and iks_fd now works directly. - -2004-07-30 Gurer - * sax.c: bug in parser's utf8 checker fixed. - -2004-07-28 Gurer - * stream.c: buffer size corrected in iks_send_header. - -2004-07-26 Gurer - * iksroster.c: "iksroster" resource is default, if not given by user. - * stream.c: iks_start_tls() cosmetic cleanup. - -2004-07-23 Gurer - * iks.c: ikstack value of attribute nodes wasnt set correctly. fixed. - -2004-07-21 Gurer - * patch from Benoit Laniel - configure.ac: objdump check for cross compiling - iksroster.c, perf.c, io-unix.c: WIN32 is changed to _WIN32 - -2004-07-19 Gurer - * iks.c: iks_child() verifies that node is a tag before accessing - children field in struct. - -2004-07-13 Gurer - * stream.c: if no realm is provided in sasl, server name is used - -2004-06-14 Gurer - * iksemel.texi: sasl&tls funcs documented a bit. - -2004-06-14 Gurer - * patch from Darrell Karbott - iksemel.h: async events are passed as a struct - ikstransport struct is defined as const - server_name is passed to the iksTConnectAsync - additional network error codes - stream.c: iks_recv() checks if iks_disconnect called during parsing - -2004-05-22 Gurer - * iks.c: iks_cdata() returns value for attributes - * sax.c: utf8 stack_pos fix - -2004-05-19 Gurer - * io-posix.c: now compiles without getaddrinfo() - -2004-05-05 Gurer - * sax.c: iks_parser_stack() added, returns the ikstack of an iksparser - * stream.c: ikstranport api is now passing iksparser instead of ikstack - to the connect functions. - -2004-05-05 Gurer - * stream.c: patch from Rafal Piotrowski - iks_sasl_challenge() cleanup - -2004-05-01 Gurer - * iksroster.c: sasl auth finally works. - -2004-04-30 Gurer - * iksroster.c: cleanup. - -2004-04-30 Gurer - * Another patch from Rafal Piotrowski - tst-md5.c: test code for md5.c functions, and new utils: - iks_make_resource_bind(), iks_make_session(), iks_stream_features() - * iksemel.h: iks_auth_sasl renamed to iks_start_sasl - IKS_AUTH_SASL_PLAIN renamed to IKS_SASL_PLAIN - IKS_AUTH_SASL_DIGEST_MD5 renamed to IKS_SASL_DIGEST_MD5 - -2004-04-29 Gurer - * Patch from Rafal Piotrowski applied - md5 and base64 api, and sasl auth support! - * iksroster.c: --sasl option added. - -2004-04-27 Gurer - * io-unix.c: renamed to io-posix.c, it runs on windows with mingw - so less confusion this way. - * stream.c: warnings cleaned up, iks_connect_async_with finished. - -2004-04-26 Gurer - * iksemel.h: new error code IKS_NET_TLSFAIL - * stream.c: tls code cleaned up. - * configure.ac: new option --disable-default-io - you can use it to disable compiling of io-unix.c if you dont need - it and want to use your own socket code. - -2004-04-13 Gurer - * iksemel.h: new error code IKS_NET_NOTSUPP - * stream.c: not supported error code is supported now :) - * sha.c: free() is replaced with iks_free() - -2004-04-10 Gurer - * stream.c: saga continues, tls is working on ikstransport. - * iksroster.c: --log option for turning on xml debug output. - -2004-04-10 Gurer - * stream.c: second part: - it is using iks_default_transport (provided by io-unix.c) now. - all network code is removed. - iks_connect_with() allows you to use your own transport code. - (note: testing needed and async api is not fully implemented yet) - -2004-04-10 Gurer - * iksemel.h: first part of the long expected socket abstraction. - many thanks to Darrell Karbott for ideas and a sample implementation. - * io-unix.c: new file, transport code for unix sockets. - -2004-03-22 Gurer - * dom.c: iks_load() now frees the resources if iks_parse returns error. - -2004-03-19 Gurer - * stream.c: iks_is_secure() added, checks that if a stream is secured. - * iksroster.c: cleanup a bit. - -2004-03-18 Gurer - * iksroster.c, stream.c: secure connection works, but api isn't - stablized yet, and some cleanup needed. - -2004-03-08 Gurer - * iksroster.c: new option for secure connection, needs testing. - -2004-03-01 Gurer - * sax.c: second part, IKS_NOMEM conditions are checked properly. - -2004-02-29 Gurer - * iksemel.h: stddef.h is included to get size_t for C apps. - * sax.c: first part of the memory usage optimization. - -2004-02-27 Gurer - * iksemel.h: cstddef is included for C++ apps to provide size_t type. - -2004-02-25 Gurer - * src/sha.c: iks_sha_print() uses lowercase hex numbers now. - -2004-02-10 Gurer - * src/iks.c: Tag, cdata and attribute structures have different sizes now. - Saves 8 bytes per tag, 20 bytes per cdata/attrib on 32 bit archs. - -2004-02-10 Gurer - * src/ikstack.c: iks_stack_stats is dead, long live iks_stack_stat. - * tools/iksperf.c: dom test now iks_delete()s the parsed tree - and even measures the freeing time. - -2004-02-07 Gurer - * src/ikstack.c: iks_stack_stats returns total values. - -2004-02-06 Gurer - * src/ikstack.c: new stack implementation, all callers changed too. - -2004-02-03 Gurer - * test/tst-ikstack.c: tst-ikstack-str.c moved here. - * test/tst-ikstack.c: alignment test added. - * src/ikstack.c: iks_stack_alloc() always returns aligned memory. - * src/ikstack.c: patch from Ilkka Lyytinen: - iks_stack_strecat alignment fix. - -2003-10-16 Gurer - * src/iks.c: escape_size off by one bug in iks_string() is fixed. - * src/dom.c: iks_load and iks_save uses (const char *) for filename now. - -2003-10-09 Gurer - * src/Makefile.am: --no-undefined changed to -no-undefined - * stream.c: data->current is NULLed *before* calling the hook, - so you can keep the node in memory when you are returning - an error from your hook. - * tools/perf.c: GetTickCount is used instead of gettimeofday on Windows. - -2003-10-08 Gurer - * dom.c: iks_save is not using unnecessary object stack. - * A great patch from Benoit Laniel applied. - This allows iksemel to be compiled on Windows with MinGW. - Detailed changes: - * configure.ac: check for st_blksize in stat structure (which is - missing in Windows). Check for libwsock32, the Windows socket library. - The check is only done when compiling for a MinGW host to avoid - problems when having Wine libraries. - * src/Makefile.am: add -no-undefined to libiksmel_la_LDFLAGS to enable - DLL compilation on Windows. - * src/stream.c: include winsock.h and do not include posix socket - headers on Windows. Use closesocket instead of close on Windows. - Check socket errors with '== -1' instead of '< 0'. - * tools/ikslint.c: conditional use of st_blksize. - * tools/iksroster.c: add Winsock initialization and cleanup code - (needed to use sockets on Windows). - -2003-10-05 Gurer - * utility.c: iks_set_mem_funcs() added. - * iksperf.c: --memdbg option added. - * tools/perf.c: mallinfo stuff removed. - -2003-09-15 Gurer - * version bump to 1.2 - * stream.c: iks_start_tls() added with the help of gnutls library. - -2003-09-11 Gurer - * stream.c: iks_connect_via() added. it can send a different name to the - connected server. useful for connecting the server via a ssh tunnel. - suggestion and patch by Wolf Bergenheim. - -2003-09-09 Gurer - * stream.c: network buffer is allocated inside the stack at the first - connect call, and not free()d with reset. - -2003-09-08 Gurer - * sax.c: iks_parser_reset() no longer free()s allocated buffers. - it also calls the delete hook of the extending parser. - * dom.c: reset zeroes internal state. - * stream.c: resetting the parser is now equal to iks_disconnect () - -2003-09-07 Gurer - * sax.c: malloc()s changed with iks_malloc() - attr buffer is not freed after each tag. minor speedup. - -2003-09-05 Gurer - * ikslint.c: tag histogram is per file now instead of global. - -2003-09-04 Gurer - * iksemel.texi: resource links moved to here from HACKING. - * utility.c: iks_malloc(), iks_free() wrappers added. - all malloc() and free() calls are changed with them. - -2003-09-03 Gurer - * ikslint.c: can display tag usage histogram now. - -2003-09-03 Gurer - * ikslint.c: benchmark options removed. reading from stdin supported. - reports tag mismatchs. - * dom.c: iks_tree() added. converts a string into a tree. - * iksemel.texi: iks_tree, iks_set_size_hint, iks_copy documented. - -2003-09-03 Gurer - * iks.c: iks_string() now malloc()s memory if no stack is given. - it also runs *very* fast now. - -2003-09-02 Gurer - * iksperf.c: errors are redirected to stderr again. - tree serialization test added. - -2003-08-31 Gurer - * dom.c: default chunk size is increased. iks_set_size_hint() - function added. you can give an approximate size for the - file, and a better chunk size is selected for memory allocations. - greatly speeds up dom parser. - * iksperf.c: dom test uses iks_set_size_hint(). small fixes. - * iksperf.c: sha1 test. - -2003-08-31 Gurer - * tools/iksperf.c: new tool for speed/memory usage testing. - * iksemel.texi: a new chapter about iksemel development added. - -2003-08-23 Gurer - * doc/iksemel.texi: document license changed to GPL from GNU Free - Documentation License. - * ikstack.c: iks_stack_strecat() added. - * iks.c: iks_insert_cdata() modified to use iks_stack_strecat(). - this greatly reduces memory usage when data is parsed in very small - chunks or cdata sections contains lots of escaped characters. - -2003-07-29 Gurer - * iksemel.h: iks_connect_tcp(), iks_send_stream() and - iks_send_raw() now take const arguments. - * iks.c: iks_root() added. - * iks.c: iks_string() works on cdata nodes. - -2003-07-20 Gurer - * iks.c: iks_copy() bug is fixed. - -2003-07-15 Gurer - * dom.c: whitespace outside of markup won't added to the tree. - * stream.c: iks_connect_fd correctly sets SF_FOREIGN flag. - * src/Makefile.am: libtool revision bump, forgot that while doing 1.1 bump. - * iks.c: new iks_copy() and iks_copy_within() functions. - -2003-06-29 Gurer - * 1.0 release! - * version bump to 1.1 - -2003-06-26 Gurer - * ikstack.c: reallocation bug in iks_stack_strcat() fixed. - * ikstack.c: iks_stack_strcat() and iks_stack_strcatv() now returns - a non-zero value if there isn't enough memory. - * iks.c: new functions: iks_next_tag(), iks_prev_tag(), iks_first_tag(). - * iks.c: new function: iks_find_with_attrib(). - -2003-06-19 Gurer - * stream.c: new function iks_connect_fd (). - * stream.c: iks_send_header () is modified. - -2003-06-17 Gurer - * sax.c: tags without attributes which contain whitespace before '>' - parsed correctly. - -2003-06-16 Gurer - * stream.c: node isn't deleted automatically after hook anymore. - * iksroster.c: upload is working. - -2003-06-15 Gurer - * tools/iksroster.c: new goodie. backups your jabber roster. - * iks.c: iks_insert_attrib() can be used for modifying and deleting attributes. - * stream.c: return value of the stream hook is actually used. - -2003-06-13 Gurer - * iksemel.texi: more text. - * iksemel.h: iksFilterHook now returns 'int' instead of 'enum iksfilterret'. - -2003-06-12 Gurer - * iksemel.h: iksStreamHook's return type is changed 'enum ikserror' to int. - type is changed 'enum iksnodetype' to int. - * iksemel.texi: more text. - -2003-06-09 Gurer - * doc/iksemel.texi: restructured. - * iksemel.h: 'enum ikstagtype' type is changed to 'int' in iksTagHook. - 'enum ikserror' changed to 'int' in iksTagHook, iksCDataHook, iks_parse(). - 'enum iksfileerror' changed to 'int' in iks_load() and iks_save(). - 'enum iksneterror' changed to 'int' in stream.c functions. - common error values removed from iksfileerror and iksneterror. - * dom.c: iks_load() checks the return value of iks_parse() now. - -2003-06-02 Gurer - * filter.c: rules now has priority: - id > from = from_partial > ns > subtype > type - -2003-05-29 Gurer - * jabber.c: fixes and API cleanup: - iks_id_new() now sets id->partial field. - pak->to field removed. - 'to' argument added to iks_make_s10n() - 'type' and 'to' arguments removed from iks_make_pres() - const keyword added to prototypes. - * filter.c: TO rule removed, FROM_PARTIAL rule added. - -2003-05-26 Gurer - * sax.c: new function iks_nr_lines(), returns how much lines parsed. - * ikslint.c: document's line number is displayed in errors. some cleanup. - -2003-05-26 Gurer - * sax.c: a bug in C_TAG context is found and fixed. - -2003-05-24 Gurer - * sax.c: saga continues: - UTF8 validity checks added. You can't feed famous 0xC0 0x80 anymore. - sections are recognized. - * tst-sax.c: related tests added as usual. - -2003-05-23 Gurer - * tools/ikslint.c: new goodie, checks xml files for well-formedness. - * sax.c: Attribute values can contain ' or " if they are quoted within - the other quote character. - -2003-05-23 Gurer - * tst-sax.c: framework and tests for badly formed xml. - * sax.c: more cleanup, and well-formedness checks: - iks_parse() argument for xml data is now const char*. - 0xFF, 0xFE and 0x00 bytes are invalid utf8. - Close tags have no attributes. - Single tags must end with '/>'. - -2003-05-22 Gurer - * sax.c: some cleanup. - * sax.c: iks_get_udata() renamed to iks_user_data() - * sax.c: new function iks_nr_bytes(), returns how much bytes parsed. - * tst-sax.c, tst-dom.c: uses iks_nr_bytes() when reporting bugs. - -2003-05-22 Gurer - * iks.c: iks_string() was printing siblings of the toplevel tag. fixed. - thanks David Yitzchak Cohen for reporting. - * HACKING: URLs of related standart documents added. - * tst-filter.c: new framework. - * tst-dom.c: new framework and tests. - -2003-05-20 Gurer - * sax.c: '>' is valid and '--' is invalid inside the comments. - -2003-05-17 Gurer - * HACKING: explanation of iksemel's design goals added. - * sax.c: parser now ignores PIs, markup and comments. - * dom.c, stream.c: PI checks removed. - -2003-05-16 Gurer - * sax.c: several fixes. - * tst-sax.c: attribute checks and more tests. - -2003-05-16 Gurer - * tst-sax.c: improved framework and more tests. - * finetune.h: DEFAULT_DOM_CHUNK_SIZE, DEFAULT_STREAM_CHUNK_SIZE - * stream.c, dom.c: now uses chunk size values from finetune.h - -2003-05-07 Gurer - * complete redesign here. - -2002-01-16 Evan Prodromou - * test/testiks.c: removed buggy unit test for previous entry, - since I couldn't figure out why it segfaulted. Will investigate - and fix later. - -2002-01-07 Evan Prodromou - * core.c: fixed off-by-one bug with reallocation of attributes. - * test/testiks.c: added test for above bug. - -2002-12-20 Evan Prodromou - * COPYING: New version of the LGPL. - * INSTALL: New FSF install info. Both of these were updated by autoreconf. - -2002-12-12 Evan Prodromou - * include/iksemel.h: added id to Jabber packets. - * src/jabber.c: get ID in Jabber packets. - -2002-12-9 Evan Prodromou - * doc/ROADMAP: added this file. - -2002-11-28 Evan Prodromou - * io.c: broke out stream initialization to its own function, in - anticipation of supporting other kinds of streams. - * iksemel.h: added new stream function. - -2002-11-15 Evan Prodromou - * configure.in: added check to see if you want to build with dmalloc. - * parser.c: make Jabber parsers use pool memory. Also, make Jabber - parser delete packets after posting them to callback function. - * convert.c: made converter used pool memory. - * iks.c: fixed iks constructor/destructor so they mark pool owner - and only delete the pool if the iks is the owner. - * sha.c: changed sha objects to use pool memory. - -2002-11-07 Evan Prodromou - - * ikspool.c: added ALIGN_ON, ALIGNED(), *_OFFSET macros. - Try to make sure that all pointer math is done with - aligned (val % ALIGN_ON == 0) values. - Fixed bug in _realloc() where incoming size wasn't - checked for alignment, size. - * testpool.c: added tests for absurdly small values - of page size, alloc size, realloc size. - -2002-11-06 Evan Prodromou - - * iksemel.h: added IKS_NS_XROSTER, for jabber:x:roster NS. - -2002-11-06 Evan Prodromou - - * core.c: changed iks_parse to use realloc instead of - malloc, copy, free. - -2002-11-04 Evan Prodromou - - * ikspool.c: For iks_pool_realloc, made it call _alloc if the - passed-in pointer is NULL. This is the way realloc() works. - * testpool.c: added a test for the above condition. - -2002-11-04 Evan Prodromou - - * ikspool.c: Added some comments. - -2002-11-03 Evan Prodromou - - * iksid.c: changed contract for iks_id_new, iks_id_set: const char * - instead of char *. - * iksemel.h: changed prototypes for iks_id_new, iks_id_set. - -2002-11-03 Evan Prodromou - - * iksid.c: fixed bug in iks_id_set causing segfault if field was - previously NULL. - * testid.c: added tests to check for above bug. - * test/.cvsignore: Ignore testpool and testid. - -2002-11-03 Evan Prodromou - - * iksid.c: fixed bug in iks_id_new with partial (no resource) IDs. - * testid.c: added tests to check for above bug. - -2002-11-03 Evan Prodromou - - * iksid.c: moved iksid functions to this file from jabber.c. - added new function, iks_id_delete, to delete an iksid. - implemented iks_id_set. - made iks_id_new use iks_pool_set_owner if it creates a pool. - changed iks_id_new so it doesn't write on src. - * iksemel.h: added prototype for iks_id_delete. - * testid.c: created basic unit tests for iksid. - -2002-11-02 Evan Prodromou - - * Added the beginnings of unit tests for memory allocation. - More needed. - -2002-11-02 Evan Prodromou - - * ikspool.c: added new best-fit memory allocation functions. - * utility.c: removed old memory-allocation functions. - * iksemel.h: added new memory allocation functions: - iks_pool_owner - iks_pool_set_owner - iks_pool_realloc - iks_pool_calloc - iks_pool_free - redefined ikspool structure for hiding. - -2001-06-08 Gurer - - * core.c: xml unescaping. - -2001-06-07 Gurer - - * convert.c: small bugfix in iks_conv_new() - -2001-05-25 Gurer - - * configure.in: now checks gcc before adding -Wall to CFLAGS - * io.c: iks_recv() and iks_load() fixes. - -2001-05-24 Gurer - - * configure.in: more checks. - * include/common.h: deals with including right files depending on - configure checks, source files include this. - -2001-05-22 Gurer - - * jabber.c: iks_id_printx() added - new packet type IKS_PAK_ERROR for - * sha.c: iks_sha_delete() added - * configure.in, parser.c: optional expat support - -2001-05-21 Gurer - - * parser.c: restructured. now parsers are allocated via iks_sax_new - * core.c: actual parser is moved to here - * convert.c: charset conversion stuff moved to here - * utility.c: alignment bug of iks_pool_alloc fixed - -2001-04-10 Gurer - - * utility.c: charset convertion functions now use a static buffer and - require string length argument - -2001-03-19 Gurer - - * utility.c: iks_conv_from/to renamed to iks_conv_utf8/locale - iconv fixes - -2001-03-17 Gurer - - * utility.c: iks_conv_from/to() fixes - * doc/: a bit more documentation - -2001-03-15 Gurer - - * jabber.c: iks_packet() uses the namespace of first child in IQ packets - instead of looking for a tag. - * utility.c: iks_conv_ functions for utf8<->locale convertions - -2001-03-13 Fabien Ninoles - - * autogen.sh: Well, autoconf are better run into the src directory, indeed. - * configure.in: Add iconv check, ripped from gabber. - * src/Makefile.am: Oops! include dir is in srcdir! - -2001-03-12 Gurer - - * doc/ : new files, basic structure for documentation - -2001-03-09 Fabien Ninoles - - * utility.c: Correction to the unescape routine... which do some - mess around with indexes. - * parser.c: Unescape CDATA et attrib value before inserting them. - * autogen.sh: Enable running it from a build directory. - -2000-03-07 Gurer - - * iks.c: iks_string() now works correctly with a NULL ikspool argument - * io.c: return code check of fputs in iks_save() is corrected - * doc: new directory - * doc/main.texi: started documenting the library API in Texinfo format - -2000-03-05 Gurer - - * iksemel.h: IKS_NS_ macros synced with latest jabber server - * parser.c: attribute buffer grow bug fixed - * iks.c: iks_hide() implemented - -2000-02-01 Gurer - - * parser.c: attribute pointers bug fixed - * testiks.c: new test for parser - -2000-01-30 Gurer - - * configure.in, makefile.am, test/makefile.am: make check target works now - * testiks.c: new tests for string and xml node functions - -2000-01-28 Gurer - - * test: new directory - * test/testiks.c: a simple program for self testing - * makefile.am, src/makefile.am: fixes for make dist - -2000-01-25 Gurer - - * sha.c: sha1 implementation - * jabber.c: iks_make_auth() now supports digest auth - -2000-01-16 Gurer - - * io.c: iks_load() implemented - -2000-12-20 Gurer - - * initial commit. diff --git a/libs/iksemel/HACKING b/libs/iksemel/HACKING deleted file mode 100644 index 5cd46d5d3a..0000000000 --- a/libs/iksemel/HACKING +++ /dev/null @@ -1,71 +0,0 @@ - -License: -======== - -iksemel is developed and released under GNU Lesser General Public License. -A copy of the license can be found in the file COPYING. You should read it -before sending patches to the iksemel, since it is implicitly assumed that -your patches are also submitted under the LGPL license. - - -Roadmap: -======== - -Main goal of the iksemel is removing complexity from programs using the -library and the library itself. This is the reason why only a subset of XML -is supported. Some things like UTF16, entity definitons, DTDs will be eventually -implemented when we found ways to implement them without adding -too much complexity to the iksemel code. Somewhat external standarts -(XPath, XQuery, XSLT, vs) will probably not make it into the iksemel. - -* validation - -I think easiest way to add this feature is writing another parser based on the -sax parser which parses a dtd (either from sax parser's markup callback which -needs to be implemented or from an external source via iks_vsax_set_dtd() call) -and checks the arguments of sax callbacks. Using it via dom or stream parsers -can require some clever tricks. there are also xml schemas. they are easy to parse -(it is xml anyway) but can be hard to apply. - -* utf16 - -There are two sides of this. Improving parser to accept utf16 can be relatively -easy. But on the client side things can get confusing. What will be the default -character set used by iks_new(), iks_insert_cdata() and similar functions? and -how they will allow other charsets to be used. Supporting more than utf8 and -utf16 is more difficult. Hopefully there is no immediate need for this. Jabber -uses only utf8 and you can use iconv if you are using another charset in your -application. Btw, there is also byte order issue which is silly. Inventor of BOM -crap must be killed. - -* jabber roster - -Roster handling generally depends on the UI system used. But I think a generic -roster handler which parses roster result, pushes, presence changes and -allows application to access and display this data can be useful. Challenge -here is making it UI independent and extensible by the application. - - -File Layout: -============ - -doc/ -* iksemel.texi Documentation in texinfo format. -include/ -* common.h Internal header for some common definitions. -* iksemel.h Library API -* finetune.h Default memory allocation sizes. -src/ -* ikstack.c Memory management functions. -* utility.c Small string utility functions. -* iks.c XML tree management. -* sax.c SAX parser. -* dom.c DOM parser. -* stream.c Stream parser. -* sha.c SHA1 hash functions. -* jabber.c Jabber utilities. -* filter.c Packet filter for Jabber. -test/ -(self test programs) -tools/ -(varius utility programs) diff --git a/libs/iksemel/INSTALL b/libs/iksemel/INSTALL deleted file mode 100644 index 7d1c323bea..0000000000 --- a/libs/iksemel/INSTALL +++ /dev/null @@ -1,365 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/libs/iksemel/Makefile.am b/libs/iksemel/Makefile.am deleted file mode 100644 index 8ba57fec42..0000000000 --- a/libs/iksemel/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -## -## Process this file with automake to produce Makefile.in -## - -SUBDIRS = include src tools test doc - -EXTRA_DIST = HACKING iksemel.pc.in - -pkgconfigdir=$(libdir)/pkgconfig -pkgconfig_DATA = iksemel.pc - -snapshot: - $(MAKE) dist distdir=$(PACKAGE)-`date +"%y%m%d"` - mv $(PACKAGE)-`date +"%y%m%d"`.tar.gz ../ - -ikslite: - cp include/iksemel.h ../ - cat include/finetune.h src/utility.c src/ikstack.c src/sax.c src/iks.c src/dom.c >../iksemel.c diff --git a/libs/iksemel/NEWS b/libs/iksemel/NEWS deleted file mode 100644 index 87d60a3a57..0000000000 --- a/libs/iksemel/NEWS +++ /dev/null @@ -1,53 +0,0 @@ -V1.3 (2007-08-02) -* Project is moved to - http://code.google.com/p/iksemel/ - there is also a new mailing list at: - http://groups.google.com/group/iksemel - Please use those instead of old jabberstudio.org addresses. -* iksemel is now participating in Coverity Inc's free software - quality improvement program (http://scan.coverity.com). As a - first result, a few problems found by Coverity's static analysis - tool in the iks_sasl_challenge() are fixed in this release, and - other than that, iksemel passes from defect test with no problems. -* Extra padding problem in the base64 encoder is fixed. Some servers - were having problems with extra '=' padded SASL digests. -* New dom functions: iks_append(), iks_prepend(), iks_append_cdata(), - iks_prepend_cdata(). You can append/prepend new nodes within the - siblings with them, insert_ functions were only appending at the - last child. Thus editing a tree is much easier now. -* iks_load was giving error on files with multiply of 4Kb sizes, fixed. - -V1.2 (2004-08-06) -* SASL authentication. -* SSH connections via gnutls library. -* Socket code abstracted, you can even provide your own transport functions. -* Compiles on Windows with MinGW. -* iks_sha_print() uses lowercase hex numbers to comply with latest jabber. -* New stack implementation, much faster and uses less memory. - Unfortunately API has changed a bit: - iks_stack_strcat, strcatv, print functions removed. - iks_stack_stats modified. - iks_stack_strecat renamed to iks_stack_strcat. - iks_stack_new takes two chunk sizes, one for structures one for strings. - iks_stack_strdup returns (char *). - -V1.1 (2003-09-11) -* Minor sax parser speed up. -* iks_string() and dom parser performance is improved greatly. -* iksperf: new tool for measuring iksemel performance. -* ikslint: better error checking. supports stdin. can display tag usage histogram. -* New dom functions: iks_copy(), iks_copy_within(), iks_root(), iks_tree(). -* License of the documentation changed to GPL from GNU FDL. - -V1.0 (2003-06-29) -* API redesigned. -* iconv interface removed. -* ikslint and iksroster tools. -* Jabber packet filter. -* IPv6 support. -* iks_find_with_attrib, iks_next_tag, iks_prev_tag, iks_first_tag functions. -* Parser improvements (CDATA sections, comments, UTF8 validity checks) -* Memory pools are replaced with object stacks. - -V0.1 (2002-10-30) -* First release. diff --git a/libs/iksemel/README b/libs/iksemel/README deleted file mode 100644 index 306c5596eb..0000000000 --- a/libs/iksemel/README +++ /dev/null @@ -1,45 +0,0 @@ - - iksemel 1.3 - -Copyright (c) 2000-2004 Gurer Ozen - - -Introduction: -------------- - -This is an XML parser library mainly designed for Jabber applications. -It provides SAX, DOM, and special Jabber stream APIs. Library is coded -in ANSI C except the network code (which is POSIX compatible), thus -highly portable. Iksemel is released under GNU Lesser General Public -License. A copy of the license is included in the COPYING file. - - -Requirements: -------------- - -Libtool, Automake and Autoconf packages are required for compiling cvs -versions. - - -Compiling & Install: --------------------- - -If you got the source from CVS, type - - ./autogen.sh - -for creating configuration script and files. - -Then type - - ./configure - make - -now library is compiled. You can test it with - - make check - -and install it with - - (become root if necessary) - make install diff --git a/libs/iksemel/TODO b/libs/iksemel/TODO deleted file mode 100644 index d20bebbba3..0000000000 --- a/libs/iksemel/TODO +++ /dev/null @@ -1,12 +0,0 @@ - -This file contains a simple list of TODO items. -More general ideas can be found in the roadmap part of the file HACKING. - -(in order of importance) - -* parser: Ӓ and ꉟ like entities must be unescaped. -* packet filter or a generic xml filter? something like a simplified xpath? -* a separate utf8 validator function can be useful -* utf8 <-> utf16 conversion functions can be useful - -anything else? :-) diff --git a/libs/iksemel/acinclude.m4 b/libs/iksemel/acinclude.m4 deleted file mode 100644 index 72e6d438a8..0000000000 --- a/libs/iksemel/acinclude.m4 +++ /dev/null @@ -1,59 +0,0 @@ - - -dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) -dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page -dnl also defines GSTUFF_PKG_ERRORS on error -AC_DEFUN([PKG_CHECK_MODULES], [ - succeeded=no - - if test -z "$PKG_CONFIG"; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - fi - - if test "$PKG_CONFIG" = "no" ; then - echo "*** The pkg-config script could not be found. Make sure it is" - echo "*** in your path, or set the PKG_CONFIG environment variable" - echo "*** to the full path to pkg-config." - echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." - else - PKG_CONFIG_MIN_VERSION=0.9.0 - if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then - AC_MSG_CHECKING(for $2) - - if $PKG_CONFIG --exists "$2" ; then - AC_MSG_RESULT(yes) - succeeded=yes - - AC_MSG_CHECKING($1_CFLAGS) - $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` - AC_MSG_RESULT($$1_CFLAGS) - - AC_MSG_CHECKING($1_LIBS) - $1_LIBS=`$PKG_CONFIG --libs "$2"` - AC_MSG_RESULT($$1_LIBS) - else - $1_CFLAGS="" - $1_LIBS="" - ## If we have a custom action on failure, don't print errors, but - ## do set a variable so people can do so. - $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - ifelse([$4], ,echo $$1_PKG_ERRORS,) - fi - - AC_SUBST($1_CFLAGS) - AC_SUBST($1_LIBS) - else - echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." - echo "*** See http://www.freedesktop.org/software/pkgconfig" - fi - fi - - if test $succeeded = yes; then - ifelse([$3], , :, [$3]) - else - ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) - fi -]) - - - diff --git a/libs/iksemel/acsite.m4 b/libs/iksemel/acsite.m4 deleted file mode 100644 index 593df04be8..0000000000 --- a/libs/iksemel/acsite.m4 +++ /dev/null @@ -1,2 +0,0 @@ -m4_include([build/libgnutls.m4]) - diff --git a/libs/iksemel/build/libgnutls.m4 b/libs/iksemel/build/libgnutls.m4 deleted file mode 100644 index cf3fe4641a..0000000000 --- a/libs/iksemel/build/libgnutls.m4 +++ /dev/null @@ -1,168 +0,0 @@ -dnl Autoconf macros for libgnutls -dnl $id$ - -# Modified for LIBGNUTLS -- nmav -# Configure paths for LIBGCRYPT -# Shamelessly stolen from the one of XDELTA by Owen Taylor -# Werner Koch 99-12-09 - -dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS -dnl -AC_DEFUN([AX_PATH_LIBGNUTLS], -[dnl -dnl Get the cflags and libraries from the libgnutls-config script -dnl -AC_ARG_WITH(libgnutls-prefix, - [ --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)], - libgnutls_config_prefix="$withval", libgnutls_config_prefix="") - - if test x$libgnutls_config_prefix != x ; then - if test x${LIBGNUTLS_CONFIG+set} != xset ; then - LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config - fi - fi - - AC_PATH_PROG(LIBGNUTLS_CONFIG, libgnutls-config, no) - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - no_libgnutls="" - if test "$LIBGNUTLS_CONFIG" != "no"; then - LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags` - LIBGNUTLS_LIBS="`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs` -lpthread -lgcrypt" - libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version` - elif test "$PKG_CONFIG" != "no"; then - LIBGNUTLS_CFLAGS=`$PKG_CONFIG --cflags gnutls` - LIBGNUTLS_LIBS="`$PKG_CONFIG --libs gnutls` -lpthread -lgcrypt" - libgnutls_config_version=`$PKG_CONFIG --modversion gnutls` - else - no_libgnutls=yes - fi - - min_libgnutls_version=ifelse([$1], ,0.1.0,$1) - AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version) - - if test x"$no_libgnutls" = x""; then - - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" - LIBS="$LIBS $LIBGNUTLS_LIBS" -dnl -dnl Now check if the installed libgnutls is sufficiently new. Also sanity -dnl checks the results of libgnutls-config to some extent -dnl - rm -f conf.libgnutlstest - AC_TRY_RUN([ -#include -#include -#include -#include - -int -main () -{ - system ("touch conf.libgnutlstest"); - - if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) ) - { - printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n", - "$libgnutls_config_version", gnutls_check_version(NULL) ); - printf("*** was found! If libgnutls-config was correct, then it is best\n"); - printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n"); - printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); - printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); - printf("*** required on your system.\n"); - printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n"); - printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n"); - printf("*** before re-running configure\n"); - } - else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) ) - { - printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION); - printf("*** library (version %s)\n", gnutls_check_version(NULL) ); - } - else - { - if ( gnutls_check_version( "$min_libgnutls_version" ) ) - { - return 0; - } - else - { - printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n", - gnutls_check_version(NULL) ); - printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n", - "$min_libgnutls_version" ); - printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n"); - printf("*** \n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); - printf("*** being found. The easiest way to fix this is to remove the old version\n"); - printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n"); - printf("*** correct copy of libgnutls-config. (In this case, you will have to\n"); - printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); - printf("*** so that the correct libraries are found at run-time))\n"); - } - } - return 1; -} -],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - - if test "x$no_libgnutls" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - if test -f conf.libgnutlstest ; then - : - else - AC_MSG_RESULT(no) - fi - if test "$LIBGNUTLS_CONFIG" = "no" ; then - echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found" - echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the" - echo "*** full path to libgnutls-config." - else - if test -f conf.libgnutlstest ; then - : - else - echo "*** Could not run libgnutls test program, checking why..." - CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" - LIBS="$LIBS $LIBGNUTLS_LIBS" - AC_TRY_LINK([ -#include -#include -#include -#include -], [ return !!gnutls_check_version(NULL); ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong" - echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" - echo "***" ], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed" - echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you" - echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - LIBGNUTLS_CFLAGS="" - LIBGNUTLS_LIBS="" - ifelse([$3], , :, [$3]) - fi - rm -f conf.libgnutlstest - AC_SUBST(LIBGNUTLS_CFLAGS) - AC_SUBST(LIBGNUTLS_LIBS) -]) - -dnl *-*wedit:notab*-* Please keep this as the last line. diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac deleted file mode 100644 index d8a7970f82..0000000000 --- a/libs/iksemel/configure.ac +++ /dev/null @@ -1,111 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(iksemel,1.3) -AC_PREREQ(2.50) -AC_CONFIG_AUX_DIR(build) -AC_CONFIG_SRCDIR([configure.ac]) -AM_INIT_AUTOMAKE -AC_CONFIG_HEADERS(include/config.h) - -CFLAGS="$CFLAGS $CONFIGURE_CFLAGS" -CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS" -LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS" - -AC_CANONICAL_HOST - -dnl Checks for programs -AC_PROG_CC -AC_PROG_INSTALL -AC_CHECK_TOOL(OBJDUMP, objdump, :) -AM_PROG_LIBTOOL -AC_LANG_C - -dnl Checks for header files -AC_HEADER_STDC -AC_CHECK_HEADERS(unistd.h strings.h errno.h) - -dnl Checks for typedefs and structures -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_CHECK_MEMBERS([struct stat.st_blksize]) - -dnl Special check for windows -case "$host_os" in - *mingw*) - AC_CHECK_LIB(wsock32, main, , AC_MSG_ERROR(Winsock is needed for a Win32 build.)) - ;; -esac - -dnl Check for posix io -AC_ARG_ENABLE(default-io, -[ --disable-default-io disable builtin socket transport code ], - defio=$enableval, defio=yes) -if test "$defio" = yes; then - AC_DEFINE(USE_DEFAULT_IO,1,[Define this is you want default transport]) -fi -AM_CONDITIONAL(DO_POSIX, test "x$defio" = "xyes") - -dnl Checks for library functions -AC_SEARCH_LIBS(recv,socket) -AC_CHECK_FUNCS(getopt_long) -AC_CHECK_FUNCS(getaddrinfo) - -#AX_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls")) - -m4_include([openssl.m4]) -SAC_OPENSSL - -dnl Check -Wall flag of GCC -if test "x$GCC" = "xyes"; then - if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then - CFLAGS="$CFLAGS -Wall" - fi -fi - -AC_DEFUN([AX_COMPILER_VENDOR], -[ -AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, - [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown - # note: don't check for gcc first since some other compilers define __GNUC__ - for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do - vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ -#if !($vencpp) - thisisanerror; -#endif -])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break]) - done - ]) -]) - -AX_COMPILER_VENDOR - -# Enable 64 bit build -AC_ARG_ENABLE(64, -[AC_HELP_STRING([--enable-64],[build with 64 bit support])],[enable_64="$enable_64"],[enable_64="no"]) - -if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then - if test "${enable_64}" = "yes"; then - CFLAGS="$CFLAGS -mt -m64 -lgpg-error" - CXXFLAGS="$CXXFLAGS -mt -m64 -lgpg-error" - SUNFLAGS="-xc99=all -mt -m64 -lgpg-error" - else - CFLAGS="$CFLAGS -mt -lgpg-error" - CXXFLAGS="$CXXFLAGS -mt -lgpg-error" - SUNFLAGS="-xc99=all -mt -lgpg-error" - fi -fi - -AC_SUBST(SUNCFLAGS) - -dnl Generating makefiles -AC_CONFIG_FILES([ -Makefile -iksemel.pc -src/Makefile -include/Makefile -tools/Makefile -test/Makefile -doc/Makefile -]) -AC_OUTPUT diff --git a/libs/iksemel/configure.gnu b/libs/iksemel/configure.gnu deleted file mode 100644 index c78238de46..0000000000 --- a/libs/iksemel/configure.gnu +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh -srcpath=$(dirname $0 2>/dev/null ) || srcpath="." -$srcpath/configure "$@" --disable-shared --with-pic - diff --git a/libs/iksemel/doc/Makefile.am b/libs/iksemel/doc/Makefile.am deleted file mode 100644 index e7701d3387..0000000000 --- a/libs/iksemel/doc/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -## -## Process this file with automake to produce Makefile.in -## - -#info_TEXINFOS = iksemel.texi diff --git a/libs/iksemel/doc/iksemel.texi b/libs/iksemel/doc/iksemel.texi deleted file mode 100644 index fd683e2685..0000000000 --- a/libs/iksemel/doc/iksemel.texi +++ /dev/null @@ -1,1534 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename iksemel -@setcontentsaftertitlepage -@settitle Iksemel Programmers Manual -@set VERSION 1.2 -@c %**end of header - -@titlepage -@title iksemel programmers manual -@subtitle A tutorial and API reference for the iksemel library @value{VERSION} -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 2001-2003 G@"urer @"Ozen - -This is a free document; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2, or -(at your option) any later version.You may obtain a copy of the -GNU General Public License from the Free Software Foundation -by visiting their Web site or by writing to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA. - -@end titlepage - -@ifinfo -@node Top, , , (dir) -@top iksemel Programmers Manual - -Copyright @copyright{} 2001-2003 G@"urer @"Ozen - -This is a free document; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2, or -(at your option) any later version.You may obtain a copy of the -GNU General Public License from the Free Software Foundation -by visiting their Web site or by writing to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA. - -@menu -* Introduction:: - -* Tutorials:: - -* Development:: - -* Datatype Index:: - -* Function Index:: -@end menu -@end ifinfo - -@node Introduction, Tutorials, ,Top -@chapter Introduction - -iksemel is an XML (eXtensible Markup Language) parser library -designed for Jabber applications. It is coded in ANSI C for POSIX -compatible environments, thus highly portable. It is free software -released under the GNU Lesser General Public License. - -The purprose of this manual is to tell you how to use the facilities -of the iksemel library. Manual is written with the assumption that you -are familiar with the C programming language, basic programming -concepts, XML and Jabber protocol. - -@section Compiling the Library - -You need to install MinGW (@url{http://mingw.org}) under Windows to be able -to compile iksemel. Although not tested by the author, Cygwin should -work equally well. - -Library can be built with: - -@example -./configure -make -@end example - -If you want to make a self test: - -@example -make test -@end example - -Now you can install it with: - -@example -make install -@end example - - -@section Using iksemel in Applications - -You need to include @file{iksemel.h} file in your source to access library API. -You can do this with: - -@code{#include "iksemel.h"} - -Now you can use iksemel functions and compile your source. In able to link -your compiled object files and generate your executable program, you have to -link with iksemel library. This can be done with: - -@example -gcc -o myprg src1.o src2.o src3.o -liksemel -@end example - -iksemel registers itself with pkg-config while installing, so if you are using -autotools in your program, you can simply check the availability of iksemel -and configure your build process accordingly with: - -@example -PKG_CHECK_MODULES(IKSEMEL,iksemel,,exit) -@end example - -This would result in IKSEMEL_LIBS and IKSEMEL_CFLAGS substitution variables -set to correct values. - -@node Tutorials,Development,Introduction,Top -@chapter Tutorials - -@ifinfo -@menu -* Parsing an XML Document:: - -* Working with XML Trees:: - -* XML Streams:: - -* Writing a Jabber Client:: - -* Utility Functions:: -@end menu -@end ifinfo - - -@comment ============================================================ -@node Parsing an XML Document,Working with XML Trees,,Tutorials -@section Parsing an XML Document - -iksemel parser sequentally processes the XML document. Each encountered XML -element (i.e. tags, character data, comments, processing instructions, etc.) -is reported to your application by calling the hook functions you have provided. -This type of interface is called SAX (serial access) interface. - -@tindex iksparser -Parser stores its state in a small structure. This structure is referenced by -@code{iksparser} type, and managed with following functions: - -@deftypefun iksparser* iks_sax_new (void* @var{user_data}, iksTagHook* @var{tagHook}, iksCDataHook* @var{cdataHook}); -This function allocates and initializes a parser structure. If allocation fails, -NULL value is returned. @var{user_data} is passed directly to hook functions. -@end deftypefun - -@deftp Typedef iksTagHook -int iksTagHook (void* @var{user_data}, char* @var{name}, char** @var{atts}, int @var{type}); - -This function is called when a tag parsed. @var{name} is the name of the tag. If tag has -no attributes @var{atts} is NULL, otherwise it contains a null terminated list of -pointers to tag's attributes and their values. If return value isn't @code{IKS_OK}, -it is passed immediately to the caller of the @code{iks_parse}. - -@var{type} is one of the following: -@table @code -@item IKS_OPEN -Opening tag, i.e. -@item IKS_CLOSE -Closing tag, i.e. -@item IKS_SINGLE -Standalone tag, i.e. -@end table -@end deftp - -@deftp Typedef iksCDataHook -int iksCDataHook (void* @var{user_data}, char* @var{data}, size_t @var{len}); - -@var{data} is a pointer to the character data. Encoding is UTF-8 and it isn't terminated -with a null character. Size of the data is given with @var{len} in bytes. This function -can be called several times with smaller sized data for a single string. If -return value isn't @code{IKS_OK}, it is passed immediately to the caller of the -@code{iks_parse}. -@end deftp - -@deftypefun int iks_parse (iksparser* @var{prs}, char *@var{data}, size_t @var{len}, int @var{finish}); -You give XML document to the parser with this function. @var{data} -is a @var{len} bytes string. If @var{len} is zero, data must be a null -terminated string. - -If @var{finish} value is zero, parser waits for more data later. If you -want to finish parsing without giving data, call it like: -@example -iks_parse (my_parser, NULL, 0, 1); -@end example - -You should check the return value for following conditions: -@table @code -@item IKS_OK -There isn't any problem. -@item IKS_NOMEM -Not enough memory. -@item IKS_BADXML -Document is not well-formed. -@item IKS_HOOK -Your hook decided that there is an error. -@end table -@end deftypefun - -@deftypefun void iks_parser_delete (iksparser* @var{prs}); -This function frees parser structure and associated data. -@end deftypefun - -Now we have learned how to create and use a sax parser. Lets parse a simple -XML document. Write following code into a @file{test.c} file. - -@smallexample -#include -#include - -int pr_tag (void *udata, char *name, char **atts, int type) -@{ - switch (type) @{ - case IKS_OPEN: - printf ("TAG <%s>\n", name); - break; - case IKS_CLOSE: - printf ("TAG \n", name); - break; - case IKS_SINGLE: - printf ("TAG <%s/>\n", name); - break; - @} - if (atts) @{ - int i = 0; - while (atts[i]) @{ - printf (" ATTRIB %s='%s'\n", atts[i], atts[i+1]); - i += 2; - @} - @} - return IKS_OK; -@} - -enum ikserror pr_cdata (void *udata, char *data, size_t len) -@{ - int i; - printf ("CDATA ["); - for (i = 0; i < len; i++) - putchar (data[i]); - printf ("]\n"); - return IKS_OK; -@} - -int main (int argc, char *argv[]) -@{ - iksparser *p; - p = iks_sax_new (NULL, pr_tag, pr_cdata); - switch (iks_parse (p, argv[1], 0, 1)) @{ - case IKS_OK: - puts ("OK"); - break; - case IKS_NOMEM: - puts ("Not enough memory"); - exit (1); - case IKS_BADXML: - puts ("XML document is not well-formed"); - exit (2); - case IKS_HOOK: - puts ("Our hooks didn't like something"); - exit (2); - @} - iks_parser_delete (p); - return 0; -@} -@end smallexample - -Now compile and test it with: - -@example -gcc -o test test.c -liksemel -./test "Hello
World!
" -./test "" -@end example - -@heading Error Handling - -XML standart states that once an error is detected, the processor must not continue -normal processing (i.e. it must not pass character data or markup information to -the application). So iksemel stops processing immediately when it encounters a -syntax error, or one of your hook functions return any one value than @code{IKS_OK}, -and @code{iks_parse} function returns with the error code. - -Since it is useful for debugging, iksemel provides functions to get position of -the error. Position is usually at the starting character for syntax errors. Since -your hooks are called after whole element (i.e. markup or character data) is -passed, position is at the end of the erroneous element for @code{IKS_HOOK} errors. - -@deftypefun {unsigned long} iks_nr_bytes (iksparser* @var{prs}); -Returns how many number of bytes parsed. -@end deftypefun - -@deftypefun {unsigned long} iks_nr_lines (iksparser* @var{prs}); -Returns how many number of lines parsed. -@end deftypefun - -If you want to parse another document with your parser again, you should use -the following function to reset your parser. - -@deftypefun void iks_parser_reset (iksparser* @var{prs}); -Resets the parser's internal state. -@end deftypefun - - -@comment ============================================================ -@node Working with XML Trees,XML Streams,Parsing an XML Document,Tutorials -@section Working with XML Trees - -SAX interface uses very little memory, but it forces you to access XML -documents sequentally. In many cases you want to keep a tree like -representation of XML document in memory and want to access and -modify its content randomly. - -iksemel provides functions for efficiently creating such trees either -from documents or programmaticaly. You can access and modify this -tree and can easily generate a new XML document from the tree. - -This is called DOM (Document Object Model) interface. - -@ifinfo -@menu -* Memory Management:: - -* Creating a Tree:: - -* Accessing the Tree:: - -* Converting a Tree into an XML Document:: - -* Parsing an XML Document into a Tree:: -@end menu -@end ifinfo - - -@comment ============================================================ -@node Memory Management,Creating a Tree,,Working with XML Trees -@subsection Memory Management - -Since keeping whole document content uses a lot of memory and requires -many calls to OS's memory allocation layer, iksemel uses a simple object -stack system for minimizing calls to the @code{malloc} function and releasing -all the memory associated with a tree in a single step. - -A parsed XML tree contains following objects: -@table @samp -@item Nodes -These are basic blocks of document. They can contain a tag, attribute pair -of a tag, or character data. Tag nodes can also contain other nodes as -children. Node structure has a small fixed size depending on the node type. -@item Names -Names of tags and attributes. They are utf-8 encoded small strings. -@item Character Data -They are similar to names but usually much bigger. -@end table - -iksemel's object stack has two separate areas for keeping these data objects. -Meta chunk contains all the structures and aligned data, while the data chunk -contains strings. Each chunk starts with a choosen size memory block, then -when necessary more blocks allocated for providing space. Unless there is a big -request, each block is double the size of the previous block, thus real memory -needs are quickly reached without allocating too many blocks, or wasting -memory with too big blocks. - -@deftp Typedef ikstack -This is a structure defining the object stack. Its fields are private -and subject to change with new iksemel releases. -@end deftp - -@deftypefun {ikstack *} iks_stack_new (size_t @var{meta_chunk}, size_t @var{data_chunk}); -Creates an object stack. @var{meta_chunk} is the initial size of the -data block used for structures and aligned data. @var{data_chunk} is -the initial size of the data block used for strings. They are both in byte units. - -These two initial chunks and a small object stack structure is allocated in -one @code{malloc} call for optimization purproses. -@end deftypefun - -@deftypefun {void *} iks_stack_alloc (ikstack * @var{stack}, size_t @var{size}); -Allocates @var{size} bytes of space from the object stack's meta chunk. -Allocated space is aligned on platform's default alignment boundary and -isn't initialized. Returns a pointer to the space, or NULL if there isn't enough -space available and allocating a new block fails. -@end deftypefun - -@deftypefun {void *} iks_stack_strdup (ikstack * @var{stack}, const char * @var{src}, size_t @var{len}); -Copies given string @var{src} into the object stack's data chunk. Returns a -pointer to the new string, or NULL if there isn't enough space in the stack. -If @var{len} is zero string must be null terminated. -@end deftypefun - -@deftypefun void iks_stack_delete (ikstack * @var{stack}); -Gives all memory associated with object stack to the system. -@end deftypefun - -Since character data sections are usually parsed in separate blocks, -a growable string implementation is necessary for saving memory. - -@deftypefun {char *} iks_stack_strcat (ikstack *@var{stack}, char *@var{old}, size_t @var{old_len}, const char *@var{src}, size_t @var{src_len}); -This function appends the string @var{src} to the string @var{old} in the -stack's data chunk. If @var{old} is NULL it behaves like @code{iks_stack_strdup}. -Otherwise @var{old} has to be a string created with @code{iks_stack_strdup} -or @code{iks_stack_strcat} functions. - -If @var{old_len} or @var{src_len} is zero, corresponding string must be null -terminated. - -Since string can be moved into another block of the data chunk, you must use the -returned value for new string, and must not reference to @var{old} anymore. -Return value can be NULL if there isn't enough space in stack, and allocating a -new block fails. -@end deftypefun - - -@comment ============================================================ -@node Creating a Tree,Accessing the Tree,Memory Management,Working with XML Trees -@subsection Creating a Tree - -@deftp Typedef iks -This is a structure defining a XML node. Its fields are private and only -accessed by following functions. -@end deftp - -@deftypefun iks* iks_new (const char *@var{name}); -Creates an object stack and creates a IKS_TAG type of node with given -tag name inside the stack. Tag name is also copied into the stack. -Returns the node pointer, or NULL if there isn't enough memory. -@end deftypefun - -@deftypefun iks* iks_new_within (const char *@var{name}, ikstack* @var{stack}); -Creates a IKS_TAG type of node with the given tag name. Node and tag -name is allocated inside the given object stack. Returns the node -pointer, or NULL if there isn't enough memory. -@end deftypefun - -@deftypefun iks* iks_insert (iks *@var{x}, const char *@var{name}); -Creates a IKS_TAG type of node with the given tag name. Node and tag -name is allocated inside the @var{x} node's object stack and linked -to @var{x} as a child node. Returns the node pointer, or NULL if there -isn't enough memory. -@end deftypefun - -@deftypefun iks* iks_insert_cdata (iks* @var{x}, const char* @var{data}, size_t @var{len}); -Creates a IKS_CDATA type of node with given character data. Node is -allocated inside the @var{x} node's object stack and linked to @var{x} -as a child node. Data is copied as well. If @var{len} is zero data must -be a null terminated string. Returns the node pointer, or NULL if -there isn't enough memory. -@end deftypefun - -@deftypefun iks* iks_insert_attrib (iks* @var{x}, const char* @var{name}, const char* @var{value}); -Creates a IKS_ATTRIBUTE type of node with given attribute name and the -value. Node is allocated inside the @var{x} node's object stack and -linked to @var{x} as an attribute node. Attribute name and value is -copied as well. Returns the node pointer, or NULL if there isn't -enough memory. - -Reinserting another value with same attribute name changes an attribute's -value. If @var{value} is NULL, attribute is removed from the tag. -@end deftypefun - -@deftypefun iks* iks_insert_node (iks* @var{x}, iks* @var{y}); -Links node @var{y} to node @var{x} as a child node. Nodes are not copied -between object stacks, be careful. -@end deftypefun - -@deftypefun void iks_hide (iks *@var{x}); -Changes the links of the other nodes so that @var{x} becomes invisible. -It stays in the same object stack with neighbour nodes, be careful. -@end deftypefun - -@deftypefun void iks_delete (iks *@var{x}); -Frees the object stack of the node @var{x}. -@end deftypefun - -Now lets create a tree representation of following XML document: - -@example - -song lyrichigh - -here is the correct version: -i just don't see why i should even care -it's not dark yet, but it's getting there - - -@end example - -here is the code: - -@example -iks *x, *y, *z; - -x = iks_new ("message"); -iks_insert_attrib (x, "type", "chat"); -iks_insert_attrib (x, "from", "bob@@bd.com"); -iks_insert_cdata (x, "\n", 1); -iks_insert_cdata (iks_insert (x, "subject"), "song lyric", 10); -iks_insert_cdata (iks_insert (x, "priority"), "high", 4); -iks_insert_cdata (x, "\n", 1); -y = iks_insert (x, "body"); -iks_insert_cdata (y, "\n", 1); -z = iks_insert (y, "em"); -iks_insert_attrib (z, "style", "underline"); -iks_insert_cdata (z, "here is the correct version", 0); -iks_insert_cdata (y, "\n", 1); -iks_insert_cdata (y, "i just don't see why", 0); -iks_insert_cdata (y, "i should even care\n", 0); -iks_insert_cdata (y, "it's not dark yet,", 0); -iks_insert_cdata (y, "but it's getting there\n", 0); -iks_insert_cdata (x, "\n", 1); -@end example - -Notice how newlines are inserted for proper formatting of document. They aren't -necessary for representing data, but they make it easier to read document for -humans. - -Also notice how @code{iks_insert} and @code{iks_insert_cdata} chained. - -There are also functions for duplicating xml trees. They are: - -@deftypefun {iks *} iks_copy (iks* @var{x}); -Creates a full copy of the tree in a newly created object stack. -@end deftypefun - -@deftypefun {iks *} iks_copy_within (iks* @var{x}, ikstack *@var{s}); -Creates a full copy of the tree in given object stack. -@end deftypefun - -@comment ============================================================ -@node Accessing the Tree,Converting a Tree into an XML Document,Creating a Tree,Working with XML Trees -@subsection Accessing a Tree - -Basic access functions allow you to move on the tree: - -@deftypefun iks* iks_next (iks* @var{x}); -@end deftypefun -@deftypefun iks* iks_prev (iks* @var{x}); -@end deftypefun -@deftypefun iks* iks_parent (iks* @var{x}); -@end deftypefun -@deftypefun iks* iks_child (iks* @var{x}); -@end deftypefun -@deftypefun iks* iks_attrib (iks* @var{x}); -@end deftypefun - -These functions return a pointer to the next, previous, parent, first child, -and first attribute node of the given node @var{x}. If that node doesn't -exist or @var{x} is NULL, a NULL value is returned. - -@deftypefun {iks *} iks_root (iks *@var{x}); -Returns the topmost parent node of the @var{x}. -@end deftypefun - -@deftypefun iks* iks_next_tag (iks* @var{x}); -@end deftypefun -@deftypefun iks* iks_prev_tag (iks* @var{x}); -@end deftypefun -@deftypefun iks* iks_first_tag (iks* @var{x}); -@end deftypefun - -These functions return a pointer to the next, previous, first child node -of the given node @var{x}. Only tag nodes are considered, other type -of the nodes are skipped. If such a node doesn't exist or @var{x} is NULL, -a NULL value is returned. - -Another group of functions allow you to access specific information and -content of the nodes: - -@deftypefun ikstack* iks_stack (iks* @var{x}); -Returns the object stack which node @var{x} stays. -@end deftypefun - -@deftypefun {enum ikstype} iks_type (iks* @var{x}); -Returns the type of the node. - -@tindex ikstype -@table @code -@item IKS_TAG -Node is a tag and can contain child nodes and attributes. -@item IKS_CDATA -Node contains character data. -@item IKS_ATTRIBUTE -Node contains an attribute and its value. -@end table -@end deftypefun - -@deftypefun char* iks_name (iks* @var{x}); -Returns the name of the tag for nodes with the type @var{IKS_TAG}. -Returns an attribute's name for nodes of type IKS_ATTRIBUTE. -@end deftypefun - -@deftypefun char* iks_cdata (iks* @var{x}); -Returns a pointer to node's character data if available, NULL otherwise. -Returns an attribute's value for nodes of type IKS_ATTRIBUTE. -@end deftypefun - -@deftypefun size_t iks_cdata_size (iks *@var{x}); -Returns the size of the node's character data in bytes. -@end deftypefun - -@deftypefun int iks_has_children (iks *@var{x}); -Returns a non-zero value if node @var{x} has a child node. -@end deftypefun - -@deftypefun int iks_has_attribs (iks *@var{x}); -Returns a non-zero value if node @var{x} has attributes. -@end deftypefun - -Last group of the functions simplifies finding and accessing the content -of a specific node: - -@deftypefun iks* iks_find (iks *@var{x}, const char *@var{name}); -Searches a IKS_TAG type of node with @var{name} as tag name in child -nodes of @var{x}. Returns a pointer to the node if found, NULL otherwise. -@end deftypefun - -@deftypefun char* iks_find_cdata (iks* @var{x}, const char* @var{name}); -Searches a IKS_TAG type of node with @var{name} as tag name in child -nodes of @var{x}. Returns a pointer to the character data of the node's -first child node if found, NULL otherwise. -@end deftypefun - -@deftypefun char* iks_find_attrib (iks* @var{x}, const char* @var{name}); -Searches an attribute with given name in attributes of the @var{x}. -Returns a pointer to attribute value if found, NULL otherwise. -@end deftypefun - -@deftypefun {iks *} iks_find_with_attrib (iks *@var{x}, const char *@var{tagname}, const char *@var{attrname}, const char *@var{value}); -Searches for a child tag of @var{x} which has an attribute with name -@var{attrname} and value @var{value}. If @var{tagname} isn't NULL, -name of the tag must also match. Returns a pointer to the node if found, -NULL otherwise. -@end deftypefun - -Here is an example which demonstrates accessing file names in a fictitious -XML playlist file: - -@example - - - /home/madcat/download/matrix_rev_trailer.mpg - 1:17 - - - /home/madcat/anim/clementine_ep1.rm - 22:00 - - - /home/madcat/anim/futurama/ep101.avi - /home/madcat/subs/futurama/ep101.txt - 30:00 - - - - - -@end example - -and here is the code: - -@example -#include -#include - -int main (int argc, char *argv[]) -@{ - iks *x, *y; - int e; - - if (argc < 2) @{ - printf ("usage: %s ", argv[0]); - return 0; - @} - e = iks_load (argv[1], &x); - if (e != IKS_OK) @{ - printf ("parse error %d\n", e); - return 1; - @} - if (iks_find (x, "repeat")) puts ("repeat mode enabled"); - y = iks_child (x); - while (y) @{ - if (iks_type (y) == IKS_TAG - && strcmp (iks_name (y), "item") == 0) @{ - printf ("Filename: [%s]\n", iks_find_cdata (y, "name")); - @} - y = iks_next (y); - @} - iks_delete (x); - return 0; -@} -@end example - - -@comment ============================================================ -@node Converting a Tree into an XML Document,Parsing an XML Document into a Tree,Accessing the Tree,Working with XML Trees -@subsection Converting a Tree to an XML Document - -There is a function for converting given XML tree into a null terminated string. - -@deftypefun {char *} iks_string (ikstack* @var{stack}, iks* @var{x}); -Converts given tree into a string. String is created inside the given object -stack. Returns a pointer to the string, or NULL if there isn't enough memory -available. - -If @var{stack} is NULL, string is created inside an @code{iks_malloc}ed buffer. -You can free it later with @code{iks_free} function. -@end deftypefun - -Here is an example which builds a tree and print it. - -@example -iks *x; -char *t; - -x = iks_new ("test"); -iks_insert_cdata (iks_insert (x, "a"), "1234", 4); -iks_insert (x, "br"); -iks_insert_cdata (x, "1234", 4); -t = iks_string (iks_stack (x), x); -puts (t); -iks_delete (x); -@end example - - -@comment ============================================================ -@node Parsing an XML Document into a Tree,,Converting a Tree into an XML Document,Working with XML Trees -@subsection Parsing a Document into a Tree - -If you want to automatically convert an XML document into a tree, you can use -iksemel's DOM parser. It is created with following function: - -@deftypefun iksparser* iks_dom_new (iks **@var{iksptr}); -Creates a DOM parser. A pointer to the created XML tree is put into the -variable pointed by @var{iksptr}. Returns a pointer to the parser, or NULL -is there isn't enough memory. -@end deftypefun - -Usage is same as SAX parser. You feed the data with @code{iks_parse}, and if -there isn't an error, you can access to your tree from variable @code{*iksptr}. - -Here is a simple example: - -@example -iks *x; -iksparser *p; - -p = iks_dom_new (&x); -if (IKS_OK != iks_parse (p, "bcd", 9, 1)) @{ - puts ("parse error"); -@} -/* x is useable after that point */ - -/* this will print 'bcd' */ -printf ("%s\n", iks_cdata (iks_child (x))); -@end example - -If you know the size of the file ahead, or you have an approximate idea, -you can tell this to the dom parser for choosing a better memory allocation -strategy. Here is the function for this. - -@deftypefun void iks_set_size_hint (iksparser *@var{prs}, size_t @var{approx_size}); -Parser @var{prs} must be a dom type parser. @var{approx_size} is the -expected size of the xml document. Parser chooses its chunk size -based on this information. Helps performance while processing big files. -@end deftypefun - -If you already have your XML document in memory, you can simply parse -it with: - -@deftypefun {iks *} iks_tree (const char *@var{xml_str}, size_t @var{len}, int *@var{err}); -This function parses the buffer pointed by @var{xml_str}. If @var{len} is zero -buffer is considered as a null terminated utf8 string. Returns the parsed tree, -or NULL if there is an error. If @var{err} is not NULL, actual error code (returned -by iks_parse) is put there. -@end deftypefun - -Most of the times you want to load your configuration (or similar) files directly -into trees. iksemel provides two functions to greatly simplify this: - -@deftypefun int iks_load (const char *@var{fname}, iks **@var{xptr}); -Loads the XML file. Tree is placed into the variable pointed by @var{xptr}. -@end deftypefun - -@deftypefun int iks_save (const char *@var{fname}, iks *@var{x}); -Converts tree @var{x} into a string and saves to the file. -@end deftypefun - -Both functions return same error codes as @code{iks_parse}. Some additional -error codes are defined for indicating file problems. They are: - -@table @code -@item IKS_FILE_NOFILE -A file with the given name doesn't exist. -@item IKS_FILE_NOACCESS -Cannot open file. Possibly a permission problem. -@item IKS_FILE_RWERR -Read or write operation failed. -@end table - -Here is a simple example which parses a file and saves it into another: - -@example -iks *x; - -if (IKS_OK != iks_load ("file1.xml", &x)) @{ - puts ("loading error"); -@} -if (IKS_OK != iks_save ("file2.xml", x)) @{ - puts ("saving error"); -@} -@end example - - -@comment ============================================================ -@node XML Streams,Writing a Jabber Client,Working with XML Trees,Tutorials -@section XML Streams - -XML streams function as containers for any XML chunks sent asynchronously -between network endpoints. They are used for asyncronously exchanging -relatively small payload of structured information between entities. - -A stream is initiated by one of hosts connecting to the other, and sending a - tag. Receiving entity replies with a second XML stream -back to the initiating entity within the same connection. Each unit of -information is send as a direct child tag of the tag. -Stream is closed with . - -XML streams use a subset of XML. Specifically they should not contain -processing instructions, non-predefined entities, comments, or DTDs. - -Jabber protocol uses XML streams for exchanging messages, presence -information, and other information like authorization, search, time and -version queries, protocol extensions. - -iksemel provides you a stream parser, which automatically handles connection -to the server, and calls your hook function with incoming information -parsed and converted to an XML tree. - -You can create such a parser with: - -@deftypefun iksparser* iks_stream_new (char* @var{name_space}, void* @var{user_data}, iksStreamHook* @var{streamHook}); -Allocates and initalizes a stream parser. @var{name_space} indicates the -stream type, jabber clients use "jabber:client" namespace. @var{user_data} -is passed directly to your hook function. -@end deftypefun - -@deftp Typedef iksStreamHook -int iksStreamHook (void* @var{user_data}, int @var{type}, iks* @var{node}); - -Depending on the value of the @var{type}, @var{node} contains: -@table @code -@item IKS_NODE_START -Got the tag, namespace, stream id and other information -is contained in the @var{node}. -@item IKS_NODE_NORMAL -A first level child of the tag is received. @var{node} contains -the parsed tag. If you are connected to a jabber server, you can get , -, or tags. -@item IKS_NODE_ERROR -Got a tag, details can be accessed from @var{node}. -@item IKS_NODE_STOP - tag is received or connection is closed, @var{node} is @code{NULL}. -@end table - -Freeing the node with @code{iks_delete} is up to you. -@end deftp - -You can manually feed this parser with @code{iks_parse} function, but using -iksemel's connection facilities is easier for most of the cases. - -This functions return @code{IKS_OK} for success. Error codes of @code{iks_parse} -are used in same manner. Following additional codes are defined for -network related problems: - -@table @code -@item IKS_NET_NODNS -Hostname lookup failed. Possible reasons: hostname is incorrect, -you are not online, your dns server isn't accessible. -@item IKS_NET_NOSOCK -Socket cannot created. -@item IKS_NET_NOCONN -Connection attemp failed. Possible reasons: host is not an XML stream -server, port number is wrong, server is busy or closed for the moment. -@item IKS_NET_RWERR -@code{send} or @code{recv} call is failed when attempting to exchange -the data with the server. You should close the connection with @code{iks_disconnect} -after getting this error from data transfer functions. -@end table - -@deftypefun int iks_connect_tcp (iksparser *@var{prs}, const char *@var{server}, int @var{port}); -This function connects the parser to a server and sends stream header for you. -@var{server} is the host name of the server and @var{port} is the tcp port -number which server is listening to. You can use @code{IKS_JABBER_PORT} -macro for the default jabber client port (5222). -@end deftypefun - -@deftypefun int iks_connect_fd (iksparser *@var{prs}, int @var{fd}); -Attaches parser to an already opened connection. @var{fd} is the socket -descriptor. Note that @code{iks_disconnect} doesn't close the socket -for this kind of connection, opening and closing of the socket is up to your -application. Stream header is not sent automatically. You can use -@code{iks_send_header} function for sending it. -@end deftypefun - -@deftypefun void iks_disconnect (iksparser *@var{prs}); -Closes connection to the server, and frees connection resources. -@end deftypefun - -After successfully connecting to a server, you can use following functions -for exchanging information with server. - -@deftypefun int iks_recv (iksparser* @var{prs}, int @var{timeout}); -If @var{timeout} is @code{-1}, waits until some data arrives from server, -and process the data. Your stream hook can be called if a complete -chunk is arrived. - -If @var{timeout} is a positive integer, @code{iks_recv} returns if no data -arrives for @var{timeout} seconds. - -If @var{timeout} is zero, @code{iks_recv} checks if there is any data -waiting at the network buffer, and returns without waiting for data. -@end deftypefun - -@deftypefun int iks_fd (iksparser* @var{prs}); -Returns the file descriptor of the connected socket. You can use this in -your @code{select} function or some other input loop to act whenever -some data from the server arrives. This value of only valid between -a successful @code{iks_connect_tcp} and @code{iks_disconnect}. -@end deftypefun - -@deftypefun int iks_send (iksparser* @var{prs}, iks* @var{x}); -Converts the tree given in @var{x} to a string, and sends to the server. -String is created inside the object stack of @var{x}. -@end deftypefun - -@deftypefun int iks_send_raw (iksparser* @var{prs}, char* @var{xmlstr}); -Sends the string given in @var{xmlstr} to the server. -@end deftypefun - -@deftypefun int iks_send_header (iksparser *@var{prs}, char *@var{to}); -Sends the stream header. @var{to} is the name of the server. -Normally @code{iks_connect_tcp} function calls this for you. This -is only useful if you are using @code{iks_connect_fd}. -@end deftypefun - -Sometimes it is useful to log incoming and outgoing data to your parser -for debugging your applications. iksemel provides a logging facility for you. - -@deftypefun void iks_set_log_hook (iksparser* @var{prs}, iksLogHook* @var{logHook}); -Sets the log function for your stream parser. You can't use this function -on any other type of parser. -@end deftypefun - -@deftp Typedef iksLogHook -void iksLogHook (void* @var{user_data}, const char* @var{data}, size_t @var{size}, int @var{is_incoming}); - -@var{user_data} is same value which you give with @code{iks_stream_new}. -@var{data} is @var{size} bytes of data. Be very careful that this data may be -coming from other side of the connection and can contain malicius bytes. It isn't -checked by iksemel yet, so you should check it yourself before displaying or -passing to other systems in your application or computer. If @var{is_incoming} -is a non-zero value, data is incoming from server, otherwise it is outgoing to the -server. -@end deftp - - -@comment ============================================================ -@node Writing a Jabber Client,Utility Functions,XML Streams,Tutorials -@section Writing a Jabber Client - -@ifinfo -@menu -* Security:: - -* Packets:: - -* Packet Filter:: - -* Creating Common Packets:: - -@end menu -@end ifinfo - -@comment ============================================================ -@node Security,Packets,,Writing a Jabber Client -@subsection Security - -iksemel supports TLS protocol for encrypted communication and SASL -protocol for authentication. TLS is handled by gnutls library. - -@deftypefun int iks_has_tls (void); -If iksemel is compiled with gnutls library, this function returns a non-zero -value indicating you can try encrypted connection with the server. -@end deftypefun - -@deftypefun int iks_start_tls (iksparser* @var{prs}); -Starts a TLS handshake over already connected parser. Returns IKS_OK or -one of the IKS_NET_ errors. If handshake succeeds you'll get another -stream header from server. -@end deftypefun - -@deftypefun int iks_is_secure (iksparser* @var{prs}); -Returns a non-zero value if a secure connection is fully established -between server. -@end deftypefun - -@deftypefun int iks_start_sasl (iksparser* @var{prs}, enum ikssasltype @var{type}, char* @var{username}, char* @var{pass}); -Starts SASL operation. -@end deftypefun - -See tools/iksroster.c for a good example. - -@comment ============================================================ -@node Packets,Packet Filter,Security,Writing a Jabber Client -@subsection Packets - -iksemel can parse a jabber XML node and provide you a public packet -structure which contains information like node type and subtype, id, -namespace, sender's jabber id, etc. - -This handles a lot of node parsing for you. Packets are also used in -the packet filter subsystem. - -@deftypefun {ikspak *} iks_packet (iks *@var{x}); -Takes a node from stream and extracts information from it to a packet structure. -Structure is allocated inside the node's object stack. -@end deftypefun - -@tindex ikspak -@code{ikspak} structure has following fields: - -@table @code -@item iks *x; -This is a pointer to the node. -@item iksid *from; -Sender's jabber id in parsed form. See below for @code{iksid} structure. -@item iks *query; -A pointer to the tag for IQ nodes. -@item char *ns; -Namespace of the content for IQ nodes. -@item char *id; -ID of the node. -@item enum ikspaktype type; -Type of the node. Possible types are: - -@table @code -@item IKS_PAK_NONE -Unknown node. -@item IKS_PAK_MESSAGE -Message node. -@item IKS_PAK_PRESENCE -Presence node with presence publishing operation. -@item IKS_PAK_S10N -Presence node with subscription operation. -@item IKS_PAK_IQ -IQ node. -@end table -@item enum iksubtype subtype; -Sub type of the node. Sub types for message nodes: - -@table @code -@item IKS_TYPE_NONE -A normal message. -@item IKS_TYPE_CHAT -Private chat message. -@item IKS_TYPE_GROUPCHAT -Multi user chat message. -@item IKS_TYPE_HEADLINE -Message from a news source. -@item IKS_TYPE_ERROR -Message error. -@end table - -Sub types for IQ nodes: - -@table @code -@item IKS_TYPE_GET -Asks for some information. -@item IKS_TYPE_SET -Request for changing information. -@item IKS_TYPE_RESULT -Reply to get and set requests. -@item IKS_TYPE_ERROR -IQ error. -@end table - -Sub types for subscription nodes: - -@table @code -@item IKS_TYPE_SUBSCRIBE, -Asks for subscribing to the presence. -@item IKS_TYPE_SUBSCRIBED, -Grants subscription. -@item IKS_TYPE_UNSUBSCRIBE, -Asks for unsubscribing to the presence. -@item IKS_TYPE_UNSUBSCRIBED, -Cancels subscription. -@item IKS_TYPE_ERROR -Presence error. -@end table - -Sub types for presence nodes: - -@table @code -@item IKS_TYPE_PROBE, -Asks presence status. -@item IKS_TYPE_AVAILABLE, -Publishes entity as available. More information can be found in @code{show} field. -@item IKS_TYPE_UNAVAILABLE -Publishes entity as unavailable. More information can be found in @code{show} field. -@end table -@item enum ikshowtype show; -Presence state for the presence nodes. - -@table @code -@item IKS_SHOW_UNAVAILABLE -Entity is unavailable. -@item IKS_SHOW_AVAILABLE -Entity is available. -@item IKS_SHOW_CHAT -Entity is free for chat. -@item IKS_SHOW_AWAY -Entity is away for a short time. -@item IKS_SHOW_XA -Entity is away for a long time. -@item IKS_SHOW_DND -Entity doesn't want to be disturbed. -@end table -@end table - -iksemel has two functions to parse and compare jabber IDs. - -@deftypefun {iksid *} iks_id_new (ikstack *@var{s}, const char *@var{jid}); -Parses a jabber id into its parts. @code{iksid} structure is created inside -the @var{s} object stack. -@end deftypefun - -@tindex iksid -@code{iksid} structure has following fields: - -@table @code -@item char *user; -User name. -@item char *server; -Server name. -@item char *resource; -Resource. -@item char *partial; -User name and server name. -@item char *full; -User name, server name and resource. -@end table - -You can access this fields and read their values. Comparing two parsed jabber -ids can be done with: - -@deftypefun int iks_id_cmp (iksid *@var{a}, iksid *@var{b}, int @var{parts}); -Compares @var{parts} of @var{a} and @var{b}. Part values are: - -@table @code -@item IKS_ID_USER -@item IKS_ID_SERVER -@item IKS_ID_RESOURCE -@end table - -@sp 1 -You can combine this values with @code{or} operator. Some common combinations -are predefined for you: - -@table @code -@item IKS_ID_PARTIAL -@code{IKS_ID_USER | IKS_ID_SERVER} -@item IKS_ID_FULL -@code{IKS_ID_USER | IKS_ID_SERVER | IKS_ID_RESOURCE} -@end table - -Return value is @code{0} for equality. If entities are not equal a combination of -part values showing different parts is returned. -@end deftypefun - - -@comment ============================================================ -@node Packet Filter,Creating Common Packets,Packets,Writing a Jabber Client -@subsection Packet Filter - -Packet filter handles routing incoming packets to related functions. - -@tindex iksfilter -@deftypefun {iksfilter *} iks_filter_new (void); -Creates a new packet filter. -@end deftypefun - -@deftypefun void iks_filter_packet (iksfilter *@var{f}, ikspak *@var{pak}); -Feeds the filter with given packet. Packet is compared to registered rules and -hook functions of the matching rules are called in most matched to least -matched order. -@end deftypefun - -@deftypefun void iks_filter_delete (iksfilter *@var{f}); -Frees filter and rules. -@end deftypefun - -Rules are created with following function: - -@tindex iksrule -@deftypefun {iksrule *} iks_filter_add_rule (iksfilter *@var{f}, iksFilterHook *@var{filterHook}, void *@var{user_data}, @dots{}); -Adds a rule to the filter @var{f}. @var{user_data} is passed directly to your -hook function @var{filterHook}. - -A rule consist of one or more type and value pairs. Possible types: -@table @code -@item IKS_RULE_ID -Compares @code{char *} value to packet ids. -@item IKS_RULE_FROM -Compares @code{char *} value to packet senders. -@item IKS_RULE_FROM_PARTIAL -Compares @code{char *} value to packet sender. Ignores resource part of jabber id. -@item IKS_RULE_NS -Compares @code{char *} value to namespace of iq packets. -@item IKS_RULE_TYPE -Compares @code{int} value to packet types. -@item IKS_RULE_SUBTYPE -Compares @code{int} value to packet sub types. -@item IKS_RULE_DONE -Terminates the rule pairs. -@end table -@end deftypefun - -Here is an example which creates a filter and adds three rules: -@example -iksfilter *f; - -f = iks_filter_new (); -iks_filter_add_rule (f, on_msg, NULL, - IKS_RULE_TYPE, IKS_PAK_MESSAGE, - IKS_RULE_DONE); -iks_filter_add_rule (f, on_auth_result, NULL, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, - IKS_RULE_ID, "auth", - IKS_RULE_DONE); -iks_filter_add_rule (f, on_roster_push, NULL, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_SET, - IKS_RULE_NS, "jabber:iq:roster", - IKS_RULE_DONE); -@end example - -@deftp Typedef iksFilterHook -int iksFilterHook (void *user_data, ikspak *pak); - -Your hook is called with your @var{user_data} and matching packet @var{pak}. -You can return two different values from your hook: -@table @code -@item IKS_FILTER_PASS -Packet is forwarded to least matching rules. -@item IKS_FILTER_EAT -Filtering process for the packet ends. -@end table -@end deftp - -You can remove the rules with following functions: - -@deftypefun void iks_filter_remove_rule (iksfilter *@var{f}, iksrule *@var{rule}); -Removes the rule from filter. -@end deftypefun - -@deftypefun void iks_filter_remove_hook (iksfilter *@var{f}, iksFilterHook *@var{filterHook}); -Remove the rules using @var{filterHook} function from filter. -@end deftypefun - - -@comment ============================================================ -@node Creating Common Packets,,Packet Filter,Writing a Jabber Client -@subsection Creating Common Packets - -A usual jabber network traffic contains many similar XML constructs. iksemel -provides several utility functions for creating them. They all generate an XML -tree, so you can add or modify some parts of the tree, and send to server then. - -@deftypefun {iks *} iks_make_auth (iksid *@var{id}, const char *@var{pass}, const char *@var{sid}); -Creates an authorization packet. @var{id} is your parsed jabber id, and @var{pass} -is your password. - -If stream id @var{sid} isn't NULL, SHA1 authentication is used, otherwise password -is attached in plain text. You can learn stream id from @code{IKS_STREAM_START} -packet in your stream hook like this: - -@example -char *sid; - -if (type == IKS_STREAM_START) @{ - sid = iks_find_attrib (node, "id"); -@} -@end example -@end deftypefun - -@deftypefun {iks *} iks_make_msg (enum iksubtype @var{type}, const char *@var{to}, const char *@var{body}); -Creates a message packet. @var{type} is the message type, @var{to} is jabber id -of the recipient, @var{body} is the message. -@end deftypefun - -@deftypefun {iks *} iks_make_s10n (enum iksubtype @var{type}, const char *@var{to}, const char *@var{msg}); -Creates a presence packet for subscription operations. @var{type} is operation, -@var{to} is jabber id of the recipient, @var{msg} is a small message for -introducing yourself, or explaning the reason of why you are subscribing or -unsubscribing. -@end deftypefun - -@deftypefun {iks *} iks_make_pres (enum ikshowtype @var{show}, const char *@var{status}); -Creates a presence packet for publishing your presence. @var{show} is your -presence state and @var{status} is a message explaining why you are not -available at the moment, or what you are doing now. -@end deftypefun - -@deftypefun {iks *} iks_make_iq (enum iksubtype @var{type}, const char *@var{xmlns}); -Creates an IQ packet. @var{type} is operation type and @var{xmlns} is the -namespace of the content. You usually have to add real content to the -tag before sending this packet. -@end deftypefun - - -@comment ============================================================ -@node Utility Functions,,Writing a Jabber Client,Tutorials -@section Utility Functions - -@subsection Memory Utilities - -@deftypefun {void *} iks_malloc (size_t @var{size}); -@end deftypefun -@deftypefun void iks_free (void *@var{ptr}); -@end deftypefun - -These are wrappers around ANSI malloc and free functions used by the -iksemel library itself. You can free the output of iks_string (only if you -passed it a NULL stack) with iks_free for example. That is important -if you are using a malloc debugger in your application but not in iksemel -or vice versa. - -@comment ============================================================ -@subsection String Utilities - -@deftypefun {char *} iks_strdup (const char *@var{src}); -@end deftypefun -@deftypefun int iks_strcmp (const char *@var{a}, const char *@var{b}); -@end deftypefun -@deftypefun int iks_strcasecmp (const char *@var{a}, const char *@var{b}); -@end deftypefun -@deftypefun int iks_strncmp (const char *@var{a}, const char *@var{b}, size_t @var{n}); -@end deftypefun -@deftypefun int iks_strncasecmp (const char *@var{a}, const char *@var{b}, size_t @var{n}); -@end deftypefun -@deftypefun size_t iks_strlen (const char *@var{src}); -@end deftypefun - -These functions work exactly like their ANSI equivalents except that they allow -NULL values for string pointers. If @var{src} is NULL, iks_strdup and iks_strlen -returns zero. If @var{a} or @var{b} is NULL in string comparisation functions -they return -1. - -Their usefulness comes from the fact that they can chained with DOM traversing -functions like this: - -@smallexample -if (iks_strcmp (iks_find_attrib (x, "id"), "x1") == 0) count++; -@end smallexample - -That example works even x doesn't have an 'id' attribute and iks_find_attrib -returns NULL. So you don't need to use temporary variables in such -situations. - -@comment ============================================================ -@subsection SHA1 Hash - -Secure Hash Algorithm (SHA1) is used in the Jabber authentication -protocol for encoding your password when sending to the server. -This is normally handled by iks_make_auth() function, but if you -want to handle it manually, or if you need a good hash function -for other purproses you can use these functions. - -@deftypefun iksha* iks_sha_new (void); -Allocates a structure for keeping calculation values and the state. -@end deftypefun - -@deftypefun void iks_sha_reset (iksha *@var{sha}); -Resets the state of the calculation. -@end deftypefun - -@deftypefun void iks_sha_hash (iksha *@var{sha}, const unsigned char *@var{data}, int @var{len}, int @var{finish}); -Calculates the hash value of the given data. If @var{finish} is non -zero, applies the last step of the calculation. -@end deftypefun - -@deftypefun void iks_sha_print (iksha *@var{sha}, char *@var{hash}); -Prints the result of a finished calculation into the buffer pointed by @var{hash} -in hexadecimal string form. Buffer must be at least 40 bytes long. String -is not null terminated. -@end deftypefun - -@deftypefun void iks_sha (const char *@var{data}, char *@var{hash}); -Calculates the hash value of @var{data} and prints into @var{hash}. -This is a helper function for simple hash calculations. It calls -other functions for the actual work. -@end deftypefun - - -@comment ============================================================ - - -@node Development,Datatype Index,Tutorials,Top -@chapter Development - -This chapter contains information on plan, procedure and standarts of -iksemel development. - -@section Roadmap - -There are three main functions iksemel tries to provide to applications: -@itemize @bullet -@item -A generic XML parser with SAX and DOM interfaces. -@item -XML stream client and server functionality. -@item -Utilities for Jabber clients. -@end itemize - -Goal of the iksemel is providing these functions while supporting embedded -environments, keeping usage simple, and having a robust implementation. - -Some decisions are made to reach this goal: - -Code is written in ANSI C with a single dependency on C library. Instead of -using expat or libxml, a simple built-in parser is used. Similarly glib and -gnu only features of glibc (like object stacks) are avoided and built-in -memory and string utilities are used. This may seem like code duplication -but since they are optimized for iksemel and only a few kb in size, -it isn't a big disadvantage. - -Code is placed files in a modular fashion, and different modules don't depend -on others' internal details. This allows taking unneeded functionality out when -building for low resource situations. - -It is tried to give functions names which are consistent, clear and short. - -API is documented with texinfo for high quality printed output and info file -output for fast and simple access during application development. Instead -of using an autogenerated system or simply listing function descriptions, -a task oriented tutorial approach is used. - -@section Coding Style - -Here is a short list describing preferred coding style for iksemel. -Please keep in mind when sending patches. - -@itemize @bullet -@item -Indentation is done with tabs. Aligning is done with spaces. -@item -Placement of braces is K&R style. -@item -Function names are put at the start of line. -@item -Function names are lowercase. -@item -Words of the function names are separated with underscore character. -@item -Structure and variable names are lowercase. -@item -Macro and enumarations names are uppercase. -@item -Exported library API is contained in the single iksemel.h file. -@item -Exported function names start with iks_ -@item -Exported structure and type names start with iks -@item -Exported macro and enumaration names start with IKS_ -@end itemize - -Here is an example: - -@smallexample -int -iks_new_func (char *text) -@{ - int i; - - i = an_internal_func (text); - if (IKS_SOME_VALUE == i) @{ - iks_some_func (text); - i++; - @} - return i; -@} -@end smallexample - -@section Resources - -@itemize @bullet -@item -RFC 2279, UTF-8 format @url{http://www.ietf.org/rfc/rfc2279.txt} -@item -W3C Recommendation, Extensible Markup Language 1.0 @url{http://www.w3.org/TR/REC-xml} -@item -Annotated XML Specification @url{http://www.xml.com/axml/testaxml.htm} -@item -Jabber Protocol Documents @url{http://www.jabber.org/protocol/} -@end itemize - - -@comment ============================================================ - - -@node Datatype Index,Function Index,Development,Top -@unnumbered Datatype Index -@printindex tp - - -@node Function Index,,Datatype Index,Top -@unnumbered Function Index -@printindex fn - - -@contents -@bye diff --git a/libs/iksemel/iksemel.pc.in b/libs/iksemel/iksemel.pc.in deleted file mode 100644 index 7f5c9d2c10..0000000000 --- a/libs/iksemel/iksemel.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: iksemel -Description: XML parser library for Jabber -Version: @VERSION@ -Libs: -L${libdir} -liksemel -Cflags: -I${includedir} diff --git a/libs/iksemel/include/Makefile.am b/libs/iksemel/include/Makefile.am deleted file mode 100644 index 23899eeea8..0000000000 --- a/libs/iksemel/include/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -## -## Process this file with automake to produce Makefile.in -## - -include_HEADERS = iksemel.h -noinst_HEADERS = common.h finetune.h diff --git a/libs/iksemel/include/common.h b/libs/iksemel/include/common.h deleted file mode 100644 index af94f6fb85..0000000000 --- a/libs/iksemel/include/common.h +++ /dev/null @@ -1,33 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#ifdef STDC_HEADERS -#include -#include -#include -#elif HAVE_STRINGS_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifndef errno -extern int errno; -#endif - -#include "finetune.h" diff --git a/libs/iksemel/include/finetune.h b/libs/iksemel/include/finetune.h deleted file mode 100644 index 1eae1d8ea3..0000000000 --- a/libs/iksemel/include/finetune.h +++ /dev/null @@ -1,29 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -/* minimum sax buffer size */ -#define SAX_BUFFER_MIN_SIZE 128 - -/* sax parser structure plus extra data of dom parser */ -#define DEFAULT_DOM_CHUNK_SIZE 256 - -/* sax parser structure plus extra data of stream parser */ -#define DEFAULT_STREAM_CHUNK_SIZE 256 - -/* iks structure, its data, child iks structures, for stream parsing */ -#define DEFAULT_IKS_CHUNK_SIZE 1024 - -/* iks structure, its data, child iks structures, for file parsing */ -#define DEFAULT_DOM_IKS_CHUNK_SIZE 2048 - -/* rule structure and from/to/id/ns strings */ -#define DEFAULT_RULE_CHUNK_SIZE 128 - -/* file is read by blocks with this size */ -#define FILE_IO_BUF_SIZE 4096 - -/* network receive buffer */ -#define NET_IO_BUF_SIZE 4096 diff --git a/libs/iksemel/include/iksemel.h b/libs/iksemel/include/iksemel.h deleted file mode 100644 index dc6df91022..0000000000 --- a/libs/iksemel/include/iksemel.h +++ /dev/null @@ -1,414 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2007 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#ifndef IKSEMEL_H -#define IKSEMEL_H 1 - -#ifdef __cplusplus -#include /* size_t for C++ */ -extern "C" { -#else -#include /* size_t for C */ -#endif - -/***** object stack *****/ - -struct ikstack_struct; -typedef struct ikstack_struct ikstack; - -ikstack *iks_stack_new (size_t meta_chunk, size_t data_chunk); -void *iks_stack_alloc (ikstack *s, size_t size); -char *iks_stack_strdup (ikstack *s, const char *src, size_t len); -char *iks_stack_strcat (ikstack *s, char *old, size_t old_len, const char *src, size_t src_len); -void iks_stack_stat (ikstack *s, size_t *allocated, size_t *used); -void iks_stack_delete (ikstack **sp); - -/***** utilities *****/ - -void *iks_malloc (size_t size); -void iks_real_free (void *ptr); -void iks_set_mem_funcs (void *(*malloc_func)(size_t size), void (*free_func)(void *ptr)); - -char *iks_strdup (const char *src); -char *iks_strcat (char *dest, const char *src); -int iks_strcmp (const char *a, const char *b); -int iks_strcasecmp (const char *a, const char *b); -int iks_strncmp (const char *a, const char *b, size_t n); -int iks_strncasecmp (const char *a, const char *b, size_t n); -size_t iks_strlen (const char *src); -char *iks_escape (ikstack *s, char *src, size_t len); -char *iks_unescape (ikstack *s, char *src, size_t len); - -#define iks_free(p) if (p) {iks_real_free(p) ; p = NULL;} - -/***** dom tree *****/ - -enum ikstype { - IKS_NONE = 0, - IKS_TAG, - IKS_ATTRIBUTE, - IKS_CDATA -}; - -struct iks_struct; -typedef struct iks_struct iks; - -iks *iks_new (const char *name); -iks *iks_new_within (const char *name, ikstack *s); -iks *iks_insert (iks *x, const char *name); -iks *iks_insert_cdata (iks *x, const char *data, size_t len); -iks *iks_insert_attrib (iks *x, const char *name, const char *value); -iks *iks_insert_node (iks *x, iks *y); -iks *iks_append (iks *x, const char *name); -iks *iks_prepend (iks *x, const char *name); -iks *iks_append_cdata (iks *x, const char *data, size_t len); -iks *iks_prepend_cdata (iks *x, const char *data, size_t len); -void iks_hide (iks *x); -void iks_delete (iks *x); -iks *iks_next (iks *x); -iks *iks_next_tag (iks *x); -iks *iks_prev (iks *x); -iks *iks_prev_tag (iks *x); -iks *iks_parent (iks *x); -iks *iks_root (iks *x); -iks *iks_child (iks *x); -iks *iks_first_tag (iks *x); -iks *iks_attrib (iks *x); -iks *iks_find (iks *x, const char *name); -char *iks_find_cdata (iks *x, const char *name); -char *iks_find_attrib (iks *x, const char *name); -iks *iks_find_with_attrib (iks *x, const char *tagname, const char *attrname, const char *value); -ikstack *iks_stack (iks *x); -enum ikstype iks_type (iks *x); -char *iks_name (iks *x); -char *iks_cdata (iks *x); -size_t iks_cdata_size (iks *x); -int iks_has_children (iks *x); -int iks_has_attribs (iks *x); -char *iks_string (ikstack *s, iks *x); -iks *iks_copy (iks *x); -iks *iks_copy_within (iks *x, ikstack *s); - -/***** sax parser *****/ - -enum ikserror { - IKS_OK = 0, - IKS_NOMEM, - IKS_BADXML, - IKS_HOOK -}; - -enum ikstagtype { - IKS_OPEN, - IKS_CLOSE, - IKS_SINGLE -}; - -typedef int (iksTagHook)(void *user_data, char *name, char **atts, int type); -typedef int (iksCDataHook)(void *user_data, char *data, size_t len); -typedef void (iksDeleteHook)(void *user_data); - -struct iksparser_struct; -typedef struct iksparser_struct iksparser; - -iksparser *iks_sax_new (void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook); -iksparser *iks_sax_extend (ikstack *s, void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook, iksDeleteHook *deleteHook); -ikstack *iks_parser_stack (iksparser *prs); -void *iks_user_data (iksparser *prs); -unsigned long iks_nr_bytes (iksparser *prs); -unsigned long iks_nr_lines (iksparser *prs); -int iks_parse (iksparser *prs, const char *data, size_t len, int finish); -void iks_parser_reset (iksparser *prs); -void iks_parser_delete (iksparser *prs); - -/***** dom parser *****/ - -enum iksfileerror { - IKS_FILE_NOFILE = 4, - IKS_FILE_NOACCESS, - IKS_FILE_RWERR -}; - -iksparser *iks_dom_new (iks **iksptr); -void iks_set_size_hint (iksparser *prs, size_t approx_size); -iks *iks_tree (const char *xml_str, size_t len, int *err); -int iks_load (const char *fname, iks **xptr); -int iks_save (const char *fname, iks *x); - -/***** transport layer *****/ - -enum iksasyncevents { - IKS_ASYNC_RESOLVED, - IKS_ASYNC_CONNECTED, - IKS_ASYNC_WRITE, - IKS_ASYNC_WRITTEN, - IKS_ASYNC_READ, - IKS_ASYNC_CLOSED, - IKS_ASYNC_ERROR -}; - -typedef struct iksasyncevent_struct { - int event; - int data0; - int data1; -} iksasyncevent; - -typedef void (iksTClose)(void *socket); -typedef int (iksTConnect)(iksparser *prs, void **socketptr, const char *server, int port); -typedef int (iksTSend)(void *socket, const char *data, size_t len); -typedef int (iksTRecv)(void *socket, char *buffer, size_t buf_len, int timeout); -typedef int (iksAsyncNotify)(void *user_data, iksasyncevent *event); -typedef int (iksTConnectAsync)(iksparser *prs, void **socketptr, const char *server, const char *server_name, int port, void *notify_data, iksAsyncNotify *notify_func); - -#define IKS_TRANSPORT_V1 0 - -typedef const struct ikstransport_struct { - int abi_version; - /* basic api, connect can be NULL if only async api is provided */ - iksTConnect *connect; - iksTSend *send; - iksTRecv *recv; - iksTClose *close; - /* optional async api */ - iksTConnectAsync *connect_async; -} ikstransport; - -extern ikstransport iks_default_transport; - -/***** stream parser *****/ - -enum iksneterror { - IKS_NET_NODNS = 4, - IKS_NET_NOSOCK, - IKS_NET_NOCONN, - IKS_NET_RWERR, - IKS_NET_NOTSUPP, - IKS_NET_TLSFAIL, - IKS_NET_DROPPED, - IKS_NET_UNKNOWN -}; - -enum iksnodetype { - IKS_NODE_START, - IKS_NODE_NORMAL, - IKS_NODE_ERROR, - IKS_NODE_STOP -}; - -enum ikssasltype { - IKS_SASL_PLAIN, - IKS_SASL_DIGEST_MD5 -}; - -#define IKS_JABBER_PORT 5222 - -typedef int (iksStreamHook)(void *user_data, int type, iks *node); -typedef void (iksLogHook)(void *user_data, const char *data, size_t size, int is_incoming); - -iksparser *iks_stream_new (char *name_space, void *user_data, iksStreamHook *streamHook); -void *iks_stream_user_data (iksparser *prs); -void iks_set_log_hook (iksparser *prs, iksLogHook *logHook); -int iks_connect_tcp (iksparser *prs, const char *server, int port); -int iks_connect_fd (iksparser *prs, int fd); -int iks_connect_via (iksparser *prs, const char *server, int port, const char *server_name); -int iks_connect_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans); -int iks_connect_async (iksparser *prs, const char *server, int port, void *notify_data, iksAsyncNotify *notify_func); -int iks_connect_async_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans, void *notify_data, iksAsyncNotify *notify_func); -int iks_fd (iksparser *prs); -int iks_recv (iksparser *prs, int timeout); -int iks_send_header (iksparser *prs, const char *to); -int iks_send (iksparser *prs, iks *x); -int iks_send_raw (iksparser *prs, const char *xmlstr); -void iks_disconnect (iksparser *prs); -int iks_has_tls (void); -int iks_is_secure (iksparser *prs); -int iks_start_tls (iksparser *prs); -int iks_proceed_tls (iksparser *prs, const char *cert_file, const char *key_file); -int iks_start_sasl (iksparser *prs, enum ikssasltype type, char *username, char *pass); - -/***** jabber *****/ - -#define IKS_NS_CLIENT "jabber:client" -#define IKS_NS_SERVER "jabber:server" -#define IKS_NS_AUTH "jabber:iq:auth" -#define IKS_NS_AUTH_0K "jabber:iq:auth:0k" -#define IKS_NS_REGISTER "jabber:iq:register" -#define IKS_NS_ROSTER "jabber:iq:roster" -#define IKS_NS_XROSTER "jabber:x:roster" -#define IKS_NS_OFFLINE "jabber:x:offline" -#define IKS_NS_AGENT "jabber:iq:agent" -#define IKS_NS_AGENTS "jabber:iq:agents" -#define IKS_NS_BROWSE "jabber:iq:browse" -#define IKS_NS_CONFERENCE "jabber:iq:conference" -#define IKS_NS_DELAY "jabber:x:delay" -#define IKS_NS_VERSION "jabber:iq:version" -#define IKS_NS_TIME "jabber:iq:time" -#define IKS_NS_VCARD "vcard-temp" -#define IKS_NS_PRIVATE "jabber:iq:private" -#define IKS_NS_SEARCH "jabber:iq:search" -#define IKS_NS_OOB "jabber:iq:oob" -#define IKS_NS_XOOB "jabber:x:oob" -#define IKS_NS_ADMIN "jabber:iq:admin" -#define IKS_NS_FILTER "jabber:iq:filter" -#define IKS_NS_GATEWAY "jabber:iq:gateway" -#define IKS_NS_LAST "jabber:iq:last" -#define IKS_NS_SIGNED "jabber:x:signed" -#define IKS_NS_ENCRYPTED "jabber:x:encrypted" -#define IKS_NS_ENVELOPE "jabber:x:envelope" -#define IKS_NS_EVENT "jabber:x:event" -#define IKS_NS_EXPIRE "jabber:x:expire" -#define IKS_NS_XHTML "http://www.w3.org/1999/xhtml" -#define IKS_NS_XMPP_SASL "urn:ietf:params:xml:ns:xmpp-sasl" -#define IKS_NS_XMPP_BIND "urn:ietf:params:xml:ns:xmpp-bind" -#define IKS_NS_XMPP_SESSION "urn:ietf:params:xml:ns:xmpp-session" - -#define IKS_ID_USER 1 -#define IKS_ID_SERVER 2 -#define IKS_ID_RESOURCE 4 -#define IKS_ID_PARTIAL IKS_ID_USER | IKS_ID_SERVER -#define IKS_ID_FULL IKS_ID_USER | IKS_ID_SERVER | IKS_ID_RESOURCE - -#define IKS_STREAM_STARTTLS 1 -#define IKS_STREAM_SESSION 2 -#define IKS_STREAM_BIND 4 -#define IKS_STREAM_SASL_PLAIN 8 -#define IKS_STREAM_SASL_MD5 16 - -typedef struct iksid_struct { - char *user; - char *server; - char *resource; - char *partial; - char *full; -} iksid; - -iksid *iks_id_new (ikstack *s, const char *jid); -int iks_id_cmp (iksid *a, iksid *b, int parts); - -enum ikspaktype { - IKS_PAK_NONE = 0, - IKS_PAK_MESSAGE, - IKS_PAK_PRESENCE, - IKS_PAK_IQ, - IKS_PAK_S10N -}; - -enum iksubtype { - IKS_TYPE_NONE = 0, - IKS_TYPE_ERROR, - - IKS_TYPE_CHAT, - IKS_TYPE_GROUPCHAT, - IKS_TYPE_HEADLINE, - - IKS_TYPE_GET, - IKS_TYPE_SET, - IKS_TYPE_RESULT, - - IKS_TYPE_SUBSCRIBE, - IKS_TYPE_SUBSCRIBED, - IKS_TYPE_UNSUBSCRIBE, - IKS_TYPE_UNSUBSCRIBED, - IKS_TYPE_PROBE, - IKS_TYPE_AVAILABLE, - IKS_TYPE_UNAVAILABLE -}; - -enum ikshowtype { - IKS_SHOW_UNAVAILABLE = 0, - IKS_SHOW_AVAILABLE, - IKS_SHOW_CHAT, - IKS_SHOW_AWAY, - IKS_SHOW_XA, - IKS_SHOW_DND -}; - -typedef struct ikspak_struct { - iks *x; - iksid *from; - iks *query; - char *ns; - char *id; - enum ikspaktype type; - enum iksubtype subtype; - enum ikshowtype show; -} ikspak; - -ikspak *iks_packet (iks *x); - -iks *iks_make_auth (iksid *id, const char *pass, const char *sid); -iks *iks_make_msg (enum iksubtype type, const char *to, const char *body); -iks *iks_make_s10n (enum iksubtype type, const char *to, const char *msg); -iks *iks_make_pres (enum ikshowtype show, const char *status); -iks *iks_make_iq (enum iksubtype type, const char *xmlns); -iks *iks_make_resource_bind(iksid *id); -iks *iks_make_session(void); -int iks_stream_features(iks *x); - -/***** jabber packet filter *****/ - -#define IKS_RULE_DONE 0 -#define IKS_RULE_ID 1 -#define IKS_RULE_TYPE 2 -#define IKS_RULE_SUBTYPE 4 -#define IKS_RULE_FROM 8 -#define IKS_RULE_FROM_PARTIAL 16 -#define IKS_RULE_NS 32 - -enum iksfilterret { - IKS_FILTER_PASS, - IKS_FILTER_EAT -}; - -typedef int (iksFilterHook)(void *user_data, ikspak *pak); - -struct iksfilter_struct; -typedef struct iksfilter_struct iksfilter; -struct iksrule_struct; -typedef struct iksrule_struct iksrule; - -iksfilter *iks_filter_new (void); -iksrule *iks_filter_add_rule (iksfilter *f, iksFilterHook *filterHook, void *user_data, ...); -void iks_filter_remove_rule (iksfilter *f, iksrule *rule); -void iks_filter_remove_hook (iksfilter *f, iksFilterHook *filterHook); -void iks_filter_packet (iksfilter *f, ikspak *pak); -void iks_filter_delete (iksfilter *f); - -/***** sha1 *****/ - -struct iksha_struct; -typedef struct iksha_struct iksha; - -iksha *iks_sha_new (void); -void iks_sha_reset (iksha *sha); -void iks_sha_hash (iksha *sha, const unsigned char *data, size_t len, int finish); -void iks_sha_print (iksha *sha, char *hash); -void iks_sha_delete (iksha *sha); -void iks_sha (const char *data, char *hash); - -/***** md5 *****/ - -struct ikmd5_struct; -typedef struct iksmd5_struct iksmd5; - -iksmd5 *iks_md5_new(void); -void iks_md5_reset(iksmd5 *md5); -void iks_md5_hash(iksmd5 *md5, const unsigned char *data, size_t slen, int finish); -void iks_md5_delete(iksmd5 *md5); -void iks_md5_print(iksmd5 *md5, char *buf); -void iks_md5_digest(iksmd5 *md5, unsigned char *digest); -void iks_md5(const char *data, char *buf); - -/***** base64 *****/ - -char *iks_base64_decode(const char *buf); -char *iks_base64_encode(const char *buf, int len); - -#ifdef __cplusplus -} -#endif - -#endif /* IKSEMEL_H */ diff --git a/libs/iksemel/include/stamp-h.in b/libs/iksemel/include/stamp-h.in deleted file mode 100644 index 9788f70238..0000000000 --- a/libs/iksemel/include/stamp-h.in +++ /dev/null @@ -1 +0,0 @@ -timestamp diff --git a/libs/iksemel/ltmain.sh b/libs/iksemel/ltmain.sh deleted file mode 100755 index 0223495a02..0000000000 --- a/libs/iksemel/ltmain.sh +++ /dev/null @@ -1,6911 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -basename="s,^.*/,,g" - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - -# The name of this program: -progname=`echo "$progpath" | $SED $basename` -modename="$progname" - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 - -PROGRAM=ltmain.sh -PACKAGE=libtool -VERSION=1.5.22 -TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" - -# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$progpath" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -duplicate_deps=no -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -##################################### -# Shell function definitions: -# This seems to be the best place for them - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $mkdir "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || { - $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 - exit $EXIT_FAILURE - } - fi - - $echo "X$my_tmpdir" | $Xsed -} - - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -func_win32_libid () -{ - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ - $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then - win32_nmres=`eval $NM -f posix -A $1 | \ - $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $echo $win32_libid_type -} - - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case "$@ " in - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - $echo "$modename: unable to infer tagged configuration" - $echo "$modename: specify a tag with \`--tag'" 1>&2 - exit $EXIT_FAILURE -# else -# $echo "$modename: using $tagname tagged configuration" - fi - ;; - esac - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - - $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" - $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 - exit $EXIT_FAILURE - fi -} - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - my_status="" - - $show "${rm}r $my_gentop" - $run ${rm}r "$my_gentop" - $show "$mkdir $my_gentop" - $run $mkdir "$my_gentop" - my_status=$? - if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then - exit $my_status - fi - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - extracted_serial=`expr $extracted_serial + 1` - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - $show "${rm}r $my_xdir" - $run ${rm}r "$my_xdir" - $show "$mkdir $my_xdir" - $run $mkdir "$my_xdir" - exit_status=$? - if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then - exit $exit_status - fi - case $host in - *-darwin*) - $show "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - if test -z "$run"; then - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` - darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` - if test -n "$darwin_arches"; then - darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - $show "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we have a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` - lipo -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - ${rm}r unfat-$$ - cd "$darwin_orig_dir" - else - cd "$darwin_orig_dir" - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - fi # $run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - func_extract_archives_result="$my_oldobjs" -} -# End of Shell function definitions -##################################### - -# Darwin sucks -eval std_shrext=\"$shrext_cmds\" - -disable_libs=no - -# Parse our command line options once, thoroughly. -while test "$#" -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - tag) - tagname="$arg" - preserve_args="${preserve_args}=$arg" - - # Check whether tagname contains only valid characters - case $tagname in - *[!-_A-Za-z0-9,/]*) - $echo "$progname: invalid tag name: $tagname" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $tagname in - CC) - # Don't test for the "default" C tag, as we know, it's there, but - # not specially marked. - ;; - *) - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then - taglist="$taglist $tagname" - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" - else - $echo "$progname: ignoring unknown tag $tagname" 1>&2 - fi - ;; - esac - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - $echo - $echo "Copyright (C) 2005 Free Software Foundation, Inc." - $echo "This is free software; see the source for copying conditions. There is NO" - $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - exit $? - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath - # Now print the configurations for the tags. - for tagname in $taglist; do - ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" - done - exit $? - ;; - - --debug) - $echo "$progname: enabling shell trace mode" - set -x - preserve_args="$preserve_args $arg" - ;; - - --dry-run | -n) - run=: - ;; - - --features) - $echo "host: $host" - if test "$build_libtool_libs" = yes; then - $echo "enable shared libraries" - else - $echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - $echo "enable static libraries" - else - $echo "disable static libraries" - fi - exit $? - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - preserve_args="$preserve_args $arg" - ;; - - --tag) - prevopt="--tag" - prev=tag - preserve_args="$preserve_args --tag" - ;; - --tag=*) - set tag "$optarg" ${1+"$@"} - shift - prev=tag - preserve_args="$preserve_args --tag" - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE -fi - -case $disable_libs in -no) - ;; -shared) - build_libtool_libs=no - build_old_libs=yes - ;; -static) - build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` - ;; -esac - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 - $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 - case $nonopt in - *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - if test -n "$libobj" ; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit $EXIT_FAILURE - fi - arg_mode=target - continue - ;; - - -static | -prefer-pic | -prefer-non-pic) - later="$later $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - base_compile="$base_compile $lastarg" - continue - ;; - - * ) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - case $lastarg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, and some SunOS ksh mistreat backslash-escaping - # in scan sets (worked around with variable expansion), - # and furthermore cannot handle '|' '&' '(' ')' in scan sets - # at all, so we specify them separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - base_compile="$base_compile $lastarg" - done # for arg - - case $arg_mode in - arg) - $echo "$modename: you must specify an argument for -Xcompile" - exit $EXIT_FAILURE - ;; - target) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit $EXIT_FAILURE - ;; - *) - # Get the name of the library object. - [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSifmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.ii) xform=ii ;; - *.class) xform=class ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - *.java) xform=java ;; - *.obj) xform=obj ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` - case $qlibobj in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qlibobj="\"$qlibobj\"" ;; - esac - test "X$libobj" != "X$qlibobj" \ - && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." - objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir= - else - xdir=$xdir/ - fi - lobj=${xdir}$objdir/$objname - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$progpath" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - $echo "$srcfile" > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` - case $qsrcfile in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qsrcfile="\"$qsrcfile\"" ;; - esac - - $run $rm "$libobj" "${libobj}T" - - # Create a libtool object file (analogous to a ".la" file), - # but don't create it if we're doing a dry run. - test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - $show "$mv $output_obj $lobj" - if $run $mv $output_obj $lobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the PIC object to the libtool object file. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the non-PIC object the libtool object file. - # Only append if the libtool object file exists. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit $EXIT_FAILURE - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat $save_arg` - do -# moreargs="$moreargs $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - done - else - $echo "$modename: link input file \`$save_arg' does not exist" - exit $EXIT_FAILURE - fi - arg=$save_arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - xcclinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - darwin_framework|darwin_framework_skip) - test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - prev= - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit $EXIT_FAILURE - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework|-arch|-isysroot) - case " $CC " in - *" ${arg} ${1} "* | *" ${arg} ${1} "*) - prev=darwin_framework_skip ;; - *) compiler_flags="$compiler_flags $arg" - prev=darwin_framework ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - notinst_path="$notinst_path $dir" - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - *) dllsearchpath="$dllsearchpath:$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - deplibs="$deplibs -framework System" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - -model) - compile_command="$compile_command $arg" - compiler_flags="$compiler_flags $arg" - finalize_command="$finalize_command $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # -64, -mips[0-9] enable 64-bit mode on the SGI compiler - # -r[0-9][0-9]* specifies the processor on the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler - # +DA*, +DD* enable 64-bit mode on the HP compiler - # -q* pass through compiler args for the IBM compiler - # -m* pass through architecture-specific compiler args for GCC - # -m*, -t[45]*, -txscale* pass through architecture-specific - # compiler args for GCC - # -pg pass through profiling flag for GCC - # @file GCC response files - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ - -t[45]*|-txscale*|@*) - - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - compiler_flags="$compiler_flags $arg" - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.$objext) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d "$output_objdir"; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - exit_status=$? - if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then - exit $exit_status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - case $host in - *cygwin* | *mingw* | *pw32*) - # don't eliminate duplications in $postdeps and $predeps - duplicate_compiler_generated_deps=yes - ;; - *) - duplicate_compiler_generated_deps=$duplicate_deps - ;; - esac - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; - esac - pre_post_deps="$pre_post_deps $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - compiler_flags="$compiler_flags $deplib" - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if (${SED} -e '2q' $lib | - grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - library_names= - old_library= - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - if eval $echo \"$deplib\" 2>/dev/null \ - | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - $echo - $echo "*** Warning: Trying to link with static lib archive $deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because the file extensions .$libext of this argument makes me believe" - $echo "*** that it is just a static archive that I should not used here." - else - $echo - $echo "*** Warning: Linking the shared library $output against the" - $echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 - exit $EXIT_FAILURE - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit $EXIT_FAILURE - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - dlprefiles="$dlprefiles $lib $dependency_libs" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $absdir" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes ; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - # This is a shared library - - # Warn about portability, can't link against -module's on - # some systems (darwin) - if test "$shouldnotlink" = yes && test "$pass" = link ; then - $echo - if test "$linkmode" = prog; then - $echo "*** Warning: Linking the executable $output against the loadable module" - else - $echo "*** Warning: Linking the shared library $output against the loadable module" - fi - $echo "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`$echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$extract_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$old_archive_from_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a module then we can not link against - # it, someone is ignoring the new warnings I added - if /usr/bin/file -L $add 2> /dev/null | - $EGREP ": [^:]* bundle" >/dev/null ; then - $echo "** Warning, lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - $echo - $echo "** And there doesn't seem to be a static archive available" - $echo "** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit $EXIT_FAILURE - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - $echo - $echo "*** Warning: This system can not link to static lib archive $lib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - $echo "*** But as you try to build a module library, libtool will still create " - $echo "*** a static module, that should work as long as the dlopening application" - $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="$absdir" - fi - depdepl= - case $host in - *-*-darwin*) - # we do not want to link against static libs, - # but need to link against shared - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$path/$depdepl" ; then - depdepl="$path/$depdepl" - fi - # do not add paths which are already there - case " $newlib_search_path " in - *" $path "*) ;; - *) newlib_search_path="$newlib_search_path $path";; - esac - fi - path="" - ;; - *) - path="-L$path" - ;; - esac - ;; - -l*) - case $host in - *-*-darwin*) - # Again, we only want to link against shared libraries - eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` - for tmp in $newlib_search_path ; do - if test -f "$tmp/lib$tmp_libs.dylib" ; then - eval depdepl="$tmp/lib$tmp_libs.dylib" - break - fi - done - path="" - ;; - *) continue ;; - esac - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - case " $deplibs " in - *" $depdepl "*) ;; - *) deplibs="$depdepl $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - tmp_libs="$tmp_libs $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit $EXIT_FAILURE - else - $echo - $echo "*** Warning: Linking the shared library $output against the non-libtool" - $echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test "$#" -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$2" - number_minor="$3" - number_revision="$4" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows|none) - current=`expr $number_major + $number_minor` - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - current=`expr $number_major + $number_minor - 1` - age="$number_minor" - revision="$number_minor" - ;; - esac - ;; - no) - current="$2" - revision="$3" - age="$4" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test "$age" -gt "$current"; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - major=`expr $current - $age + 1` - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$echo "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - removelist="$removelist $p" - ;; - *) ;; - esac - done - if test -n "$removelist"; then - $show "${rm}r $removelist" - $run ${rm}r $removelist - fi - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. -# for path in $notinst_path; do -# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` -# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` -# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` -# done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for file magic test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name=`expr $a_deplib : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval $echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` - done - fi - if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ - | grep . >/dev/null; then - $echo - if test "X$deplibs_check_method" = "Xnone"; then - $echo "*** Warning: inter-library dependencies are not supported in this platform." - else - $echo "*** Warning: inter-library dependencies are not known to be supported." - fi - $echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - $echo - $echo "*** Warning: libtool could not satisfy all declared inter-library" - $echo "*** dependencies of module $libname. Therefore, libtool will create" - $echo "*** a static module, that should work as long as the dlopening" - $echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - $echo "*** The inter-library dependencies that have been dropped here will be" - $echo "*** automatically added whenever a program is linked with this library" - $echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - $echo - $echo "*** Since this library must not contain undefined symbols," - $echo "*** because either the platform does not support them or" - $echo "*** it was explicitly requested with -no-undefined," - $echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; - esac - ;; - *) new_libs="$new_libs $deplib" ;; - esac - done - deplibs="$new_libs" - - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - linknames="$linknames $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - if len=`expr "X$cmd" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - $show "$cmd" - $run eval "$cmd" || exit $? - skipped_export=false - else - # The command line is too long to execute in one step. - $show "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - tmp_deplibs="$tmp_deplibs $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - libobjs="$libobjs $func_extract_archives_result" - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise. - $echo "creating reloadable object files..." - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - output_la=`$echo "X$output" | $Xsed -e "$basename"` - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - delfiles= - last_robj= - k=1 - output=$output_objdir/$output_la-${k}.$objext - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" - if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - k=`expr $k + 1` - output=$output_objdir/$output_la-${k}.$objext - objlist=$obj - len=1 - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" - - if ${skipped_export-false}; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - libobjs=$output - # Append the command to create the export file. - eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" - fi - - # Set up a command to remove the reloadable object files - # after they are used. - i=0 - while test "$i" -lt "$k" - do - i=`expr $i + 1` - delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" - done - - $echo "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - - # Append the command to remove the reloadable object files - # to the just-reset $cmds. - eval cmds=\"\$cmds~\$rm $delfiles\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit $EXIT_FAILURE - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $run eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - if test "$tagname" = CXX ; then - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - fi - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; - esac - ;; - *) new_libs="$new_libs $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - *) dllsearchpath="$dllsearchpath:$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* ) - $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - else - $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* ) - $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval '$echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - $echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -" - - case $host in - *cygwin* | *mingw* ) - $echo >> "$output_objdir/$dlsyms" "\ -/* DATA imports from DLLs on WIN32 can't be const, because - runtime relocations are performed -- see ld's documentation - on pseudo-relocs */ -struct { -" - ;; - * ) - $echo >> "$output_objdir/$dlsyms" "\ -const struct { -" - ;; - esac - - - $echo >> "$output_objdir/$dlsyms" "\ - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - case $host in - *cygwin* | *mingw* ) - if test -f "$output_objdir/${outputname}.def" ; then - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` - else - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - fi - ;; - * ) - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - ;; - esac - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` - fi - - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - exit_status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $exit_status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then - case $progpath in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; - *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - output_name=`basename $output` - output_path=`dirname $output` - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $rm $cwrappersource $cwrapper - trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - cat > $cwrappersource <> $cwrappersource<<"EOF" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -/* -DDEBUG is fairly common in CFLAGS. */ -#undef DEBUG -#if defined DEBUGWRAPPER -# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) -#else -# define DEBUG(format, ...) -#endif - -const char *program_name = NULL; - -void * xmalloc (size_t num); -char * xstrdup (const char *string); -const char * base_name (const char *name); -char * find_executable(const char *wrapper); -int check_executable(const char *path); -char * strendzap(char *str, const char *pat); -void lt_fatal (const char *message, ...); - -int -main (int argc, char *argv[]) -{ - char **newargz; - int i; - - program_name = (char *) xstrdup (base_name (argv[0])); - DEBUG("(main) argv[0] : %s\n",argv[0]); - DEBUG("(main) program_name : %s\n",program_name); - newargz = XMALLOC(char *, argc+2); -EOF - - cat >> $cwrappersource <> $cwrappersource <<"EOF" - newargz[1] = find_executable(argv[0]); - if (newargz[1] == NULL) - lt_fatal("Couldn't find %s", argv[0]); - DEBUG("(main) found exe at : %s\n",newargz[1]); - /* we know the script has the same name, without the .exe */ - /* so make sure newargz[1] doesn't end in .exe */ - strendzap(newargz[1],".exe"); - for (i = 1; i < argc; i++) - newargz[i+1] = xstrdup(argv[i]); - newargz[argc+1] = NULL; - - for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" - return 127; -} - -void * -xmalloc (size_t num) -{ - void * p = (void *) malloc (num); - if (!p) - lt_fatal ("Memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL -; -} - -const char * -base_name (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha ((unsigned char)name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return base; -} - -int -check_executable(const char * path) -{ - struct stat st; - - DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); - if ((!path) || (!*path)) - return 0; - - if ((stat (path, &st) >= 0) && - ( - /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ -#if defined (S_IXOTH) - ((st.st_mode & S_IXOTH) == S_IXOTH) || -#endif -#if defined (S_IXGRP) - ((st.st_mode & S_IXGRP) == S_IXGRP) || -#endif - ((st.st_mode & S_IXUSR) == S_IXUSR)) - ) - return 1; - else - return 0; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise */ -char * -find_executable (const char* wrapper) -{ - int has_slash = 0; - const char* p; - const char* p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char* concat_name; - - DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char* path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char* q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR(*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - tmp_len = strlen(tmp); - concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - tmp_len = strlen(tmp); - concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - return NULL; -} - -char * -strendzap(char *str, const char *pat) -{ - size_t len, patlen; - - assert(str != NULL); - assert(pat != NULL); - - len = strlen(str); - patlen = strlen(pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp(str, pat) == 0) - *str = '\0'; - } - return str; -} - -static void -lt_error_core (int exit_status, const char * mode, - const char * message, va_list ap) -{ - fprintf (stderr, "%s: %s: ", program_name, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, "FATAL", message, ap); - va_end (ap); -} -EOF - # we should really use a build-platform specific compiler - # here, but OTOH, the wrappers (shell script and this C one) - # are only useful if you want to execute the "real" binary. - # Since the "real" binary is built for $host, then this - # wrapper might as well be built for $host, too. - $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource - ;; - esac - $rm $output - trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='${SED} -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - $echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit $EXIT_FAILURE - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - $echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \$*\" - exit $EXIT_FAILURE - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - $echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit $EXIT_FAILURE - fi -fi\ -" - chmod +x $output - fi - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $addlibs - oldobjs="$oldobjs $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - $echo "X$obj" | $Xsed -e 's%^.*/%%' - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "copying selected object files to avoid basename conflicts..." - - if test -z "$gentop"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - exit_status=$? - if test "$exit_status" -ne 0 && test ! -d "$gentop"; then - exit $exit_status - fi - fi - - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - counter=`expr $counter + 1` - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - $run ln "$obj" "$gentop/$newobj" || - $run cp "$obj" "$gentop/$newobj" - oldobjs="$oldobjs $gentop/$newobj" - ;; - *) oldobjs="$oldobjs $obj" ;; - esac - done - fi - - eval cmds=\"$old_archive_cmds\" - - if len=`expr "X$cmds" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - $echo "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - for obj in $save_oldobjs - do - oldobjs="$objlist $obj" - objlist="$objlist $obj" - eval test_cmds=\"$old_archive_cmds\" - if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - eval cmd=\"$cmd\" - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlfiles="$newdlfiles $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlprefiles="$newdlprefiles $abs" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit $EXIT_SUCCESS - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - case " $install_prog " in - *[\\\ /]cp\ *) ;; - *) prev=$arg ;; - esac - ;; - -g | -m | -o) prev=$arg ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test "$#" -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` - else - relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - exit $EXIT_FAILURE - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - cmds=$postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - file=`$echo $file|${SED} 's,.exe$,,'` - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit $EXIT_FAILURE - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir=`func_mktempdir` - file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$old_striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - cmds=$old_postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - cmds=$finish_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = : && exit $EXIT_SUCCESS - - $echo "X----------------------------------------------------------------------" | $Xsed - $echo "Libraries have been installed in:" - for libdir in $libdirs; do - $echo " $libdir" - done - $echo - $echo "If you ever happen to want to link against installed libraries" - $echo "in a given directory, LIBDIR, you must either use libtool, and" - $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - $echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - $echo " during execution" - fi - if test -n "$runpath_var"; then - $echo " - add LIBDIR to the \`$runpath_var' environment variable" - $echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - $echo - $echo "See any operating system documentation about shared libraries for" - $echo "more information, such as the ld(1) and ld.so(8) manual pages." - $echo "X----------------------------------------------------------------------" | $Xsed - exit $EXIT_SUCCESS - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit $EXIT_FAILURE - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit $EXIT_FAILURE - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit $EXIT_SUCCESS - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - rmdirs= - - origobjdir="$objdir" - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$origobjdir" - else - objdir="$dir/$origobjdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test "$mode" = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - - case "$mode" in - clean) - case " $library_names " in - # " " in the beginning catches empty $dlname - *" $dlname "*) ;; - *) rmfiles="$rmfiles $objdir/$dlname" ;; - esac - test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - cmds=$postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - cmds=$old_postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - - # Read the .lo file - . $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" \ - && test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" \ - && test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$mode" = clean ; then - noexename=$name - case $file in - *.exe) - file=`$echo $file|${SED} 's,.exe$,,'` - noexename=`$echo $name|${SED} 's,.exe$,,'` - # $file with .exe has already been added to rmfiles, - # add $file without .exe - rmfiles="$rmfiles $file" - ;; - esac - # Do a test to see if this is a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$noexename - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - objdir="$origobjdir" - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit $EXIT_FAILURE -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE. - -Report bugs to ." - exit $EXIT_SUCCESS - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; -esac - -$echo -$echo "Try \`$modename --help' for more information about other modes." - -exit $? - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -disable_libs=shared -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -disable_libs=static -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/libs/iksemel/openssl.m4 b/libs/iksemel/openssl.m4 deleted file mode 100644 index 6bf1851021..0000000000 --- a/libs/iksemel/openssl.m4 +++ /dev/null @@ -1,49 +0,0 @@ -dnl ====================================================================== -dnl SAC_OPENSSL -dnl ====================================================================== -AC_DEFUN([SAC_OPENSSL], [ - -AC_ARG_WITH(openssl, -[ --with-openssl use OpenSSL [[enabled]]],, with_openssl=pkg-config) - -dnl SOSXXX:SAC_ASSERT_DEF([openssl libraries]) - - -if test "$with_openssl" = no ;then - : # No openssl -else - - if test "$with_openssl" = "pkg-config" ; then - PKG_CHECK_MODULES(openssl, openssl, - [HAVE_TLS=1 HAVE_SSL=1 LIBS="$openssl_LIBS $LIBS"], - [HAVE_SSL=0]) - fi - - if test x$HAVE_SSL = x1 ; then - AC_DEFINE([HAVE_LIBCRYPTO], 1, [Define to 1 if you have the `crypto' library (-lcrypto).]) - AC_DEFINE([HAVE_LIBSSL], 1, [Define to 1 if you have the `ssl' library (-lssl).]) - else - AC_CHECK_HEADERS([openssl/tls1.h], [ - HAVE_SSL=1 HAVE_TLS=1 - - AC_CHECK_LIB(crypto, BIO_new,, - HAVE_SSL=0 - AC_MSG_WARN(OpenSSL crypto library was not found)) - - AC_CHECK_LIB(ssl, TLSv1_method,, - HAVE_TLS=0 - AC_MSG_WARN(OpenSSL protocol library was not found)) - ],[AC_MSG_WARN(OpenSSL include files were not found)],[#include ]) - fi - - if test x$HAVE_SSL = x1; then - AC_DEFINE([HAVE_SSL], 1, [Define to 1 if you have OpenSSL]) - fi - - if test x$HAVE_TLS = x1; then - AC_DEFINE([HAVE_TLS], 1, [Define to 1 if you have TLS]) - fi -fi - -AM_CONDITIONAL(HAVE_TLS, test x$HAVE_TLS = x1) -]) diff --git a/libs/iksemel/src/Makefile.am b/libs/iksemel/src/Makefile.am deleted file mode 100644 index 0997e84221..0000000000 --- a/libs/iksemel/src/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -## -## Process this file with automake to produce Makefile.in -## - -AM_CPPFLAGS = -I$(top_srcdir)/include - -lib_LTLIBRARIES = libiksemel.la - -if DO_POSIX -posix_c = io-posix.c -endif - -libiksemel_la_SOURCES = \ - ikstack.c \ - utility.c \ - iks.c \ - sax.c \ - dom.c \ - $(posix_c) \ - stream.c \ - sha.c \ - jabber.c \ - filter.c \ - md5.c \ - base64.c - -libiksemel_la_LDFLAGS = -version-info 4:0:1 -no-undefined -libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) -libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) diff --git a/libs/iksemel/src/base64.c b/libs/iksemel/src/base64.c deleted file mode 100644 index bb89ce86a7..0000000000 --- a/libs/iksemel/src/base64.c +++ /dev/null @@ -1,103 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -static const char base64_charset[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - -char *iks_base64_decode(const char *buf) -{ - char *res, *save; - char val; - const char *foo; - const char *end; - int index; - size_t len; - - if (!buf) - return NULL; - - len = iks_strlen(buf) * 6 / 8 + 1; - - save = res = iks_malloc(len); - if (!save) - return NULL; - memset(res, 0, len); - - index = 0; - end = buf + iks_strlen(buf); - - while (*buf && buf < end) { - if (!(foo = strchr(base64_charset, *buf))) - foo = base64_charset; - val = (int)(foo - base64_charset); - buf++; - switch (index) { - case 0: - *res |= val << 2; - break; - case 1: - *res++ |= val >> 4; - *res |= val << 4; - break; - case 2: - *res++ |= val >> 2; - *res |= val << 6; - break; - case 3: - *res++ |= val; - break; - } - index++; - index %= 4; - } - *res = 0; - - return save; -} - -char *iks_base64_encode(const char *buf, int len) -{ - char *res, *save; - int k, t; - - len = (len > 0) ? (len) : (iks_strlen(buf)); - save = res = iks_malloc((len*8) / 6 + 4); - if (!save) return NULL; - - for (k = 0; k < len/3; ++k) { - *res++ = base64_charset[*buf >> 2]; - t = ((*buf & 0x03) << 4); - buf++; - *res++ = base64_charset[t | (*buf >> 4)]; - t = ((*buf & 0x0F) << 2); - buf++; - *res++ = base64_charset[t | (*buf >> 6)]; - *res++ = base64_charset[*buf++ & 0x3F]; - } - - switch (len % 3) { - case 2: - *res++ = base64_charset[*buf >> 2]; - t = ((*buf & 0x03) << 4); - buf++; - *res++ = base64_charset[t | (*buf >> 4)]; - *res++ = base64_charset[((*buf++ & 0x0F) << 2)]; - *res++ = '='; - break; - case 1: - *res++ = base64_charset[*buf >> 2]; - *res++ = base64_charset[(*buf++ & 0x03) << 4]; - *res++ = '='; - *res++ = '='; - break; - } - *res = 0; - return save; -} diff --git a/libs/iksemel/src/dom.c b/libs/iksemel/src/dom.c deleted file mode 100644 index 849bf20fd7..0000000000 --- a/libs/iksemel/src/dom.c +++ /dev/null @@ -1,181 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -struct dom_data { - iks **iksptr; - iks *current; - size_t chunk_size; -}; - -static int -tagHook (struct dom_data *data, char *name, char **atts, int type) -{ - iks *x; - - if (IKS_OPEN == type || IKS_SINGLE == type) { - if (data->current) { - x = iks_insert (data->current, name); - } else { - ikstack *s; - s = iks_stack_new (data->chunk_size, data->chunk_size); - x = iks_new_within (name, s); - } - if (atts) { - int i=0; - while (atts[i]) { - iks_insert_attrib (x, atts[i], atts[i+1]); - i += 2; - } - } - data->current = x; - } - if (IKS_CLOSE == type || IKS_SINGLE == type) { - x = iks_parent (data->current); - if (iks_strcmp(iks_name(data->current), name) != 0) - return IKS_BADXML; - if (x) - data->current = x; - else { - *(data->iksptr) = data->current; - data->current = NULL; - } - } - return IKS_OK; -} - -static int -cdataHook (struct dom_data *data, char *cdata, size_t len) -{ - if (data->current) iks_insert_cdata (data->current, cdata, len); - return IKS_OK; -} - -static void -deleteHook (struct dom_data *data) -{ - if (data->current) iks_delete (data->current); - data->current = NULL; -} - -iksparser * -iks_dom_new (iks **iksptr) -{ - ikstack *s; - struct dom_data *data; - - *iksptr = NULL; - s = iks_stack_new (DEFAULT_DOM_CHUNK_SIZE, 0); - if (!s) return NULL; - data = iks_stack_alloc (s, sizeof (struct dom_data)); - data->iksptr = iksptr; - data->current = NULL; - data->chunk_size = DEFAULT_DOM_IKS_CHUNK_SIZE; - return iks_sax_extend (s, data, (iksTagHook *) tagHook, (iksCDataHook *) cdataHook, (iksDeleteHook *) deleteHook); -} - -void -iks_set_size_hint (iksparser *prs, size_t approx_size) -{ - size_t cs; - struct dom_data *data = iks_user_data (prs); - - cs = approx_size / 10; - if (cs < DEFAULT_DOM_IKS_CHUNK_SIZE) cs = DEFAULT_DOM_IKS_CHUNK_SIZE; - data->chunk_size = cs; -} - -iks * -iks_tree (const char *xml_str, size_t len, int *err) -{ - iksparser *prs; - iks *x; - int e; - - if (0 == len) len = strlen (xml_str); - prs = iks_dom_new (&x); - if (!prs) { - if (err) *err = IKS_NOMEM; - return NULL; - } - e = iks_parse (prs, xml_str, len, 1); - if (err) *err = e; - iks_parser_delete (prs); - return x; -} - -int -iks_load (const char *fname, iks **xptr) -{ - iksparser *prs; - char *buf; - FILE *f; - int len, done = 0; - int ret; - - *xptr = NULL; - - buf = iks_malloc (FILE_IO_BUF_SIZE); - if (!buf) return IKS_NOMEM; - ret = IKS_NOMEM; - prs = iks_dom_new (xptr); - if (prs) { - f = fopen (fname, "r"); - if (f) { - while (0 == done) { - len = fread (buf, 1, FILE_IO_BUF_SIZE, f); - if (len < FILE_IO_BUF_SIZE) { - if (0 == feof (f)) { - ret = IKS_FILE_RWERR; - break; - } - if (0 == len) ret = IKS_OK; - done = 1; - } - if (len > 0) { - int e; - e = iks_parse (prs, buf, len, done); - if (IKS_OK != e) { - ret = e; - break; - } - if (done) ret = IKS_OK; - } - } - fclose (f); - } else { - if (ENOENT == errno) ret = IKS_FILE_NOFILE; - else ret = IKS_FILE_NOACCESS; - } - iks_parser_delete (prs); - } - iks_free (buf); - return ret; -} - -int -iks_save (const char *fname, iks *x) -{ - FILE *f; - char *data; - int ret; - - ret = IKS_NOMEM; - data = iks_string (NULL, x); - if (data) { - ret = IKS_FILE_NOACCESS; - f = fopen (fname, "w"); - if (f) { - ret = IKS_FILE_RWERR; - if (fputs (data, f) >= 0) ret = IKS_OK; - fclose (f); - } - iks_free (data); - } - return ret; -} diff --git a/libs/iksemel/src/filter.c b/libs/iksemel/src/filter.c deleted file mode 100644 index d5cea11055..0000000000 --- a/libs/iksemel/src/filter.c +++ /dev/null @@ -1,181 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -struct iksrule_struct { - struct iksrule_struct *next, *prev; - ikstack *s; - void *user_data; - iksFilterHook *filterHook; - char *id; - char *from; - char *ns; - int score; - int rules; - enum ikstype type; - enum iksubtype subtype; -}; - -struct iksfilter_struct { - iksrule *rules; - iksrule *last_rule; -}; - -iksfilter * -iks_filter_new (void) -{ - iksfilter *f; - - f = iks_malloc (sizeof (iksfilter)); - if (!f) return NULL; - memset (f, 0, sizeof (iksfilter)); - - return f; -} - -iksrule * -iks_filter_add_rule (iksfilter *f, iksFilterHook *filterHook, void *user_data, ...) -{ - ikstack *s; - iksrule *rule; - va_list ap; - int type; - - s = iks_stack_new (sizeof (iksrule), DEFAULT_RULE_CHUNK_SIZE); - if (!s) return NULL; - rule = iks_stack_alloc (s, sizeof (iksrule)); - memset (rule, 0, sizeof (iksrule)); - rule->s = s; - rule->user_data = user_data; - rule->filterHook = filterHook; - - va_start (ap, user_data); - while (1) { - type = va_arg (ap, int); - if (IKS_RULE_DONE == type) break; - rule->rules += type; - switch (type) { - case IKS_RULE_TYPE: - rule->type = va_arg (ap, int); - break; - case IKS_RULE_SUBTYPE: - rule->subtype = va_arg (ap, int); - break; - case IKS_RULE_ID: - rule->id = iks_stack_strdup (s, va_arg (ap, char *), 0); - break; - case IKS_RULE_NS: - rule->ns = iks_stack_strdup (s, va_arg (ap, char *), 0); - break; - case IKS_RULE_FROM: - rule->from = iks_stack_strdup (s, va_arg (ap, char *), 0); - break; - case IKS_RULE_FROM_PARTIAL: - rule->from = iks_stack_strdup (s, va_arg (ap, char *), 0); - break; - } - } - va_end (ap); - - if (!f->rules) f->rules = rule; - if (f->last_rule) f->last_rule->next = rule; - rule->prev = f->last_rule; - f->last_rule = rule; - return rule; -} - -void -iks_filter_remove_rule (iksfilter *f, iksrule *rule) -{ - if (rule->prev) rule->prev->next = rule->next; - if (rule->next) rule->next->prev = rule->prev; - if (f->rules == rule) f->rules = rule->next; - if (f->last_rule == rule) f->last_rule = rule->prev; - iks_stack_delete (&rule->s); -} - -void -iks_filter_remove_hook (iksfilter *f, iksFilterHook *filterHook) -{ - iksrule *rule, *tmp; - - rule = f->rules; - while (rule) { - tmp = rule->next; - if (rule->filterHook == filterHook) iks_filter_remove_rule (f, rule); - rule = tmp; - } -} - -void -iks_filter_packet (iksfilter *f, ikspak *pak) -{ - iksrule *rule, *max_rule; - int fail, score, max_score; - - rule = f->rules; - max_rule = NULL; - max_score = 0; - while (rule) { - score = 0; - fail = 0; - if (rule->rules & IKS_RULE_TYPE) { - if (rule->type == pak->type) score += 1; else fail = 1; - } - if (rule->rules & IKS_RULE_SUBTYPE) { - if (rule->subtype == pak->subtype) score += 2; else fail = 1; - } - if (rule->rules & IKS_RULE_ID) { - if (iks_strcmp (rule->id, pak->id) == 0) score += 16; else fail = 1; - } - if (rule->rules & IKS_RULE_NS) { - if (iks_strcmp (rule->ns, pak->ns) == 0) score += 4; else fail = 1; - } - if (rule->rules & IKS_RULE_FROM) { - if (pak->from && iks_strcmp (rule->from, pak->from->full) == 0) score += 8; else fail = 1; - } - if (rule->rules & IKS_RULE_FROM_PARTIAL) { - if (pak->from && iks_strcmp (rule->from, pak->from->partial) == 0) score += 8; else fail = 1; - } - if (fail != 0) score = 0; - rule->score = score; - if (score > max_score) { - max_rule = rule; - max_score = score; - } - rule = rule->next; - } - while (max_rule) { - if (IKS_FILTER_EAT == max_rule->filterHook (max_rule->user_data, pak)) return; - max_rule->score = 0; - max_rule = NULL; - max_score = 0; - rule = f->rules; - while (rule) { - if (rule->score > max_score) { - max_rule = rule; - max_score = rule->score; - } - rule = rule->next; - } - } -} - -void -iks_filter_delete (iksfilter *f) -{ - iksrule *rule, *tmp; - - rule = f->rules; - while (rule) { - tmp = rule->next; - iks_stack_delete (&rule->s); - rule = tmp; - } - iks_free (f); -} diff --git a/libs/iksemel/src/iks.c b/libs/iksemel/src/iks.c deleted file mode 100644 index 75071c1329..0000000000 --- a/libs/iksemel/src/iks.c +++ /dev/null @@ -1,765 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2007 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -#define IKS_COMMON \ - struct iks_struct *next, *prev; \ - struct iks_struct *parent; \ - enum ikstype type; \ - ikstack *s - -struct iks_struct { - IKS_COMMON; -}; - -struct iks_tag { - IKS_COMMON; - struct iks_struct *children, *last_child; - struct iks_struct *attribs, *last_attrib; - char *name; -}; - -#define IKS_TAG_NAME(x) ((struct iks_tag *) (x) )->name -#define IKS_TAG_CHILDREN(x) ((struct iks_tag *) (x) )->children -#define IKS_TAG_LAST_CHILD(x) ((struct iks_tag *) (x) )->last_child -#define IKS_TAG_ATTRIBS(x) ((struct iks_tag *) (x) )->attribs -#define IKS_TAG_LAST_ATTRIB(x) ((struct iks_tag *) (x) )->last_attrib - -struct iks_cdata { - IKS_COMMON; - char *cdata; - size_t len; -}; - -#define IKS_CDATA_CDATA(x) ((struct iks_cdata *) (x) )->cdata -#define IKS_CDATA_LEN(x) ((struct iks_cdata *) (x) )->len - -struct iks_attrib { - IKS_COMMON; - char *name; - char *value; -}; - -#define IKS_ATTRIB_NAME(x) ((struct iks_attrib *) (x) )->name -#define IKS_ATTRIB_VALUE(x) ((struct iks_attrib *) (x) )->value - -/***** Node Creating & Deleting *****/ - -iks * -iks_new (const char *name) -{ - ikstack *s; - iks *x; - - s = iks_stack_new (sizeof (struct iks_tag) * 6, 256); - if (!s) return NULL; - x = iks_new_within (name, s); - if (!x) { - iks_stack_delete (&s); - return NULL; - } - return x; -} - -iks * -iks_new_within (const char *name, ikstack *s) -{ - iks *x; - size_t len; - - if (name) len = sizeof (struct iks_tag); else len = sizeof (struct iks_cdata); - x = iks_stack_alloc (s, len); - if (!x) return NULL; - memset (x, 0, len); - x->s = s; - x->type = IKS_TAG; - if (name) { - IKS_TAG_NAME (x) = iks_stack_strdup (s, name, 0); - if (!IKS_TAG_NAME (x)) return NULL; - } - return x; -} - -iks * -iks_insert (iks *x, const char *name) -{ - iks *y; - - if (!x) return NULL; - - y = iks_new_within (name, x->s); - if (!y) return NULL; - y->parent = x; - if (!IKS_TAG_CHILDREN (x)) IKS_TAG_CHILDREN (x) = y; - if (IKS_TAG_LAST_CHILD (x)) { - IKS_TAG_LAST_CHILD (x)->next = y; - y->prev = IKS_TAG_LAST_CHILD (x); - } - IKS_TAG_LAST_CHILD (x) = y; - return y; -} - -iks * -iks_insert_cdata (iks *x, const char *data, size_t len) -{ - iks *y; - - if(!x || !data) return NULL; - if(len == 0) len = strlen (data); - - y = IKS_TAG_LAST_CHILD (x); - if (y && y->type == IKS_CDATA) { - IKS_CDATA_CDATA (y) = iks_stack_strcat (x->s, IKS_CDATA_CDATA (y), IKS_CDATA_LEN (y), data, len); - IKS_CDATA_LEN (y) += len; - } else { - y = iks_insert (x, NULL); - if (!y) return NULL; - y->type = IKS_CDATA; - IKS_CDATA_CDATA (y) = iks_stack_strdup (x->s, data, len); - if (!IKS_CDATA_CDATA (y)) return NULL; - IKS_CDATA_LEN (y) = len; - } - return y; -} - -iks * -iks_insert_attrib (iks *x, const char *name, const char *value) -{ - iks *y; - - if (!x) return NULL; - - y = IKS_TAG_ATTRIBS (x); - while (y) { - if (strcmp (name, IKS_ATTRIB_NAME (y)) == 0) break; - y = y->next; - } - if (NULL == y) { - if (!value) return NULL; - y = iks_stack_alloc (x->s, sizeof (struct iks_attrib)); - if (!y) return NULL; - memset (y, 0, sizeof (struct iks_attrib)); - y->type = IKS_ATTRIBUTE; - y->s = x->s; - IKS_ATTRIB_NAME (y) = iks_stack_strdup (x->s, name, 0); - if (!IKS_ATTRIB_NAME (y)) return NULL; - y->parent = x; - if (!IKS_TAG_ATTRIBS (x)) IKS_TAG_ATTRIBS (x) = y; - if (IKS_TAG_LAST_ATTRIB (x)) { - IKS_TAG_LAST_ATTRIB (x)->next = y; - y->prev = IKS_TAG_LAST_ATTRIB (x); - } - IKS_TAG_LAST_ATTRIB (x) = y; - } - - if (value) { - IKS_ATTRIB_VALUE (y) = iks_stack_strdup (x->s, value, 0); - if (!IKS_ATTRIB_VALUE (y)) return NULL; - } else { - if (y->next) y->next->prev = y->prev; - if (y->prev) y->prev->next = y->next; - if (IKS_TAG_ATTRIBS (x) == y) IKS_TAG_ATTRIBS (x) = y->next; - if (IKS_TAG_LAST_ATTRIB (x) == y) IKS_TAG_LAST_ATTRIB (x) = y->prev; - } - - return y; -} - -iks * -iks_insert_node (iks *x, iks *y) -{ - y->parent = x; - if (!IKS_TAG_CHILDREN (x)) IKS_TAG_CHILDREN (x) = y; - if (IKS_TAG_LAST_CHILD (x)) { - IKS_TAG_LAST_CHILD (x)->next = y; - y->prev = IKS_TAG_LAST_CHILD (x); - } - IKS_TAG_LAST_CHILD (x) = y; - return y; -} - -iks * -iks_append (iks *x, const char *name) -{ - iks *y; - - if (!x) return NULL; - y = iks_new_within (name, x->s); - if (!y) return NULL; - - if (x->next) { - x->next->prev = y; - } else { - IKS_TAG_LAST_CHILD (x->parent) = y; - } - y->next = x->next; - x->next = y; - y->parent = x->parent; - y->prev = x; - - return y; -} - -iks * -iks_prepend (iks *x, const char *name) -{ - iks *y; - - if (!x) return NULL; - y = iks_new_within (name, x->s); - if (!y) return NULL; - - if (x->prev) { - x->prev->next = y; - } else { - IKS_TAG_CHILDREN (x->parent) = y; - } - y->prev = x->prev; - x->prev = y; - y->parent = x->parent; - y->next = x; - - return y; -} - -iks * -iks_append_cdata (iks *x, const char *data, size_t len) -{ - iks *y; - - if (!x || !data) return NULL; - if (len == 0) len = strlen (data); - - y = iks_new_within (NULL, x->s); - if (!y) return NULL; - y->type = IKS_CDATA; - IKS_CDATA_CDATA (y) = iks_stack_strdup (x->s, data, len); - if (!IKS_CDATA_CDATA (y)) return NULL; - IKS_CDATA_LEN (y) = len; - - if (x->next) { - x->next->prev = y; - } else { - IKS_TAG_LAST_CHILD (x->parent) = y; - } - y->next = x->next; - x->next = y; - y->parent = x->parent; - y->prev = x; - - return y; -} - -iks * -iks_prepend_cdata (iks *x, const char *data, size_t len) -{ - iks *y; - - if (!x || !data) return NULL; - if (len == 0) len = strlen (data); - - y = iks_new_within (NULL, x->s); - if (!y) return NULL; - y->type = IKS_CDATA; - IKS_CDATA_CDATA(y) = iks_stack_strdup (x->s, data, len); - if (!IKS_CDATA_CDATA (y)) return NULL; - IKS_CDATA_LEN (y) = len; - - if (x->prev) { - x->prev->next = y; - } else { - IKS_TAG_CHILDREN (x->parent) = y; - } - y->prev = x->prev; - x->prev = y; - y->parent = x->parent; - y->next = x; - - return y; -} - -void -iks_hide (iks *x) -{ - iks *y; - - if (!x) return; - - if (x->prev) x->prev->next = x->next; - if (x->next) x->next->prev = x->prev; - y = x->parent; - if (y) { - if (IKS_TAG_CHILDREN (y) == x) IKS_TAG_CHILDREN (y) = x->next; - if (IKS_TAG_LAST_CHILD (y) == x) IKS_TAG_LAST_CHILD (y) = x->prev; - } -} - -void -iks_delete (iks *x) -{ - if (x) iks_stack_delete (&x->s); -} - -/***** Node Traversing *****/ - -iks * -iks_next (iks *x) -{ - if (x) return x->next; - return NULL; -} - -iks * -iks_next_tag (iks *x) -{ - if (x) { - while (1) { - x = x->next; - if (NULL == x) break; - if (IKS_TAG == x->type) return x; - } - } - return NULL; -} - -iks * -iks_prev (iks *x) -{ - if (x) return x->prev; - return NULL; -} - -iks * -iks_prev_tag (iks *x) -{ - if (x) { - while (1) { - x = x->prev; - if (NULL == x) break; - if (IKS_TAG == x->type) return x; - } - } - return NULL; -} - -iks * -iks_parent (iks *x) -{ - if (x) return x->parent; - return NULL; -} - -iks * -iks_root (iks *x) -{ - if (x) { - while (x->parent) - x = x->parent; - } - return x; -} - -iks * -iks_child (iks *x) -{ - if (x && IKS_TAG == x->type) return IKS_TAG_CHILDREN (x); - return NULL; -} - -iks * -iks_first_tag (iks *x) -{ - if (x) { - x = IKS_TAG_CHILDREN (x); - while (x) { - if (IKS_TAG == x->type) return x; - x = x->next; - } - } - return NULL; -} - -iks * -iks_attrib (iks *x) -{ - if (x) return IKS_TAG_ATTRIBS (x); - return NULL; -} - -iks * -iks_find (iks *x, const char *name) -{ - iks *y; - - if (!x) return NULL; - y = IKS_TAG_CHILDREN (x); - while (y) { - if (IKS_TAG == y->type && IKS_TAG_NAME (y) && strcmp (IKS_TAG_NAME (y), name) == 0) return y; - y = y->next; - } - return NULL; -} - -char * -iks_find_cdata (iks *x, const char *name) -{ - iks *y; - - y = iks_find (x, name); - if (!y) return NULL; - y = IKS_TAG_CHILDREN (y); - if (!y || IKS_CDATA != y->type) return NULL; - return IKS_CDATA_CDATA (y); -} - -char * -iks_find_attrib (iks *x, const char *name) -{ - iks *y; - - if (!x) return NULL; - - y = IKS_TAG_ATTRIBS (x); - while (y) { - if (IKS_ATTRIB_NAME (y) && strcmp (IKS_ATTRIB_NAME (y), name) == 0) - return IKS_ATTRIB_VALUE (y); - y = y->next; - } - return NULL; -} - -iks * -iks_find_with_attrib (iks *x, const char *tagname, const char *attrname, const char *value) -{ - iks *y; - - if (NULL == x) return NULL; - - if (tagname) { - for (y = IKS_TAG_CHILDREN (x); y; y = y->next) { - if (IKS_TAG == y->type - && strcmp (IKS_TAG_NAME (y), tagname) == 0 - && iks_strcmp (iks_find_attrib (y, attrname), value) == 0) { - return y; - } - } - } else { - for (y = IKS_TAG_CHILDREN (x); y; y = y->next) { - if (IKS_TAG == y->type - && iks_strcmp (iks_find_attrib (y, attrname), value) == 0) { - return y; - } - } - } - return NULL; -} - -/***** Node Information *****/ - -ikstack * -iks_stack (iks *x) -{ - if (x) return x->s; - return NULL; -} - -enum ikstype -iks_type (iks *x) -{ - if (x) return x->type; - return IKS_NONE; -} - -char * -iks_name (iks *x) -{ - if (x) { - if (IKS_TAG == x->type) - return IKS_TAG_NAME (x); - else - return IKS_ATTRIB_NAME (x); - } - return NULL; -} - -char * -iks_cdata (iks *x) -{ - if (x) { - if (IKS_CDATA == x->type) - return IKS_CDATA_CDATA (x); - else - return IKS_ATTRIB_VALUE (x); - } - return NULL; -} - -size_t -iks_cdata_size (iks *x) -{ - if (x) return IKS_CDATA_LEN (x); - return 0; -} - -int -iks_has_children (iks *x) -{ - if (x && IKS_TAG == x->type && IKS_TAG_CHILDREN (x)) return 1; - return 0; -} - -int -iks_has_attribs (iks *x) -{ - if (x && IKS_TAG == x->type && IKS_TAG_ATTRIBS (x)) return 1; - return 0; -} - -/***** Serializing *****/ - -static size_t -escape_size (char *src, size_t len) -{ - size_t sz; - char c; - int i; - - sz = 0; - for (i = 0; i < len; i++) { - c = src[i]; - switch (c) { - case '&': sz += 5; break; - case '\'': sz += 6; break; - case '"': sz += 6; break; - case '<': sz += 4; break; - case '>': sz += 4; break; - default: sz++; break; - } - } - return sz; -} - -static char * -my_strcat (char *dest, char *src, size_t len) -{ - if (0 == len) len = strlen (src); - memcpy (dest, src, len); - return dest + len; -} - -static char * -escape (char *dest, char *src, size_t len) -{ - char c; - int i; - int j = 0; - - for (i = 0; i < len; i++) { - c = src[i]; - if ('&' == c || '<' == c || '>' == c || '\'' == c || '"' == c) { - if (i - j > 0) dest = my_strcat (dest, src + j, i - j); - j = i + 1; - switch (c) { - case '&': dest = my_strcat (dest, "&", 5); break; - case '\'': dest = my_strcat (dest, "'", 6); break; - case '"': dest = my_strcat (dest, """, 6); break; - case '<': dest = my_strcat (dest, "<", 4); break; - case '>': dest = my_strcat (dest, ">", 4); break; - } - } - } - if (i - j > 0) dest = my_strcat (dest, src + j, i - j); - return dest; -} - -char * -iks_string (ikstack *s, iks *x) -{ - size_t size; - int level, dir; - iks *y, *z; - char *ret, *t; - - if (!x) return NULL; - - if (x->type == IKS_CDATA) { - if (s) { - return iks_stack_strdup (s, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x)); - } else { - ret = iks_malloc (IKS_CDATA_LEN (x)); - memcpy (ret, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x)); - return ret; - } - } - - size = 0; - level = 0; - dir = 0; - y = x; - while (1) { - if (dir==0) { - if (y->type == IKS_TAG) { - size++; - size += strlen (IKS_TAG_NAME (y)); - for (z = IKS_TAG_ATTRIBS (y); z; z = z->next) { - if (z->type == IKS_NONE) { - continue; - } - size += 4 + strlen (IKS_ATTRIB_NAME (z)) - + escape_size (IKS_ATTRIB_VALUE (z), strlen (IKS_ATTRIB_VALUE (z))); - } - if (IKS_TAG_CHILDREN (y)) { - size++; - y = IKS_TAG_CHILDREN (y); - level++; - continue; - } else { - size += 2; - } - } else { - size += escape_size (IKS_CDATA_CDATA (y), IKS_CDATA_LEN (y)); - } - } - z = y->next; - if (z) { - if (0 == level) { - if (IKS_TAG_CHILDREN (y)) size += 3 + strlen (IKS_TAG_NAME (y)); - break; - } - y = z; - dir = 0; - } else { - y = y->parent; - level--; - if (level >= 0) size += 3 + strlen (IKS_TAG_NAME (y)); - if (level < 1) break; - dir = 1; - } - } - - if (s) ret = iks_stack_alloc (s, size + 1); - else ret = iks_malloc (size + 1); - - if (!ret) return NULL; - - t = ret; - level = 0; - dir = 0; - while (1) { - if (dir==0) { - if (x->type == IKS_TAG) { - *t++ = '<'; - t = my_strcat (t, IKS_TAG_NAME (x), 0); - y = IKS_TAG_ATTRIBS (x); - while (y) { - *t++ = ' '; - t = my_strcat (t, IKS_ATTRIB_NAME (y), 0); - *t++ = '='; - *t++ = '\''; - t = escape (t, IKS_ATTRIB_VALUE (y), strlen (IKS_ATTRIB_VALUE (y))); - *t++ = '\''; - y = y->next; - } - if (IKS_TAG_CHILDREN (x)) { - *t++ = '>'; - x = IKS_TAG_CHILDREN (x); - level++; - continue; - } else { - *t++ = '/'; - *t++ = '>'; - } - } else { - t = escape (t, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x)); - } - } - y = x->next; - if (y) { - if (0 == level) { - if (IKS_TAG_CHILDREN (x)) { - *t++ = '<'; - *t++ = '/'; - t = my_strcat (t, IKS_TAG_NAME (x), 0); - *t++ = '>'; - } - break; - } - x = y; - dir = 0; - } else { - x = x->parent; - level--; - if (level >= 0) { - *t++ = '<'; - *t++ = '/'; - t = my_strcat (t, IKS_TAG_NAME (x), 0); - *t++ = '>'; - } - if (level < 1) break; - dir = 1; - } - } - *t = '\0'; - - return ret; -} - -/***** Copying *****/ - -iks * -iks_copy_within (iks *x, ikstack *s) -{ - int level=0, dir=0; - iks *copy = NULL; - iks *cur = NULL; - iks *y; - - while (1) { - if (dir == 0) { - if (x->type == IKS_TAG) { - if (copy == NULL) { - copy = iks_new_within (IKS_TAG_NAME (x), s); - cur = copy; - } else { - cur = iks_insert (cur, IKS_TAG_NAME (x)); - } - for (y = IKS_TAG_ATTRIBS (x); y; y = y->next) { - iks_insert_attrib (cur, IKS_ATTRIB_NAME (y), IKS_ATTRIB_VALUE (y)); - } - if (IKS_TAG_CHILDREN (x)) { - x = IKS_TAG_CHILDREN (x); - level++; - continue; - } else { - cur = cur->parent; - } - } else { - iks_insert_cdata (cur, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x)); - } - } - y = x->next; - if (y) { - if (0 == level) break; - x = y; - dir = 0; - } else { - if (level < 2) break; - level--; - x = x->parent; - cur = cur->parent; - dir = 1; - } - } - return copy; -} - -iks * -iks_copy (iks *x) -{ - return iks_copy_within (x, iks_stack_new (sizeof (struct iks_tag) * 6, 256)); -} diff --git a/libs/iksemel/src/ikstack.c b/libs/iksemel/src/ikstack.c deleted file mode 100644 index b5fd75ef68..0000000000 --- a/libs/iksemel/src/ikstack.c +++ /dev/null @@ -1,214 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2004 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -struct align_test { char a; double b; }; -#define DEFAULT_ALIGNMENT ((size_t) ((char *) &((struct align_test *) 0)->b - (char *) 0)) -#define ALIGN_MASK ( DEFAULT_ALIGNMENT - 1 ) -#define MIN_CHUNK_SIZE ( DEFAULT_ALIGNMENT * 8 ) -#define MIN_ALLOC_SIZE DEFAULT_ALIGNMENT -#define ALIGN(x) ( (x) + (DEFAULT_ALIGNMENT - ( (x) & ALIGN_MASK)) ) - -typedef struct ikschunk_struct { - struct ikschunk_struct *next; - size_t size; - size_t used; - size_t last; - char data[4]; -} ikschunk; - -struct ikstack_struct { - size_t allocated; - ikschunk *meta; - ikschunk *data; -}; - -static ikschunk * -find_space (ikstack *s, ikschunk *c, size_t size) -{ - /* FIXME: dont use *2 after over allocated chunks */ - while (c) { - if (c->size - c->used >= size) return c; - if (!c->next) { - if ((c->size * 2) > size) size = c->size * 2; - c->next = iks_malloc (sizeof (ikschunk) + size); - if (!c->next) return NULL; - s->allocated += sizeof (ikschunk) + size; - c = c->next; - c->next = NULL; - c->size = size; - c->used = 0; - c->last = (size_t) -1; - return c; - } - c = c->next; - } - return NULL; -} - -ikstack * -iks_stack_new (size_t meta_chunk, size_t data_chunk) -{ - ikstack *s; - size_t len; - - if (meta_chunk < MIN_CHUNK_SIZE) meta_chunk = MIN_CHUNK_SIZE; - if (meta_chunk & ALIGN_MASK) meta_chunk = ALIGN (meta_chunk); - if (data_chunk < MIN_CHUNK_SIZE) data_chunk = MIN_CHUNK_SIZE; - if (data_chunk & ALIGN_MASK) data_chunk = ALIGN (data_chunk); - - len = sizeof (ikstack) + meta_chunk + data_chunk + (sizeof (ikschunk) * 2); - s = iks_malloc (len); - if (!s) return NULL; - s->allocated = len; - s->meta = (ikschunk *) ((char *) s + sizeof (ikstack)); - s->meta->next = NULL; - s->meta->size = meta_chunk; - s->meta->used = 0; - s->meta->last = (size_t) -1; - s->data = (ikschunk *) ((char *) s + sizeof (ikstack) + sizeof (ikschunk) + meta_chunk); - s->data->next = NULL; - s->data->size = data_chunk; - s->data->used = 0; - s->data->last = (size_t) -1; - return s; -} - -void * -iks_stack_alloc (ikstack *s, size_t size) -{ - ikschunk *c; - void *mem; - - if (size < MIN_ALLOC_SIZE) size = MIN_ALLOC_SIZE; - if (size & ALIGN_MASK) size = ALIGN (size); - - c = find_space (s, s->meta, size); - if (!c) return NULL; - mem = c->data + c->used; - c->used += size; - return mem; -} - -char * -iks_stack_strdup (ikstack *s, const char *src, size_t len) -{ - ikschunk *c; - char *dest; - - if (!src) return NULL; - if (0 == len) len = strlen (src); - - c = find_space (s, s->data, len + 1); - if (!c) return NULL; - dest = c->data + c->used; - c->last = c->used; - c->used += len + 1; - memcpy (dest, src, len); - dest[len] = '\0'; - return dest; -} - -char * -iks_stack_strcat (ikstack *s, char *old, size_t old_len, const char *src, size_t src_len) -{ - char *ret; - ikschunk *c; - - if (!old) { - return iks_stack_strdup (s, src, src_len); - } - if (0 == old_len) old_len = strlen (old); - if (0 == src_len) src_len = strlen (src); - - for (c = s->data; c; c = c->next) { - if (c->data + c->last == old) break; - } - if (!c) { - c = find_space (s, s->data, old_len + src_len + 1); - if (!c) return NULL; - ret = c->data + c->used; - c->last = c->used; - c->used += old_len + src_len + 1; - memcpy (ret, old, old_len); - memcpy (ret + old_len, src, src_len); - ret[old_len + src_len] = '\0'; - return ret; - } - - if (c->size - c->used > src_len) { - ret = c->data + c->last; - memcpy (ret + old_len, src, src_len); - c->used += src_len; - ret[old_len + src_len] = '\0'; - } else { - /* FIXME: decrease c->used before moving string to new place */ - c = find_space (s, s->data, old_len + src_len + 1); - if (!c) return NULL; - c->last = c->used; - ret = c->data + c->used; - memcpy (ret, old, old_len); - c->used += old_len; - memcpy (c->data + c->used, src, src_len); - c->used += src_len; - c->data[c->used] = '\0'; - c->used++; - } - return ret; -} - -void -iks_stack_stat (ikstack *s, size_t *allocated, size_t *used) -{ - ikschunk *c; - - if (allocated) { - *allocated = s->allocated; - } - if (used) { - *used = 0; - for (c = s->meta; c; c = c->next) { - (*used) += c->used; - } - for (c = s->data; c; c = c->next) { - (*used) += c->used; - } - } -} - -void -iks_stack_delete (ikstack **sp) -{ - ikschunk *c, *tmp; - ikstack *s; - - if (!sp) { - return; - } - - s = *sp; - - if (!s) { - return; - } - - *sp = NULL; - c = s->meta->next; - while (c) { - tmp = c->next; - iks_free (c); - c = tmp; - } - c = s->data->next; - while (c) { - tmp = c->next; - iks_free (c); - c = tmp; - } - iks_free (s); -} diff --git a/libs/iksemel/src/io-posix.c b/libs/iksemel/src/io-posix.c deleted file mode 100644 index f0a8e07101..0000000000 --- a/libs/iksemel/src/io-posix.c +++ /dev/null @@ -1,172 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2004 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#include -#endif - -static void -io_close (void *socket) -{ - int sock = (int) socket; -#ifdef _WIN32 - closesocket (sock); -#else - close (sock); -#endif -} - -static int -io_connect (iksparser *prs, void **socketptr, const char *server, int port) -{ - int sock = -1; - int tmp; -#ifdef HAVE_GETADDRINFO - struct addrinfo hints; - struct addrinfo *addr_res, *addr_ptr; - char port_str[6]; - int err = 0; - int family = AF_INET; - - if (strchr(server, ':')) { - family = AF_INET6; - } - - hints.ai_flags = AI_CANONNAME; - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = 0; - hints.ai_addrlen = 0; - hints.ai_canonname = NULL; - hints.ai_addr = NULL; - hints.ai_next = NULL; - sprintf (port_str, "%i", port); - - if (getaddrinfo (server, port_str, &hints, &addr_res) != 0) - return IKS_NET_NODNS; - - addr_ptr = addr_res; - while (addr_ptr) { - err = IKS_NET_NOSOCK; - sock = socket (addr_ptr->ai_family, addr_ptr->ai_socktype, addr_ptr->ai_protocol); - if (sock != -1) { - err = IKS_NET_NOCONN; - tmp = connect (sock, addr_ptr->ai_addr, addr_ptr->ai_addrlen); - - if (tmp == 0) break; - io_close ((void *) sock); - sock = -1; - } - addr_ptr = addr_ptr->ai_next; - } - freeaddrinfo (addr_res); - - if (sock == -1) return err; -#else - struct hostent *host; - struct sockaddr_in sin; - - host = gethostbyname (server); - if (!host) return IKS_NET_NODNS; - - memcpy (&sin.sin_addr, host->h_addr, host->h_length); - sin.sin_family = host->h_addrtype; - sin.sin_port = htons (port); - sock = socket (host->h_addrtype, SOCK_STREAM, 0); - if (sock == -1) return IKS_NET_NOSOCK; - - tmp = connect (sock, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); - if (tmp != 0) { - io_close ((void *) sock); - return IKS_NET_NOCONN; - } -#endif - - *socketptr = (void *) sock; - - return IKS_OK; -} - -static int -io_send (void *socket, const char *data, size_t len) -{ - int sock = (int) socket; - - if (send (sock, data, len, 0) == -1) return IKS_NET_RWERR; - return IKS_OK; -} - -static int -io_recv (void *socket, char *buffer, size_t buf_len, int timeout) -{ - int sock = (int) socket; - fd_set fds; - struct timeval tv, *tvptr; - int len; - char *bound; - - tv.tv_sec = 0; - tv.tv_usec = 0; - - FD_ZERO (&fds); - FD_SET (sock, &fds); - tv.tv_sec = timeout; - - if (timeout != -1) tvptr = &tv; else tvptr = NULL; - if (select (sock + 1, &fds, NULL, NULL, tvptr) > 0) { - len = recv (sock, buffer, buf_len, 0); - if (len > 0) { - char *p, *e = NULL, *t = NULL; - bound = buffer + (len -1); - - for (p = buffer; p < bound; p++) { - if (*p == '>') { - e = p; - t = p+1; - if (*t == '<') { - continue; - } - while(p < bound && t < bound) { - if (*t != ' ' && *t != '<') { - t = e = NULL; - break; - } - if (*t == '<') { - p = t; - *(p-1) = '>'; - *e = ' '; - e = NULL; - break; - } - - t++; - } - } - } - return len; - } else if (len <= 0) { - return -1; - } - } - return 0; -} - -ikstransport iks_default_transport = { - IKS_TRANSPORT_V1, - io_connect, - io_send, - io_recv, - io_close, - NULL -}; diff --git a/libs/iksemel/src/jabber.c b/libs/iksemel/src/jabber.c deleted file mode 100644 index 91437517ac..0000000000 --- a/libs/iksemel/src/jabber.c +++ /dev/null @@ -1,330 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -iksid * -iks_id_new (ikstack *s, const char *jid) -{ - iksid *id; - char *src, *tmp; - -/* FIXME: add jabber id validity checks to this function */ -/* which characters are allowed in id parts? */ - - if (!jid) return NULL; - id = iks_stack_alloc (s, sizeof (iksid)); - if (!id) return NULL; - memset (id, 0, sizeof (iksid)); - - /* skip scheme */ - if (strncmp ("jabber:", jid, 7) == 0) jid += 7; - - id->full = iks_stack_strdup (s, jid, 0); - src = id->full; - - /* split resource */ - tmp = strchr (src, '/'); - if (tmp) { - id->partial = iks_stack_strdup (s, src, tmp - src); - id->resource = tmp + 1; - src = id->partial; - } else { - id->partial = src; - } - - /* split user */ - tmp = strchr (src, '@'); - if (tmp) { - id->user = iks_stack_strdup (s, src, tmp - src); - src = ++tmp; - } - - id->server = src; - - return id; -} - -int -iks_id_cmp (iksid *a, iksid *b, int parts) -{ - int diff; - - if (!a || !b) return (IKS_ID_RESOURCE | IKS_ID_USER | IKS_ID_SERVER); - diff = 0; - if (parts & IKS_ID_RESOURCE && !(!a->resource && !b->resource) && iks_strcmp (a->resource, b->resource) != 0) - diff += IKS_ID_RESOURCE; - if (parts & IKS_ID_USER && !(!a->user && !b->user) && iks_strcasecmp (a->user, b->user) != 0) - diff += IKS_ID_USER; - if (parts & IKS_ID_SERVER && !(!a->server && !b->server) && iks_strcmp (a->server, b->server) != 0) - diff += IKS_ID_SERVER; - return diff; -} - -ikspak * -iks_packet (iks *x) -{ - ikspak *pak; - ikstack *s; - char *tmp; - - s = iks_stack (x); - pak = iks_stack_alloc (s, sizeof (ikspak)); - if (!pak) return NULL; - memset (pak, 0, sizeof (ikspak)); - pak->x = x; - tmp = iks_find_attrib (x, "from"); - if (tmp) pak->from = iks_id_new (s, tmp); - pak->id = iks_find_attrib (x, "id"); - - tmp = iks_find_attrib (x, "type"); - if (strcmp (iks_name (x), "message") == 0) { - pak->type = IKS_PAK_MESSAGE; - if (tmp) { - if (strcmp (tmp, "chat") == 0) - pak->subtype = IKS_TYPE_CHAT; - else if (strcmp (tmp, "groupchat") == 0) - pak->subtype = IKS_TYPE_GROUPCHAT; - else if (strcmp (tmp, "headline") == 0) - pak->subtype = IKS_TYPE_HEADLINE; - else if (strcmp (tmp, "error") == 0) - pak->subtype = IKS_TYPE_ERROR; - } - } else if (strcmp (iks_name (x), "presence") == 0) { - pak->type = IKS_PAK_S10N; - if (tmp) { - if (strcmp (tmp, "unavailable") == 0) { - pak->type = IKS_PAK_PRESENCE; - pak->subtype = IKS_TYPE_UNAVAILABLE; - pak->show = IKS_SHOW_UNAVAILABLE; - } else if (strcmp (tmp, "probe") == 0) { - pak->type = IKS_PAK_PRESENCE; - pak->subtype = IKS_TYPE_PROBE; - } else if(strcmp(tmp, "subscribe") == 0) - pak->subtype = IKS_TYPE_SUBSCRIBE; - else if(strcmp(tmp, "subscribed") == 0) - pak->subtype = IKS_TYPE_SUBSCRIBED; - else if(strcmp(tmp, "unsubscribe") == 0) - pak->subtype = IKS_TYPE_UNSUBSCRIBE; - else if(strcmp(tmp, "unsubscribed") == 0) - pak->subtype = IKS_TYPE_UNSUBSCRIBED; - else if(strcmp(tmp, "error") == 0) - pak->subtype = IKS_TYPE_ERROR; - } else { - pak->type = IKS_PAK_PRESENCE; - pak->subtype = IKS_TYPE_AVAILABLE; - tmp = iks_find_cdata (x, "show"); - pak->show = IKS_SHOW_AVAILABLE; - if (tmp) { - if (strcmp (tmp, "chat") == 0) - pak->show = IKS_SHOW_CHAT; - else if (strcmp (tmp, "away") == 0) - pak->show = IKS_SHOW_AWAY; - else if (strcmp (tmp, "xa") == 0) - pak->show = IKS_SHOW_XA; - else if (strcmp (tmp, "dnd") == 0) - pak->show = IKS_SHOW_DND; - } - } - } else if (strcmp (iks_name (x), "iq") == 0) { - iks *q; - pak->type = IKS_PAK_IQ; - if (tmp) { - if (strcmp (tmp, "get") == 0) - pak->subtype = IKS_TYPE_GET; - else if (strcmp (tmp, "set") == 0) - pak->subtype = IKS_TYPE_SET; - else if (strcmp (tmp, "result") == 0) - pak->subtype = IKS_TYPE_RESULT; - else if (strcmp (tmp, "error") == 0) - pak->subtype = IKS_TYPE_ERROR; - } - for (q = iks_child (x); q; q = iks_next (q)) { - if (IKS_TAG == iks_type (q)) { - char *ns; - ns = iks_find_attrib (q, "xmlns"); - if (ns) { - pak->query = q; - pak->ns = ns; - break; - } - } - } - } - return pak; -} - -iks * -iks_make_auth (iksid *id, const char *pass, const char *sid) -{ - iks *x, *y; - - x = iks_new ("iq"); - iks_insert_attrib (x, "type", "set"); - y = iks_insert (x, "query"); - iks_insert_attrib (y, "xmlns", IKS_NS_AUTH); - iks_insert_cdata (iks_insert (y, "username"), id->user, 0); - iks_insert_cdata (iks_insert (y, "resource"), id->resource, 0); - if(sid) { - char buf[41]; - iksha *sha; - sha = iks_sha_new (); - iks_sha_hash (sha, (const unsigned char*)sid, strlen (sid), 0); - iks_sha_hash (sha, (const unsigned char*)pass, strlen (pass), 1); - iks_sha_print (sha, buf); - iks_sha_delete (sha); - iks_insert_cdata (iks_insert (y, "digest"), buf, 40); - } else { - iks_insert_cdata (iks_insert (y, "password"), pass, 0); - } - return x; -} - -iks * -iks_make_msg (enum iksubtype type, const char *to, const char *body) -{ - iks *x; - char *t = NULL; - - x = iks_new ("message"); - switch (type) { - case IKS_TYPE_CHAT: t = "chat"; break; - case IKS_TYPE_GROUPCHAT: t = "groupchat"; break; - case IKS_TYPE_HEADLINE: t = "headline"; break; - default: break; - } - if (t) iks_insert_attrib (x, "type", t); - if (to) iks_insert_attrib (x, "to", to); - if (body) iks_insert_cdata (iks_insert (x, "body"), body, 0); - return x; -} - -iks * -iks_make_s10n (enum iksubtype type, const char *to, const char *msg) -{ - iks *x; - char *t; - - x = iks_new ("presence"); - switch (type) { - case IKS_TYPE_SUBSCRIBE: t = "subscribe"; break; - case IKS_TYPE_SUBSCRIBED: t = "subscribed"; break; - case IKS_TYPE_UNSUBSCRIBE: t = "unsubscribe"; break; - case IKS_TYPE_UNSUBSCRIBED: t = "unsubscribed"; break; - case IKS_TYPE_PROBE: t = "probe"; break; - default: t = NULL; break; - } - if (t) iks_insert_attrib (x, "type", t); - if (to) iks_insert_attrib (x, "to", to); - if (msg) iks_insert_cdata(iks_insert (x, "status"), msg, 0); - return x; -} - -iks * -iks_make_pres (enum ikshowtype show, const char *status) -{ - iks *x; - char *t; - - x = iks_new ("presence"); - switch (show) { - case IKS_SHOW_CHAT: t = "chat"; break; - case IKS_SHOW_AWAY: t = "away"; break; - case IKS_SHOW_XA: t = "xa"; break; - case IKS_SHOW_DND: t = "dnd"; break; - case IKS_SHOW_UNAVAILABLE: - t = NULL; - iks_insert_attrib (x, "type", "unavailable"); - break; - default: t = NULL; break; - } - if (t) iks_insert_cdata (iks_insert (x, "show"), t, 0); - if (status) iks_insert_cdata(iks_insert (x, "status"), status, 0); - return x; -} - -iks * -iks_make_iq (enum iksubtype type, const char *xmlns) -{ - iks *x; - char *t = NULL; - - x = iks_new ("iq"); - switch (type) { - case IKS_TYPE_GET: t = "get"; break; - case IKS_TYPE_SET: t = "set"; break; - case IKS_TYPE_RESULT: t = "result"; break; - case IKS_TYPE_ERROR: t = "error"; break; - default: break; - } - if (t) iks_insert_attrib (x, "type", t); - iks_insert_attrib (iks_insert (x, "query"), "xmlns", xmlns); - - return x; -} - -iks * -iks_make_resource_bind (iksid *id) -{ - iks *x, *y, *z; - - x = iks_new("iq"); - iks_insert_attrib(x, "type", "set"); - y = iks_insert(x, "bind"); - iks_insert_attrib(y, "xmlns", IKS_NS_XMPP_BIND); - if (id->resource && iks_strcmp(id->resource, "")) { - z = iks_insert(y, "resource"); - iks_insert_cdata(z, id->resource, 0); - } - return x; -} - -iks * -iks_make_session (void) -{ - iks *x, *y; - - x = iks_new ("iq"); - iks_insert_attrib (x, "type", "set"); - y = iks_insert (x, "session"); - iks_insert_attrib (y, "xmlns", IKS_NS_XMPP_SESSION); - return x; -} - -static int -iks_sasl_mechanisms (iks *x) -{ - int sasl_mech = 0; - - while (x) { - if (!iks_strcmp(iks_cdata(iks_child(x)), "DIGEST-MD5")) - sasl_mech |= IKS_STREAM_SASL_MD5; - else if (!iks_strcmp(iks_cdata(iks_child(x)), "PLAIN")) - sasl_mech |= IKS_STREAM_SASL_PLAIN; - x = iks_next_tag(x); - } - return sasl_mech; -} - -int -iks_stream_features (iks *x) -{ - int features = 0; - - if (iks_strcmp(iks_name(x), "stream:features")) - return 0; - for (x = iks_child(x); x; x = iks_next_tag(x)) - if (!iks_strcmp(iks_name(x), "starttls")) - features |= IKS_STREAM_STARTTLS; - else if (!iks_strcmp(iks_name(x), "bind")) - features |= IKS_STREAM_BIND; - else if (!iks_strcmp(iks_name(x), "session")) - features |= IKS_STREAM_SESSION; - else if (!iks_strcmp(iks_name(x), "mechanisms")) - features |= iks_sasl_mechanisms(iks_child(x)); - return features; -} diff --git a/libs/iksemel/src/md5.c b/libs/iksemel/src/md5.c deleted file mode 100644 index 11af2d8d55..0000000000 --- a/libs/iksemel/src/md5.c +++ /dev/null @@ -1,189 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -#define GET_UINT32(n,b,i) { \ - (n) = ( (unsigned long int) (b)[(i) ] ) \ - | ( (unsigned long int) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long int) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long int) (b)[(i) + 3] << 24 ); \ -} - -#define PUT_UINT32(n,b,i) { \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} - -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define G(x,y,z) ((y) ^ ((z) & ((x) ^ (y)))) - -#define H(x,y,z) ((x) ^ (y) ^ (z)) - -#define I(x,y,z) ((y) ^ ((x) | ~(z))) - -#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - -#define P(r,i,f,k,s,t) { \ - r[i] += f(r[((i)+1)%4],r[((i)+2)%4],r[((i)+3)%4]) + X[k] + t; \ - r[i] = S(r[i],s) + r[((i)+1)%4]; \ -} - -struct iksmd5_struct { - unsigned long int total[2]; - unsigned long int state[4]; - unsigned char buffer[64]; - unsigned char blen; -}; - -static const unsigned long int T[] = - { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; - -static void iks_md5_compute(iksmd5 *md5); - -void iks_md5_reset(iksmd5 *md5) -{ - memset(md5, 0, sizeof(iksmd5)); - md5->state[0] = 0x67452301; - md5->state[1] = 0xEFCDAB89; - md5->state[2] = 0x98BADCFE; - md5->state[3] = 0x10325476; -} - -iksmd5 *iks_md5_new(void) -{ - iksmd5 *md5 = malloc(sizeof(iksmd5)); - - if (!md5) - return NULL; - iks_md5_reset(md5); - return md5; -} - -void iks_md5_hash(iksmd5 *md5, const unsigned char *data, size_t slen, int finish) -{ - int i, j; - int len = slen; - - i = (64 - md5->blen); - j = (len < i) ? (len) : (i); - memcpy(md5->buffer + md5->blen, data, j); - md5->blen += j; - len -= j; - data += j; - while (len > 0) { - iks_md5_compute(md5); - md5->blen = 0; - md5->total[0] += 8*64; - md5->total[1] += (md5->total[0] < 8*64); - j = (len < 64) ? (len) : (64); - memcpy(md5->buffer, data, j); - md5->blen = j; - len -= j; - data += j; - } - if (finish) { - md5->total[0] += 8*md5->blen; - md5->total[1] += (md5->total[0] < 8*md5->blen); - md5->buffer[(md5->blen)++] = 0x80; - if (md5->blen > 56) { - while (md5->blen < 64) - md5->buffer[(md5->blen)++] = 0x00; - iks_md5_compute(md5); - md5->blen = 0; - } - while (md5->blen < 56) - md5->buffer[(md5->blen)++] = 0x00; - PUT_UINT32(md5->total[0], md5->buffer, 56); - PUT_UINT32(md5->total[1], md5->buffer, 60); - iks_md5_compute(md5); - } -} - -void iks_md5_delete(iksmd5 *md5) -{ - free(md5); -} - -void iks_md5_digest(iksmd5 *md5, unsigned char *digest) -{ - PUT_UINT32(md5->state[0], digest, 0); - PUT_UINT32(md5->state[1], digest, 4); - PUT_UINT32(md5->state[2], digest, 8); - PUT_UINT32(md5->state[3], digest, 12); -} - -void iks_md5_print(iksmd5 *md5, char *buf) -{ - int i; - unsigned char digest[16]; - - iks_md5_digest(md5, digest); - for (i = 0; i < 16; i++) { - sprintf (buf, "%02x", digest[i]); - buf += 2; - } -} - -void iks_md5(const char *data, char *buf) -{ - iksmd5 *md5 = iks_md5_new(); - - iks_md5_hash(md5, (const unsigned char*)data, strlen(data), 1); - iks_md5_print(md5, buf); - iks_md5_delete(md5); -} - -static void iks_md5_compute(iksmd5 *md5) -{ - unsigned long int X[16], R[4]; - unsigned char RS1[] = { 7, 12 ,17, 22 }; - unsigned char RS2[] = { 5, 9 ,14, 20 }; - unsigned char RS3[] = { 4, 11 ,16, 23 }; - unsigned char RS4[] = { 6, 10 ,15, 21 }; - int i, j, k, p; - - for (i = 0; i < 16; ++i) - GET_UINT32(X[i], md5->buffer, i*4); - - for (i = 0; i < 4; ++i) - R[i] = md5->state[i]; - - for (i = j = k = 0; i < 16; ++i, j = i%4, k = (k+3)%4) - P(R, k, F, i, RS1[j], T[i]); - - for (i = j = k = 0, p = 1; i < 16; ++i, j = i%4, k = (k+3)%4, p = (p+5)%16) - P(R, k, G, p, RS2[j], T[i+16]); - - for (i = j = k = 0, p = 5; i < 16; ++i, j = i%4, k = (k+3)%4, p = (p+3)%16) - P(R, k, H, p, RS3[j], T[i+32]); - - for (i = j = k = p = 0; i < 16; ++i, j = i%4, k = (k+3)%4, p = (p+7)%16) - P(R, k, I, p, RS4[j], T[i+48]); - - for (i = 0; i < 4; ++i) - md5->state[i] += R[i]; -} - diff --git a/libs/iksemel/src/sax.c b/libs/iksemel/src/sax.c deleted file mode 100644 index beb3621588..0000000000 --- a/libs/iksemel/src/sax.c +++ /dev/null @@ -1,635 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2004 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -enum cons_e { - C_CDATA = 0, - C_TAG_START, - C_TAG, - C_TAG_END, - C_ATTRIBUTE, - C_ATTRIBUTE_1, - C_ATTRIBUTE_2, - C_VALUE, - C_VALUE_APOS, - C_VALUE_QUOT, - C_WHITESPACE, - C_ENTITY, - C_COMMENT, - C_COMMENT_1, - C_COMMENT_2, - C_COMMENT_3, - C_MARKUP, - C_MARKUP_1, - C_SECT, - C_SECT_CDATA, - C_SECT_CDATA_1, - C_SECT_CDATA_2, - C_SECT_CDATA_3, - C_SECT_CDATA_4, - C_SECT_CDATA_C, - C_SECT_CDATA_E, - C_SECT_CDATA_E2, - C_PI -}; - -/* if you add a variable here, dont forget changing iks_parser_reset */ -struct iksparser_struct { - ikstack *s; - void *user_data; - iksTagHook *tagHook; - iksCDataHook *cdataHook; - iksDeleteHook *deleteHook; - /* parser context */ - char *stack; - size_t stack_pos; - size_t stack_max; - - enum cons_e context; - enum cons_e oldcontext; - - char *tag_name; - enum ikstagtype tagtype; - - unsigned int attmax; - unsigned int attcur; - int attflag; - char **atts; - int valflag; - - unsigned int entpos; - char entity[8]; - - unsigned long nr_bytes; - unsigned long nr_lines; - - int uni_max; - int uni_len; -}; - -iksparser * -iks_sax_new (void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook) -{ - iksparser *prs; - - prs = iks_malloc (sizeof (iksparser)); - if (NULL == prs) return NULL; - memset (prs, 0, sizeof (iksparser)); - prs->user_data = user_data; - prs->tagHook = tagHook; - prs->cdataHook = cdataHook; - return prs; -} - -iksparser * -iks_sax_extend (ikstack *s, void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook, iksDeleteHook *deleteHook) -{ - iksparser *prs; - - prs = iks_stack_alloc (s, sizeof (iksparser)); - if (NULL == prs) return NULL; - memset (prs, 0, sizeof (iksparser)); - prs->s = s; - prs->user_data = user_data; - prs->tagHook = tagHook; - prs->cdataHook = cdataHook; - prs->deleteHook = deleteHook; - return prs; -} - -ikstack * -iks_parser_stack (iksparser *prs) -{ - return prs->s; -} - -void * -iks_user_data (iksparser *prs) -{ - return prs->user_data; -} - -unsigned long -iks_nr_bytes (iksparser *prs) -{ - return prs->nr_bytes; -} - -unsigned long -iks_nr_lines (iksparser *prs) -{ - return prs->nr_lines; -} - -#define IS_WHITESPACE(x) ' ' == (x) || '\t' == (x) || '\r' == (x) || '\n' == (x) -#define NOT_WHITESPACE(x) ' ' != (x) && '\t' != (x) && '\r' != (x) && '\n' != (x) - -static int -stack_init (iksparser *prs) -{ - prs->stack = iks_malloc (128); - if (!prs->stack) return 0; - prs->stack_max = 128; - prs->stack_pos = 0; - return 1; -} - -static int -stack_expand (iksparser *prs, int len) -{ - size_t need; - off_t diff; - char *tmp; - need = len - (prs->stack_max - prs->stack_pos); - if (need < prs->stack_max) { - need = prs->stack_max * 2; - } else { - /* need x 1.2 for integer only archs like ARM */ - need = prs->stack_max + ( (need * 6) / 5); - } - tmp = iks_malloc (need); - if (!tmp) return 0; - diff = tmp - prs->stack; - memcpy (tmp, prs->stack, prs->stack_max); - iks_free (prs->stack); - prs->stack = tmp; - prs->stack_max = need; - prs->tag_name += diff; - if (prs->attflag != 0) { - int i = 0; - while (i < (prs->attmax * 2)) { - if (prs->atts[i]) prs->atts[i] += diff; - i++; - } - } - return 1; -} - -#define STACK_INIT \ - if (NULL == prs->stack && 0 == stack_init (prs)) return IKS_NOMEM - -#define STACK_PUSH_START (prs->stack + prs->stack_pos) - -#define STACK_PUSH(buf,len) \ -{ \ - char *sbuf = (buf); \ - size_t slen = (len); \ - if (prs->stack_max - prs->stack_pos <= slen) { \ - if (0 == stack_expand (prs, slen)) return IKS_NOMEM; \ - } \ - memcpy (prs->stack + prs->stack_pos, sbuf, slen); \ - prs->stack_pos += slen; \ -} - -#define STACK_PUSH_END \ -{ \ - if (prs->stack_pos >= prs->stack_max) { \ - if (0 == stack_expand (prs, 1)) return IKS_NOMEM; \ - } \ - prs->stack[prs->stack_pos] = '\0'; \ - prs->stack_pos++; \ -} - -static enum ikserror -sax_core (iksparser *prs, char *buf, int len) -{ - enum ikserror err; - int pos = 0, old = 0, re, stack_old = -1; - unsigned char c; - - while (pos < len) { - re = 0; - c = buf[pos]; - if (0 == c || 0xFE == c || 0xFF == c) return IKS_BADXML; - if (prs->uni_max) { - if ((c & 0xC0) != 0x80) return IKS_BADXML; - prs->uni_len++; - if (prs->uni_len == prs->uni_max) prs->uni_max = 0; - goto cont; - } else { - if (c & 0x80) { - if ((c & 0x60) == 0x40) { - prs->uni_max = 2; - } else if ((c & 0x70) == 0x60) { - prs->uni_max = 3; - } else if ((c & 0x78) == 0x70) { - prs->uni_max = 4; - } else if ((c & 0x7C) == 0x78) { - prs->uni_max = 5; - } else if ((c & 0x7E) == 0x7C) { - prs->uni_max = 6; - } else { - return IKS_BADXML; - } - /* if ((c & mask) == 0) return IKS_BADXML; I AM WRONG */ - prs->uni_len = 1; - if (stack_old == -1 - && (prs->context == C_TAG - || prs->context == C_ATTRIBUTE_1 - || prs->context == C_VALUE_APOS - || prs->context == C_VALUE_QUOT)) stack_old = pos; - goto cont; - } - } - - switch (prs->context) { - case C_CDATA: - if ('&' == c) { - if (old < pos && prs->cdataHook) { - err = prs->cdataHook (prs->user_data, &buf[old], pos - old); - if (IKS_OK != err) return err; - } - prs->context = C_ENTITY; - prs->entpos = 0; - break; - } - if ('<' == c) { - if (old < pos && prs->cdataHook) { - err = prs->cdataHook (prs->user_data, &buf[old], pos - old); - if (IKS_OK != err) return err; - } - STACK_INIT; - prs->tag_name = STACK_PUSH_START; - if (!prs->tag_name) return IKS_NOMEM; - prs->context = C_TAG_START; - } - break; - - case C_TAG_START: - prs->context = C_TAG; - if ('/' == c) { - prs->tagtype = IKS_CLOSE; - break; - } - if ('?' == c) { - prs->context = C_PI; - break; - } - if ('!' == c) { - prs->context = C_MARKUP; - break; - } - prs->tagtype = IKS_OPEN; - stack_old = pos; - break; - - case C_TAG: - if (IS_WHITESPACE(c)) { - if (IKS_CLOSE == prs->tagtype) - prs->oldcontext = C_TAG_END; - else - prs->oldcontext = C_ATTRIBUTE; - prs->context = C_WHITESPACE; - if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); - stack_old = -1; - STACK_PUSH_END; - break; - } - if ('/' == c) { - if (IKS_CLOSE == prs->tagtype) return IKS_BADXML; - prs->tagtype = IKS_SINGLE; - prs->context = C_TAG_END; - if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); - stack_old = -1; - STACK_PUSH_END; - break; - } - if ('>' == c) { - prs->context = C_TAG_END; - if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); - stack_old = -1; - STACK_PUSH_END; - re = 1; - break; - } - if (stack_old == -1) stack_old = pos; - break; - - case C_TAG_END: - if (c != '>') return IKS_BADXML; - if (prs->tagHook) { - char **tmp; - if (prs->attcur == 0) tmp = NULL; else tmp = prs->atts; - err = prs->tagHook (prs->user_data, prs->tag_name, tmp, prs->tagtype); - if (IKS_OK != err) return err; - } - prs->stack_pos = 0; - stack_old = -1; - prs->attcur = 0; - prs->attflag = 0; - prs->context = C_CDATA; - old = pos + 1; - break; - - case C_ATTRIBUTE: - if ('/' == c) { - prs->tagtype = IKS_SINGLE; - prs->context = C_TAG_END; - break; - } - if ('>' == c) { - prs->context = C_TAG_END; - re = 1; - break; - } - if (!prs->atts) { - prs->attmax = 12; - prs->atts = iks_malloc (sizeof(char *) * 2 * 12); - if (!prs->atts) return IKS_NOMEM; - memset (prs->atts, 0, sizeof(char *) * 2 * 12); - prs->attcur = 0; - } else { - if (prs->attcur >= (prs->attmax * 2)) { - void *tmp; - prs->attmax += 12; - tmp = iks_malloc (sizeof(char *) * 2 * prs->attmax); - if (!tmp) return IKS_NOMEM; - memset (tmp, 0, sizeof(char *) * 2 * prs->attmax); - memcpy (tmp, prs->atts, sizeof(char *) * prs->attcur); - free (prs->atts); - prs->atts = tmp; - } - } - prs->attflag = 1; - prs->atts[prs->attcur] = STACK_PUSH_START; - stack_old = pos; - prs->context = C_ATTRIBUTE_1; - break; - - case C_ATTRIBUTE_1: - if ('=' == c) { - if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); - stack_old = -1; - STACK_PUSH_END; - prs->context = C_VALUE; - break; - } - if (stack_old == -1) stack_old = pos; - break; - - case C_ATTRIBUTE_2: - if ('/' == c) { - prs->tagtype = IKS_SINGLE; - prs->atts[prs->attcur] = NULL; - prs->context = C_TAG_END; - break; - } - if ('>' == c) { - prs->atts[prs->attcur] = NULL; - prs->context = C_TAG_END; - re = 1; - break; - } - prs->context = C_ATTRIBUTE; - re = 1; - break; - - case C_VALUE: - prs->atts[prs->attcur + 1] = STACK_PUSH_START; - if ('\'' == c) { - prs->context = C_VALUE_APOS; - break; - } - if ('"' == c) { - prs->context = C_VALUE_QUOT; - break; - } - return IKS_BADXML; - - case C_VALUE_APOS: - if ('\'' == c) { - if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); - stack_old = -1; - STACK_PUSH_END; - prs->oldcontext = C_ATTRIBUTE_2; - prs->context = C_WHITESPACE; - prs->attcur += 2; - } - if (stack_old == -1) stack_old = pos; - break; - - case C_VALUE_QUOT: - if ('"' == c) { - if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); - stack_old = -1; - STACK_PUSH_END; - prs->oldcontext = C_ATTRIBUTE_2; - prs->context = C_WHITESPACE; - prs->attcur += 2; - } - if (stack_old == -1) stack_old = pos; - break; - - case C_WHITESPACE: - if (NOT_WHITESPACE(c)) { - prs->context = prs->oldcontext; - re = 1; - } - break; - - case C_ENTITY: - if (';' == c) { - char hede[2]; - char t = '?'; - prs->entity[prs->entpos] = '\0'; - if (strcmp(prs->entity, "amp") == 0) - t = '&'; - else if (strcmp(prs->entity, "quot") == 0) - t = '"'; - else if (strcmp(prs->entity, "apos") == 0) - t = '\''; - else if (strcmp(prs->entity, "lt") == 0) - t = '<'; - else if (strcmp(prs->entity, "gt") == 0) - t = '>'; - old = pos + 1; - hede[0] = t; - if (prs->cdataHook) { - err = prs->cdataHook (prs->user_data, &hede[0], 1); - if (IKS_OK != err) return err; - } - prs->context = C_CDATA; - } else { - prs->entity[prs->entpos++] = buf[pos]; - if (prs->entpos > 7) return IKS_BADXML; - } - break; - - case C_COMMENT: - if ('-' != c) return IKS_BADXML; - prs->context = C_COMMENT_1; - break; - - case C_COMMENT_1: - if ('-' == c) prs->context = C_COMMENT_2; - break; - - case C_COMMENT_2: - if ('-' == c) - prs->context = C_COMMENT_3; - else - prs->context = C_COMMENT_1; - break; - - case C_COMMENT_3: - if ('>' != c) return IKS_BADXML; - prs->context = C_CDATA; - old = pos + 1; - break; - - case C_MARKUP: - if ('[' == c) { - prs->context = C_SECT; - break; - } - if ('-' == c) { - prs->context = C_COMMENT; - break; - } - prs->context = C_MARKUP_1; - - case C_MARKUP_1: - if ('>' == c) { - old = pos + 1; - prs->context = C_CDATA; - } - break; - - case C_SECT: - if ('C' == c) { - prs->context = C_SECT_CDATA; - break; - } - return IKS_BADXML; - - case C_SECT_CDATA: - if ('D' != c) return IKS_BADXML; - prs->context = C_SECT_CDATA_1; - break; - - case C_SECT_CDATA_1: - if ('A' != c) return IKS_BADXML; - prs->context = C_SECT_CDATA_2; - break; - - case C_SECT_CDATA_2: - if ('T' != c) return IKS_BADXML; - prs->context = C_SECT_CDATA_3; - break; - - case C_SECT_CDATA_3: - if ('A' != c) return IKS_BADXML; - prs->context = C_SECT_CDATA_4; - break; - - case C_SECT_CDATA_4: - if ('[' != c) return IKS_BADXML; - old = pos + 1; - prs->context = C_SECT_CDATA_C; - break; - - case C_SECT_CDATA_C: - if (']' == c) { - prs->context = C_SECT_CDATA_E; - if (prs->cdataHook && old < pos) { - err = prs->cdataHook (prs->user_data, &buf[old], pos - old); - if (IKS_OK != err) return err; - } - } - break; - - case C_SECT_CDATA_E: - if (']' == c) { - prs->context = C_SECT_CDATA_E2; - } else { - if (prs->cdataHook) { - err = prs->cdataHook (prs->user_data, "]", 1); - if (IKS_OK != err) return err; - } - old = pos; - prs->context = C_SECT_CDATA_C; - } - break; - - case C_SECT_CDATA_E2: - if ('>' == c) { - old = pos + 1; - prs->context = C_CDATA; - } else if (']' == c) { - /* ]]] scenario */ - if (prs->cdataHook) { - err = prs->cdataHook (prs->user_data, "]", 1); - if (IKS_OK != err) return err; - } - old = pos; - } else { - if (prs->cdataHook) { - err = prs->cdataHook (prs->user_data, "]]", 2); - if (IKS_OK != err) return err; - } - old = pos; - prs->context = C_SECT_CDATA_C; - } - break; - - case C_PI: - old = pos + 1; - if ('>' == c) prs->context = C_CDATA; - break; - } -cont: - if (0 == re) { - pos++; - prs->nr_bytes++; - if ('\n' == c) prs->nr_lines++; - } - } - - if (stack_old != -1) - STACK_PUSH (buf + stack_old, pos - stack_old); - - err = IKS_OK; - if (prs->cdataHook && (prs->context == C_CDATA || prs->context == C_SECT_CDATA_C) && old < pos) - err = prs->cdataHook (prs->user_data, &buf[old], pos - old); - return err; -} - -int -iks_parse (iksparser *prs, const char *data, size_t len, int finish) -{ - if (!data) return IKS_OK; - if (len == 0) len = strlen (data); - return sax_core (prs, (char *) data, len); -} - -void -iks_parser_reset (iksparser *prs) -{ - if (prs->deleteHook) prs->deleteHook (prs->user_data); - prs->stack_pos = 0; - prs->context = 0; - prs->oldcontext = 0; - prs->tagtype = 0; - prs->attcur = 0; - prs->attflag = 0; - prs->valflag = 0; - prs->entpos = 0; - prs->nr_bytes = 0; - prs->nr_lines = 0; - prs->uni_max = 0; - prs->uni_len = 0; -} - -void -iks_parser_delete (iksparser *prs) -{ - if (prs->deleteHook) prs->deleteHook (prs->user_data); - if (prs->stack) iks_free (prs->stack); - if (prs->atts) iks_free (prs->atts); - if (prs->s) iks_stack_delete (&prs->s); else iks_free (prs); -} diff --git a/libs/iksemel/src/sha.c b/libs/iksemel/src/sha.c deleted file mode 100644 index 330e1b0143..0000000000 --- a/libs/iksemel/src/sha.c +++ /dev/null @@ -1,152 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -static void sha_buffer (iksha *sha, const unsigned char *data, int len); -static void sha_calculate (iksha *sha); - -struct iksha_struct { - unsigned int hash[5]; - unsigned int buf[80]; - int blen; - unsigned int lenhi, lenlo; -}; - -iksha * -iks_sha_new (void) -{ - iksha *sha; - - sha = iks_malloc (sizeof (iksha)); - if (!sha) return NULL; - iks_sha_reset (sha); - return sha; -} - -void -iks_sha_reset (iksha *sha) -{ - memset (sha, 0, sizeof (iksha)); - sha->hash[0] = 0x67452301; - sha->hash[1] = 0xefcdab89; - sha->hash[2] = 0x98badcfe; - sha->hash[3] = 0x10325476; - sha->hash[4] = 0xc3d2e1f0; -} - -void -iks_sha_hash (iksha *sha, const unsigned char *data, size_t len, int finish) -{ - unsigned char pad[8]; - unsigned char padc; - - if (data && len != 0) sha_buffer (sha, data, len); - if (!finish) return; - - pad[0] = (unsigned char)((sha->lenhi >> 24) & 0xff); - pad[1] = (unsigned char)((sha->lenhi >> 16) & 0xff); - pad[2] = (unsigned char)((sha->lenhi >> 8) & 0xff); - pad[3] = (unsigned char)(sha->lenhi & 0xff); - pad[4] = (unsigned char)((sha->lenlo >> 24) & 0xff); - pad[5] = (unsigned char)((sha->lenlo >> 16) & 0xff); - pad[6] = (unsigned char)((sha->lenlo >> 8) & 0xff); - pad[7] = (unsigned char)(sha->lenlo & 255); - - padc = 0x80; - sha_buffer (sha, &padc, 1); - - padc = 0x00; - while (sha->blen != 56) - sha_buffer (sha, &padc, 1); - - sha_buffer (sha, pad, 8); -} - -void -iks_sha_print (iksha *sha, char *hash) -{ - int i; - - for (i=0; i<5; i++) - { - sprintf (hash, "%08x", sha->hash[i]); - hash += 8; - } -} - -void -iks_sha_delete (iksha *sha) -{ - iks_free (sha); -} - -void -iks_sha (const char *data, char *hash) -{ - iksha *sha; - - sha = iks_sha_new (); - iks_sha_hash (sha, (const unsigned char*)data, strlen (data), 1); - iks_sha_print (sha, hash); - iks_free (sha); -} - -static void -sha_buffer (iksha *sha, const unsigned char *data, int len) -{ - int i; - - for (i=0; ibuf[sha->blen / 4] <<= 8; - sha->buf[sha->blen / 4] |= (unsigned int)data[i]; - if ((++sha->blen) % 64 == 0) { - sha_calculate (sha); - sha->blen = 0; - } - sha->lenlo += 8; - sha->lenhi += (sha->lenlo < 8); - } -} - -#define SRL(x,y) (((x) << (y)) | ((x) >> (32-(y)))) -#define SHA(a,b,f,c) \ - for (i= (a) ; i<= (b) ; i++) { \ - TMP = SRL(A,5) + ( (f) ) + E + sha->buf[i] + (c) ; \ - E = D; \ - D = C; \ - C = SRL(B,30); \ - B = A; \ - A = TMP; \ - } - -static void -sha_calculate (iksha *sha) -{ - int i; - unsigned int A, B, C, D, E, TMP; - - for (i=16; i<80; i++) - sha->buf[i] = SRL (sha->buf[i-3] ^ sha->buf[i-8] ^ sha->buf[i-14] ^ sha->buf[i-16], 1); - - A = sha->hash[0]; - B = sha->hash[1]; - C = sha->hash[2]; - D = sha->hash[3]; - E = sha->hash[4]; - - SHA (0, 19, ((C^D)&B)^D, 0x5a827999); - SHA (20, 39, B^C^D, 0x6ed9eba1); - SHA (40, 59, (B&C)|(D&(B|C)), 0x8f1bbcdc); - SHA (60, 79, B^C^D, 0xca62c1d6); - - sha->hash[0] += A; - sha->hash[1] += B; - sha->hash[2] += C; - sha->hash[3] += D; - sha->hash[4] += E; -} diff --git a/libs/iksemel/src/stream.c b/libs/iksemel/src/stream.c deleted file mode 100644 index f304f67c64..0000000000 --- a/libs/iksemel/src/stream.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2007 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "config.h" -#ifdef HAVE_GNUTLS -#define _XOPEN_SOURCE 500 -#define _GNU_SOURCE -#include -#endif - - -#include "common.h" -#include "iksemel.h" - -#ifdef HAVE_GNUTLS -#include -#endif - -#ifdef HAVE_SSL -#include -#include -#ifdef WIN32 -#include "Winsock2.h" -typedef unsigned __int32 uint32_t; -#else -#ifdef HAVE_SYS_SELECT_H -#include -#endif -#include -#endif -#endif - -#define SF_FOREIGN 1 -#define SF_TRY_SECURE 2 -#define SF_SECURE 4 -#define SF_SERVER 8 - -struct stream_data { - iksparser *prs; - ikstack *s; - ikstransport *trans; - char *name_space; - void *user_data; - const char *server; - iksStreamHook *streamHook; - iksLogHook *logHook; - iks *current; - char *buf; - void *sock; - unsigned int flags; - char *auth_username; - char *auth_pass; - char *cert_file; - char *key_file; -#ifdef HAVE_GNUTLS - gnutls_session sess; - gnutls_certificate_credentials cred; -#elif HAVE_SSL - SSL* ssl; - SSL_CTX* ssl_ctx; -#endif -}; - -#define WANT_READ 1 -#define WANT_WRITE 0 - -#ifdef HAVE_SSL -#ifdef WIN32 -static int sock_ready(struct stream_data *data, int ms, int w_read) -{ - int r = 0, e = 0; - fd_set rfds, wfds, efds, *fds; - struct timeval tv; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&efds); - - if (w_read) { - fds = &rfds; - } else { - fds = &wfds; - } - -#ifdef WIN32 -#pragma warning( push ) -#pragma warning( disable : 4127 ) - FD_SET(SSL_get_fd(data->ssl), fds); -#pragma warning( pop ) -#else - FD_SET(SSL_get_fd(data->ssl), fds); -#endif - - tv.tv_sec = ms / 1000; - tv.tv_usec = (ms % 1000) * ms; - - r = select (SSL_get_fd(data->ssl) + 1, w_read ? &rfds : NULL, w_read ? NULL : &wfds, &efds, &tv); - - if (r > 0) { - -#ifdef WIN32 -#pragma warning( push ) -#pragma warning( disable : 4127 ) - e = FD_ISSET(SSL_get_fd(data->ssl), &efds); -#pragma warning( pop ) -#else - e = FD_ISSET(SSL_get_fd(data->ssl), &efds); -#endif - - if (e) { - r = -1; - } else { - -#ifdef WIN32 -#pragma warning( push ) -#pragma warning( disable : 4127 ) - r = FD_ISSET(SSL_get_fd(data->ssl), fds); -#pragma warning( pop ) -#else - r = FD_ISSET(SSL_get_fd(data->ssl), fds); -#endif - - } - } - - return r; -} -#else -static int sock_ready(struct stream_data *data, int ms, int w_read) -{ - struct pollfd pfds[2] = { { 0 } }; - int s = 0, r = 0, w = w_read ? POLLIN : POLLOUT; - - pfds[0].fd = SSL_get_fd(data->ssl); - pfds[0].events = w | POLLHUP | POLLERR; - - s = poll(pfds, 1, ms); - - - if (s < 0) { - r = s; - } else if (s > 0) { - if ((pfds[0].revents & w)) { - r = 1; - } else if ((pfds[0].revents & POLLHUP) || (pfds[0].revents & POLLERR)) { - r = -1; - } - } - - return r; -} -#endif -#endif - -#ifdef HAVE_GNUTLS -#ifndef WIN32 -#include -GCRY_THREAD_OPTION_PTHREAD_IMPL; -#endif - -static size_t -tls_push (iksparser *prs, const char *buffer, size_t len) -{ - struct stream_data *data = iks_user_data (prs); - int ret; - ret = data->trans->send (data->sock, buffer, len); - if (ret) return (size_t) -1; - return len; -} - -static size_t -tls_pull (iksparser *prs, char *buffer, size_t len) -{ - struct stream_data *data = iks_user_data (prs); - int ret; - ret = data->trans->recv (data->sock, buffer, len, -1); - if (ret == -1) return (size_t) -1; - return ret; -} - -static int -handshake (struct stream_data *data) -{ - const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; - const int kx_priority[] = { GNUTLS_KX_RSA, 0 }; - const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0}; - const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; - const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; - int ret; - -#ifndef WIN32 - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); -#endif - - if (gnutls_global_init () != 0) - return IKS_NOMEM; - - if (gnutls_certificate_allocate_credentials (&data->cred) < 0) - return IKS_NOMEM; - - if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) { - gnutls_certificate_free_credentials (data->cred); - return IKS_NOMEM; - } - - gnutls_protocol_set_priority (data->sess, protocol_priority); - gnutls_cipher_set_priority(data->sess, cipher_priority); - gnutls_compression_set_priority(data->sess, comp_priority); - gnutls_kx_set_priority(data->sess, kx_priority); - gnutls_mac_set_priority(data->sess, mac_priority); - gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred); - - - gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push); - gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull); - - gnutls_transport_set_ptr (data->sess, data->prs); - - ret = gnutls_handshake (data->sess); - if (ret != 0) { - gnutls_deinit (data->sess); - gnutls_certificate_free_credentials (data->cred); - return IKS_NET_TLSFAIL; - } - - data->flags &= (~SF_TRY_SECURE); - data->flags |= SF_SECURE; - - if (!(data->flags & SF_SERVER)) { - iks_send_header (data->prs, data->server); - } - - return IKS_OK; -} // HAVE_GNUTLS -#elif HAVE_SSL -static int wait_for_data(struct stream_data *data, int ret, int timeout) -{ - int err; - int retval = IKS_OK; - - err = SSL_get_error(data->ssl, ret); - - switch(err) - { - case SSL_ERROR_WANT_READ: - ret = sock_ready(data, timeout*1000, WANT_READ); - break; - case SSL_ERROR_WANT_WRITE: - ret = sock_ready(data, timeout*1000, WANT_WRITE); - break; - default: - if (data->logHook) { - data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1); - } - ret = -1; - break; - - - - } - - if (ret == -1) { - retval = IKS_NET_TLSFAIL; - } - - - ERR_clear_error(); - - return retval; -} - - -#ifndef WIN32 -#include -#endif - -int iks_set_blocking(void *fd, int blocking) -{ -#ifdef WIN32 - unsigned long mode = !blocking; -#endif - if (!fd) { - return -1; - } - -#ifdef WIN32 - if (ioctlsocket((SOCKET)(intptr_t) fd, FIONBIO, &mode)) { - return -1; - } - -#else - int flags; - int mfd = (int)(intptr_t)fd; - - if ((flags = fcntl(mfd, F_GETFL, 0)) < 0) { - return -1; - } - - if (fcntl(mfd, F_SETFL, flags | (!blocking ? O_NONBLOCK : ~O_NONBLOCK)) < 0) { - return -1; - } -#endif - - return 0; -} - - - -static int -handshake (struct stream_data *data) -{ - int ret; - int finished; - - SSL_library_init(); - SSL_load_error_strings(); - - if (data->flags & SF_SERVER) { - data->ssl_ctx = SSL_CTX_new(TLSv1_server_method()); - if(!data->ssl_ctx) return IKS_NOMEM; - - if (SSL_CTX_use_certificate_file(data->ssl_ctx, data->cert_file, SSL_FILETYPE_PEM) <= 0) { - return IKS_NET_TLSFAIL; - } - if (SSL_CTX_use_PrivateKey_file(data->ssl_ctx, data->key_file, SSL_FILETYPE_PEM) <= 0) { - return IKS_NET_TLSFAIL; - } - SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_NONE, NULL); - } else { - data->ssl_ctx = SSL_CTX_new(TLSv1_method()); - if(!data->ssl_ctx) return IKS_NOMEM; - } - - data->ssl = SSL_new(data->ssl_ctx); - if(!data->ssl) return IKS_NOMEM; - - iks_set_blocking(data->sock, 0); - - if( SSL_set_fd(data->ssl, (int)(intptr_t)data->sock) != 1 ) return IKS_NOMEM; - - /* Set both the read and write BIO's to non-blocking mode */ - BIO_set_nbio(SSL_get_rbio(data->ssl), 1); - BIO_set_nbio(SSL_get_wbio(data->ssl), 1); - - finished = 0; - - do - { - if (data->flags & SF_SERVER) { - ret = SSL_accept(data->ssl); - } else { - ret = SSL_connect(data->ssl); - } - - if( ret != 1 ) - { - if( wait_for_data(data, ret, 1) != IKS_OK ) - { - finished = 1; - SSL_free(data->ssl); - } - } - } while( ret != 1 && finished != 1 ); - - if( ret == 1 ) - { - data->flags &= (~SF_TRY_SECURE); - data->flags |= SF_SECURE; - - if (!(data->flags & SF_SERVER)) { - iks_send_header (data->prs, data->server); - } - } - - return ret == 1 ? IKS_OK : IKS_NET_TLSFAIL; -} -#endif - -static void -insert_attribs (iks *x, char **atts) -{ - if (atts) { - int i = 0; - while (atts[i]) { - iks_insert_attrib (x, atts[i], atts[i+1]); - i += 2; - } - } -} - -#define CNONCE_LEN 4 - -static void -parse_digest (char *message, const char *key, char **value_ptr, char **value_end_ptr) -{ - char *t; - - *value_ptr = NULL; - *value_end_ptr = NULL; - - t = strstr(message, key); - if (t) { - t += strlen(key); - *value_ptr = t; - while (t[0] != '\0') { - if (t[0] != '\\' && t[1] == '"') { - ++t; - *value_end_ptr = t; - return; - } - ++t; - } - } -} - -static iks * -make_sasl_response (struct stream_data *data, char *message) -{ - iks *x = NULL; - char *realm, *realm_end; - char *nonce, *nonce_end; - char cnonce[CNONCE_LEN*8 + 1]; - iksmd5 *md5; - unsigned char a1_h[16], a1[33], a2[33], response_value[33]; - char *response, *response_coded; - int i; - - parse_digest(message, "realm=\"", &realm, &realm_end); - parse_digest(message, "nonce=\"", &nonce, &nonce_end); - - /* nonce is necessary for auth */ - if (!nonce || !nonce_end) return NULL; - *nonce_end = '\0'; - - /* if no realm is given use the server hostname */ - if (realm) { - if (!realm_end) return NULL; - *realm_end = '\0'; - } else { - realm = (char *) data->server; - } - - /* generate random client challenge */ - for (i = 0; i < CNONCE_LEN; ++i) - sprintf (cnonce + i*8, "%08x", rand()); - - md5 = iks_md5_new(); - if (!md5) return NULL; - - iks_md5_hash (md5, (const unsigned char*)data->auth_username, iks_strlen (data->auth_username), 0); - iks_md5_hash (md5, (const unsigned char*)":", 1, 0); - iks_md5_hash (md5, (const unsigned char*)realm, iks_strlen (realm), 0); - iks_md5_hash (md5, (const unsigned char*)":", 1, 0); - iks_md5_hash (md5, (const unsigned char*)data->auth_pass, iks_strlen (data->auth_pass), 1); - iks_md5_digest (md5, a1_h); - - iks_md5_reset (md5); - iks_md5_hash (md5, (const unsigned char*)a1_h, 16, 0); - iks_md5_hash (md5, (const unsigned char*)":", 1, 0); - iks_md5_hash (md5, (const unsigned char*)nonce, iks_strlen (nonce), 0); - iks_md5_hash (md5, (const unsigned char*)":", 1, 0); - iks_md5_hash (md5, (const unsigned char*)cnonce, iks_strlen (cnonce), 1); - iks_md5_print (md5, (char*)a1); - - iks_md5_reset (md5); - iks_md5_hash (md5, (const unsigned char*)"AUTHENTICATE:xmpp/", 18, 0); - iks_md5_hash (md5, (const unsigned char*)data->server, iks_strlen (data->server), 1); - iks_md5_print (md5, (char*)a2); - - iks_md5_reset (md5); - iks_md5_hash (md5, (const unsigned char*)a1, 32, 0); - iks_md5_hash (md5, (const unsigned char*)":", 1, 0); - iks_md5_hash (md5, (const unsigned char*)nonce, iks_strlen (nonce), 0); - iks_md5_hash (md5, (const unsigned char*)":00000001:", 10, 0); - iks_md5_hash (md5, (const unsigned char*)cnonce, iks_strlen (cnonce), 0); - iks_md5_hash (md5, (const unsigned char*)":auth:", 6, 0); - iks_md5_hash (md5, (const unsigned char*)a2, 32, 1); - iks_md5_print (md5, (char*)response_value); - - iks_md5_delete (md5); - - i = iks_strlen (data->auth_username) + iks_strlen (realm) + - iks_strlen (nonce) + iks_strlen (data->server) + - CNONCE_LEN*8 + 136; - response = iks_malloc (i); - if (!response) return NULL; - - sprintf (response, "username=\"%s\",realm=\"%s\",nonce=\"%s\"" - ",cnonce=\"%s\",nc=00000001,qop=auth,digest-uri=\"" - "xmpp/%s\",response=%s,charset=utf-8", - data->auth_username, realm, nonce, cnonce, - data->server, response_value); - - response_coded = iks_base64_encode (response, 0); - if (response_coded) { - x = iks_new ("response"); - iks_insert_cdata (x, response_coded, 0); - iks_free (response_coded); - } - iks_free (response); - - return x; -} - -static void -iks_sasl_challenge (struct stream_data *data, iks *challenge) -{ - char *message; - iks *x; - char *tmp; - - tmp = iks_cdata (iks_child (challenge)); - if (!tmp) return; - - /* decode received blob */ - message = iks_base64_decode (tmp); - if (!message) return; - - /* reply the challenge */ - if (strstr (message, "rspauth")) { - x = iks_new ("response"); - } else { - x = make_sasl_response (data, message); - } - if (x) { - iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); - iks_send (data->prs, x); - iks_delete (x); - } - iks_free (message); -} - -static int -tagHook (struct stream_data *data, char *name, char **atts, int type) -{ - iks *x; - int err; - - switch (type) { - case IKS_OPEN: - case IKS_SINGLE: -#ifdef HAVE_GNUTLS - if (data->flags & SF_TRY_SECURE) { - if (strcmp (name, "proceed") == 0) { - err = handshake (data); - return err; - } else if (strcmp (name, "failure") == 0){ - return IKS_NET_TLSFAIL; - } - } -#elif HAVE_SSL - if (data->flags & SF_TRY_SECURE) { - if (strcmp (name, "proceed") == 0) { - err = handshake (data); - return err; - } else if (strcmp (name, "failure") == 0){ - return IKS_NET_TLSFAIL; - } - } -#endif - if (data->current) { - x = iks_insert (data->current, name); - insert_attribs (x, atts); - } else { - x = iks_new (name); - insert_attribs (x, atts); - if (iks_strcmp (name, "stream:stream") == 0) { - err = data->streamHook (data->user_data, IKS_NODE_START, x); - if (err != IKS_OK) return err; - break; - } - } - data->current = x; - if (IKS_OPEN == type) break; - case IKS_CLOSE: - x = data->current; - if (NULL == x) { - err = data->streamHook (data->user_data, IKS_NODE_STOP, NULL); - if (err != IKS_OK) return err; - break; - } - if (NULL == iks_parent (x)) { - data->current = NULL; - if (iks_strcmp (name, "challenge") == 0) - iks_sasl_challenge(data, x); - else if (iks_strcmp (name, "stream:error") == 0) { - err = data->streamHook (data->user_data, IKS_NODE_ERROR, x); - if (err != IKS_OK) return err; - } else { - err = data->streamHook (data->user_data, IKS_NODE_NORMAL, x); - if (err != IKS_OK) return err; - } - break; - } - data->current = iks_parent (x); - } - return IKS_OK; -} - -static int -cdataHook (struct stream_data *data, char *cdata, size_t len) -{ - if (data->current) iks_insert_cdata (data->current, cdata, len); - return IKS_OK; -} - -static void -deleteHook (struct stream_data *data) -{ -#ifdef HAVE_GNUTLS - if (data->flags & SF_SECURE) { - gnutls_bye (data->sess, GNUTLS_SHUT_WR); - gnutls_deinit (data->sess); - gnutls_certificate_free_credentials (data->cred); - } -#elif HAVE_SSL - if (data->flags & SF_SECURE) { - if( SSL_shutdown(data->ssl) == 0 ) SSL_shutdown(data->ssl); - SSL_free(data->ssl); - } -#endif - if (data->trans) data->trans->close (data->sock); - data->trans = NULL; - if (data->current) iks_delete (data->current); - data->current = NULL; - data->flags = 0; -} - -iksparser * -iks_stream_new (char *name_space, void *user_data, iksStreamHook *streamHook) -{ - ikstack *s; - struct stream_data *data; - - s = iks_stack_new (DEFAULT_STREAM_CHUNK_SIZE, 0); - if (NULL == s) return NULL; - data = iks_stack_alloc (s, sizeof (struct stream_data)); - memset (data, 0, sizeof (struct stream_data)); - data->s = s; - data->prs = iks_sax_extend (s, data, (iksTagHook *)tagHook, (iksCDataHook *)cdataHook, (iksDeleteHook *)deleteHook); - data->name_space = name_space; - data->user_data = user_data; - data->streamHook = streamHook; - return data->prs; -} - -void * -iks_stream_user_data (iksparser *prs) -{ - struct stream_data *data = iks_user_data (prs); - - return data->user_data; -} - -void -iks_set_log_hook (iksparser *prs, iksLogHook *logHook) -{ - struct stream_data *data = iks_user_data (prs); - - data->logHook = logHook; -} - -int -iks_connect_tcp (iksparser *prs, const char *server, int port) -{ -#ifdef USE_DEFAULT_IO - return iks_connect_with (prs, server, port, server, &iks_default_transport); -#else - return IKS_NET_NOTSUPP; -#endif -} - -int -iks_connect_via (iksparser *prs, const char *server, int port, const char *server_name) -{ -#ifdef USE_DEFAULT_IO - return iks_connect_with (prs, server, port, server_name, &iks_default_transport); -#else - return IKS_NET_NOTSUPP; -#endif -} - -int -iks_connect_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans) -{ - struct stream_data *data = iks_user_data (prs); - int ret; - - if (!trans->connect) return IKS_NET_NOTSUPP; - - if (!data->buf) { - data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); - if (NULL == data->buf) return IKS_NOMEM; - } - - ret = trans->connect (prs, &data->sock, server, port); - if (ret) return ret; - - data->trans = trans; - - return iks_send_header (prs, server_name); -} - -int -iks_connect_async (iksparser *prs, const char *server, int port, void *notify_data, iksAsyncNotify *notify_func) -{ -#ifdef USE_DEFAULT_IO - return iks_connect_async_with (prs, server, port, server, &iks_default_transport, notify_data, notify_func); -#else - return IKS_NET_NOTSUPP; -#endif -} - -int -iks_connect_async_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans, void *notify_data, iksAsyncNotify *notify_func) -{ - struct stream_data *data = iks_user_data (prs); - int ret; - - if (NULL == trans->connect_async) - return IKS_NET_NOTSUPP; - - if (!data->buf) { - data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); - if (NULL == data->buf) return IKS_NOMEM; - } - - ret = trans->connect_async (prs, &data->sock, server, server_name, port, notify_data, notify_func); - if (ret) return ret; - - data->trans = trans; - data->server = server_name; - - return IKS_OK; -} - -int -iks_connect_fd (iksparser *prs, int fd) -{ -#ifdef USE_DEFAULT_IO - struct stream_data *data = iks_user_data (prs); - - if (!data->buf) { - data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); - if (NULL == data->buf) return IKS_NOMEM; - } - - data->sock = (void *) (intptr_t) fd; - data->flags |= SF_FOREIGN; - data->trans = &iks_default_transport; - - return IKS_OK; -#else - return IKS_NET_NOTSUPP; -#endif -} - -int -iks_fd (iksparser *prs) -{ - struct stream_data *data; - - if (prs) { - data = iks_user_data (prs); - if (data) { - return (int)(intptr_t) data->sock; - } - } - return -1; -} - -int -iks_recv (iksparser *prs, int timeout) -{ - struct stream_data *data = iks_user_data (prs); - int len, ret; - -#ifdef HAVE_SSL - int err; -#endif - - while (1) { -#ifdef HAVE_GNUTLS - if (data->flags & SF_SECURE) { - len = gnutls_record_recv (data->sess, data->buf, NET_IO_BUF_SIZE - 1); - if (len > 0 && len < 5) { - len += gnutls_record_recv (data->sess, data->buf + len, NET_IO_BUF_SIZE - 1 - len); - } else if (len == 0) len = -1; - } else -#elif HAVE_SSL - if (data->flags & SF_SECURE) { - ret = sock_ready(data, timeout*1000, WANT_READ); - - if (ret == -1) { - return IKS_NET_TLSFAIL; - } else if( ret == 0 ) { - return IKS_OK; - } else { - len = SSL_read(data->ssl, data->buf, NET_IO_BUF_SIZE - 1); - if (len > 0 && len < 5) { - len += SSL_read(data->ssl, data->buf + len, NET_IO_BUF_SIZE - 1 - len); - } - } - - if( len <= 0 ) - { - switch( err = SSL_get_error(data->ssl, len) ) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - return IKS_OK; - break; - default: - if(data->logHook) - data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1); - return IKS_NET_TLSFAIL; - break; - } - } - } else -#endif - { - len = data->trans->recv (data->sock, data->buf, NET_IO_BUF_SIZE - 1, timeout); - } - if (len < 0) return IKS_NET_RWERR; - if (len == 0) break; - data->buf[len] = '\0'; - if (data->logHook) data->logHook (data->user_data, data->buf, len, 1); - ret = iks_parse (prs, data->buf, len, 0); - - if (ret != IKS_OK) return ret; - if (!data->trans) { - /* stream hook called iks_disconnect */ - return IKS_NET_NOCONN; - } - timeout = 0; - } - return IKS_OK; -} - -int -iks_send_header (iksparser *prs, const char *to) -{ - struct stream_data *data = iks_user_data (prs); - char *msg; - int len, err; - - len = 91 + strlen (data->name_space) + 6 + strlen (to) + 16 + 1; - msg = iks_malloc (len); - if (!msg) return IKS_NOMEM; - sprintf (msg, "" - "", data->name_space, to); - err = iks_send_raw (prs, msg); - iks_free (msg); - if (err) return err; - data->server = to; - return IKS_OK; -} - -int -iks_send (iksparser *prs, iks *x) -{ - return iks_send_raw (prs, iks_string (iks_stack (x), x)); -} - -int -iks_send_raw (iksparser *prs, const char *xmlstr) -{ - struct stream_data *data = iks_user_data (prs); - int ret; - -#ifdef HAVE_GNUTLS - if (data->flags & SF_SECURE) { - if (gnutls_record_send (data->sess, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR; - } else -#elif HAVE_SSL - if (data->flags & SF_SECURE) { - int r; - - do { - r = SSL_write(data->ssl, xmlstr, strlen (xmlstr)); - } while (r == -1 && SSL_get_error(data->ssl, r) == SSL_ERROR_WANT_WRITE); - - if (r < 0) { - return IKS_NET_RWERR; - } - - } else -#endif - { - ret = data->trans->send (data->sock, xmlstr, strlen (xmlstr)); - if (ret) return ret; - } - if (data->logHook) data->logHook (data->user_data, xmlstr, strlen (xmlstr), 0); - return IKS_OK; -} - -void -iks_disconnect (iksparser *prs) -{ - iks_parser_reset (prs); -} - -/***** tls api *****/ - -int -iks_has_tls (void) -{ -#ifdef HAVE_GNUTLS - return 1; -#elif HAVE_SSL - return 1; -#else - return 0; -#endif -} - -int -iks_is_secure (iksparser *prs) -{ -#ifdef HAVE_GNUTLS - struct stream_data *data = iks_user_data (prs); - - return data->flags & SF_SECURE; -#elif HAVE_SSL - struct stream_data *data = iks_user_data (prs); - - return data->flags & SF_SECURE; -#else - return 0; -#endif -} -#ifdef HAVE_GNUTLS - - -int -iks_init(void) -{ - int ok = 0; - -#ifndef WIN32 - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); -#endif - - if (gnutls_global_init () != 0) - return IKS_NOMEM; - - return ok; - -} -#else -int -iks_init(void) -{ - return 0; -} -#endif - - -int -iks_start_tls (iksparser *prs) -{ -#ifdef HAVE_GNUTLS - int ret; - struct stream_data *data = iks_user_data (prs); - - ret = iks_send_raw (prs, ""); - if (ret) return ret; - data->flags |= SF_TRY_SECURE; - return IKS_OK; -#elif HAVE_SSL - int ret; - struct stream_data *data = iks_user_data (prs); - - ret = iks_send_raw (prs, ""); - if (ret) return ret; - data->flags |= SF_TRY_SECURE; - return IKS_OK; -#else - return IKS_NET_NOTSUPP; -#endif -} - -int -iks_proceed_tls (iksparser *prs, const char *cert_file, const char *key_file) -{ -#ifdef HAVE_GNUTLS - int ret; - struct stream_data *data = iks_user_data (prs); - - ret = iks_send_raw (prs, ""); - if (ret) return ret; - data->cert_file = iks_stack_strdup(data->s, cert_file, 0); - data->key_file = iks_stack_strdup(data->s, key_file, 0); - data->flags |= SF_TRY_SECURE | SF_SERVER; - return handshake (data); -#elif HAVE_SSL - int ret; - struct stream_data *data = iks_user_data (prs); - - ret = iks_send_raw (prs, ""); - if (ret) return ret; - data->cert_file = iks_stack_strdup(data->s, cert_file, 0); - data->key_file = iks_stack_strdup(data->s, key_file, 0); - data->flags |= SF_TRY_SECURE | SF_SERVER; - return handshake (data); -#else - return IKS_NET_NOTSUPP; -#endif -} - -/***** sasl *****/ - -int -iks_start_sasl (iksparser *prs, enum ikssasltype type, char *username, char *pass) -{ - iks *x; - - x = iks_new ("auth"); - iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); - switch (type) { - case IKS_SASL_PLAIN: { - int len = iks_strlen (username) + iks_strlen (pass) + 2; - char *s = iks_malloc (80+len); - char *base64; - - iks_insert_attrib (x, "mechanism", "PLAIN"); - sprintf (s, "%c%s%c%s", 0, username, 0, pass); - base64 = iks_base64_encode (s, len); - iks_insert_cdata (x, base64, 0); - iks_free (base64); - iks_free (s); - break; - } - case IKS_SASL_DIGEST_MD5: { - struct stream_data *data = iks_user_data (prs); - - iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); - data->auth_username = username; - data->auth_pass = pass; - break; - } - default: - iks_delete (x); - return IKS_NET_NOTSUPP; - } - iks_send (prs, x); - iks_delete (x); - return IKS_OK; -} diff --git a/libs/iksemel/src/utility.c b/libs/iksemel/src/utility.c deleted file mode 100644 index 5653bb534f..0000000000 --- a/libs/iksemel/src/utility.c +++ /dev/null @@ -1,180 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -/***** malloc wrapper *****/ - -static void *(*my_malloc_func)(size_t size); -static void (*my_free_func)(void *ptr); - -void * -iks_malloc (size_t size) -{ - if (my_malloc_func) - return my_malloc_func (size); - else - return malloc (size); -} - -void -iks_real_free (void *ptr) -{ - if (my_free_func) - my_free_func (ptr); - else - free (ptr); -} - -void -iks_set_mem_funcs (void *(*malloc_func)(size_t size), void (*free_func)(void *ptr)) -{ - my_malloc_func = malloc_func; - my_free_func = free_func; -} - -/***** NULL-safe Functions *****/ - -char * -iks_strdup (const char *src) -{ - if (src) return strdup(src); - return NULL; -} - -char * -iks_strcat (char *dest, const char *src) -{ - size_t len; - - if (!src) return dest; - - len = strlen (src); - memcpy (dest, src, len); - dest[len] = '\0'; - return dest + len; -} - -int -iks_strcmp (const char *a, const char *b) -{ - if (!a || !b) return -1; - return strcmp (a, b); -} - -int -iks_strcasecmp (const char *a, const char *b) -{ - if (!a || !b) return -1; - return strcasecmp (a, b); -} - -int -iks_strncmp (const char *a, const char *b, size_t n) -{ - if (!a || !b) return -1; - return strncmp (a, b, n); -} - -int -iks_strncasecmp (const char *a, const char *b, size_t n) -{ - if (!a || !b) return -1; - return strncasecmp (a, b, n); -} - -size_t -iks_strlen (const char *src) -{ - if (!src) return 0; - return strlen (src); -} - -/***** XML Escaping *****/ - -char * -iks_escape (ikstack *s, char *src, size_t len) -{ - char *ret; - int i, j, nlen; - - if (!src || !s) return NULL; - if (len == -1) len = strlen (src); - - nlen = len; - for (i=0; i': nlen += 3; break; - case '\'': nlen += 5; break; - case '"': nlen += 5; break; - } - } - if (len == nlen) return src; - - ret = iks_stack_alloc (s, nlen + 1); - if (!ret) return NULL; - - for (i=j=0; i': memcpy (&ret[j], ">", 4); j += 4; break; - default: ret[j++] = src[i]; - } - } - ret[j] = '\0'; - - return ret; -} - -char * -iks_unescape (ikstack *s, char *src, size_t len) -{ - int i,j; - char *ret; - - if (!s || !src) return NULL; - if (!strchr (src, '&')) return src; - if (len == -1) len = strlen (src); - - ret = iks_stack_alloc (s, len + 1); - if (!ret) return NULL; - - for (i=j=0; i -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include -#include - -#include "iksemel.h" - -iks *my_x; -int nr_tests; - -#define PR_TEST printf ("DOM test %d:\n", nr_tests) - -void -document (char *xml) -{ - enum ikserror err; - iksparser *p; - - nr_tests++; - if (my_x) iks_delete (my_x); - p = iks_dom_new (&my_x); - err = iks_parse (p, xml, 0, 1); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - PR_TEST; - puts ("Not enough memory."); - exit (1); - case IKS_BADXML: - PR_TEST; - printf ("Invalid xml at byte %ld in\n[%s]\n", iks_nr_bytes (p), xml); - exit (1); - case IKS_HOOK: - PR_TEST; - puts ("Hook."); - } - iks_parser_delete (p); -} - -void -tag (char *name, ...) -{ - iks *x; - va_list ap; - - x = my_x; - va_start (ap, name); - while (1) { - char *name = iks_name (x); - char *tmp = va_arg (ap, char*); - if (NULL == tmp) break; - x = iks_find (x, tmp); - if (!x) { - PR_TEST; - printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name); - exit (1); - } - } - if (!x || NULL == iks_find (x, name)) { - PR_TEST; - printf ("Tag <%s> is not a child of tag <%s>\n", name, iks_name (x)); - exit (1); - } - va_end (ap); -} - -void -cdata (char *data, ...) -{ - iks *x; - va_list ap; - - x = my_x; - va_start (ap, data); - while (1) { - char *name = iks_name (x); - char *tmp = va_arg (ap, char*); - if (NULL == tmp) break; - x = iks_find (x, tmp); - if (!x) { - PR_TEST; - printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name); - exit (1); - } - } - if (iks_strcmp ( iks_cdata (iks_child (x)), data) != 0) { - PR_TEST; - printf ("CDATA [%s] not found.\n", data); - exit (1); - } - va_end (ap); -} - -void -attrib (char *att, char *val, ...) -{ - iks *x; - va_list ap; - - x = my_x; - va_start (ap, val); - while (1) { - char *name = iks_name (x); - char *tmp = va_arg (ap, char*); - if (NULL == tmp) break; - x = iks_find (x, tmp); - if (!x) { - PR_TEST; - printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name); - exit (1); - } - } - if (iks_strcmp (val, iks_find_attrib (x, att)) != 0) { - PR_TEST; - printf ("Attribute '%s' not found.\n", att); - exit (1); - } - va_end (ap); -} - -void -string (char *xml) -{ - char *tmp; - - tmp = iks_string (iks_stack (my_x), my_x); - if (iks_strcmp (tmp, xml) != 0) { - PR_TEST; - printf ("Result: %s\n", tmp); - printf ("Expected: %s\n", xml); - exit (1); - } -} - -static char buf[] = - "" - "" <online&dangerous> "meow" - ""; - -int main (int argc, char *argv[]) -{ - document (""); - string (""); - - document ("lalaboldblablabla"); - tag ("b", 0); - tag ("c", "a", 0); - string ("lalaboldblablabla"); - - document (buf); - cdata ("\" \"", "status", 0); - attrib ("c", "d", "a", "b", 0); - tag ("test", 0); - string (buf); - - return 0; -} diff --git a/libs/iksemel/test/tst-filter.c b/libs/iksemel/test/tst-filter.c deleted file mode 100644 index 64adbd1f62..0000000000 --- a/libs/iksemel/test/tst-filter.c +++ /dev/null @@ -1,260 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include -#include -#include - -#include "iksemel.h" - -struct { - iksfilter *f; - char *xml; - int nr; - iksFilterHook *hook[20]; - int nr_hook; - iksFilterHook *call[20]; - int nr_call; -} tester; - -void -document (char *xml) -{ - tester.nr++; - tester.xml = xml; - tester.nr_hook = 0; -} - -void -hook (iksFilterHook *hk) -{ - tester.hook[tester.nr_hook++] = hk; -} - -void -debug (void) -{ - int i; - - printf ("Filter test %d:\n", tester.nr); - if (tester.nr_hook) { - puts ("Expected hook order:"); - for (i = 0; i < tester.nr_hook; i++) { - printf (" "); - tester.hook[i] (NULL, NULL); - } - } else { - puts("No hooks expected."); - } - if (tester.nr_call) { - puts ("Hook order:"); - for (i = 0; i < tester.nr_call; i++) { - printf (" "); - tester.call[i] (NULL, NULL); - } - } else { - puts("No hooks called."); - } - exit (1); -} - -void -test (void) -{ - iksparser *prs; - iks *x; - int i; - - tester.nr_call = 0; - - prs = iks_dom_new (&x); - iks_parse (prs, tester.xml, strlen (tester.xml), 1); - iks_parser_delete (prs); - iks_filter_packet (tester.f, iks_packet (x)); - iks_delete (x); - - if (tester.nr_call != tester.nr_hook) debug (); - for (i = 0; i < tester.nr_hook; i++) { - if (tester.call[i] != tester.hook[i]) debug (); - } -} - -#define DEBUG(x) if (NULL == pak) { puts ( (x) ); return IKS_FILTER_PASS; } - -int -on_msg (void *user_data, ikspak *pak) -{ - DEBUG ("on_msg"); - assert (IKS_PAK_MESSAGE == pak->type); - tester.call[tester.nr_call++] = on_msg; - return IKS_FILTER_PASS; -} - -int -on_iq (void *user_data, ikspak *pak) -{ - DEBUG ("on_iq"); - assert (IKS_PAK_IQ == pak->type); - tester.call[tester.nr_call++] = on_iq; - return IKS_FILTER_PASS; -} - -int -on_iq_result (void *user_data, ikspak *pak) -{ - DEBUG ("on_iq_result"); - assert (IKS_PAK_IQ == pak->type); - assert (IKS_TYPE_RESULT == pak->subtype); - tester.call[tester.nr_call++] = on_iq_result; - return IKS_FILTER_PASS; -} - -int -on_iq_result_id_auth (void *user_data, ikspak *pak) -{ - DEBUG ("on_iq_result_id_auth"); - assert (IKS_PAK_IQ == pak->type); - assert (IKS_TYPE_RESULT == pak->subtype); - assert (iks_strcmp (pak->id, "auth") == 0); - tester.call[tester.nr_call++] = on_iq_result_id_auth; - return IKS_FILTER_PASS; -} - -int -on_id_auth (void *user_data, ikspak *pak) -{ - DEBUG ("on_id_auth"); - assert (iks_strcmp (pak->id, "auth") == 0); - tester.call[tester.nr_call++] = on_id_auth; - return IKS_FILTER_PASS; -} - -int -on_from_patrician (void *user_data, ikspak *pak) -{ - DEBUG ("on_from_patrician"); - assert (iks_strcmp (pak->from->partial, "patrician@morpork.gov") == 0); - tester.call[tester.nr_call++] = on_from_patrician; - return IKS_FILTER_PASS; -} - -int -on_msg_chat_from_patrician (void *user_data, ikspak *pak) -{ - DEBUG ("on_msg_chat_from_patrician"); - assert (pak->type == IKS_PAK_MESSAGE); - assert (pak->subtype == IKS_TYPE_CHAT); - assert (iks_strcmp (pak->from->partial, "patrician@morpork.gov") == 0); - tester.call[tester.nr_call++] = on_msg_chat_from_patrician; - return IKS_FILTER_PASS; -} - -int -on_id_albatros (void *user_data, ikspak *pak) -{ - DEBUG ("on_id_albatros"); - assert (iks_strcmp (pak->id, "albatros") == 0); - tester.call[tester.nr_call++] = on_id_albatros; - return IKS_FILTER_PASS; -} - -int -on_from_dean (void *user_data, ikspak *pak) -{ - DEBUG ("on_from_dean"); - assert (iks_strcmp (pak->from->partial, "dean@unseen.edu") == 0); - tester.call[tester.nr_call++] = on_from_dean; - return IKS_FILTER_PASS; -} - -int -main (int argc, char *argv[]) -{ - tester.f = iks_filter_new (); - iks_filter_add_rule (tester.f, on_msg, 0, - IKS_RULE_TYPE, IKS_PAK_MESSAGE, - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_iq, 0, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_iq_result, 0, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_iq_result_id_auth, 0, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, - IKS_RULE_ID, "auth", - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_id_auth, 0, - IKS_RULE_ID, "auth", - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_from_dean, 0, - IKS_RULE_FROM_PARTIAL, "dean@unseen.edu", - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_from_patrician, 0, - IKS_RULE_FROM_PARTIAL, "patrician@morpork.gov", - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_msg_chat_from_patrician, 0, - IKS_RULE_TYPE, IKS_PAK_MESSAGE, - IKS_RULE_SUBTYPE, IKS_TYPE_CHAT, - IKS_RULE_FROM_PARTIAL, "patrician@morpork.gov", - IKS_RULE_DONE); - iks_filter_add_rule (tester.f, on_id_albatros, 0, - IKS_RULE_ID, "albatros", - IKS_RULE_DONE); - - document ("Born to Rune."); - hook (on_from_dean); - hook (on_msg); - test (); - - document (""); - test (); - - document ("yaaargh"); - hook (on_id_albatros); - hook (on_msg); - test (); - - document (""); - hook (on_iq); - test (); - - document ("so you admit it?"); - hook (on_from_patrician); - hook (on_msg); - test (); - - document ("cabbar1.0"); - hook (on_iq_result); - hook (on_iq); - test (); - - document (""); - hook (on_from_dean); - test (); - - document ("hmm"); - hook (on_id_albatros); - hook (on_msg_chat_from_patrician); - hook (on_from_patrician); - hook (on_msg); - test (); - - document (""); - hook (on_iq_result_id_auth); - hook (on_id_auth); - hook (on_iq_result); - hook (on_iq); - test (); - - iks_filter_delete (tester.f); - - return 0; -} diff --git a/libs/iksemel/test/tst-iks.c b/libs/iksemel/test/tst-iks.c deleted file mode 100644 index 5573b07e3d..0000000000 --- a/libs/iksemel/test/tst-iks.c +++ /dev/null @@ -1,77 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include -#include - -#include "iksemel.h" - -int main (int argc, char *argv[]) -{ - static char xml[] = - "" - "TestClientSuxOS 2000" - "1.2.0 patchlevel 2"; - static char xml2[] = - "lala
Hello World
"; - iks *x, *y, *z; - char *t; - - setlocale (LC_ALL, ""); - - x = iks_new ("iq"); - iks_insert_attrib (x, "type", "resultypo"); - iks_insert_attrib (x, "type", "result"); - iks_insert_attrib (x, "to", "ydobon@jabber.org"); - y = iks_new_within ("query", iks_stack (x)); - iks_insert_cdata (iks_insert (y, "name"), "TestClient", 10); - iks_insert_cdata (iks_insert (y, "os"), "SuxOS", 0); - z = iks_insert (y, "version"); - iks_insert (z, "stable"); - iks_insert_cdata (z, "1.2", 3); - iks_insert_cdata (z, ".0 patchlevel 2", 0); - iks_insert_node (x, y); - z = iks_find (y, "os"); - iks_insert_attrib (z, "error", "yes"); - iks_insert_attrib (z, "error", NULL); - iks_insert_cdata (z, " 2000", 5); - z = iks_next (z); - z = iks_find (z, "stable"); - iks_insert_attrib (z, "solidity", "rock"); - z = iks_parent (iks_parent (z)); - iks_insert_attrib (z, "xmlns", "jabber:iq:version"); - - t = iks_string (iks_stack (x), x); - if(!t || strcmp(t, xml) != 0) { - printf("Result: %s\n", t); - printf("Expected: %s\n", xml); - return 1; - } - iks_delete(x); - - - x = iks_new ("Ni"); - y = iks_insert (x, "br"); - z = iks_prepend_cdata (y, "lala", 4); - iks_prepend (z, "C"); - z = iks_insert_cdata (x, "Hello", 5); - y = iks_append (z, "B"); - iks_prepend (z, "A"); - iks_append_cdata (z, " ", 1); - iks_prepend_cdata (y, "World", 5); - - t = iks_string (iks_stack (x), x); - if(!t || strcmp(t, xml2) != 0) { - printf("Result: %s\n", t); - printf("Expected: %s\n", xml2); - return 1; - } - iks_delete(x); - - return 0; -} diff --git a/libs/iksemel/test/tst-ikstack.c b/libs/iksemel/test/tst-ikstack.c deleted file mode 100644 index d123e20047..0000000000 --- a/libs/iksemel/test/tst-ikstack.c +++ /dev/null @@ -1,54 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2004 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include - -#include "iksemel.h" - -struct align_test { char a; double b; }; -#define DEFAULT_ALIGNMENT ((size_t) ((char *) &((struct align_test *) 0)->b - (char *) 0)) -#define ALIGN_MASK ( DEFAULT_ALIGNMENT - 1 ) - -const char buf[] = "1234567890abcdefghijklmnopqrstuv"; - -void -test_stack (int cs) -{ - ikstack *s; - char *mem, *old; - int i; - - s = iks_stack_new (cs, cs); - old = NULL; - for (i = 0; i < strlen (buf); i++) { - iks_stack_strdup (s, buf, i); - mem = iks_stack_alloc (s, i); - if (((unsigned long) mem) & ALIGN_MASK) { - printf ("ikstack bug, addr %p should be a multiply of %d\n", - mem, DEFAULT_ALIGNMENT); - exit (1); - } - memset (mem, 'x', i); - old = iks_stack_strcat (s, old, 0, buf + i, 1); - } - if (old && strcmp (old, buf) != 0) { - printf ("ikstack strcat bug:\nExpected: %s\n Result: %s\n", buf, old); - exit (1); - } - iks_stack_delete (&s); -} - -int main (int argc, char *argv[]) -{ - test_stack (0); - test_stack (16); - test_stack (237); - test_stack (1024); - - return 0; -} diff --git a/libs/iksemel/test/tst-jid.c b/libs/iksemel/test/tst-jid.c deleted file mode 100644 index a3899db976..0000000000 --- a/libs/iksemel/test/tst-jid.c +++ /dev/null @@ -1,63 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include -#include - -#include "iksemel.h" - -ikstack *my_stack; - -void -print_id (iksid *id) -{ - printf (" Full: [%s]\n Partial: [%s]\n User: [%s]\n Server: [%s]\n Resource: [%s]\n", - id->full, id->partial, id->user, id->server, id->resource); -} - -#define BUG(x) { print_id ( (x) ); exit (1); } - -void -test_id (char *id, char *partial, char *user, char *server, char *resource) -{ - iksid *a; - - a = iks_id_new (my_stack, id); - if ((a->partial || partial) && iks_strcmp (a->partial, partial) != 0) BUG(a); - if ((a->user || user) && iks_strcmp (a->user, user) != 0) BUG(a); - if ((a->server || server) && iks_strcmp (a->server, server) != 0) BUG(a); - if ((a->resource || resource) && iks_strcmp (a->resource, resource) != 0) BUG(a); -} - -void -test_cmp (char *stra, char *strb, int parts, int diff) -{ - iksid *a, *b; - - a = iks_id_new (my_stack, stra); - b = iks_id_new (my_stack, strb); - if (diff != iks_id_cmp (a, b, parts)) exit (1); -} - -int main (int argc, char *argv[]) -{ - my_stack = iks_stack_new (1024, 1024); - - test_id ("jabber:madcat@jabber.org/cabbar", "madcat@jabber.org", "madcat", "jabber.org", "cabbar"); - test_id ("bob@silent.org", "bob@silent.org", "bob", "silent.org", NULL); - - test_cmp ("dante@jabber.org/hell", "dante@jabber.org/heaven", IKS_ID_PARTIAL, 0); - test_cmp ("madcat@jabber.org/cabbar", "madcat@jabber.org/jabberx", IKS_ID_FULL, IKS_ID_RESOURCE); - test_cmp ("dean@unseen.edu/pda", "librarian@unseen.edu/jabberx", IKS_ID_FULL, IKS_ID_USER | IKS_ID_RESOURCE); - test_cmp ("patrician@morpork.gov/gabber", "cohen@guild.org/gsm", IKS_ID_FULL, IKS_ID_FULL); - test_cmp ("peter@family.com", "peter@family.com/clam", IKS_ID_PARTIAL, 0); - - iks_stack_delete (&my_stack); - - return 0; -} diff --git a/libs/iksemel/test/tst-md5.c b/libs/iksemel/test/tst-md5.c deleted file mode 100644 index 82584ae167..0000000000 --- a/libs/iksemel/test/tst-md5.c +++ /dev/null @@ -1,38 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2004 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include - -#include "iksemel.h" - -int main (int argc, char *argv[]) -{ - struct lala { - char *str; - char *hash; - } known_hashes[] = { - { "abc", "900150983cd24fb0d6963f7d28e17f72" }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", - "57edf4a22be3c955ac49da2e2107b67a" }, - { NULL, NULL } - }; - int i = 0; - char buf[33]; - - while (known_hashes[i].str) { - iks_md5 (known_hashes[i].str, buf); - if (strcmp (buf, known_hashes[i].hash) != 0) { - printf("MD5 hash of \"%s\"\n", known_hashes[i].str); - printf(" Result: %s\n", buf); - printf(" Expected: %s\n", known_hashes[i].hash); - return 1; - } - i++; - } - return 0; -} diff --git a/libs/iksemel/test/tst-sax.c b/libs/iksemel/test/tst-sax.c deleted file mode 100644 index c0a041aee1..0000000000 --- a/libs/iksemel/test/tst-sax.c +++ /dev/null @@ -1,384 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include -#include - -#include "iksemel.h" - -struct element_s { - struct element_s *next; - enum ikstype type; - - enum ikstagtype tag; - char *name; - int nr_atts; - char *atts[10]; - char *vals[10]; - - char *cdata; - int len; -}; - -struct { - char *doc; - int len; - struct element_s *elements; - struct element_s *last_element; - struct element_s *cur; - int nr_tests; - int nr_cur; - int blocksize; -} tester; - -void -document (char *xml) -{ - if (tester.elements) { - struct element_s *tmp; - for (; tester.elements; tester.elements = tmp) { - tmp = tester.elements->next; - free (tester.elements); - } - } - tester.doc = xml; - tester.len = strlen (xml); - tester.elements = NULL; - tester.last_element = NULL; - tester.nr_tests++; -} - -void -element (enum ikstype type, ...) -{ - struct element_s *el; - va_list ap; - char *tmp; - - el = malloc (sizeof (struct element_s)); - memset (el, 0, sizeof (struct element_s)); - el->type = type; - - va_start (ap, type); - switch (type) { - case IKS_TAG: - el->tag = va_arg (ap, int); - el->name = va_arg (ap, char*); - if (IKS_CLOSE == el->tag) break; - while (1) { - tmp = va_arg (ap, char*); - if (tmp) { - el->atts[el->nr_atts] = tmp; - el->vals[el->nr_atts] = va_arg (ap, char*); - el->nr_atts++; - } else { - break; - } - } - break; - case IKS_CDATA: - tmp = va_arg (ap, char*); - el->cdata = tmp; - el->len = strlen (tmp); - break; - case IKS_NONE: - case IKS_ATTRIBUTE: - puts ("invalid element() call"); - exit (1); - } - va_end (ap); - - if (NULL == tester.elements) tester.elements = el; - if (tester.last_element) tester.last_element->next = el; - tester.last_element = el; -} - -#define PRINT_TEST printf ("Sax test %d, blocksize %d, element %d:\n", tester.nr_tests, tester.blocksize, tester.nr_cur) -#define NEXT_ELEM { tester.cur = tester.cur->next; tester.nr_cur++; } - -void -debug_tag (enum ikstagtype type, char *name, char **atts) -{ - int i; - - PRINT_TEST; - if (tester.cur && tester.cur->type == IKS_TAG) { - switch (tester.cur->tag) { - case IKS_OPEN: - printf (" Expecting tag <%s>\n", tester.cur->name); - break; - case IKS_CLOSE: - printf (" Expecting tag \n", tester.cur->name); - break; - case IKS_SINGLE: - printf (" Expecting tag <%s/>\n", tester.cur->name); - break; - } - for (i = 0; i < tester.cur->nr_atts; i++) { - printf (" %s='%s'\n", tester.cur->atts[i], tester.cur->vals[i]); - } - } else { - printf (" Not expecting a tag here.\n"); - } - switch (type) { - case IKS_OPEN: - printf (" Got tag <%s>\n", name); - break; - case IKS_CLOSE: - printf (" Got tag \n", name); - break; - case IKS_SINGLE: - printf (" Got tag <%s/>\n", name); - break; - } - i = 0; - while (atts && atts[i]) { - printf (" %s='%s'\n", atts[i], atts[i+1]); - i += 2; - } -} - -#define TAG_FAIL { debug_tag (type,name,atts); exit (1); } - -int -tagHook (void *udata, char *name, char **atts, int type) -{ - int nr, i, flag; - - if (!tester.cur) TAG_FAIL; - if (tester.cur->type != IKS_TAG) TAG_FAIL; - if (tester.cur->tag != type) TAG_FAIL; - if (iks_strcmp (tester.cur->name, name) != 0) TAG_FAIL; - if (!atts && tester.cur->nr_atts > 0) TAG_FAIL; - if (atts && tester.cur->nr_atts == 0) TAG_FAIL; - - nr = tester.cur->nr_atts; - while (nr) { - flag = 0; - for (i = 0;atts&&atts[i]; i+= 2) { - if (iks_strcmp (atts[i], tester.cur->atts[nr-1]) == 0 && iks_strcmp (atts[i+1], tester.cur->vals[nr-1]) == 0) { - flag = 1; - break; - } - } - if (flag == 0) TAG_FAIL; - nr--; - } - - NEXT_ELEM; - return IKS_OK; -} - -void -debug_cdata (char *data, size_t len, int pos) -{ - int i; - - PRINT_TEST; - if (tester.cur && tester.cur->type == IKS_CDATA) - printf (" Expecting cdata [%s]\n", tester.cur->cdata); - else - printf (" Not expecting cdata here\n"); - printf (" Got cdata ["); - for (i = 0; i < len; i++) putchar (data[i]); - printf ("] at the pos %d.\n", pos); -} - -#define CDATA_FAIL { debug_cdata (data, len, pos); exit (1); } - -int -cdataHook (void *udata, char *data, size_t len) -{ - static int pos = 0; - - if (!tester.cur) CDATA_FAIL; - if (tester.cur->type != IKS_CDATA) CDATA_FAIL; - if (iks_strncmp (tester.cur->cdata + pos, data, len) != 0) CDATA_FAIL; - pos += len; - if (pos > tester.cur->len) CDATA_FAIL; - if (pos == tester.cur->len) { - pos = 0; - NEXT_ELEM; - } - return IKS_OK; -} - -void -test_size (int blocksize) -{ - enum ikserror err; - iksparser *prs; - int i, len; - - tester.cur = tester.elements; - tester.nr_cur = 1; - tester.blocksize = blocksize; - len = tester.len; - - prs = iks_sax_new (NULL, tagHook, cdataHook); - i = 0; - if (0 == blocksize) blocksize = len; - while (i < len) { - if (i + blocksize > len) blocksize = len - i; - err = iks_parse (prs, tester.doc + i, blocksize, 0); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - exit (1); - case IKS_BADXML: - PRINT_TEST; - printf ("Invalid xml at byte %ld in\n[%s]\n", iks_nr_bytes (prs), tester.doc); - exit (1); - case IKS_HOOK: - exit (1); - } - i += blocksize; - } - if (tester.cur) exit (1); - iks_parser_delete (prs); -} - -void -test (void) -{ - int i; - - for (i = 0; i < tester.len; i++) { - test_size (i); - } -} - -void -test_bad (int badbyte) -{ - iksparser *p; - enum ikserror err; - - p = iks_sax_new (NULL, NULL, NULL); - err = iks_parse (p, tester.doc, tester.len, 1); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - exit (1); - case IKS_BADXML: - if (iks_nr_bytes (p) == badbyte) return; - break; - case IKS_HOOK: - exit (1); - } - printf ("Sax test %d:\n", tester.nr_tests); - printf ("Expected bad byte %d, got %ld in\n[%s]\n", badbyte, iks_nr_bytes (p), tester.doc); - exit (1); -} - -int -main (int argc, char *argv[]) -{ - document (""); - element (IKS_TAG, IKS_SINGLE, "lonely", 0); - test (); - - document ("child"); - element (IKS_TAG, IKS_OPEN, "parent", 0); - element (IKS_TAG, IKS_SINGLE, "child", 0); - element (IKS_TAG, IKS_SINGLE, "child", 0); - element (IKS_CDATA, "child"); - element (IKS_TAG, IKS_CLOSE, "parent"); - test (); - - document (""); - element (IKS_TAG, IKS_OPEN, "mytag", "abc", "123", "id", "XC72", 0); - element (IKS_TAG, IKS_CLOSE, "mytag"); - test (); - - document ("I'm fixing parser&tester for "<" and ">" chars."); - element (IKS_TAG, IKS_OPEN, "body", 0); - element (IKS_CDATA, "I'm fixing parser&tester for \"<\" and \">\" chars."); - element (IKS_TAG, IKS_CLOSE, "body"); - test (); - - document (""); - element (IKS_TAG, IKS_OPEN, "tag", "a", "1", "b", "2", "c", "3", "d", "4", "e", "5", "f", "6", "g", "7", "id", "xyz9", 0); - element (IKS_TAG, IKS_OPEN, "sub", 0); - element (IKS_TAG, IKS_CLOSE, "sub"); - element (IKS_TAG, IKS_CLOSE, "tag"); - test (); - - document ("Jabber Site"); - element (IKS_TAG, IKS_OPEN, "item", "url", "http://jabber.org", 0); - element (IKS_CDATA, "Jabber Site"); - element (IKS_TAG, IKS_CLOSE, "item"); - test (); - - document (""); - element (IKS_TAG, IKS_OPEN, "index", 0); - element (IKS_TAG, IKS_SINGLE, "item", "name", "lala", "page", "42", 0); - element (IKS_TAG, IKS_CLOSE, "index"); - test (); - - document ("1234 lala ] ]] ]]] ]]>4321"); - element (IKS_TAG, IKS_OPEN, "ka", 0); - element (IKS_CDATA, "1234 lala ] ]] ]]] 4321"); - element (IKS_TAG, IKS_CLOSE, "ka"); - test (); - - document ("abcd
<escape>
"); - element (IKS_TAG, IKS_OPEN, "test", 0); - element (IKS_TAG, IKS_SINGLE, "standalone", "be", "happy", 0); - element (IKS_CDATA, "abcd"); - element (IKS_TAG, IKS_SINGLE, "br", 0); - element (IKS_CDATA, ""); - element (IKS_TAG, IKS_CLOSE, "test"); - test (); - - document ("
john&mary"); - element (IKS_TAG, IKS_OPEN, "a", 0); - element (IKS_TAG, IKS_OPEN, "b", 0); - element (IKS_CDATA, "john&mary"); - element (IKS_TAG, IKS_OPEN, "c", 0); - element (IKS_TAG, IKS_SINGLE, "d", "e", "f", "g", "123456", "h", "madcat", "klm", "nop", 0); - element (IKS_TAG, IKS_CLOSE, "c", 0); - element (IKS_TAG, IKS_CLOSE, "b", 0); - element (IKS_TAG, IKS_CLOSE, "a", 0); - test (); - - document ("\xFF"); - test_bad (6); - - document (""); - tester.len = 8; - test_bad (2); - - document (""); - test_bad (13); - - document (""); - test_bad (10); - - document (""); - test_bad (17); - - document (""); - test_bad (22); - - document ("<<>"); - test_bad (16); - - document ("\xC0\x80"); - test_bad (3); - - document ("<\x8F\x85>"); - test_bad (1); - - document ("\xC1\x80
\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4\xC1\x65
"); - test_bad (28); - - return 0; -} diff --git a/libs/iksemel/test/tst-sha.c b/libs/iksemel/test/tst-sha.c deleted file mode 100644 index ff6b3e373e..0000000000 --- a/libs/iksemel/test/tst-sha.c +++ /dev/null @@ -1,38 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include - -#include "iksemel.h" - -int main (int argc, char *argv[]) -{ - struct lala { - char *str; - char *hash; - } known_hashes[] = { - { "abc", "a9993e364706816aba3e25717850c26c9cd0d89d" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "84983e441c3bd26ebaae4aa1f95129e5e54670f1" }, - { NULL, NULL } - }; - int i = 0; - char buf[42]; - - while (known_hashes[i].str) { - iks_sha (known_hashes[i].str, buf); - if (strcmp (buf, known_hashes[i].hash) != 0) { - printf("SHA1 hash of \"%s\"\n", known_hashes[i].str); - printf(" Result: %s\n", buf); - printf(" Expected: %s\n", known_hashes[i].hash); - return 1; - } - i++; - } - return 0; -} diff --git a/libs/iksemel/tools/Makefile.am b/libs/iksemel/tools/Makefile.am deleted file mode 100644 index e9e71bff83..0000000000 --- a/libs/iksemel/tools/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -## -## Process this file with automake to produce Makefile.in -## - -AM_CPPFLAGS = -I$(top_srcdir)/include - -bin_PROGRAMS = ikslint iksroster iksperf - -noinst_HEADERS = perf.h - -ikslint_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ -ikslint_SOURCES = ikslint.c hash.c - -iksroster_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ -iksroster_SOURCES = iksroster.c - -iksperf_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ -iksperf_SOURCES = iksperf.c perf.c diff --git a/libs/iksemel/tools/hash.c b/libs/iksemel/tools/hash.c deleted file mode 100644 index c4b1179a87..0000000000 --- a/libs/iksemel/tools/hash.c +++ /dev/null @@ -1,144 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -static unsigned int -hash_str (const char *str) -{ - const char *p; - unsigned int h = 0; - - for (p = str; *p != '\0'; p++) { - h = ( h << 5 ) - h + *p; - } - return h; -} - -struct item { - char *name; - unsigned int count; - struct item *next; -}; - -struct hash_s { - struct item **table; - unsigned int size; - unsigned int count; - ikstack *s; -}; - -typedef struct hash_s hash; - -hash * -hash_new (unsigned int table_size) -{ - hash *h; - - h = malloc (sizeof (struct hash_s)); - if (!h) return NULL; - h->table = calloc (sizeof (struct item *), table_size); - if (!h->table) { - free (h); - return NULL; - } - h->s = iks_stack_new (sizeof (hash) * 128, 8192); - if (!h->s) { - free (h->table); - free (h); - return NULL; - } - h->size = table_size; - h->count = 0; - - return h; -} - -char * -hash_insert (hash *h, const char *name) -{ - struct item *t, *p; - unsigned int val; - - val = hash_str (name) % h->size; - h->count++; - - for (t = h->table[val]; t; t = t->next) { - if (strcmp (t->name, name) == 0) - break; - } - if (NULL == t) { - t = iks_stack_alloc (h->s, sizeof (struct item)); - if (!t) return NULL; - t->name = iks_stack_strdup (h->s, name, 0); - t->count = 0; - t->next = NULL; - p = h->table[val]; - if (!p) { - h->table[val] = t; - } else { - while (1) { - if (p->next == NULL) { - p->next = t; - break; - } - p = p->next; - } - } - } - t->count++; - - return t->name; -} - -static int -my_cmp (const void *a, const void *b) -{ - unsigned int c1, c2; - - c1 = (*(struct item **)a)->count; - c2 = (*(struct item **)b)->count; - - if (c1 > c2) - return -1; - else if (c1 == c2) - return 0; - else - return 1; -} - -void -hash_print (hash *h, char *title_fmt, char *line_fmt) -{ - struct item **tags, *t; - unsigned int i = 0, pos = 0; - - tags = calloc (sizeof (struct item *), h->count); - - for (; i < h->size; i ++) { - for (t = h->table[i]; t; t = t->next) { - tags[pos++] = t; - } - } - - qsort (tags, pos, sizeof (struct item *), my_cmp); - - printf (title_fmt, pos); - for (i = 0; i < pos; i++) { - printf (line_fmt, tags[i]->name, tags[i]->count); - } - - free (tags); -} - -void -hash_delete (hash *h) -{ - iks_stack_delete (h->s); - free (h->table); - free (h); -} diff --git a/libs/iksemel/tools/ikslint.c b/libs/iksemel/tools/ikslint.c deleted file mode 100644 index 0b655d2df4..0000000000 --- a/libs/iksemel/tools/ikslint.c +++ /dev/null @@ -1,283 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -struct hash_s; -typedef struct hash_s hash; - -hash *hash_new (unsigned int table_size); -char *hash_insert (hash *table, const char *name); -void hash_print (hash *h, char *title_fmt, char *line_fmt); -void hash_delete (hash *table); - -#include - -#ifdef HAVE_GETOPT_LONG -#include -#endif - -#ifdef HAVE_GETOPT_LONG -static struct option longopts[] = { - { "stats", 0, 0, 's' }, - { "histogram", 0, 0, 't' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { 0, 0, 0, 0 } -}; -#endif - -static char *shortopts = "sthV"; - -static void -print_usage (void) -{ - puts ("Usage: ikslint [OPTIONS] FILE\n" - "This tool checks the well-formedness of an XML document.\n" - " -s, --stats Print statistics.\n" - " -t, --histogram Print tag histogram.\n" - " -h, --help Print this text and exit.\n" - " -V, --version Print version and exit.\n" -#ifndef HAVE_GETOPT_LONG - "(long options are not supported on your system)\n" -#endif - "Report bugs to ."); -} - -/* calculate and print statistics */ -int lint_pr_stats = 0; - -/* print tag histogram */ -int lint_pr_hist = 0; - -hash *tag_table; - -char **tag_list; -int tag_size, tag_pos; - -void -tag_push (const char *name) -{ - if (!tag_list) { - tag_size = 128; - tag_list = malloc (sizeof (char *) * tag_size); - if (!tag_list) exit (2); - } - tag_list[tag_pos] = hash_insert (tag_table, name); - if (!tag_list[tag_pos]) exit (2); - tag_pos++; - if (tag_pos == tag_size) { - char **tmp; - tmp = malloc (sizeof (char *) * tag_size * 2); - if (!tmp) exit (2); - memcpy (tmp, tag_list, sizeof (char *) * tag_size); - free (tag_list); - tag_list = tmp; - tag_size *= 2; - } -} - -char * -tag_pull (void) -{ - tag_pos--; - return tag_list[tag_pos]; -} - -struct stats { - unsigned int level; - unsigned int max_depth; - unsigned int nr_tags; - unsigned int nr_stags; - unsigned int cdata_size; -}; - -int -tagHook (void *udata, char *name, char **atts, int type) -{ - struct stats *st = (struct stats *) udata; - char *tmp; - - switch (type) { - case IKS_OPEN: - tag_push (name); - st->level++; - if (st->level > st->max_depth) st->max_depth = st->level; - break; - case IKS_CLOSE: - tmp = tag_pull (); - if (iks_strcmp (tmp, name) != 0) { - fprintf (stderr, "Tag mismatch, expecting '%s', got '%s'.\n", - tmp, name); - return IKS_HOOK; - } - st->level--; - st->nr_tags++; - break; - case IKS_SINGLE: - if (NULL == hash_insert (tag_table, name)) exit (2); - st->nr_stags++; - break; - } - return IKS_OK; -} - -int -cdataHook (void *udata, char *data, size_t len) -{ - struct stats *st = (struct stats *) udata; - - st->cdata_size += len; - return IKS_OK; -} - -void -check_file (char *fname) -{ - iksparser *prs; - struct stats st; - FILE *f; - char *buf; - struct stat fs; - size_t sz, blk, ret, pos; - enum ikserror err; - int done; - - memset (&st, 0, sizeof (struct stats)); - prs = iks_sax_new (&st, tagHook, cdataHook); - if (NULL == prs) exit (2); - - if (fname) { - if (stat (fname, &fs) != 0) { - fprintf (stderr, "Cannot access file '%s'.\n", fname); - exit (1); - } - sz = fs.st_size; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - blk = fs.st_blksize; -#else - blk = 4096; -#endif - f = fopen (fname, "r"); - if (!f) { - fprintf (stderr, "Cannot open file '%s'.\n", fname); - exit (1); - } - buf = malloc (blk); - if (!buf) { - fclose (f); - fprintf (stderr, "Cannot allocate %d bytes.\n", blk); - exit (2); - } - } else { - f = stdin; - blk = 4096; - sz = 0; - buf = malloc (blk); - if (!buf) exit (2); - } - - tag_table = hash_new (367); - if (!tag_table) exit (2); - - pos = 0; - done = 0; - while (0 == done) { - ret = fread (buf, 1, blk, f); - pos += ret; - if (feof (f)) { - done = 1; - } else { - if (ret != blk) { - if (fname) - fprintf (stderr, "Read error in file '%s'.\n", fname); - else - fprintf (stderr, "Read error in stream.\n"); - exit (1); - } - } - err = iks_parse (prs, buf, ret, done); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - exit (2); - case IKS_BADXML: - if (fname) - fprintf (stderr, "Invalid xml at byte %ld, line %ld in file '%s'.\n", - iks_nr_bytes (prs), iks_nr_lines (prs), fname); - else - fprintf (stderr, "Invalid xml at byte %ld, line %ld in stream.\n", - iks_nr_bytes (prs), iks_nr_lines (prs)); - exit (1); - case IKS_HOOK: - if (fname) - fprintf (stderr, "Byte %ld, line %ld in file '%s'.\n", - iks_nr_bytes (prs), iks_nr_lines (prs), fname); - else - fprintf (stderr, "Byte %ld, line %ld in stream.\n", - iks_nr_bytes (prs), iks_nr_lines (prs)); - exit (1); - } - } - - free (buf); - if (fname) fclose (f); - - if (fname && (lint_pr_stats || lint_pr_hist)) { - printf ("File '%s' (%d bytes):\n", fname, sz); - } - if (lint_pr_stats) { - printf ("Tags: %d pairs, %d single, %d max depth.\n", st.nr_tags, st.nr_stags, st.max_depth); - printf ("Total size of character data: %d bytes.\n", st.cdata_size); - } - if (lint_pr_hist) { - hash_print (tag_table, - "Histogram of %d unique tags:\n", - "<%s> %d times.\n"); - } - hash_delete (tag_table); - - iks_parser_delete (prs); -} - -int -main (int argc, char *argv[]) -{ - int c; - -#ifdef HAVE_GETOPT_LONG - int i; - while ((c = getopt_long (argc, argv, shortopts, longopts, &i)) != -1) { -#else - while ((c = getopt (argc, argv, shortopts)) != -1) { -#endif - switch (c) { - case 's': - lint_pr_stats = 1; - break; - case 't': - lint_pr_hist = 1; - break; - case 'h': - print_usage (); - exit (0); - case 'V': - puts ("ikslint (iksemel) "VERSION); - exit (0); - } - } - if (!argv[optind]) { - check_file (NULL); - } else { - for (; optind < argc; optind++) { - check_file (argv[optind]); - } - } - - return 0; -} diff --git a/libs/iksemel/tools/iksperf.c b/libs/iksemel/tools/iksperf.c deleted file mode 100644 index 4bcd4b3e57..0000000000 --- a/libs/iksemel/tools/iksperf.c +++ /dev/null @@ -1,315 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" -#include "perf.h" - -#include - -#ifdef HAVE_GETOPT_LONG -#include -#endif - -#ifdef HAVE_GETOPT_LONG -static struct option longopts[] = { - { "all", 0, 0, 'a' }, - { "sax", 0, 0, 's' }, - { "dom", 0, 0, 'd' }, - { "serialize", 0, 0, 'e' }, - { "sha1", 0, 0, '1' }, - { "block", required_argument, 0, 'b' }, - { "memdbg", 0, 0, 'm' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { 0, 0, 0, 0 } -}; -#endif - -static char *shortopts = "asde1b:mhV"; - -static void -print_usage (void) -{ - puts ("Usage: iksperf [OPTIONS] FILE\n" - "This tool measures the performance of the iksemel library.\n" - " -a, --all Make all tests.\n" - " -s, --sax Sax test.\n" - " -d, --dom Tree generating test.\n" - " -e, --serialize Tree serializing test.\n" - " -1, --sha1 SHA1 hashing test.\n" - " -b, --block SIZE Parse the file in SIZE byte blocks.\n" - " -m, --memdbg Trace malloc and free calls.\n" - " -h, --help Print this text and exit.\n" - " -V, --version Print version and exit.\n" -#ifndef HAVE_GETOPT_LONG - "(long options are not supported on your system)\n" -#endif - "Report bugs to ."); -} - -/* if not 0, file is parsed in block_size byte blocks */ -int block_size; - -char *load_file (const char *fname, int *sizeptr) -{ - FILE *f; - char *buf; - struct stat fs; - size_t size, ret; - - if (stat (fname, &fs) != 0) { - fprintf (stderr, "Cannot access file '%s'.\n", fname); - exit (1); - } - size = fs.st_size; - - printf ("Test file '%s' (%d bytes):\n", fname, size); - - f = fopen (fname, "rb"); - if (!f) { - fprintf (stderr, "Cannot open file.\n"); - exit (1); - } - - buf = malloc (size); - if (!buf) { - fclose (f); - fprintf (stderr, "Cannot allocate %d bytes for buffer.\n", size); - exit (2); - } - - ret = fread (buf, 1, size, f); - if (ret < size) { - fprintf (stderr, "Read error in file.\n"); - exit (1); - } - - *sizeptr = size; - fclose (f); - return buf; -} - -/* stats */ -int sax_tag; -int sax_cdata; - -int -tagHook (void *udata, char *name, char **atts, int type) -{ - ++sax_tag; - return IKS_OK; -} - -int -cdataHook (void *udata, char *data, size_t len) -{ - ++sax_cdata; - return IKS_OK; -} - -void -sax_test (char *buf, int len) -{ - unsigned long time; - iksparser *prs; - int bs, i, err; - - bs = block_size; - if (0 == bs) bs = len; - sax_tag = 0; - sax_cdata = 0; - - t_reset (); - - prs = iks_sax_new (NULL, tagHook, cdataHook); - i = 0; - while (i < len) { - if (i + bs > len) bs = len - i; - err = iks_parse (prs, buf + i, bs, 0); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - exit (2); - case IKS_BADXML: - fprintf (stderr, "Invalid xml at byte %ld, line %ld\n", - iks_nr_bytes (prs), iks_nr_lines (prs)); - exit (1); - case IKS_HOOK: - exit (1); - } - i += bs; - } - - time = t_elapsed (); - - printf ("SAX: parsing took %ld milliseconds.\n", time); - printf ("SAX: tag hook called %d, cdata hook called %d times.\n", sax_tag, sax_cdata); - - iks_parser_delete (prs); -} - -void dom_test (char *buf, int len) -{ - int bs, i, err; - iksparser *prs; - unsigned long time; - iks *x; - size_t allocated, used; - - bs = block_size; - if (0 == bs) bs = len; - - t_reset (); - - prs = iks_dom_new (&x); - iks_set_size_hint (prs, len); - i = 0; - while (i < len) { - if (i + bs > len) bs = len - i; - err = iks_parse (prs, buf + i, bs, 0); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - exit (2); - case IKS_BADXML: - fprintf (stderr, "Invalid xml at byte %ld, line %ld\n", - iks_nr_bytes (prs), iks_nr_lines (prs)); - exit (1); - case IKS_HOOK: - exit (1); - } - i += bs; - } - - time = t_elapsed (); - iks_stack_stat (iks_stack (x), &allocated, &used); - - printf ("DOM: parsing and building the tree took %ld milliseconds.\n", time); - printf ("DOM: ikstack: %d bytes allocated, %d bytes used.\n", allocated, used); - - t_reset (); - iks_delete (x); - time = t_elapsed (); - printf ("DOM: deleting the tree took %ld milliseconds.\n", time); - - iks_parser_delete (prs); -} - -void -serialize_test (char *buf, int len) -{ - unsigned long time; - iks *x; - iksparser *prs; - int err; - - prs = iks_dom_new (&x); - err = iks_parse (prs, buf, len, 1); - switch (err) { - case IKS_OK: - break; - case IKS_NOMEM: - exit (2); - case IKS_BADXML: - fprintf (stderr, "Invalid xml at byte %ld, line %ld\n", - iks_nr_bytes (prs), iks_nr_lines (prs)); - exit (1); - case IKS_HOOK: - exit (1); - } - iks_parser_delete (prs); - - t_reset (); - - iks_string (iks_stack (x), x); - - time = t_elapsed (); - - printf ("Serialize: serializing the tree took %ld milliseconds.\n", time); - - iks_delete (x); -} - -void -sha_test (char *buf, int len) -{ - unsigned long time; - iksha *s; - char out[41]; - - t_reset (); - - s = iks_sha_new (); - iks_sha_hash (s, buf, len, 1); - iks_sha_print (s, out); - out[40] = '\0'; - iks_sha_delete (s); - - time = t_elapsed (); - - printf ("SHA: hashing took %ld milliseconds.\n", time); - printf ("SHA: hash [%s]\n", out); -} - -int -main (int argc, char *argv[]) -{ - int test_type = 0; - int c; - -#ifdef HAVE_GETOPT_LONG - int i; - while ((c = getopt_long (argc, argv, shortopts, longopts, &i)) != -1) { -#else - while ((c = getopt (argc, argv, shortopts)) != -1) { -#endif - switch (c) { - case 'a': - test_type = 0xffff; - break; - case 's': - test_type |= 1; - break; - case 'd': - test_type |= 2; - break; - case 'e': - test_type |= 4; - break; - case '1': - test_type |= 8; - break; - case 'b': - block_size = atoi (optarg); - break; - case 'm': - m_trace (); - break; - case 'h': - print_usage (); - exit (0); - case 'V': - puts ("iksperf (iksemel) "VERSION); - exit (0); - } - } - for (; optind < argc; optind++) { - char *buf; - int len; - - buf = load_file (argv[optind], &len); - if (test_type & 1) sax_test (buf, len); - if (test_type == 0 || test_type & 2) dom_test (buf, len); - if (test_type & 4) serialize_test (buf, len); - if (test_type & 8) sha_test (buf, len); - free (buf); - } - - return 0; -} diff --git a/libs/iksemel/tools/iksroster.c b/libs/iksemel/tools/iksroster.c deleted file mode 100644 index 71237972b3..0000000000 --- a/libs/iksemel/tools/iksroster.c +++ /dev/null @@ -1,380 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2004 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include "common.h" -#include "iksemel.h" - -#ifdef HAVE_GETOPT_LONG -#include -#endif - -#ifdef _WIN32 -#include -#endif - -#ifdef HAVE_GETOPT_LONG -static struct option longopts[] = { - { "backup", required_argument, 0, 'b' }, - { "restore", required_argument, 0, 'r' }, - { "file", required_argument, 0, 'f' }, - { "timeout", required_argument, 0, 't' }, - { "secure", 0, 0, 's' }, - { "sasl", 0, 0, 'a' }, - { "log", 0, 0, 'l' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { 0, 0, 0, 0 } -}; -#endif - -static char *shortopts = "b:r:f:t:salhV"; - -static void -print_usage (void) -{ - puts ("Usage: iksroster [OPTIONS]\n" - "This is a backup tool for your jabber roster.\n" - " -b, --backup=JID Download roster from the server.\n" - " -r, --restore=JID Upload roster to the server.\n" - " -f, --file=FILE Load/Save roster to this file.\n" - " -t, --timeout=SECS Set network timeout.\n" - " -s, --secure Use encrypted connection.\n" - " -a, --sasl Use SASL authentication.\n" - " -l, --log Print exchanged xml data.\n" - " -h, --help Print this text and exit.\n" - " -V, --version Print version and exit.\n" -#ifndef HAVE_GETOPT_LONG - "(long options are not supported on your system)\n" -#endif -#ifndef HAVE_GNUTLS - "(secure connections are not supported on your system)\n" -#endif - "Report bugs to ."); -} - -/* stuff we keep per session */ -struct session { - iksparser *prs; - iksid *acc; - char *pass; - int features; - int authorized; - int counter; - int set_roster; - int job_done; -}; - -/* precious roster we'll deal with */ -iks *my_roster; - -/* out packet filter */ -iksfilter *my_filter; - -/* connection time outs if nothing comes for this much seconds */ -int opt_timeout = 30; - -/* connection flags */ -int opt_use_tls; -int opt_use_sasl; -int opt_log; - -void -j_error (char *msg) -{ - fprintf (stderr, "iksroster: %s\n", msg); - exit (2); -} - -int -on_result (struct session *sess, ikspak *pak) -{ - iks *x; - - if (sess->set_roster == 0) { - x = iks_make_iq (IKS_TYPE_GET, IKS_NS_ROSTER); - iks_insert_attrib (x, "id", "roster"); - iks_send (sess->prs, x); - iks_delete (x); - } else { - iks_insert_attrib (my_roster, "type", "set"); - iks_send (sess->prs, my_roster); - } - return IKS_FILTER_EAT; -} - -int -on_stream (struct session *sess, int type, iks *node) -{ - sess->counter = opt_timeout; - - switch (type) { - case IKS_NODE_START: - if (opt_use_tls && !iks_is_secure (sess->prs)) { - iks_start_tls (sess->prs); - break; - } - if (!opt_use_sasl) { - iks *x; - - x = iks_make_auth (sess->acc, sess->pass, iks_find_attrib (node, "id")); - iks_insert_attrib (x, "id", "auth"); - iks_send (sess->prs, x); - iks_delete (x); - } - break; - - case IKS_NODE_NORMAL: - if (strcmp ("stream:features", iks_name (node)) == 0) { - sess->features = iks_stream_features (node); - if (opt_use_sasl) { - if (opt_use_tls && !iks_is_secure (sess->prs)) break; - if (sess->authorized) { - iks *t; - if (sess->features & IKS_STREAM_BIND) { - t = iks_make_resource_bind (sess->acc); - iks_send (sess->prs, t); - iks_delete (t); - } - if (sess->features & IKS_STREAM_SESSION) { - t = iks_make_session (); - iks_insert_attrib (t, "id", "auth"); - iks_send (sess->prs, t); - iks_delete (t); - } - } else { - if (sess->features & IKS_STREAM_SASL_MD5) - iks_start_sasl (sess->prs, IKS_SASL_DIGEST_MD5, sess->acc->user, sess->pass); - else if (sess->features & IKS_STREAM_SASL_PLAIN) - iks_start_sasl (sess->prs, IKS_SASL_PLAIN, sess->acc->user, sess->pass); - } - } - } else if (strcmp ("failure", iks_name (node)) == 0) { - j_error ("sasl authentication failed"); - } else if (strcmp ("success", iks_name (node)) == 0) { - sess->authorized = 1; - iks_send_header (sess->prs, sess->acc->server); - } else { - ikspak *pak; - - pak = iks_packet (node); - iks_filter_packet (my_filter, pak); - if (sess->job_done == 1) return IKS_HOOK; - } - break; - - case IKS_NODE_STOP: - j_error ("server disconnected"); - - case IKS_NODE_ERROR: - j_error ("stream error"); - } - - if (node) iks_delete (node); - return IKS_OK; -} - -int -on_error (void *user_data, ikspak *pak) -{ - j_error ("authorization failed"); - return IKS_FILTER_EAT; -} - -int -on_roster (struct session *sess, ikspak *pak) -{ - my_roster = pak->x; - sess->job_done = 1; - return IKS_FILTER_EAT; -} - -void -on_log (struct session *sess, const char *data, size_t size, int is_incoming) -{ - if (iks_is_secure (sess->prs)) fprintf (stderr, "Sec"); - if (is_incoming) fprintf (stderr, "RECV"); else fprintf (stderr, "SEND"); - fprintf (stderr, "[%s]\n", data); -} - -void -j_setup_filter (struct session *sess) -{ - if (my_filter) iks_filter_delete (my_filter); - my_filter = iks_filter_new (); - iks_filter_add_rule (my_filter, (iksFilterHook *) on_result, sess, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, - IKS_RULE_ID, "auth", - IKS_RULE_DONE); - iks_filter_add_rule (my_filter, on_error, sess, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_ERROR, - IKS_RULE_ID, "auth", - IKS_RULE_DONE); - iks_filter_add_rule (my_filter, (iksFilterHook *) on_roster, sess, - IKS_RULE_TYPE, IKS_PAK_IQ, - IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, - IKS_RULE_ID, "roster", - IKS_RULE_DONE); -} - -void -j_connect (char *jabber_id, char *pass, int set_roster) -{ - struct session sess; - int e; - - memset (&sess, 0, sizeof (sess)); - sess.prs = iks_stream_new (IKS_NS_CLIENT, &sess, (iksStreamHook *) on_stream); - if (opt_log) iks_set_log_hook (sess.prs, (iksLogHook *) on_log); - sess.acc = iks_id_new (iks_parser_stack (sess.prs), jabber_id); - if (NULL == sess.acc->resource) { - /* user gave no resource name, use the default */ - char *tmp; - tmp = iks_malloc (strlen (sess.acc->user) + strlen (sess.acc->server) + 9 + 3); - sprintf (tmp, "%s@%s/%s", sess.acc->user, sess.acc->server, "iksroster"); - sess.acc = iks_id_new (iks_parser_stack (sess.prs), tmp); - iks_free (tmp); - } - sess.pass = pass; - sess.set_roster = set_roster; - - j_setup_filter (&sess); - - e = iks_connect_tcp (sess.prs, sess.acc->server, IKS_JABBER_PORT); - switch (e) { - case IKS_OK: - break; - case IKS_NET_NODNS: - j_error ("hostname lookup failed"); - case IKS_NET_NOCONN: - j_error ("connection failed"); - default: - j_error ("io error"); - } - - sess.counter = opt_timeout; - while (1) { - e = iks_recv (sess.prs, 1); - if (IKS_HOOK == e) break; - if (IKS_NET_TLSFAIL == e) j_error ("tls handshake failed"); - if (IKS_OK != e) j_error ("io error"); - sess.counter--; - if (sess.counter == 0) j_error ("network timeout"); - } - iks_parser_delete (sess.prs); -} - -int -main (int argc, char *argv[]) -{ - char *from = NULL; - char *to = NULL; - char *file = NULL; - char from_pw[128], to_pw[128]; - int c; -#ifdef HAVE_GETOPT_LONG - int i; - - while ((c = getopt_long (argc, argv, shortopts, longopts, &i)) != -1) { -#else - while ((c = getopt (argc, argv, shortopts)) != -1) { -#endif - switch (c) { - case 'b': - from = optarg; - printf ("Password for %s: ", optarg); - fflush (stdout); - fgets (from_pw, 127, stdin); - strtok (from_pw, "\r\n"); - break; - case 'r': - to = optarg; - printf ("Password for %s: ", optarg); - fflush (stdout); - fgets (to_pw, 127, stdin); - strtok (to_pw, "\r\n"); - break; - case 'f': - if (file) free(file); - file = strdup (optarg); - break; - case 't': - opt_timeout = atoi (optarg); - if (opt_timeout < 10) opt_timeout = 10; - break; - case 's': - if (!iks_has_tls ()) { - puts ("Cannot make encrypted connections."); - puts ("iksemel library is not compiled with GnuTLS support."); - exit (1); - } - opt_use_tls = 1; - break; - case 'a': - opt_use_sasl = 1; - break; - case 'l': - opt_log = 1; - break; - case 'h': - print_usage (); - exit (0); - case 'V': - puts ("iksroster (iksemel) "VERSION); - exit (0); - } - } - if (from == NULL && to == NULL) { - puts ("What I'm supposed to do?"); - print_usage (); - exit (1); - } - if (to && (from == NULL && file == NULL)) { - puts ("Store which roster?"); - print_usage (); - exit (1); - } - -#ifdef _WIN32 - WSADATA wsaData; - WSAStartup (MAKEWORD (1,1), &wsaData); -#endif - - if (from) { - j_connect (from, from_pw, 0); - if (file) { - switch (iks_save (file, my_roster)) { - case IKS_OK: - break; - case IKS_FILE_NOACCESS: - j_error ("cannot write to file"); - default: - j_error ("file io error"); - } - } - } else { - switch (iks_load (file, &my_roster)) { - case IKS_OK: - break; - case IKS_FILE_NOFILE: - j_error ("file not found"); - case IKS_FILE_NOACCESS: - j_error ("cannot read file"); - default: - j_error ("file io error"); - } - } - if (to) { - j_connect (to, to_pw, 1); - } - -#ifdef _WIN32 - WSACleanup (); -#endif - if (file) free(file); - return 0; -} diff --git a/libs/iksemel/tools/perf.c b/libs/iksemel/tools/perf.c deleted file mode 100644 index ac5a8483d1..0000000000 --- a/libs/iksemel/tools/perf.c +++ /dev/null @@ -1,84 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -#include -#include -#include -#ifdef _WIN32 -#include -#include -#else -#include -#endif - -#include "iksemel.h" - -/* timing functions */ - -#ifdef _WIN32 -static DWORD start_tv; - -void -t_reset (void) -{ - start_tv = GetTickCount (); -} - -unsigned long -t_elapsed (void) -{ - DWORD end_tv; - - end_tv = GetTickCount (); - if (end_tv < start_tv) - return UINT_MAX - (start_tv - end_tv - 1); - else - return end_tv - start_tv; -} - -#else -static struct timeval start_tv; - -void -t_reset (void) -{ - gettimeofday (&start_tv, NULL); -} - -unsigned long -t_elapsed (void) -{ - unsigned long msec; - struct timeval cur_tv; - - gettimeofday (&cur_tv, NULL); - msec = (cur_tv.tv_sec * 1000) + (cur_tv.tv_usec / 1000); - msec -= (start_tv.tv_sec * 1000) + (start_tv.tv_usec / 1000); - return msec; -} -#endif - -/* memory functions */ - -static void * -m_malloc (size_t size) -{ - void *ptr = malloc (size); - printf ("MEM: malloc (%d) => %p\n", size, ptr); - return ptr; -} - -static void -m_free (void *ptr) -{ - printf ("MEM: free (%p)\n", ptr); -} - -void -m_trace (void) -{ - iks_set_mem_funcs (m_malloc, m_free); -} diff --git a/libs/iksemel/tools/perf.h b/libs/iksemel/tools/perf.h deleted file mode 100644 index 04f1638c9b..0000000000 --- a/libs/iksemel/tools/perf.h +++ /dev/null @@ -1,10 +0,0 @@ -/* iksemel (XML parser for Jabber) -** Copyright (C) 2000-2003 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU Lesser General Public License. -*/ - -void t_reset (void); -unsigned long t_elapsed (void); - -void m_trace (void); diff --git a/libs/win32/iksemel/cleancount b/libs/win32/iksemel/cleancount deleted file mode 100644 index 56a6051ca2..0000000000 --- a/libs/win32/iksemel/cleancount +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/libs/win32/iksemel/config.h b/libs/win32/iksemel/config.h deleted file mode 100644 index cf035d9c57..0000000000 --- a/libs/win32/iksemel/config.h +++ /dev/null @@ -1,93 +0,0 @@ -/* include/config.h. Generated by configure. */ -/* include/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ - -#define strcasecmp stricmp -#define strncasecmp strnicmp - -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `getaddrinfo' function. */ -//#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `getopt_long' function. */ -//#define HAVE_GETOPT_LONG 1 - -/* "Use libgnutls" */ -//#define HAVE_GNUTLS - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `wsock32' library (-lwsock32). */ -/* #undef HAVE_LIBWSOCK32 */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -//#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "iksemel" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define this is you want default transport */ -#define USE_DEFAULT_IO 1 - -/* Version number of package */ -#define VERSION "1.3" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned' if does not define. */ -/* #undef size_t */ diff --git a/libs/win32/iksemel/iksemel.2017.vcxproj b/libs/win32/iksemel/iksemel.2017.vcxproj deleted file mode 100644 index 38f4e4d429..0000000000 --- a/libs/win32/iksemel/iksemel.2017.vcxproj +++ /dev/null @@ -1,141 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - iksemel - {E727E8F6-935D-46FE-8B0E-37834748A0E3} - iksemel - Win32Proj - - - - StaticLibrary - Unicode - true - $(DefaultPlatformToolset) - - - StaticLibrary - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - Unicode - true - $(DefaultPlatformToolset) - - - StaticLibrary - Unicode - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - Disabled - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - TurnOffAllWarnings - - - - - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - MultiThreadedDLL - TurnOffAllWarnings - - - - - X64 - - - Disabled - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - TurnOffAllWarnings - - - - - X64 - - - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - MultiThreadedDLL - TurnOffAllWarnings - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/scripts/ci/common.sh b/scripts/ci/common.sh index cecb1289bc..e5a4ba2dea 100755 --- a/scripts/ci/common.sh +++ b/scripts/ci/common.sh @@ -126,11 +126,6 @@ set_fs_ver () { sed -e "s|\(%define nonparsedversion \).*|\1$rpm_version|" \ freeswitch.spec > freeswitch.spec.$$ mv freeswitch.spec.$$ freeswitch.spec - - sed -e "s|\(%define nonparsedversion \).*|\1$rpm_version|" \ - freeswitch-config-rayo.spec > freeswitch-config-rayo.spec.$$ - mv freeswitch-config-rayo.spec.$$ freeswitch-config-rayo.spec - #%define version 1.5.16 } @@ -141,10 +136,6 @@ set_fs_release () { sed -e "s|\(%define release \).*|\1$release|" \ freeswitch.spec > freeswitch.spec.$$ mv freeswitch.spec.$$ freeswitch.spec - - sed -e "s|\(%define release \).*|\1$release|" \ - freeswitch-config-rayo.spec > freeswitch-config-rayo.spec.$$ - mv freeswitch-config-rayo.spec.$$ freeswitch-config-rayo.spec fi } diff --git a/scripts/ci/config-rayo.sh b/scripts/ci/config-rayo.sh deleted file mode 100755 index 54b77f81ca..0000000000 --- a/scripts/ci/config-rayo.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*- - -sdir="." -[ -n "${0%/*}" ] && sdir="${0%/*}" -. $sdir/common.sh - -check_pwd -check_input_ver_build $@ -eval $(parse_version "$1") - -if [ -n "$rev" ]; then - dst_name="freeswitch-$cmajor.$cminor.$cmicro.$rev" -else - dst_name="freeswitch-$cmajor.$cminor.$cmicro" -fi -dst_parent="/tmp/" -dst_dir="/tmp/$dst_name" -release="1" -if [ $# -gt 1 ]; then - release="$2" -fi - -(mkdir -p rpmbuild && cd rpmbuild && mkdir -p SOURCES BUILD BUILDROOT i386 x86_64 SPECS) - -cd $src_repo -cp -a src_dist/*.spec rpmbuild/SPECS/ || true -cp -a src_dist/* rpmbuild/SOURCES/ || true -cd rpmbuild/SPECS -set_fs_release "$release" -cd ../../ - -rpmbuild --define "_topdir %(pwd)/rpmbuild" \ - --define "_rpmdir %{_topdir}" \ - --define "_srcrpmdir %{_topdir}" \ - -ba rpmbuild/SPECS/freeswitch-config-rayo.spec - -mkdir -p $src_repo/RPMS -mv $src_repo/rpmbuild/*/freeswitch-config-rayo*.rpm $src_repo/RPMS/. - -cat 1>&2 < - diff --git a/src/mod/event_handlers/mod_rayo/Makefile.am b/src/mod/event_handlers/mod_rayo/Makefile.am deleted file mode 100644 index a9ca95d51b..0000000000 --- a/src/mod/event_handlers/mod_rayo/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_rayo - -IKS_DIR=$(switch_srcdir)/libs/iksemel -IKS_BUILDDIR=$(switch_builddir)/libs/iksemel -IKS_LA=$(IKS_BUILDDIR)/src/libiksemel.la - -noinst_LTLIBRARIES = librayomod.la -librayomod_la_SOURCES = mod_rayo.c iks_helpers.c nlsml.c rayo_components.c rayo_cpa_component.c rayo_cpa_detector.c rayo_elements.c rayo_fax_components.c -librayomod_la_SOURCES += rayo_input_component.c rayo_output_component.c rayo_prompt_component.c rayo_record_component.c sasl.c srgs.c xmpp_streams.c rayo_exec_component.c -librayomod_la_CFLAGS = $(AM_CFLAGS) -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) - -mod_LTLIBRARIES = mod_rayo.la -mod_rayo_la_SOURCES = -mod_rayo_la_CFLAGS = $(AM_CFLAGS) -I$(IKS_DIR)/include $(PCRE_CFLAGS) -mod_rayo_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(IKS_LA) $(PCRE_LIBS) librayomod.la -mod_rayo_la_LDFLAGS = -avoid-version -module -no-undefined -shared - -BUILT_SOURCES=$(IKS_LA) - -$(IKS_LA): $(IKS_BUILDDIR) $(IKS_DIR) $(IKS_DIR)/.update - @cd $(IKS_BUILDDIR) && $(MAKE) - @$(TOUCH_TARGET) - -noinst_PROGRAMS = test/test_iks test/test_nlsml test/test_srgs - -test_test_iks_SOURCES = test/test_iks.c -test_test_iks_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\" -test_test_iks_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) -test_test_iks_LDADD = librayomod.la $(IKS_LA) $(PCRE_LIBS) $(switch_builddir)/libfreeswitch.la - -test_test_nlsml_SOURCES = test/test_nlsml.c -test_test_nlsml_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\" -test_test_nlsml_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) -test_test_nlsml_LDADD = librayomod.la $(IKS_LA) $(PCRE_LIBS) $(switch_builddir)/libfreeswitch.la - -test_test_srgs_SOURCES = test/test_srgs.c -test_test_srgs_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\" -test_test_srgs_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) -test_test_srgs_LDADD = librayomod.la $(IKS_LA) $(PCRE_LIBS) $(switch_builddir)/libfreeswitch.la - - -TESTS = $(noinst_PROGRAMS) - diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml deleted file mode 100644 index 9f525c597c..0000000000 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - ]]> - ]]> -
]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - ]]> - - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - -

Please press a digit.

]]]]> -
-
- - - 0123456789]]]]> - - - - ]]> -
- - - - 0123456789]]]]> - - - ]]> - - - - - - yesno - ]]]]> - - - ]]> - - - - - - yesno - ]]]]> - - - ]]> - - - - - diff --git a/src/mod/event_handlers/mod_rayo/gateway/README b/src/mod/event_handlers/mod_rayo/gateway/README deleted file mode 100644 index 18c4f4b678..0000000000 --- a/src/mod/event_handlers/mod_rayo/gateway/README +++ /dev/null @@ -1,24 +0,0 @@ -# Still a work in progress... - -# Compile on CentOS 6.4 -erlc -I /usr/lib64/ejabberd/include mod_rayo_gateway.erl - -# Install in ejabberd -cp mod_rayo_gateway.beam /usr/lib64/ejabberd/ebin/ - -vi /etc/ejabberd/ejabberd.cfg - %% - %% Modules enabled in all ejabberd virtual hosts - %% - {modules, - [ - ... - {mod_rayo_gateway,[]}, - ... - ]}. - -ejabberdctl debug -(ejabberd@jabber)1> l(mod_rayo_gateway). -{module,mod_rayo_gateway} -(ejabberd@jabber)2> - diff --git a/src/mod/event_handlers/mod_rayo/gateway/mod_rayo_gateway.erl b/src/mod/event_handlers/mod_rayo/gateway/mod_rayo_gateway.erl deleted file mode 100644 index 72bcd48ea2..0000000000 --- a/src/mod/event_handlers/mod_rayo/gateway/mod_rayo_gateway.erl +++ /dev/null @@ -1,759 +0,0 @@ -%% -%% Copyright (c) 2013 Grasshopper -%% -%% Permission is hereby granted, free of charge, to any person obtaining a copy -%% of this software and associated documentation files (the "Software"), to deal -%% in the Software without restriction, including without limitation the rights -%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -%% copies of the Software, and to permit persons to whom the Software is -%% furnished to do so, subject to the following conditions: -%% -%% The above copyright notice and this permission notice shall be included in -%% all copies or substantial portions of the Software. -%% -%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -%% THE SOFTWARE. -%% -%% Contributors: -%% Chris Rienzo -%% -%% Maintainer: Chris Rienzo -%% -%% mod_rayo_gateway.erl -- ejabberd Rayo gateway module -%% --module(mod_rayo_gateway). - --include("ejabberd.hrl"). --include("jlib.hrl"). - --behavior(gen_server). --behavior(gen_mod). - -%% JID mappings -%% -%% Entity Internal JID Mapped JID -%% ====== =============== =============== -%% Client user@domain/resource gateway@internal_domain/gw-resource -%% Node node_domain external_domain -%% Call uuid@node_domain node_domain|uuid@external_domain -%% Call Resource uuid@node_domain/resource node_domain|uuid@external_domain/resource -%% Mixer name@node_domain node_domain|name@external_domain -%% Mixer Resource name@node_domain/resource node_domain|name@external_domain/resource - -%% TODO don't allow nodes to act as clients -%% TODO don't allow clients to act as nodes - --export([ - start_link/2, - start/2, - stop/1, - init/1, - handle_call/3, - handle_cast/2, - handle_info/2, - terminate/2, - code_change/3, - route_internal/3, - route_external/3 -]). - --define(PROCNAME, ejabberd_mod_rayo_gateway). --define(NS_RAYO, "urn:xmpp:rayo:1"). --define(NS_PING, "urn:xmpp:ping"). - --record(rayo_config, {name, value}). --record(rayo_clients, {jid, status}). --record(rayo_nodes, {jid, status}). --record(rayo_entities, {external_jid, internal_jid, dcp_jid, type}). - -start_link(Host, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). - -% Start the module process -start(Host, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - ChildSpec = {Proc, - {?MODULE, start_link, [Host, Opts]}, - temporary, - 1000, - worker, - [?MODULE]}, - supervisor:start_child(ejabberd_sup, ChildSpec). - -% Shutdown the module -stop(Host) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - gen_server:call(Proc, stop), - supervisor:terminate_child(ejabberd_sup, Proc), - supervisor:delete_child(ejabberd_sup, Proc). - -% Initialize the module -init([Host, Opts]) -> - ?DEBUG("MOD_RAYO_GATEWAY: Starting", []), - - mnesia:delete_table(rayo_clients), - mnesia:create_table(rayo_clients, [{attributes, record_info(fields, rayo_clients)}]), - mnesia:delete_table(rayo_nodes), - mnesia:create_table(rayo_nodes, [{attributes, record_info(fields, rayo_nodes)}]), - mnesia:delete_table(rayo_entities), - mnesia:create_table(rayo_entities, [{attributes, record_info(fields, rayo_entities)}, {index, [internal_jid]}]), - mnesia:delete_table(rayo_config), - mnesia:create_table(rayo_config, [{attributes, record_info(fields, rayo_config)}]), - - {A1,A2,A3} = now(), - random:seed(A1, A2, A3), - - % create virtual domains - InternalDomain = gen_mod:get_opt_host(Host, Opts, "rayo-int.@HOST@"), - ExternalDomain = gen_mod:get_opt_host(Host, Opts, "rayo.@HOST@"), - {ok, Hostname} = inet:gethostname(), - InternalClient = "gateway@" ++ InternalDomain ++ "/" ++ Hostname ++ "-" ++ integer_to_list(random:uniform(65535)), - ?DEBUG("MOD_RAYO_GATEWAY: InternalDomain = ~p, ExternalDomain = ~p, InternalClient = ~p", [InternalDomain, ExternalDomain, InternalClient]), - mnesia:transaction( - fun() -> - mnesia:write(#rayo_config{name = "internal_domain", value = InternalDomain}), - mnesia:write(#rayo_config{name = "internal_client", value = InternalClient}), - mnesia:write(#rayo_config{name = "external_domain", value = ExternalDomain}) - end - ), - - % set up routes to virtual domains - ejabberd_router:register_route(InternalDomain, {apply, ?MODULE, route_internal}), - ejabberd_router:register_route(ExternalDomain, {apply, ?MODULE, route_external}), - {ok, Host}. - -handle_call(stop, _From, Host) -> - {stop, normal, ok, Host}. - -handle_cast(_Msg, Host) -> - {noreply, Host}. - -handle_info(_Msg, Host) -> - {noreply, Host}. - -terminate(_Reason, Host) -> - ejabberd_router:unregister_route(Host), - ok. - -code_change(_OldVsn, Host, _Extra) -> - {ok, Host}. - -register_rayo_node(Jid) -> - Write = fun() -> - mnesia:write(#rayo_nodes{jid = Jid, status = "online" }) - end, - Result = mnesia:transaction(Write), - ?DEBUG("MOD_RAYO_GATEWAY: register node: ~p, result = ~p, ~p nodes total", [jlib:jid_to_string(Jid), Result, num_rayo_nodes()]), - case num_clients() >= 1 of - true -> - ejabberd_router:route(internal_client(), Jid, online_presence()); - _ -> - ok - end, - ok. - -% TODO call this when s2s connection is dropped -unregister_rayo_node(Jid) -> - Delete = fun() -> - mnesia:delete({rayo_nodes, Jid}) - end, - Result = mnesia:transaction(Delete), - Size = mnesia:table_info(rayo_nodes, size), - ?DEBUG("MOD_RAYO_GATEWAY: unregister node: ~p, result = ~p, ~p nodes total", [jlib:jid_to_string(Jid), Result, Size]), - ok. - -% Add client -register_rayo_client(Jid) -> - Write = fun() -> - mnesia:write(#rayo_clients{jid = Jid, status = "online" }) - end, - Result = mnesia:transaction(Write), - Size = num_clients(), - ?DEBUG("MOD_RAYO_GATEWAY: register client: ~p, result = ~p, ~p clients total", [jlib:jid_to_string(Jid), Result, Size]), - case Size of - 1 -> - route_to_list(internal_client(), all_rayo_nodes(), online_presence()); - _ -> - ok - end, - ok. - -% Remove client -% TODO call this when c2s connection is dropped -unregister_rayo_client(Jid) -> - Delete = fun() -> - mnesia:delete({rayo_clients, Jid}) - end, - Result = mnesia:transaction(Delete), - Size = num_clients(), - ?DEBUG("MOD_RAYO_GATEWAY: unregister client: ~p, result = ~p, ~p clients total", [jlib:jid_to_string(Jid), Result, Size]), - case Size of - 0 -> - route_to_list(internal_client(), all_rayo_nodes(), offline_presence()); - _ -> - ok - end, - ok. - -% Add node entity -register_rayo_node_entity(ExtJid, IntJid, DcpJid, Type) -> - Write = fun() -> - mnesia:write(#rayo_entities{external_jid = ExtJid, internal_jid = IntJid, dcp_jid = DcpJid, type = Type}) - end, - Result = mnesia:transaction(Write), - Size = mnesia:table_info(rayo_entities, size), - ?DEBUG("MOD_RAYO_GATEWAY: register entity: ~p, result = ~p, ~p entities total", [jlib:jid_to_string(ExtJid), Result, Size]), - ok. - -% Remove node entity -unregister_rayo_node_entity(ExtJid) -> - Delete = fun() -> - mnesia:delete({rayo_entities, ExtJid}) - end, - Result = mnesia:transaction(Delete), - Size = mnesia:table_info(rayo_entities, size), - ?DEBUG("MOD_RAYO_GATEWAY: unregister entity: ~p, result = ~p, ~p entities total", [jlib:jid_to_string(ExtJid), Result, Size]), - ok. - -% find node entity given enitity's (or its component's) internal JID -find_rayo_node_entity_by_int_jid(IntJid) -> - % remove resource from JID to find component's parent call/mixer - case mnesia:dirty_index_read(rayo_entities, jlib:jid_remove_resource(IntJid), #rayo_entities.internal_jid) of - [Entity | _] -> - Entity; - _ -> - none - end. - -% find node entity given enitity's (or its component's) external JID -find_rayo_node_entity_by_ext_jid(ExtJid) -> - % remove resource from JID to find component's parent call/mixer - case mnesia:dirty_read(rayo_entities, jlib:jid_remove_resource(ExtJid)) of - [Entity | _] -> - Entity; - _ -> - none - end. - -% find entity Definitive Controlling Party JID given entity external JID -find_rayo_node_entity_dcp_by_ext_jid(ExtJid) -> - case find_rayo_node_entity_by_ext_jid(ExtJid) of - {rayo_entities, _, _, DcpJid, _} -> - DcpJid; - _ -> - none - end. - -% find entity Definitive Controlling Party JID given entity internal JID -find_rayo_node_entity_dcp_by_int_jid(IntJid) -> - case find_rayo_node_entity_by_int_jid(IntJid) of - {rayo_entities, _, _, DcpJid, _} -> - DcpJid; - _ -> - none - end. - -% create External JID from Internal JID -% intnode@intdomain/resource -> intdomain-intnode@extdomain/resource -create_external_jid({jid, Node, Domain, Resource, _, _, _}) -> - jlib:make_jid(Domain ++ "|" ++ Node, jlib:jid_to_string(external_domain()), Resource). - -% create Internal JID from External JID -% intdomain-intnode@extdomain/resource -> intnode@intdomain/resource -create_internal_jid({jid, Node, _Domain, Resource, _, _, _}) -> - % TODO use rayo_entities to lookup node... it's safer - Idx = string:str(Node, "|"), - case Idx > 0 of - true -> - jlib:make_jid(string:substr(Node, Idx + 1), string:substr(Node, 1, Idx - 1), Resource); - false -> - none - end. - -% Take control of entity -% Return {true, internal entity JID} if successful -set_entity_dcp(PcpJid, EntityJid) -> - SetDcp = fun() -> - case mnesia:wread(rayo_entities, EntityJid) of - [{rayo_entities, EntityJid, InternalJid, none, Type}] -> - % take control - case mnesia:write(#rayo_entities{external_jid = EntityJid, internal_jid = InternalJid, dcp_jid = PcpJid, type = Type}) of - ok -> - {true, InternalJid}; - Else -> - {error, Else} - end; - _ -> - {false, []} - end - end, - {_, Result} = mnesia:transaction(SetDcp), - Result. - -% Check if PCP has control of entity -% Return {true, internal entity JID} if true -is_entity_dcp(PcpJid, EntityJid) -> - % quick check first - case mnesia:dirty_read(rayo_entities, EntityJid) of - [{rayo_entities, EntityJid, _, none, _}] -> - % take control - set_entity_dcp(PcpJid, EntityJid); - [{rayo_entities, EntityJid, InternalJid, PcpJid, _}] -> - {true, InternalJid}; - [{rayo_entities, EntityJid, InternalJid, _, _}] -> - {false, InternalJid}; - [] -> - ?DEBUG("MOD_RAYO_GATEWAY: no match for EntityJid ~p", [EntityJid]), - {false, none} - end. - -% Handle presence to external domain -route_external(From, {jid, [], _Domain, [], [], _LDomain, []} = To, {xmlelement, "presence", _Attrs, _Els} = Presence) -> - ?DEBUG("MOD_RAYO_GATEWAY: got client presence ~n~p", [Presence]), - route_client_presence(From, To, Presence), - ok; - -% Handle presence to external domain resource -route_external(From, To, {xmlelement, "presence", _Attrs, _Els} = Presence) -> - ?DEBUG("MOD_RAYO_GATEWAY: got client presence to mixer ~n~p", [Presence]), - % TODO check if actually being sent to mixer... - route_client_presence_to_mixer(From, To, Presence), - ok; - -% Handle to external domain -route_external(_From, _To, {xmlelement, "message", _Attrs, _Els} = Message) -> - % ignore - ?DEBUG("MOD_RAYO_GATEWAY: got client message ~n~p", [Message]), - ok; - -% Handle to external domain -route_external(From, {jid, [], _Domain, [], [], _LDomain, []} = To, {xmlelement, "iq", _Attrs, _Els} = IQ) -> - ?DEBUG("MOD_RAYO_GATEWAY: got client iq to gateway ~n~p", [IQ]), - case get_attribute_as_list(IQ, "type", "") of - "get" -> - case get_element(IQ, ?NS_PING, "ping") of - undefined -> - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST); - _ -> - route_result_reply(To, From, IQ) - end; - "set" -> - case get_element(IQ, ?NS_RAYO, "dial") of - undefined-> - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST); - _ -> - route_dial_call(To, From, IQ) - end; - "" -> - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST) - end, - ok; - -% Handle to external domain resource -route_external(From, To, {xmlelement, "iq", _Attrs, _Els} = IQ) -> - ?DEBUG("MOD_RAYO_GATEWAY: got client iq ~n~p", [IQ]), - case is_entity_dcp(From, To) of - {true, _} -> - IntFrom = internal_client(), - IntTo = create_internal_jid(To), - route_iq_request(IntFrom, IntTo, IQ, fun(IQReply) -> route_iq_response(From, To, IQ, IQReply) end); - {false, _} -> - route_error_reply(To, From, IQ, ?ERR_CONFLICT); - _ -> - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST) - end, - ok. - -% Handle to internal domain -route_internal(From, {jid, [], _Domain, [], [], _LDomain, []} = To, {xmlelement, "presence", _Attrs, _Els} = Presence) -> - ?DEBUG("MOD_RAYO_GATEWAY: got node presence to internal domain ~n~p", [Presence]), - route_server_presence(From, To, Presence), - ok; - -% Handle to internal domain resource -route_internal(From, To, {xmlelement, "presence", _Attrs, _Els} = Presence) -> - ?DEBUG("MOD_RAYO_GATEWAY: got node presence to internal domain ~n~p", [Presence]), - case To =:= internal_client() of - true -> - route_server_presence(From, To, Presence); - false -> - % TODO implement - ok - end, - ok; - -% Handle to internal domain -route_internal(_From, _To, {xmlelement, "message", _Attrs, _Els} = Message) -> - ?DEBUG("MOD_RAYO_GATEWAY: got node message ~n~p", [Message]), - % ignore - ok; - -% Handle to internal domain. -route_internal(From, {jid, [], _Domain, [], [], _LDomain, []} = To, {xmlelement, "iq", _Attrs, _Els} = IQ) -> - ?DEBUG("MOD_RAYO_GATEWAY: got node iq ~n~p", [IQ]), - case get_attribute_as_list(IQ, "type", "") of - "get" -> - case get_element(IQ, ?NS_PING, "ping") of - undefined -> - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST); - _ -> - route_result_reply(To, From, IQ) - end; - "result" -> - ejabberd_local:process_iq_reply(From, To, jlib:iq_query_or_response_info(IQ)); - "error" -> - ejabberd_local:process_iq_reply(From, To, jlib:iq_query_or_response_info(IQ)); - "" -> - % don't allow get/set from nodes - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST) - end, - ok; - -% Handle to internal domain resource. -route_internal(From, To, {xmlelement, "iq", _Attrs, _Els} = IQ) -> - ?DEBUG("MOD_RAYO_GATEWAY: got node iq ~n~p", [IQ]), - case get_attribute_as_list(IQ, "type", "") of - "result" -> - ejabberd_local:process_iq_reply(From, To, jlib:iq_query_or_response_info(IQ)); - "error" -> - ejabberd_local:process_iq_reply(From, To, jlib:iq_query_or_response_info(IQ)); - _ -> - % Don't allow get/set from nodes - route_error_reply(To, From, IQ, ?ERR_BAD_REQUEST) - end, - ok. - -% Process presence message from rayo node -route_rayo_node_presence(From, _To, Presence) -> - case get_attribute_as_list(Presence, "type", "") of - "" -> - case get_element(Presence, "show") of - undefined -> - ?DEBUG("MOD_RAYO_GATEWAY: ignoring empty presence", []); - Show -> - case get_cdata_as_list(Show) of - "chat" -> - register_rayo_node(From); - "dnd" -> - unregister_rayo_node(From); - "xa" -> - unregister_rayo_node(From); - "" -> - unregister_rayo_node(From) - end - end; - "unavailable" -> - %TODO broadcast end instead? - unregister_rayo_node(From) - end, - ok. - -% Process presence from call -route_call_presence(From, _To, Presence) -> - %TODO join/unjoin mixer events - case get_attribute_as_list(Presence, "type", "") of - "" -> - case get_element(Presence, ?NS_RAYO, "offer") of - undefined -> - route_rayo_entity_stanza(From, Presence); - _ -> - route_offer_call(From, Presence) - end; - "unavailable" -> - case get_element(Presence, ?NS_RAYO, "end") of - undefined -> - route_rayo_entity_stanza(From, Presence); - _ -> - route_rayo_entity_stanza(From, Presence), - unregister_rayo_node_entity(create_external_jid(From)) - end - end, - ok. - -% presence from node -route_server_presence({jid, [], _Domain, [], [], _LDomain, []} = From, To, Presence) -> - route_rayo_node_presence(From, To, Presence), - ok; - -% presence from call/mixer -route_server_presence(From, To, Presence) -> - % TODO mixer - route_call_presence(From, To, Presence), - ok. - -% presence from Rayo Client -route_client_presence(From, _To, Presence) -> - case get_attribute_as_list(Presence, "type", "") of - "" -> - case get_element(Presence, "show") of - undefined -> - ?DEBUG("MOD_RAYO_GATEWAY: ignoring empty presence", []); - Show -> - case get_cdata_as_list(Show) of - "chat" -> - register_rayo_client(From); - "dnd" -> - unregister_rayo_client(From); - _ -> - unregister_rayo_client(From) - end - end; - "unavailable" -> - unregister_rayo_client(From); - _ -> - ok - end, - ok. - -% route client directed presence to mixer -route_client_presence_to_mixer(_From, _To, _Presence) -> - % TODO - ok. - -% Handle offer to client -route_offer_call(From, Offer) -> - % Any clients available? - case pick_client() of - none -> - % TODO reject? - ok; - ClientDcp -> - % Remember call - ExtFrom = create_external_jid(From), - register_rayo_node_entity(ExtFrom, From, ClientDcp, call), - ejabberd_router:route(ExtFrom, ClientDcp, Offer) - end, - ok. - -% convert URI to a JID -uri_to_jid(Uri) -> - JidString = case string:str(Uri, "xmpp:") of - 1 -> - string:substr(Uri, 6); - _ -> - Uri - end, - jlib:string_to_jid(JidString). - -% convert internal IQ reply to an external reply -create_external_iq_reply(OrigIQ, {xmlelement, _, _, Els} = IQReply) -> - IQId = get_attribute_as_list(OrigIQ, "id", ""), - IQType = get_attribute_as_list(IQReply, "type", ""), - {xmlelement, "iq", [{"id", IQId}, {"type", IQType}], Els}. - -% Process dial response -route_dial_call_response(OrigFrom, OrigTo, OrigIQ, timeout) -> - % TODO retry on different node? - route_iq_response(OrigFrom, OrigTo, OrigIQ, timeout); - -route_dial_call_response(OrigFrom, OrigTo, OrigIQ, IQReply) -> - ?DEBUG("MOD_RAYO_GATEWAY: IQ response for ~p", [OrigIQ]), - IQReplyPacket = jlib:iq_to_xml(IQReply), - case get_element(IQReplyPacket, "error") of - undefined -> - case get_element(IQReplyPacket, "ref") of - undefined -> - ok; - Ref -> - IntJid = uri_to_jid(get_attribute_as_list(Ref, "uri", "")), - register_rayo_node_entity(create_external_jid(IntJid), IntJid, OrigFrom, call) - end; - _ -> - ok - end, - ejabberd_router:route(OrigTo, OrigFrom, create_external_iq_reply(OrigIQ, IQReplyPacket)), - ok. - -% Forward dial to node -route_dial_call(From, To, Dial) -> - % any nodes available? - case num_rayo_nodes() > 0 of - true -> - IntFrom = internal_client(), - case pick_rayo_node() of - none -> - route_error_reply(To, From, Dial, ?ERR_SERVICE_UNAVAILABLE); - NodeJid -> - route_iq_request(IntFrom, NodeJid, Dial, fun(IQReply) -> route_dial_call_response(From, To, Dial, IQReply) end) - end; - _ -> - route_error_reply(To, From, Dial, ?ERR_RESOURCE_CONSTRAINT) - end. - -% return configuration value given name -config_value(Name) -> - case catch mnesia:dirty_read(rayo_config, Name) of - [{rayo_config, Name, Value}] -> - Value; - _ -> - "" - end. - -% return internal client name -internal_client() -> - jlib:string_to_jid(config_value("internal_client")). - -% return internal domain name -internal_domain() -> - jlib:string_to_jid(config_value("internal_domain")). - -% return external domain name -external_domain() -> - jlib:string_to_jid(config_value("external_domain")). - -% return number of registered clients -num_clients() -> - mnesia:table_info(rayo_clients, size). - -% return all registered client JIDs -all_clients() -> - case mnesia:transaction(fun() -> mnesia:all_keys(rayo_clients) end) of - {atomic, Keys} -> - Keys; - _ -> - [] - end. - -% pick a registered client -pick_client() -> - % pick at random for now... - case all_clients() of - [] -> - none; - AllClients -> - lists:nth(random:uniform(length(AllClients)), AllClients) - end. - -% pick a registered node -pick_rayo_node() -> - % pick at random for now... - case all_rayo_nodes() of - [] -> - none; - AllNodes -> - lists:nth(random:uniform(length(AllNodes)), AllNodes) - end. - -% return number of registered rayo nodes -num_rayo_nodes() -> - mnesia:table_info(rayo_nodes, size). - -% return all rayo node JIDs -all_rayo_nodes() -> - case mnesia:transaction(fun() -> mnesia:all_keys(rayo_nodes) end) of - {atomic, Keys} -> - Keys; - _ -> - [] - end. - -presence(Status) -> - {xmlelement, "presence", [], [ - {xmlelement, "show", [], [ - {xmlcdata, Status} - ]} - ]}. - -online_presence() -> - presence(<<"chat">>). - -offline_presence() -> - presence(<<"dnd">>). - -route_to_list(From, ToList, Stanza) -> - lists:map(fun(To) -> ejabberd_router:route(From, To, Stanza) end, ToList), - ok. - -% route stanza from entity -route_rayo_entity_stanza(From, Stanza) -> - case find_rayo_node_entity_dcp_by_int_jid(From) of - none -> - ?DEBUG("MOD_RAYO_GATEWAY: Failed to find DCP for ~p", [From]), - ok; - DcpJid -> - ejabberd_router:route(create_external_jid(From), DcpJid, Stanza) - end, - ok. - -% route IQ response from node to client -route_iq_response(OrigFrom, OrigTo, OrigIQ, timeout) -> - route_error_reply(OrigTo, OrigFrom, OrigIQ, ?ERR_REMOTE_SERVER_TIMEOUT), - ok; - -route_iq_response(OrigFrom, OrigTo, OrigIQ, IQReply) -> - ?DEBUG("MOD_RAYO_GATEWAY: IQ response for ~p", [OrigIQ]), - ejabberd_router:route(OrigTo, OrigFrom, create_external_iq_reply(OrigIQ, jlib:iq_to_xml(IQReply))), - ok. - -% route IQ from client to node -route_iq_request(From, To, {xmlelement, "iq", _Atts, Els}, ResponseCallback) -> - ejabberd_local:route_iq(From, To, #iq{type = set, sub_el = Els}, ResponseCallback), - ok. - -% route IQ error given request -route_error_reply(From, To, IQ, Reason) -> - ejabberd_router:route(From, To, jlib:make_error_reply(IQ, Reason)), - ok. - -% route IQ result given request -route_result_reply(From, To, IQ) -> - ejabberd_router:route(From, To, jlib:make_result_iq_reply(IQ)), - ok. - -% XML parsing helpers - -get_element(Element, Name) -> - case xml:get_subtag(Element, Name) of - false -> - undefined; - Subtag -> - Subtag - end. - -get_element(Element, NS, Name) -> - case get_element(Element, Name) of - undefined -> - undefined; - Subtag -> - case get_attribute_as_list(Subtag, "xmlns", "") of - "" -> - undefined; - NS -> - Subtag - end - end. - -get_cdata_as_list(undefined) -> - ""; - -get_cdata_as_list(Element) -> - xml:get_tag_cdata(Element). - -get_element_cdata_as_list(Element, Name) -> - get_cdata_as_list(get_element(Element, Name)). - -get_element_cdata_as_list(Element, NS, Name) -> - get_cdata_as_list(get_element(Element, NS, Name)). - -get_element_attribute_as_list(Element, Name, AttrName, Default) -> - get_attribute_as_list(get_element(Element, Name), AttrName, Default). - -get_element_attribute_as_list(Element, NS, Name, AttrName, Default) -> - get_attribute_as_list(get_element(Element, NS, Name), AttrName, Default). - -get_attribute_as_list(undefined, _Name, _Default) -> - undefined; - -get_attribute_as_list(Element, Name, Default) -> - case xml:get_tag_attr_s(Name, Element) of - "" -> - Default; - Attr -> - Attr - end. diff --git a/src/mod/event_handlers/mod_rayo/iks_helpers.c b/src/mod/event_handlers/mod_rayo/iks_helpers.c deleted file mode 100644 index 2f293aabb7..0000000000 --- a/src/mod/event_handlers/mod_rayo/iks_helpers.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2014, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * iks_helpers.c -- iksemel helpers - * - */ -#include "iks_helpers.h" -#include -#include -#include - -#undef XMPP_ERROR -#define XMPP_ERROR(def_name, name, type) \ - const struct xmpp_error def_name##_val = { name, type }; \ - const struct xmpp_error *def_name = &def_name##_val; -#include "xmpp_errors.def" - -/** - * Create a event - * @param name the event name - * @param namespace the event namespace - * @param from - * @param to - * @return the event XML node - */ -iks *iks_new_presence(const char *name, const char *namespace, const char *from, const char *to) -{ - iks *event = iks_new("presence"); - iks *x; - /* iks makes copies of attrib name and value */ - iks_insert_attrib(event, "from", from); - iks_insert_attrib(event, "to", to); - x = iks_insert(event, name); - if (!zstr(namespace)) { - iks_insert_attrib(x, "xmlns", namespace); - } - return event; -} - -/** - * Create error response from request - * @param req the request - * @param from - * @param to - * @param err the XMPP stanza error - * @return the error response - */ -iks *iks_new_error(iks *req, const struct xmpp_error *err) -{ - iks *response = iks_copy(req); - iks *x; - - /* */ - iks_insert_attrib(response, "from", iks_find_attrib(req, "to")); - iks_insert_attrib(response, "to", iks_find_attrib(req, "from")); - iks_insert_attrib(response, "type", "error"); - - /* */ - x = iks_insert(response, "error"); - iks_insert_attrib(x, "type", err->type); - - /* e.g. */ - x = iks_insert(x, err->name); - iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_STANZAS); - - return response; -} - -/** - * Create error response from request - * @param req the request - * @param from - * @param to - * @param err the XMPP stanza error - * @param detail_text optional text to include in message - * @return the error response - */ -iks *iks_new_error_detailed(iks *req, const struct xmpp_error *err, const char *detail_text) -{ - iks *reply = iks_new_error(req, err); - if (!zstr(detail_text)) { - iks *error = iks_find(reply, "error"); - iks *text = iks_insert(error, "text"); - iks_insert_attrib(text, "xml:lang", "en"); - iks_insert_attrib(text, "xmlns", IKS_NS_XMPP_STANZAS); - iks_insert_cdata(text, detail_text, strlen(detail_text)); - } - return reply; -} - -/** - * Create error response from request - * @param req the request - * @param from - * @param to - * @param err the XMPP stanza error - * @param detail_text_format format string - * @param ... - * @return the error response - */ -iks *iks_new_error_detailed_printf(iks *req, const struct xmpp_error *err, const char *detail_text_format, ...) -{ - iks *reply = NULL; - char *data; - va_list ap; - int ret; - - va_start(ap, detail_text_format); - ret = switch_vasprintf(&data, detail_text_format, ap); - va_end(ap); - - if (ret == -1) { - return NULL; - } - reply = iks_new_error_detailed(req, err, data); - free(data); - return reply; -} - -/** - * Create result response from request - * @param iq the request - * @return the result response - */ -iks *iks_new_iq_result(iks *iq) -{ - iks *response = iks_new("iq"); - iks_insert_attrib(response, "from", iks_find_attrib(iq, "to")); - iks_insert_attrib(response, "to", iks_find_attrib(iq, "from")); - iks_insert_attrib(response, "type", "result"); - iks_insert_attrib(response, "id", iks_find_attrib(iq, "id")); - return response; -} - -/** - * Get attribute value of node, returning empty string if non-existent or not set. - * @param xml the XML node to search - * @param attrib the Attribute name - * @return the attribute value - */ -const char *iks_find_attrib_soft(iks *xml, const char *attrib) -{ - char *value = iks_find_attrib(xml, attrib); - return zstr(value) ? "" : value; -} - -/** - * Get attribute value of node, returning default value if missing. The default value - * is set in the node if missing. - * @param xml the XML node to search - * @param attrib the Attribute name - * @return the attribute value - */ -const char *iks_find_attrib_default(iks *xml, const char *attrib, const char *def) -{ - char *value = iks_find_attrib(xml, attrib); - if (!value) { - iks_insert_attrib(xml, attrib, def); - return def; - } - return value; -} - -/** - * Get attribute integer value of node - * @param xml the XML node to search - * @param attrib the Attribute name - * @return the attribute value - */ -int iks_find_int_attrib(iks *xml, const char *attrib) -{ - return atoi(iks_find_attrib_soft(xml, attrib)); -} - -/** - * Get attribute boolean value of node - * @param xml the XML node to search - * @param attrib the Attribute name - * @return the attribute value - */ -int iks_find_bool_attrib(iks *xml, const char *attrib) -{ - return switch_true(iks_find_attrib_soft(xml, attrib)); -} - -/** - * Get attribute double value of node - * @param xml the XML node to search - * @param attrib the Attribute name - * @return the attribute value - */ -double iks_find_decimal_attrib(iks *xml, const char *attrib) -{ - return atof(iks_find_attrib_soft(xml, attrib)); -} - -/** - * Get attribute character value of node - * @param xml the XML node to search - * @param attrib the Attribute name - * @return the attribute value - */ -char iks_find_char_attrib(iks *xml, const char *attrib) -{ - return iks_find_attrib_soft(xml, attrib)[0]; -} - -/** - * Convert iksemel XML node type to string - * @param type the XML node type - * @return the string value of type or "UNKNOWN" - */ -const char *iks_node_type_to_string(int type) -{ - switch(type) { - case IKS_NODE_START: return "NODE_START"; - case IKS_NODE_NORMAL: return "NODE_NORMAL"; - case IKS_NODE_ERROR: return "NODE_ERROR"; - case IKS_NODE_STOP: return "NODE_START"; - default: return "NODE_UNKNOWN"; - } -} - -/** - * Convert iksemel error code to string - * @param err the iksemel error code - * @return the string value of error or "UNKNOWN" - */ -const char *iks_net_error_to_string(int err) -{ - switch (err) { - case IKS_OK: return "OK"; - case IKS_NOMEM: return "NOMEM"; - case IKS_BADXML: return "BADXML"; - case IKS_HOOK: return "HOOK"; - case IKS_NET_NODNS: return "NET_NODNS"; - case IKS_NET_NOSOCK: return "NET_NOSOCK"; - case IKS_NET_NOCONN: return "NET_NOCONN"; - case IKS_NET_RWERR: return "NET_RWERR"; - case IKS_NET_NOTSUPP: return "NET_NOTSUPP"; - case IKS_NET_TLSFAIL: return "NET_TLSFAIL"; - case IKS_NET_DROPPED: return "NET_DROPPED"; - case IKS_NET_UNKNOWN: return "NET_UNKNOWN"; - default: return "UNKNOWN"; - } -} - -/** - * Insert attribute using format string - * @param xml node to insert attribute into - * @param name of attribute - * @param fmt format string - * @param ... format string args - */ -iks *iks_insert_attrib_printf(iks *xml, const char *name, const char *fmt, ...) -{ - iks *node; - char *data; - va_list ap; - int ret; - - va_start(ap, fmt); - ret = switch_vasprintf(&data, fmt, ap); - va_end(ap); - - if (ret == -1) { - return NULL; - } - node = iks_insert_attrib(xml, name, data); - free(data); - - return node; -} - -/** - * @param value to match - * @param rule to check - * @return true if value is one of the comma-separated values in rule - */ -int value_matches(const char *value, const char *rule) -{ - if (rule && *rule && value && *value && !strchr(value, ',')) { - const char *begin = strstr(rule, value); - const char *end = begin + strlen(value); - if (!begin) { - return 0; - } - if ((begin == rule || *(begin - 1) == ',') && (*end == ',' || *end == '\0')) { - return 1; - } - /* substring matched... try farther down the string */ - return value_matches(value, end); - } - return 0; -} - -/** - * Validate boolean - * @param value - * @return SWTICH_TRUE if boolean - */ -int iks_attrib_is_bool(const char *value) -{ - if (value && *value && (!strcasecmp("true", value) || !strcasecmp("false", value))) { - return SWITCH_TRUE; - } - return SWITCH_FALSE; -} - -/** - * Validate integer - * @param value - * @return SWTICH_TRUE if not negative - */ -int iks_attrib_is_not_negative(const char *value) -{ - if (value && *value && switch_is_number(value)) { - int value_i = atoi(value); - if (value_i >= 0) { - return SWITCH_TRUE; - } - } - return SWITCH_FALSE; -} - -/** - * Validate integer - * @param value - * @return SWTICH_TRUE if positive - */ -int iks_attrib_is_positive(const char *value) -{ - if (value && *value && switch_is_number(value)) { - int value_i = atoi(value); - if (value_i > 0) { - return SWITCH_TRUE; - } - } - return SWITCH_FALSE; -} - -/** - * Validate integer - * @param value - * @return SWTICH_TRUE if positive or -1 - */ -int iks_attrib_is_positive_or_neg_one(const char *value) -{ - if (value && *value && switch_is_number(value)) { - int value_i = atoi(value); - if (value_i == -1 || value_i > 0) { - return SWITCH_TRUE; - } - } - return SWITCH_FALSE; -} - -/** - * Validate string - * @param value - * @return SWTICH_TRUE - */ -int iks_attrib_is_any(const char *value) -{ - return SWITCH_TRUE; -} - -/** - * Validate decimal - * @param value - * @return SWTICH_TRUE if 0.0 <= x <= 1.0 - */ -int iks_attrib_is_decimal_between_zero_and_one(const char *value) -{ - if (value && *value && switch_is_number(value)) { - double value_d = atof(value); - if (value_d >= 0.0 && value_d <= 1.0) { - return SWITCH_TRUE; - } - } - return SWITCH_FALSE; -} - -/** - * Validate dtmf digit - * @param value - * @return SWITCH_TRUE if 0-9,a,b,c,d,A,B,C,D,*,# - */ -int iks_attrib_is_dtmf_digit(const char *value) -{ - if (value && *value && strlen(value) == 1) { - switch (*value) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'A': - case 'a': - case 'B': - case 'b': - case 'C': - case 'c': - case 'D': - case 'd': - case '*': - case '#': - return SWITCH_TRUE; - } - } - return SWITCH_FALSE; -} - -/** - * @param fn to evaluate attribute - * @param attrib to evaluate - * @return true if not set or is valid - */ -int validate_optional_attrib(iks_attrib_validation_function fn, const char *attrib) -{ - if (!attrib || !*attrib) { - return SWITCH_TRUE; - } - return fn(attrib); -} - -#define IKS_SHA256_HEX_DIGEST_LENGTH ((SHA256_DIGEST_LENGTH * 2) + 1) - -/** - * Convert hash to a hex string. - * @param hash hash to convert - * @param str buffer to store hash - this buffer must be hashlen * 2 + 1 in size. - */ -static void iks_hash_to_hex_string(unsigned char *hash, int hashlen, unsigned char *str) -{ - static const char *HEX = "0123456789abcdef"; - int i; - - /* convert to hex string with in-place algorithm */ - for (i = hashlen - 1; i >= 0; i--) { - str[i * 2 + 1] = HEX[hash[i] & 0x0f]; - str[i * 2] = HEX[(hash[i] >> 4) & 0x0f]; - } - str[hashlen * 2] = '\0'; -} - -/** - * Generate SHA-256 hash of value as hex string - * @param data to hash - * @param datalen length of data to hash - * @return hash as a hex string - */ -static void iks_sha256_hex_string(const unsigned char *data, int datalen, unsigned char *hash) -{ - /* hash data */ - SHA256(data, datalen, hash); - iks_hash_to_hex_string(hash, SHA256_DIGEST_LENGTH, hash); -} - -/** - * Generate HMAC SHA-256 - * @param key the key - * @param keylen length of key - * @param message the message - * @param messagelen length of message - * @param hash buffer to store the hash - must be IKS_SHA256_HEX_DIGEST_LENGTH - */ -static void iks_hmac_sha256_hex_string(const unsigned char *key, int keylen, const unsigned char *message, int messagelen, unsigned char *hash) -{ - unsigned int hash_len = SHA256_DIGEST_LENGTH; - HMAC(EVP_sha256(), key, keylen, message, messagelen, hash, &hash_len); - iks_hash_to_hex_string(hash, SHA256_DIGEST_LENGTH, hash); -} - -/** - * Generate server dialback key. free() the returned value - * @param secret originating server shared secret - * @param receiving_server domain - * @param originating_server domain - * @param stream_id stream ID - * @return the dialback key - */ -char *iks_server_dialback_key(const char *secret, const char *receiving_server, const char *originating_server, const char *stream_id) -{ - if (!zstr(secret) && !zstr(receiving_server) && !zstr(originating_server) && !zstr(stream_id)) { - unsigned char secret_hash[IKS_SHA256_HEX_DIGEST_LENGTH]; - unsigned char *message = NULL; - unsigned char *dialback_key = malloc(sizeof(unsigned char) * IKS_SHA256_HEX_DIGEST_LENGTH); - iks_sha256_hex_string((unsigned char *)secret, strlen(secret), secret_hash); - message = (unsigned char *)switch_mprintf("%s %s %s", receiving_server, originating_server, stream_id); - iks_hmac_sha256_hex_string(secret_hash, strlen((char *)secret_hash), message, strlen((char *)message), dialback_key); - free(message); - return (char *)dialback_key; - } - return NULL; -} - -/** - * Print base 64 encoded SHA-1 hash - * @param sha hash to print - * @param buf to store baes 64 encoded hash - */ -void iks_sha_print_base64(iksha *sha, char *buf) -{ - int i; - char hex_digit[3] = { 0 }; - char hex_buf[SHA_1_HASH_BUF_SIZE]; - unsigned char bin_buf[SHA_1_HASH_BUF_SIZE / 2]; - iks_sha_print(sha, hex_buf); - - /* convert hex string to octets */ - for (i = 0; i < SHA_1_HASH_BUF_SIZE; i += 2) { - hex_digit[0] = hex_buf[i]; - hex_digit[1] = hex_buf[i + 1]; - bin_buf[i / 2] = strtol(hex_digit, NULL, 16); - } - - switch_b64_encode(bin_buf, SHA_1_HASH_BUF_SIZE / 2, (unsigned char *)buf, SHA_1_HASH_BUF_SIZE); -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/iks_helpers.h b/src/mod/event_handlers/mod_rayo/iks_helpers.h deleted file mode 100644 index b98dbf5be6..0000000000 --- a/src/mod/event_handlers/mod_rayo/iks_helpers.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * iks_helpers.h -- iksemel constants and helpers - * - */ -#ifndef IKS_EXT_H -#define IKS_EXT_H - -#include -#include - -#define SHA_1_HASH_BUF_SIZE 40 - -#define IKS_JABBER_SERVER_PORT 5269 - -#define IKS_NS_XMPP_DISCO "http://jabber.org/protocol/disco#info" -#define IKS_NS_XMPP_PING "urn:xmpp:ping" -#define IKS_NS_XMPP_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas" -#define IKS_NS_XMPP_STREAMS "http://etherx.jabber.org/streams" -#define IKS_NS_XMPP_DIALBACK "jabber:server:dialback" -#define IKS_NS_XMPP_TLS "urn:ietf:params:xml:ns:xmpp-tls" -#define IKS_NS_XMPP_ENTITY_CAPABILITIES "http://jabber.org/protocol/caps" - -struct xmpp_error { - const char *name; - const char *type; -}; - -#undef XMPP_ERROR -#define XMPP_ERROR(def_name, name, type) \ - extern const struct xmpp_error *def_name; -#include "xmpp_errors.def" - -/* See RFC-3920 XMPP core for error definitions */ -SWITCH_DECLARE(iks *) iks_new_presence(const char *name, const char *namespace, const char *from, const char *to); -SWITCH_DECLARE(iks *) iks_new_error(iks *iq, const struct xmpp_error *err); -SWITCH_DECLARE(iks *) iks_new_error_detailed(iks *iq, const struct xmpp_error *err, const char *detail_text); -SWITCH_DECLARE(iks *) iks_new_error_detailed_printf(iks *iq, const struct xmpp_error *err, const char *detail_text_format, ...); -SWITCH_DECLARE(iks *) iks_new_iq_result(iks *iq); -SWITCH_DECLARE(const char *) iks_find_attrib_soft(iks *xml, const char *attrib); -SWITCH_DECLARE(const char *) iks_find_attrib_default(iks *xml, const char *attrib, const char *def); -SWITCH_DECLARE(int) iks_find_bool_attrib(iks *xml, const char *attrib); -SWITCH_DECLARE(int) iks_find_int_attrib(iks *xml, const char *attrib); -SWITCH_DECLARE(char) iks_find_char_attrib(iks *xml, const char *attrib); -SWITCH_DECLARE(double) iks_find_decimal_attrib(iks *xml, const char *attrib); -SWITCH_DECLARE(const char *) iks_node_type_to_string(int type); -SWITCH_DECLARE(const char *) iks_net_error_to_string(int err); -SWITCH_DECLARE(iks *) iks_insert_attrib_printf(iks *xml, const char *name, const char *fmt, ...); - -SWITCH_DECLARE(char *) iks_server_dialback_key(const char *secret, const char *receiving_server, const char *originating_server, const char *stream_id); -SWITCH_DECLARE(void) iks_sha_print_base64(iksha *sha, char *buf); - -/** A function to validate attribute value */ -typedef int (*iks_attrib_validation_function)(const char *); - -SWITCH_DECLARE(int) validate_optional_attrib(iks_attrib_validation_function fn, const char *attrib); - -#define ELEMENT_DECL(name) SWITCH_DECLARE(int) VALIDATE_##name(iks *node); -#define ELEMENT(name) int VALIDATE_##name(iks *node) { int result = 1; if (!node) return 0; -#define ATTRIB(name, def, rule) result &= iks_attrib_is_##rule(iks_find_attrib_default(node, #name, #def)); -#define OPTIONAL_ATTRIB(name, def, rule) result &= validate_optional_attrib(iks_attrib_is_##rule, iks_find_attrib_default(node, #name, #def)); -#define STRING_ATTRIB(name, def, rule) result &= value_matches(iks_find_attrib_default(node, #name, #def), rule); -#define ELEMENT_END return result; } - -SWITCH_DECLARE(int) value_matches(const char *value, const char *rule); - -SWITCH_DECLARE(int) iks_attrib_is_bool(const char *value); -SWITCH_DECLARE(int) iks_attrib_is_not_negative(const char *value); -SWITCH_DECLARE(int) iks_attrib_is_positive(const char *value); -SWITCH_DECLARE(int) iks_attrib_is_positive_or_neg_one(const char *value); -SWITCH_DECLARE(int) iks_attrib_is_any(const char *value); -SWITCH_DECLARE(int) iks_attrib_is_decimal_between_zero_and_one(const char *value); -SWITCH_DECLARE(int) iks_attrib_is_dtmf_digit(const char *value); - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c deleted file mode 100644 index 228e89b323..0000000000 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ /dev/null @@ -1,5411 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * mod_rayo.c -- Rayo server / node implementation. Allows MxN clustering of FreeSWITCH and Rayo Clients (like Adhearsion) - * - */ -#include -#include - -#include "mod_rayo.h" -#include "rayo_components.h" -#include "rayo_elements.h" -#include "xmpp_streams.h" - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rayo_shutdown); -SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load); -SWITCH_MODULE_RUNTIME_FUNCTION(mod_rayo_runtime); -SWITCH_MODULE_DEFINITION(mod_rayo, mod_rayo_load, mod_rayo_shutdown, mod_rayo_runtime); - -#define RAYO_CAUSE_HANGUP SWITCH_CAUSE_NORMAL_CLEARING -#define RAYO_CAUSE_DECLINE SWITCH_CAUSE_CALL_REJECTED -#define RAYO_CAUSE_BUSY SWITCH_CAUSE_USER_BUSY -#define RAYO_CAUSE_ERROR SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE - -#define RAYO_END_REASON_HANGUP "hungup" -#define RAYO_END_REASON_HANGUP_LOCAL "hangup-command" -#define RAYO_END_REASON_TIMEOUT "timeout" -#define RAYO_END_REASON_BUSY "busy" -#define RAYO_END_REASON_REJECT "rejected" -#define RAYO_END_REASON_ERROR "error" - -#define RAYO_SIP_REQUEST_HEADER "sip_h_" -#define RAYO_SIP_RESPONSE_HEADER "sip_rh_" -#define RAYO_SIP_PROVISIONAL_RESPONSE_HEADER "sip_ph_" -#define RAYO_SIP_BYE_RESPONSE_HEADER "sip_bye_h_" - -#define RAYO_CONFIG_FILE "rayo.conf" - -#define JOINED_CALL 1 -#define JOINED_MIXER 2 - -#define OFFER_ALL 0 -#define OFFER_FIRST 1 -#define OFFER_RANDOM 2 - -struct rayo_actor; -struct rayo_client; -struct rayo_call; - -#define rayo_call_get_uuid(call) RAYO_ID(call) - -/** - * Function pointer wrapper for the handlers hash - */ -struct rayo_xmpp_handler { - const char *from_type; - const char *from_subtype; - const char *to_type; - const char *to_subtype; - rayo_actor_xmpp_handler fn; -}; - -/** - * Client availability - */ -enum presence_status { - PS_UNKNOWN = -1, - PS_OFFLINE = 0, - PS_ONLINE = 1 -}; - -/** - * A xmpp peer server that routes messages to/from clients - */ -struct rayo_peer_server { - /** base class */ - struct rayo_actor base; - /** clients connected via this server */ - switch_hash_t *clients; -}; -#define RAYO_PEER_SERVER(x) ((struct rayo_peer_server *)x) - -/** - * A Rayo client that controls calls - */ -struct rayo_client { - /** base class */ - struct rayo_actor base; - /** availability */ - enum presence_status availability; - /** set if reachable via s2s */ - struct rayo_peer_server *peer_server; - /** domain or full JID to route to */ - const char *route; - /** time when last probe was sent */ - switch_time_t last_probe; -}; -#define RAYO_CLIENT(x) ((struct rayo_client *)x) - -/** - * A call controlled by a Rayo client - */ -struct rayo_call { - /** actor base class */ - struct rayo_actor base; - /** Definitive controlling party JID */ - char *dcp_jid; - /** Potential controlling parties (have sent offers to) */ - switch_hash_t *pcps; - /** Available controlling parties (not sent offers to) */ - switch_hash_t *acps; - /** Number of available controlling parties */ - int num_acps; - /** current idle start time */ - switch_time_t idle_start_time; - /** true if fax is in progress */ - int faxing; - /** 1 if joined to call, 2 if joined to mixer */ - int joined; - /** pending join */ - iks *pending_join_request; - /** ID of joined party TODO this will be many mixers / calls */ - const char *joined_id; - /** set if response needs to be sent to IQ request */ - const char *dial_request_id; - /** channel destroy event */ - switch_event_t *end_event; - /** True if ringing event sent to client */ - int ringing_sent; - /** true if rayo app has started */ - int rayo_app_started; - /** delayed delivery of answer event because rayo APP wasn't started yet */ - switch_event_t *answer_event; - /** True if request to create this call failed */ - int dial_request_failed; -}; - -/** - * A conference - */ -struct rayo_mixer { - /** actor base class */ - struct rayo_actor base; - /** member JIDs */ - switch_hash_t *members; - /** subscriber JIDs */ - switch_hash_t *subscribers; -}; - -/** - * A member of a mixer - */ -struct rayo_mixer_member { - /** JID of member */ - const char *jid; - /** Controlling party JID */ - const char *dcp_jid; -}; - -/** - * A subscriber to mixer events - */ -struct rayo_mixer_subscriber { - /** JID of client */ - const char *jid; - /** Number of client's calls in mixer */ - int ref_count; -}; - -/** - * Module state - */ -static struct { - /** module memory pool */ - switch_memory_pool_t *pool; - /** Rayo set commands mapped to functions */ - switch_hash_t *command_handlers; - /** Rayo events mapped to functions */ - switch_hash_t *event_handlers; - /** Active Rayo actors mapped by JID */ - switch_hash_t *actors; - /** Rayo actors pending destruction */ - switch_hash_t *destroy_actors; - /** Active Rayo actors mapped by internal ID */ - switch_hash_t *actors_by_id; - /** synchronizes access to actors */ - switch_mutex_t *actors_mutex; - /** map of DCP JID to client */ - switch_hash_t *clients_roster; - /** synchronizes access to available clients */ - switch_mutex_t *clients_mutex; - /** server for calls/mixers/etc */ - struct rayo_actor *server; - /** Maximum idle time before call is considered abandoned */ - int max_idle_ms; - /** Conference profile to use for mixers */ - char *mixer_conf_profile; - /** to URI prefixes mapped to gateways */ - switch_hash_t *dial_gateways; - /** synchronizes access to dial gateways */ - switch_mutex_t *dial_gateways_mutex; - /** console command aliases */ - switch_hash_t *cmd_aliases; - /** global console */ - struct rayo_client *console; - /** XMPP context */ - struct xmpp_stream_context *xmpp_context; - /** number of message threads */ - int num_message_threads; - /** message delivery queue */ - switch_queue_t *msg_queue; - /** in progress offer queue */ - switch_queue_t *offer_queue; - /** shutdown flag */ - int shutdown; - /** prevents context shutdown until all threads are finished */ - switch_thread_rwlock_t *shutdown_rwlock; - /** if true, URI is put in from/to of offer if available */ - int offer_uri; - /** if true, pause inbound calling if all clients are offline */ - int pause_when_offline; - /** flag to reduce log noise */ - int offline_logged; - /** if true, channel variables are added to offer */ - int add_variables_to_offer; - /** if true, channel variables are added to answered, ringing, end events */ - int add_variables_to_events; - /** How to distribute offers to clients */ - int offer_algorithm; - /** How long to wait for offer response before retrying */ - int offer_timeout_us; -} globals; - -/** - * An outbound dial gateway - */ -struct dial_gateway { - /** URI prefix to match */ - const char *uri_prefix; - /** dial prefix to match */ - const char *dial_prefix; - /** number of digits to strip from dialstring */ - int strip; -}; - -static void rayo_call_send(struct rayo_actor *call, struct rayo_message *msg); -static void rayo_server_send(struct rayo_actor *server, struct rayo_message *msg); -static void rayo_mixer_send(struct rayo_actor *mixer, struct rayo_message *msg); -static void rayo_component_send(struct rayo_actor *component, struct rayo_message *msg); -static void rayo_client_send(struct rayo_actor *client, struct rayo_message *msg); -static void rayo_console_client_send(struct rayo_actor *client, struct rayo_message *msg); - -static void on_client_presence(struct rayo_client *rclient, iks *node); - -typedef switch_bool_t (* rayo_actor_match_fn)(struct rayo_actor *); - -static switch_bool_t is_call_actor(struct rayo_actor *actor); - -static void rayo_call_send_end(struct rayo_call *call, switch_event_t *event, int local_hangup, const char *cause_str, const char *cause_q850_str); - - -/** - * Entity features returned by service discovery - */ -struct entity_identity { - /** identity category */ - const char *category; - /** identity type */ - const char *type; -}; - -static struct entity_identity rayo_server_identity = { "server", "im" }; -static const char *rayo_server_features[] = { IKS_NS_XMPP_ENTITY_CAPABILITIES, IKS_NS_XMPP_DISCO, RAYO_NS, RAYO_CPA_NS, RAYO_FAX_NS, 0 }; - -static struct entity_identity rayo_mixer_identity = { "client", "rayo_mixer" }; -static const char *rayo_mixer_features[] = { 0 }; - -static struct entity_identity rayo_call_identity = { "client", "rayo_call" }; -static const char *rayo_call_features[] = { 0 }; - -/** - * Calculate SHA-1 hash of entity capabilities - * @param identity of entity - * @param features of identity (NULL terminated) - * @return base64 hash (free when done) - */ -static char *calculate_entity_sha1_ver(struct entity_identity *identity, const char **features) -{ - int i; - const char *feature; - char ver[SHA_1_HASH_BUF_SIZE + 1] = { 0 }; - iksha *sha; - - sha = iks_sha_new(); - iks_sha_hash(sha, (const unsigned char *)identity->category, strlen(identity->category), 0); - iks_sha_hash(sha, (const unsigned char *)"/", 1, 0); - iks_sha_hash(sha, (const unsigned char *)identity->type, strlen(identity->type), 0); - iks_sha_hash(sha, (const unsigned char *)"//", 2, 0); - i = 0; - while ((feature = features[i++])) { - iks_sha_hash(sha, (const unsigned char *)"<", 1, 0); - iks_sha_hash(sha, (const unsigned char *)feature, strlen(feature), 0); - } - iks_sha_hash(sha, (const unsigned char *)"<", 1, 1); - iks_sha_print_base64(sha, ver); - iks_sha_delete(sha); - - return strdup(ver); -} - -/** - * @param msg to check - * @return true if message was sent by admin client (console) - */ -static int is_admin_client_message(struct rayo_message *msg) -{ - return !zstr(msg->from_jid) && !strcmp(RAYO_JID(globals.console), msg->from_jid); -} - -/** - * @param msg to check - * @return true if from/to bare JIDs match - */ -static int is_internal_message(struct rayo_message *msg) -{ - return msg->from && msg->to && (iks_id_cmp(msg->from, msg->to, IKS_ID_PARTIAL) == 0); -} - -/** - * Presence status - * @param status the presence status - * @return the string value of status - */ -static const char *presence_status_to_string(enum presence_status status) -{ - switch(status) { - case PS_OFFLINE: return "OFFLINE"; - case PS_ONLINE: return "ONLINE"; - case PS_UNKNOWN: return "UNKNOWN"; - } - return "UNKNOWN"; -} - -/** - * Get rayo cause code from FS hangup cause - * @param cause FS hangup cause - * @return rayo end cause - */ -static const char *switch_cause_to_rayo_cause(switch_call_cause_t cause) -{ - switch (cause) { - case SWITCH_CAUSE_NONE: - case SWITCH_CAUSE_NORMAL_CLEARING: - return RAYO_END_REASON_HANGUP; - - case SWITCH_CAUSE_UNALLOCATED_NUMBER: - case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET: - case SWITCH_CAUSE_NO_ROUTE_DESTINATION: - case SWITCH_CAUSE_CHANNEL_UNACCEPTABLE: - return RAYO_END_REASON_ERROR; - - case SWITCH_CAUSE_CALL_AWARDED_DELIVERED: - return RAYO_END_REASON_HANGUP; - - case SWITCH_CAUSE_USER_BUSY: - return RAYO_END_REASON_BUSY; - - case SWITCH_CAUSE_NO_USER_RESPONSE: - case SWITCH_CAUSE_NO_ANSWER: - return RAYO_END_REASON_TIMEOUT; - - case SWITCH_CAUSE_SUBSCRIBER_ABSENT: - return RAYO_END_REASON_ERROR; - - case SWITCH_CAUSE_CALL_REJECTED: - return RAYO_END_REASON_REJECT; - - case SWITCH_CAUSE_NUMBER_CHANGED: - case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION: - case SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR: - case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER: - case SWITCH_CAUSE_INVALID_NUMBER_FORMAT: - return RAYO_END_REASON_ERROR; - - case SWITCH_CAUSE_FACILITY_REJECTED: - return RAYO_END_REASON_REJECT; - - case SWITCH_CAUSE_RESPONSE_TO_STATUS_ENQUIRY: - case SWITCH_CAUSE_NORMAL_UNSPECIFIED: - return RAYO_END_REASON_HANGUP; - - case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION: - case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER: - case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE: - case SWITCH_CAUSE_SWITCH_CONGESTION: - case SWITCH_CAUSE_ACCESS_INFO_DISCARDED: - case SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL: - case SWITCH_CAUSE_PRE_EMPTED: - case SWITCH_CAUSE_FACILITY_NOT_SUBSCRIBED: - case SWITCH_CAUSE_OUTGOING_CALL_BARRED: - case SWITCH_CAUSE_INCOMING_CALL_BARRED: - case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH: - case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL: - case SWITCH_CAUSE_SERVICE_UNAVAILABLE: - case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL: - case SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED: - case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED: - case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED: - case SWITCH_CAUSE_INVALID_CALL_REFERENCE: - case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION: - case SWITCH_CAUSE_INVALID_MSG_UNSPECIFIED: - case SWITCH_CAUSE_MANDATORY_IE_MISSING: - return RAYO_END_REASON_ERROR; - - case SWITCH_CAUSE_MESSAGE_TYPE_NONEXIST: - case SWITCH_CAUSE_WRONG_MESSAGE: - case SWITCH_CAUSE_IE_NONEXIST: - case SWITCH_CAUSE_INVALID_IE_CONTENTS: - case SWITCH_CAUSE_WRONG_CALL_STATE: - case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE: - case SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR: - case SWITCH_CAUSE_PROTOCOL_ERROR: - return RAYO_END_REASON_ERROR; - - case SWITCH_CAUSE_INTERWORKING: - case SWITCH_CAUSE_SUCCESS: - case SWITCH_CAUSE_ORIGINATOR_CANCEL: - return RAYO_END_REASON_HANGUP; - - case SWITCH_CAUSE_CRASH: - case SWITCH_CAUSE_SYSTEM_SHUTDOWN: - case SWITCH_CAUSE_LOSE_RACE: - case SWITCH_CAUSE_MANAGER_REQUEST: - case SWITCH_CAUSE_BLIND_TRANSFER: - case SWITCH_CAUSE_ATTENDED_TRANSFER: - case SWITCH_CAUSE_ALLOTTED_TIMEOUT: - case SWITCH_CAUSE_USER_CHALLENGE: - case SWITCH_CAUSE_MEDIA_TIMEOUT: - case SWITCH_CAUSE_PICKED_OFF: - case SWITCH_CAUSE_USER_NOT_REGISTERED: - case SWITCH_CAUSE_PROGRESS_TIMEOUT: - case SWITCH_CAUSE_INVALID_GATEWAY: - case SWITCH_CAUSE_GATEWAY_DOWN: - case SWITCH_CAUSE_INVALID_URL: - case SWITCH_CAUSE_INVALID_PROFILE: - case SWITCH_CAUSE_NO_PICKUP: - case SWITCH_CAUSE_SRTP_READ_ERROR: - return RAYO_END_REASON_ERROR; - default: - break; - } - return RAYO_END_REASON_HANGUP; -} - -/** - * Add
to node - * @param node to add
to - * @param name of header - * @param value of header - */ -static void add_header(iks *node, const char *name, const char *value) -{ - if (!zstr(name) && !zstr(value)) { - iks *header = iks_insert(node, "header"); - iks_insert_attrib(header, "name", name); - iks_insert_attrib(header, "value", value); - } -} - -/** - * Add SIP
s to node - * @param node to add
to - * @param event source - * @param add_variables true if channel variables should be added - */ -static void add_headers_to_event(iks *node, switch_event_t *event, int add_variables) -{ - switch_event_header_t *header; - /* get all variables prefixed with sip_h_ */ - for (header = event->headers; header; header = header->next) { - if (!strncmp("variable_sip_h_", header->name, 15)) { - if (!zstr(header->name)) { - add_header(node, header->name + 15, header->value); - } - } else if (add_variables && !strncmp("variable_", header->name, 9)) { - if (!zstr(header->name)) { - char header_name[1024]; - snprintf(header_name, 1024, "variable-%s", header->name + 9); - add_header(node, header_name, header->value); - } - } - } -} - -/** - * Add SIP
s to node - * @param node to add
to - * @param add_variables true if channel variables should be added - */ -static void add_channel_headers_to_event(iks *node, switch_channel_t *channel, int add_variables) -{ - switch_event_header_t *var; - - /* add all SIP header variables and (if configured) all other variables */ - for (var = switch_channel_variable_first(channel); var; var = var->next) { - if (!strncmp("sip_h_", var->name, 6)) { - add_header(node, var->name + 6, var->value); - } - if (add_variables) { - char var_name[1024]; - snprintf(var_name, 1024, "variable-%s", var->name); - add_header(node, var_name, var->value); - } - } - switch_channel_variable_last(channel); -} - -static void pause_inbound_calling(void) -{ - int32_t arg = 1; - switch_mutex_lock(globals.clients_mutex); - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); - if (!globals.offline_logged) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Pausing inbound calling\n"); - globals.offline_logged = 1; - } - switch_mutex_unlock(globals.clients_mutex); -} - -static void resume_inbound_calling(void) -{ - int32_t arg = 0; - switch_mutex_lock(globals.clients_mutex); - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); - if (globals.offline_logged) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Resuming inbound calling\n"); - globals.offline_logged = 0; - } - switch_mutex_unlock(globals.clients_mutex); -} - -/** - * Check online status of rayo client(s) and pause/resume the server - */ -static void pause_when_offline(void) -{ - if (globals.pause_when_offline) { - int is_online = 0; - switch_hash_index_t *hi; - - switch_mutex_lock(globals.clients_mutex); - - for (hi = switch_core_hash_first(globals.clients_roster); hi; hi = switch_core_hash_next(&hi)) { - const void *key; - void *client; - switch_core_hash_this(hi, &key, NULL, &client); - switch_assert(client); - if (RAYO_CLIENT(client)->availability == PS_ONLINE) { - is_online = 1; - break; - } - } - switch_safe_free(hi); - - if (is_online) { - resume_inbound_calling(); - } else { - pause_inbound_calling(); - } - - switch_mutex_unlock(globals.clients_mutex); - } -} - -/** - * Send event to clients - * @param from event sender - * @param rayo_event the event to send - * @param online_only only send to online clients - */ -static void broadcast_event(struct rayo_actor *from, iks *rayo_event, int online_only) -{ - switch_hash_index_t *hi = NULL; - switch_mutex_lock(globals.clients_mutex); - for (hi = switch_core_hash_first(globals.clients_roster); hi; hi = switch_core_hash_next(&hi)) { - struct rayo_client *rclient; - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - rclient = (struct rayo_client *)val; - switch_assert(rclient); - - if (!online_only || rclient->availability == PS_ONLINE) { - iks_insert_attrib(rayo_event, "to", RAYO_JID(rclient)); - RAYO_SEND_MESSAGE_DUP(from, RAYO_JID(rclient), rayo_event); - } - } - switch_mutex_unlock(globals.clients_mutex); -} - -/** - * Add an outbound dialing gateway - * @param uri_prefix to match - * @param dial_prefix to use - * @param strip number of digits to strip from dialstring - */ -static void dial_gateway_add(const char *uri_prefix, const char *dial_prefix, int strip) -{ - struct dial_gateway *gateway = switch_core_alloc(globals.pool, sizeof(*gateway)); - gateway->uri_prefix = uri_prefix ? switch_core_strdup(globals.pool, uri_prefix) : ""; - gateway->dial_prefix = dial_prefix ? switch_core_strdup(globals.pool, dial_prefix) : ""; - gateway->strip = strip > 0 ? strip : 0; - switch_core_hash_insert(globals.dial_gateways, uri_prefix, gateway); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dial-gateway uriprefix = %s, dialprefix = %s, strip = %i\n", uri_prefix, dial_prefix, strip); -} - -/** - * Find outbound dial gateway for the specified dialstring - */ -static struct dial_gateway *dial_gateway_find(const char *uri) -{ - switch_hash_index_t *hi = NULL; - int match_len = 0; - struct dial_gateway *gateway = (struct dial_gateway *)switch_core_hash_find(globals.dial_gateways, "default"); - - /* find longest prefix match */ - switch_mutex_lock(globals.dial_gateways_mutex); - for (hi = switch_core_hash_first(globals.dial_gateways); hi; hi = switch_core_hash_next(&hi)) { - struct dial_gateway *candidate = NULL; - const void *prefix; - int prefix_len = 0; - void *val; - switch_core_hash_this(hi, &prefix, NULL, &val); - candidate = (struct dial_gateway *)val; - switch_assert(candidate); - - prefix_len = strlen(prefix); - if (!zstr(prefix) && !strncmp(prefix, uri, prefix_len) && prefix_len > match_len) { - match_len = prefix_len; - gateway = candidate; - } - } - switch_mutex_unlock(globals.dial_gateways_mutex); - return gateway; -} - -/** - * Add command handler function - * @param name the command name - * @param handler the command handler function - */ -static void rayo_command_handler_add(const char *name, struct rayo_xmpp_handler *handler) -{ - char full_name[1024]; - full_name[1023] = '\0'; - snprintf(full_name, sizeof(full_name) - 1, "%s:%s:%s", handler->to_type, handler->to_subtype, name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding command: %s\n", full_name); - switch_core_hash_insert(globals.command_handlers, full_name, handler); -} - -/** - * Add command handler function - * @param type the actor type - * @param subtype the actor subtype - * @param name the command name - * @param fn the command callback function - */ -void rayo_actor_command_handler_add(const char *type, const char *subtype, const char *name, rayo_actor_xmpp_handler fn) -{ - struct rayo_xmpp_handler *handler = switch_core_alloc(globals.pool, sizeof (*handler)); - handler->to_type = zstr(type) ? "" : switch_core_strdup(globals.pool, type); - handler->to_subtype = zstr(subtype) ? "" : switch_core_strdup(globals.pool, subtype); - handler->fn = fn; - rayo_command_handler_add(name, handler); -} - -/** - * Get command handler function from hash - * @param hash the hash to search - * @param msg the command - * @return the command handler function or NULL - */ -rayo_actor_xmpp_handler rayo_actor_command_handler_find(struct rayo_actor *actor, struct rayo_message *msg) -{ - iks *iq = msg->payload; - const char *iq_type = iks_find_attrib_soft(iq, "type"); - iks *command = iks_first_tag(iq); - const char *name = ""; - const char *namespace = ""; - struct rayo_xmpp_handler *handler = NULL; - char full_name[1024]; - - full_name[1023] = '\0'; - if (command) { - name = iks_name(command); - namespace = iks_find_attrib_soft(command, "xmlns"); - if (zstr(name)) { - name = ""; - } - } - - snprintf(full_name, sizeof(full_name) - 1, "%s:%s:%s:%s:%s", actor->type, actor->subtype, iq_type, namespace, name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, looking for %s command\n", RAYO_JID(actor), full_name); - handler = (struct rayo_xmpp_handler *)switch_core_hash_find(globals.command_handlers, full_name); - if (handler) { - return handler->fn; - } - - return NULL; -} - -/** - * Add event handler function - * @param name the event name - * @param handler the event handler function - */ -static void rayo_event_handler_add(const char *name, struct rayo_xmpp_handler *handler) -{ - char full_name[1024]; - full_name[1023] = '\0'; - snprintf(full_name, sizeof(full_name) - 1, "%s:%s:%s:%s:%s", handler->from_type, handler->from_subtype, handler->to_type, handler->to_subtype, name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding event: %s\n", full_name); - switch_core_hash_insert(globals.event_handlers, full_name, handler); -} - -/** - * Add event handler function - * @param from_type the source actor type - * @param from_subtype the source actor subtype - * @param to_type the destination actor type - * @param to_subtype the destination actor subtype - * @param name the event name - * @param fn the event callback function - */ -void rayo_actor_event_handler_add(const char *from_type, const char *from_subtype, const char *to_type, const char *to_subtype, const char *name, rayo_actor_xmpp_handler fn) -{ - struct rayo_xmpp_handler *handler = switch_core_alloc(globals.pool, sizeof (*handler)); - handler->from_type = zstr(from_type) ? "" : switch_core_strdup(globals.pool, from_type); - handler->from_subtype = zstr(from_subtype) ? "" : switch_core_strdup(globals.pool, from_subtype); - handler->to_type = zstr(to_type) ? "" : switch_core_strdup(globals.pool, to_type); - handler->to_subtype = zstr(to_subtype) ? "" : switch_core_strdup(globals.pool, to_subtype); - handler->fn = fn; - rayo_event_handler_add(name, handler); -} - -/** - * Get event handler function from hash - * @param actor the event destination - * @param msg the event - * @return the event handler function or NULL - */ -rayo_actor_xmpp_handler rayo_actor_event_handler_find(struct rayo_actor *actor, struct rayo_message *msg) -{ - iks *presence = msg->payload; - iks *event = iks_first_tag(presence); - if (event) { - struct rayo_xmpp_handler *handler = NULL; - const char *presence_type = iks_find_attrib_soft(presence, "type"); - const char *event_name = iks_name(event); - const char *event_namespace = iks_find_attrib_soft(event, "xmlns"); - char full_name[1024]; - full_name[1023] = '\0'; - if (zstr(event_name)) { - return NULL; - } - snprintf(full_name, sizeof(full_name) - 1, "%s:%s:%s:%s:%s:%s:%s", msg->from_type, msg->from_subtype, actor->type, actor->subtype, presence_type, event_namespace, event_name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s => %s, looking for %s event handler\n", msg->from_jid, RAYO_JID(actor), full_name); - handler = (struct rayo_xmpp_handler *)switch_core_hash_find(globals.event_handlers, full_name); - if (handler) { - return handler->fn; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s => %s, event missing child element\n", msg->from_jid, RAYO_JID(actor)); - } - return NULL; -} - -/** - * Clean up a message - * @param msg to destroy - */ -void rayo_message_destroy(struct rayo_message *msg) -{ - if (msg) { - if (msg->payload) { - iks_delete(msg->payload); - } - switch_safe_free(msg->to_jid); - switch_safe_free(msg->from_jid); - switch_safe_free(msg->from_type); - switch_safe_free(msg->from_subtype); - switch_safe_free(msg->file); - free(msg); - } -} - -/** - * Remove payload from message - */ -iks *rayo_message_remove_payload(struct rayo_message *msg) -{ - iks *payload = msg->payload; - msg->payload = NULL; - msg->from = NULL; - msg->to = NULL; - return payload; -} - -/** - * Thread that delivers internal XMPP messages - * @param thread this thread - * @param obj unused - * @return NULL - */ -static void *SWITCH_THREAD_FUNC deliver_message_thread(switch_thread_t *thread, void *obj) -{ - struct rayo_message *msg = NULL; - switch_thread_rwlock_rdlock(globals.shutdown_rwlock); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "New message delivery thread\n"); - while (!globals.shutdown) { - if (switch_queue_pop(globals.msg_queue, (void *)&msg) == SWITCH_STATUS_SUCCESS) { - struct rayo_actor *actor = RAYO_LOCATE(msg->to_jid); - if (actor) { - /* deliver to actor */ - switch_mutex_lock(actor->mutex); - switch_log_printf(SWITCH_CHANNEL_ID_LOG, msg->file, "", msg->line, "", SWITCH_LOG_DEBUG, "Deliver %s => %s %s\n", msg->from_jid, msg->to_jid, iks_string(iks_stack(msg->payload), msg->payload)); - actor->send_fn(actor, msg); - switch_mutex_unlock(actor->mutex); - RAYO_RELEASE(actor); - } else if (!msg->is_reply) { - /* unknown actor */ - RAYO_SEND_REPLY(globals.server, msg->from_jid, iks_new_error(msg->payload, STANZA_ERROR_ITEM_NOT_FOUND)); - } - rayo_message_destroy(msg); - } - } - - /* clean up remaining messages */ - while(switch_queue_trypop(globals.msg_queue, (void *)&msg) == SWITCH_STATUS_SUCCESS) { - rayo_message_destroy(msg); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Message delivery thread finished\n"); - switch_thread_rwlock_unlock(globals.shutdown_rwlock); - return NULL; -} - -/** - * Create a new message thread - * @param pool to use - */ -static void start_deliver_message_thread(switch_memory_pool_t *pool) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, deliver_message_thread, NULL, pool); -} - -/** - * Stop all threads - */ -static void stop_all_threads(void) -{ - globals.shutdown = 1; - if (globals.msg_queue) { - switch_queue_interrupt_all(globals.msg_queue); - } - if (globals.offer_queue) { - switch_queue_interrupt_all(globals.offer_queue); - } - if (globals.shutdown_rwlock) { - switch_thread_rwlock_wrlock(globals.shutdown_rwlock); - } -} - -/** - * Send message to actor addressed by JID - * @param from actor sending the message - * @param to destination JID - * @param payload the message payload to deliver - * @param dup true if payload is to be copied - * @param reply true if a reply - * @param file file name - * @param line line number - */ -void rayo_message_send(struct rayo_actor *from, const char *to, iks *payload, int dup, int reply, const char *file, int line) -{ - const char *msg_name; - struct rayo_message *msg = malloc(sizeof(*msg)); - switch_assert(msg); - if (dup) { - msg->payload = iks_copy(payload); - } else { - msg->payload = payload; - } - msg->is_reply = reply; - msg->to_jid = strdup(zstr(to) ? "" : to); - if (!zstr(msg->to_jid)) { - msg->to = iks_id_new(iks_stack(msg->payload), msg->to_jid); - } - msg->from_jid = strdup(RAYO_JID(from)); - if (!zstr(msg->from_jid)) { - msg->from = iks_id_new(iks_stack(msg->payload), msg->from_jid); - } - msg->from_type = strdup(zstr(from->type) ? "" : from->type); - msg->from_subtype = strdup(zstr(from->subtype) ? "" : from->subtype); - msg->file = strdup(file); - msg->line = line; - - /* add timestamp to presence events */ - msg_name = iks_name(msg->payload); - if (!zstr(msg_name) && !strcmp("presence", msg_name)) { - /* don't add timestamp if there already is one */ - iks *delay = iks_find(msg->payload, "delay"); - if (!delay || strcmp("urn:xmpp:delay", iks_find_attrib_soft(delay, "xmlns"))) { - switch_time_exp_t tm; - char timestamp[80]; - switch_size_t retsize; - delay = iks_insert(msg->payload, "delay"); - iks_insert_attrib(delay, "xmlns", "urn:xmpp:delay"); - switch_time_exp_tz(&tm, switch_time_now(), 0); - switch_strftime_nocheck(timestamp, &retsize, sizeof(timestamp), "%Y-%m-%dT%TZ", &tm); - iks_insert_attrib_printf(delay, "stamp", "%s", timestamp); - } - } - - if (switch_queue_trypush(globals.msg_queue, msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to queue message!\n"); - rayo_message_destroy(msg); - } -} - -/** - * Get access to Rayo actor with JID. - * @param jid the JID - * @return the actor or NULL. Call RAYO_RELEASE() when done with pointer. - */ -struct rayo_actor *rayo_actor_locate(const char *jid, const char *file, int line) -{ - struct rayo_actor *actor = NULL; - switch_mutex_lock(globals.actors_mutex); - if (!strncmp("xmpp:", jid, 5)) { - jid = jid + 5; - } - actor = (struct rayo_actor *)switch_core_hash_find(globals.actors, jid); - if (actor) { - if (!actor->destroy) { - actor->ref_count++; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Locate (jid) %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); - } else { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Locate (jid) %s: already marked for destruction!\n", jid); - actor = NULL; - } - } - switch_mutex_unlock(globals.actors_mutex); - return actor; -} - -/** - * Get exclusive access to Rayo actor with internal ID - * @param id the internal ID - * @return the actor or NULL. Call RAYO_RELEASE() when done with pointer. - */ -struct rayo_actor *rayo_actor_locate_by_id(const char *id, const char *file, int line) -{ - struct rayo_actor *actor = NULL; - if (!zstr(id)) { - switch_mutex_lock(globals.actors_mutex); - actor = (struct rayo_actor *)switch_core_hash_find(globals.actors_by_id, id); - if (actor) { - if (!actor->destroy) { - actor->ref_count++; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Locate (id) %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); - } else { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Locate (id) %s: already marked for destruction!\n", id); - actor = NULL; - } - } - switch_mutex_unlock(globals.actors_mutex); - } - return actor; -} - -/** - * Destroy a rayo actor - */ -void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int line) -{ - switch_memory_pool_t *pool = actor->pool; - switch_mutex_lock(globals.actors_mutex); - if (!actor->destroy) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Destroy %s requested: ref_count = %i\n", RAYO_JID(actor), actor->ref_count); - switch_core_hash_delete(globals.actors, RAYO_JID(actor)); - if (!zstr(actor->id)) { - switch_core_hash_delete(globals.actors_by_id, actor->id); - } - } - actor->destroy = 1; - if (actor->ref_count <= 0) { - if (actor->ref_count < 0) { - /* too many unlocks detected! */ - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Destroying %s, ref_count = %i\n", RAYO_JID(actor), actor->ref_count); - } else { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Destroying %s\n", RAYO_JID(actor)); - } - switch_core_hash_delete(globals.destroy_actors, RAYO_JID(actor)); - switch_mutex_unlock(globals.actors_mutex); - /* safe to destroy parent now */ - if (actor->cleanup_fn) { - actor->cleanup_fn(actor); - } - if (actor->parent) { - RAYO_RELEASE(actor->parent); - } - switch_core_destroy_memory_pool(&pool); - } else { - switch_core_hash_insert(globals.destroy_actors, RAYO_JID(actor), actor); - switch_mutex_unlock(globals.actors_mutex); - } -} - -/** - * Increment actor ref count - locks from destruction. - */ -void rayo_actor_retain(struct rayo_actor *actor, const char *file, int line) -{ - if (actor) { - switch_mutex_lock(globals.actors_mutex); - actor->ref_count++; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Lock %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); - switch_mutex_unlock(globals.actors_mutex); - } -} - -/** - * Release rayo actor reference - */ -void rayo_actor_release(struct rayo_actor *actor, const char *file, int line) -{ - if (actor) { - switch_mutex_lock(globals.actors_mutex); - actor->ref_count--; - if (actor->ref_count < 0) { - /* too many unlocks detected! */ - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Release %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); - } else { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Release %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); - } - if (actor->ref_count <= 0 && actor->destroy) { - rayo_actor_destroy(actor, file, line); - } - switch_mutex_unlock(globals.actors_mutex); - } -} - -/** - * Get next number in sequence - */ -int rayo_actor_seq_next(struct rayo_actor *actor) -{ - int seq; - switch_mutex_lock(actor->mutex); - seq = actor->seq++; - switch_mutex_unlock(actor->mutex); - return seq; -} - -#define RAYO_CALL_LOCATE(call_uri) rayo_call_locate(call_uri, __FILE__, __LINE__) -/** - * Get access to Rayo call data. Use to access call data outside channel thread. - * @param call_uri the Rayo XMPP URI - * @return the call or NULL. - */ -static struct rayo_call *rayo_call_locate(const char *call_uri, const char *file, int line) -{ - struct rayo_actor *actor = rayo_actor_locate(call_uri, file, line); - if (actor && is_call_actor(actor)) { - return RAYO_CALL(actor); - } else if (actor) { - RAYO_RELEASE(actor); - } - return NULL; -} - -#define RAYO_CALL_LOCATE_BY_ID(call_uuid) rayo_call_locate_by_id(call_uuid, __FILE__, __LINE__) -/** - * Get access to Rayo call data. Use to access call data outside channel thread. - * @param call_uuid the FreeSWITCH call UUID - * @return the call or NULL. - */ -static struct rayo_call *rayo_call_locate_by_id(const char *call_uuid, const char *file, int line) -{ - struct rayo_actor *actor = rayo_actor_locate_by_id(call_uuid, file, line); - if (actor && is_call_actor(actor)) { - return RAYO_CALL(actor); - } else if (actor) { - RAYO_RELEASE(actor); - } - return NULL; -} - -/** - * Send event to DCP and PCPs - */ -static void rayo_call_send_end(struct rayo_call *call, switch_event_t *event, int local_hangup, const char *cause_str, const char *cause_q850_str) -{ - int no_offered_clients = 1; - switch_hash_index_t *hi = NULL; - iks *revent; - iks *end; - const char *dcp_jid = rayo_call_get_dcp_jid(call); - - /* build call end event */ - revent = iks_new_presence("end", RAYO_NS, RAYO_JID(call), "foo"); - iks_insert_attrib(revent, "type", "unavailable"); - end = iks_find(revent, "end"); - - if (local_hangup) { - iks_insert(end, RAYO_END_REASON_HANGUP_LOCAL); - } else { - /* remote hangup... translate to specific rayo reason */ - iks *reason; - switch_call_cause_t cause = SWITCH_CAUSE_NONE; - if (!zstr(cause_str)) { - cause = switch_channel_str2cause(cause_str); - } - reason = iks_insert(end, switch_cause_to_rayo_cause(cause)); - if (!zstr(cause_q850_str)) { - iks_insert_attrib(reason, "platform-code", cause_q850_str); - } - } - - #if 0 - if (event) { - char *event_str; - if (switch_event_serialize(event, &event_str, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "%s\n", event_str); - switch_safe_free(event_str); - } - } - #endif - - /* add signaling headers */ - if (event) { - add_headers_to_event(end, event, globals.add_variables_to_events); - } - - /* send to all offered clients */ - for (hi = switch_core_hash_first(call->pcps); hi; hi = switch_core_hash_next(&hi)) { - const void *key; - void *val; - const char *client_jid = NULL; - switch_core_hash_this(hi, &key, NULL, &val); - client_jid = (const char *)key; - switch_assert(client_jid); - iks_insert_attrib(revent, "to", client_jid); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "Sending to offered client %s\n", client_jid); - RAYO_SEND_MESSAGE_DUP(call, client_jid, revent); - no_offered_clients = 0; - } - - if (no_offered_clients && !zstr(dcp_jid)) { - /* send to DCP only */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "Sending to DCP %s\n", dcp_jid); - iks_insert_attrib(revent, "to", dcp_jid); - RAYO_SEND_MESSAGE_DUP(call, dcp_jid, revent); - } - - iks_delete(revent); -} - -/** - * Fire event when call is cleaned up completely - */ -static void rayo_call_cleanup(struct rayo_actor *actor) -{ - struct rayo_call *call = RAYO_CALL(actor); - switch_event_t *event = call->end_event; - const char *dcp_jid = rayo_call_get_dcp_jid(call); - - if (!event || call->dial_request_failed) { - /* destroyed before FS session was created (in originate, for example) */ - goto done; - } - - /* send call unjoined event, if not already sent */ - if (call->joined && call->joined_id) { - if (!zstr(dcp_jid)) { - iks *unjoined; - iks *uevent = iks_new_presence("unjoined", RAYO_NS, RAYO_JID(call), dcp_jid); - unjoined = iks_find(uevent, "unjoined"); - iks_insert_attrib_printf(unjoined, "call-uri", "%s", call->joined_id); - RAYO_SEND_MESSAGE(call, dcp_jid, uevent); - } - } - - rayo_call_send_end(call, - event, - switch_true(switch_event_get_header(event, "variable_rayo_local_hangup")), - switch_event_get_header(event, "variable_hangup_cause"), - switch_event_get_header(event, "variable_hangup_cause_q850")); - -done: - - /* lost the race: pending join failed... send IQ result to client now. */ - if (call->pending_join_request) { - iks *request = call->pending_join_request; - iks *result = iks_new_error_detailed(request, STANZA_ERROR_ITEM_NOT_FOUND, "call ended"); - call->pending_join_request = NULL; - RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); - iks_delete(call->pending_join_request); - } - - if (event) { - switch_event_destroy(&event); - } - if (call->answer_event) { - switch_event_destroy(&call->answer_event); - } - switch_core_hash_destroy(&call->pcps); - switch_core_hash_destroy(&call->acps); -} - -/** - * @param call the Rayo call - * @return the Rayo call DCP JID - */ -const char *rayo_call_get_dcp_jid(struct rayo_call *call) -{ - return call->dcp_jid; -} - -/** - * @param call the Rayo call - * @return true if joined (or a join is in progress) - */ -int rayo_call_is_joined(struct rayo_call *call) -{ - return call->joined || call->pending_join_request; -} - -/** - * @param call to check if faxing - * @return true if faxing is in progress - */ -int rayo_call_is_faxing(struct rayo_call *call) -{ - return call->faxing; -} - -/** - * Set faxing flag - * @param call the call to flag - * @param faxing true if faxing is in progress - */ -void rayo_call_set_faxing(struct rayo_call *call, int faxing) -{ - call->faxing = faxing; -} - -#define RAYO_MIXER_LOCATE(mixer_name) rayo_mixer_locate(mixer_name, __FILE__, __LINE__) -/** - * Get access to Rayo mixer data. - * @param mixer_name the mixer name - * @return the mixer or NULL. Call RAYO_RELEASE() when done with mixer pointer. - */ -static struct rayo_mixer *rayo_mixer_locate(const char *mixer_name, const char *file, int line) -{ - struct rayo_actor *actor = rayo_actor_locate_by_id(mixer_name, file, line); - if (actor && !strcmp(RAT_MIXER, actor->type)) { - return RAYO_MIXER(actor); - } else if (actor) { - RAYO_RELEASE(actor); - } - return NULL; -} - -/** - * Default message handler - drops messages - */ -void rayo_actor_send_ignore(struct rayo_actor *to, struct rayo_message *msg) -{ - switch_log_printf(SWITCH_CHANNEL_ID_LOG, msg->file, "", msg->line, "", SWITCH_LOG_WARNING, "%s, dropping unexpected message to %s.\n", msg->from_jid, RAYO_JID(to)); -} - -#define RAYO_ACTOR_INIT(actor, pool, type, subtype, id, jid, cleanup, send) rayo_actor_init(actor, pool, type, subtype, id, jid, cleanup, send, NULL, __FILE__, __LINE__) -#define RAYO_ACTOR_INIT_PARENT(actor, pool, type, subtype, id, jid, cleanup, send, parent) rayo_actor_init(actor, pool, type, subtype, id, jid, cleanup, send, parent, __FILE__, __LINE__) - -/** - * Initialize a rayo actor - * @param actor to initialize - * @param pool to use - * @param type of actor (MIXER, CALL, SERVER, COMPONENT) - * @param subtype of actor (input/output/prompt) - * @param id internal ID - * @param jid external ID - * @param cleanup function - * @param send sent message handler - * @param parent of actor - * @param file that called this function - * @param line that called this function - * @return the actor or NULL if JID conflict - */ -static struct rayo_actor *rayo_actor_init(struct rayo_actor *actor, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, const char *jid, rayo_actor_cleanup_fn cleanup, rayo_actor_send_fn send, struct rayo_actor *parent, const char *file, int line) -{ - char *domain; - actor->type = switch_core_strdup(pool, type); - actor->subtype = switch_core_strdup(pool, subtype); - actor->pool = pool; - if (!zstr(id)) { - actor->id = switch_core_strdup(pool, id); - } - /* TODO validate JID with regex */ - if (!zstr(jid)) { - RAYO_JID(actor) = switch_core_strdup(pool, jid); - if (!(domain = strrchr(RAYO_JID(actor), '@'))) { - RAYO_DOMAIN(actor) = RAYO_JID(actor); - } else if (!zstr(++domain)) { - RAYO_DOMAIN(actor) = switch_core_strdup(pool, domain); - /* strip resource from domain if it exists */ - domain = strrchr(RAYO_DOMAIN(actor), '/'); - if (domain) { - *domain = '\0'; - } - } - } - actor->seq = 1; - actor->ref_count = 1; - actor->destroy = 0; - actor->cleanup_fn = cleanup; - if (send == NULL) { - actor->send_fn = rayo_actor_send_ignore; - } else { - actor->send_fn = send; - } - - actor->parent = parent; - if (!actor->parent) { - switch_mutex_init(&actor->mutex, SWITCH_MUTEX_NESTED, pool); - } else { - /* inherit mutex from parent */ - actor->mutex = actor->parent->mutex; - - /* prevent parent destruction */ - RAYO_RETAIN(actor->parent); - } - - /* add to hash of actors, so commands can route to call */ - switch_mutex_lock(globals.actors_mutex); - if (!zstr(jid)) { - if (switch_core_hash_find(globals.actors, RAYO_JID(actor))) { - /* duplicate JID, give up! */ - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_NOTICE, "JID conflict! %s\n", RAYO_JID(actor)); - switch_mutex_unlock(globals.actors_mutex); - if (actor->parent) { - /* unlink from parent */ - RAYO_RELEASE(actor->parent); - actor->parent = NULL; - } - return NULL; - } - switch_core_hash_insert(globals.actors, RAYO_JID(actor), actor); - } - if (!zstr(id)) { - if (switch_core_hash_find(globals.actors_by_id, actor->id)) { - /* duplicate ID - only log for now... */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "ID conflict! %s\n", actor->id); - } - switch_core_hash_insert(globals.actors_by_id, actor->id, actor); - } - switch_mutex_unlock(globals.actors_mutex); - - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Init %s\n", RAYO_JID(actor)); - - return actor; -} - -/** - * Initialize rayo call - * @return the call or NULL if JID conflict - */ -static struct rayo_call *rayo_call_init(struct rayo_call *call, switch_memory_pool_t *pool, const char *uuid, const char *file, int line) -{ - char *call_jid; - char uuid_id_buf[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (zstr(uuid)) { - switch_uuid_str(uuid_id_buf, sizeof(uuid_id_buf)); - uuid = uuid_id_buf; - } - call_jid = switch_mprintf("%s@%s", uuid, RAYO_JID(globals.server)); - - call = RAYO_CALL(rayo_actor_init(RAYO_ACTOR(call), pool, RAT_CALL, "", uuid, call_jid, rayo_call_cleanup, rayo_call_send, NULL, file, line)); - if (call) { - call->dcp_jid = ""; - call->idle_start_time = switch_micro_time_now(); - call->joined = 0; - call->joined_id = NULL; - call->ringing_sent = 0; - call->pending_join_request = NULL; - call->dial_request_id = NULL; - call->end_event = NULL; - call->dial_request_failed = 0; - call->rayo_app_started = 0; - call->answer_event = NULL; - switch_core_hash_init(&call->pcps); - switch_core_hash_init(&call->acps); - call->num_acps = 0; - } - - switch_safe_free(call_jid); - - return call; -} - -#define rayo_call_create(uuid) _rayo_call_create(uuid, __FILE__, __LINE__) -/** - * Create Rayo call - * @param uuid uuid to assign call, if NULL one is picked - * @param file file that called this function - * @param line number of file that called this function - * @return the call, or NULL if JID conflict - */ -static struct rayo_call *_rayo_call_create(const char *uuid, const char *file, int line) -{ - switch_memory_pool_t *pool; - struct rayo_call *call; - switch_core_new_memory_pool(&pool); - call = switch_core_alloc(pool, sizeof(*call)); - call = rayo_call_init(call, pool, uuid, file, line); - if (!call) { - switch_core_destroy_memory_pool(&pool); - } - return call; -} - -/** - * Mixer destructor - */ -static void rayo_mixer_cleanup(struct rayo_actor *actor) -{ - struct rayo_mixer *mixer = RAYO_MIXER(actor); - switch_core_hash_destroy(&mixer->members); - switch_core_hash_destroy(&mixer->subscribers); -} - -/** - * Initialize mixer - * @return the mixer or NULL if JID conflict - */ -static struct rayo_mixer *rayo_mixer_init(struct rayo_mixer *mixer, switch_memory_pool_t *pool, const char *name, const char *file, int line) -{ - char *mixer_jid = switch_mprintf("%s@%s", name, RAYO_JID(globals.server)); - mixer = RAYO_MIXER(rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, rayo_mixer_cleanup, rayo_mixer_send, NULL, file, line)); - if (mixer) { - switch_core_hash_init(&mixer->members); - switch_core_hash_init(&mixer->subscribers); - } - switch_safe_free(mixer_jid); - return mixer; -} - -#define rayo_mixer_create(name) _rayo_mixer_create(name, __FILE__, __LINE__) -/** - * Create Rayo mixer - * @param name of this mixer - * @return the mixer or NULL if JID conflict - */ -static struct rayo_mixer *_rayo_mixer_create(const char *name, const char *file, int line) -{ - switch_memory_pool_t *pool; - struct rayo_mixer *mixer = NULL; - switch_core_new_memory_pool(&pool); - mixer = rayo_mixer_init(switch_core_alloc(pool, sizeof(*mixer)), pool, name, file, line); - if (!mixer) { - switch_core_destroy_memory_pool(&pool); - } - return mixer; -} - -/** - * Initialize Rayo component - * @param type of this component - * @param subtype of this component - * @param id internal ID of this component - * @param parent the parent that owns this component - * @param client_jid the client that created this component - * @param cleanup optional cleanup function - * @param file file that called this function - * @param line line number that called this function - * @return the component or NULL if JID conflict - */ -struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line) -{ - char *ref = switch_mprintf("%s-%d", subtype, rayo_actor_seq_next(parent)); - char *jid = switch_mprintf("%s/%s", RAYO_JID(parent), ref); - if (zstr(id)) { - id = jid; - } - - component = RAYO_COMPONENT(rayo_actor_init(RAYO_ACTOR(component), pool, type, subtype, id, jid, cleanup, rayo_component_send, parent, file, line)); - if (component) { - component->client_jid = switch_core_strdup(pool, client_jid); - component->ref = switch_core_strdup(pool, ref); - } - - switch_safe_free(ref); - switch_safe_free(jid); - return component; -} - -/** - * Send XMPP message to client - */ -void rayo_client_send(struct rayo_actor *client, struct rayo_message *msg) -{ - xmpp_stream_context_send(globals.xmpp_context, RAYO_CLIENT(client)->route, msg->payload); -} - -/** - * Cleanup rayo client - */ -static void rayo_client_cleanup(struct rayo_actor *actor) -{ - /* remove session from map */ - switch_mutex_lock(globals.clients_mutex); - if (!zstr(RAYO_JID(actor))) { - switch_core_hash_delete(globals.clients_roster, RAYO_JID(actor)); - if (RAYO_CLIENT(actor)->peer_server) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Removing %s from peer server %s\n", RAYO_JID(actor), RAYO_JID(RAYO_CLIENT(actor)->peer_server)); - switch_core_hash_delete(RAYO_CLIENT(actor)->peer_server->clients, RAYO_JID(actor)); - } - } - switch_mutex_unlock(globals.clients_mutex); - - pause_when_offline(); -} - -/** - * Initialize rayo client - * @param pool the memory pool for this client - * @param jid for this client - * @param route to this client - * @param availability of client - * @param send message transmission function - * @param peer_server NULL if locally connected client - * @return the new client or NULL if JID conflict - */ -static struct rayo_client *rayo_client_init(struct rayo_client *client, switch_memory_pool_t *pool, const char *jid, const char *route, enum presence_status availability, rayo_actor_send_fn send, struct rayo_peer_server *peer_server) -{ - client = RAYO_CLIENT(RAYO_ACTOR_INIT(RAYO_ACTOR(client), pool, RAT_CLIENT, "", jid, jid, rayo_client_cleanup, send)); - if (client) { - client->availability = availability; - client->peer_server = peer_server; - client->last_probe = 0; - if (route) { - client->route = switch_core_strdup(pool, route); - } - - /* make client available for offers */ - switch_mutex_lock(globals.clients_mutex); - switch_core_hash_insert(globals.clients_roster, RAYO_JID(client), client); - if (peer_server) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding %s to peer server %s\n", RAYO_JID(client), RAYO_JID(peer_server)); - switch_core_hash_insert(peer_server->clients, RAYO_JID(client), client); - } - switch_mutex_unlock(globals.clients_mutex); - } - - pause_when_offline(); - - return client; -} - -/** - * Create a new Rayo client - * @param jid for this client - * @param route to this client - * @param availability of client - * @param send message transmission function - * @param peer_server NULL if locally connected client - * @return the new client or NULL - */ -static struct rayo_client *rayo_client_create(const char *jid, const char *route, enum presence_status availability, rayo_actor_send_fn send, struct rayo_peer_server *peer_server) -{ - switch_memory_pool_t *pool; - struct rayo_client *rclient = NULL; - - switch_core_new_memory_pool(&pool); - if (!(rclient = switch_core_alloc(pool, sizeof(*rclient)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n"); - return NULL; - } - rclient = rayo_client_init(rclient, pool, jid, route, availability, send, peer_server); - if (!rclient) { - switch_core_destroy_memory_pool(&pool); - } - return rclient; -} - -/** - * Send XMPP message to peer server - */ -void rayo_peer_server_send(struct rayo_actor *server, struct rayo_message *msg) -{ - xmpp_stream_context_send(globals.xmpp_context, RAYO_JID(server), msg->payload); -} - -/** - * Destroy peer server and its associated clients - */ -static void rayo_peer_server_cleanup(struct rayo_actor *actor) -{ - switch_hash_index_t *hi = NULL; - struct rayo_peer_server *rserver = RAYO_PEER_SERVER(actor); - - /* a little messy... client will remove itself from the peer server when it is destroyed, - * however, there is no guarantee the client will actually be destroyed now so - * the server must remove the client. - */ - switch_mutex_lock(globals.clients_mutex); - while ((hi = switch_core_hash_first_iter(rserver->clients, hi))) { - const void *key; - void *client; - switch_core_hash_this(hi, &key, NULL, &client); - switch_assert(client); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Removing %s from peer server %s\n", RAYO_JID(client), RAYO_JID(rserver)); - switch_core_hash_delete(rserver->clients, key); - RAYO_CLIENT(client)->peer_server = NULL; - RAYO_RELEASE(client); - RAYO_DESTROY(client); - } - switch_core_hash_destroy(&rserver->clients); - switch_mutex_unlock(globals.clients_mutex); -} - -/** - * Create a new Rayo peer server - * @param jid of this server - * @return the peer server - */ -static struct rayo_peer_server *rayo_peer_server_create(const char *jid) -{ - switch_memory_pool_t *pool; - struct rayo_peer_server *rserver = NULL; - - switch_core_new_memory_pool(&pool); - if (!(rserver = switch_core_alloc(pool, sizeof(*rserver)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n"); - return NULL; - } - rserver = RAYO_PEER_SERVER(RAYO_ACTOR_INIT(RAYO_ACTOR(rserver), pool, RAT_PEER_SERVER, "", jid, jid, rayo_peer_server_cleanup, rayo_peer_server_send)); - if (rserver) { - switch_core_hash_init(&rserver->clients); - } else { - switch_core_destroy_memory_pool(&pool); - } - return rserver; -} - -/** - * Check if message sender has control of offered call. - * @param call the Rayo call - * @param msg the message - * @return 1 if sender has call control, 0 if sender does not have control - */ -static int has_call_control(struct rayo_call *call, struct rayo_message *msg) -{ - return (!strcmp(rayo_call_get_dcp_jid(call), msg->from_jid) || is_internal_message(msg) || is_admin_client_message(msg)); -} - -/** - * Check if message sender has control of offered call. Take control if nobody else does. - * @param call the Rayo call - * @param session the session - * @param msg the message - * @return 1 if sender has call control - */ -static int take_call_control(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg) -{ - int control = 0; - - /* nobody in charge */ - if (zstr(call->dcp_jid)) { - /* was offered to this session? */ - if (!zstr(msg->from_jid) && switch_core_hash_find(call->pcps, msg->from_jid)) { - /* take charge */ - call->dcp_jid = switch_core_strdup(RAYO_POOL(call), msg->from_jid); - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_dcp_jid", rayo_call_get_dcp_jid(call)); - control = 1; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s has control of call\n", rayo_call_get_dcp_jid(call)); - } - } else if (has_call_control(call, msg)) { - control = 1; - } - - if (!control) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s does not have control of call\n", msg->from_jid); - } - - return control; -} - -/** - * Check Rayo server command for errors. - * @param server the server - * @param msg the command - * @return 1 if OK - */ -static iks *rayo_server_command_ok(struct rayo_actor *server, struct rayo_message *msg) -{ - iks *node = msg->payload; - iks *response = NULL; - int bad = zstr(iks_find_attrib(node, "id")); - - if (bad) { - response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST); - } - - return response; -} - -/** - * Check Rayo call command for errors. - * @param call the Rayo call - * @param session the session - * @param msg the command - * @return 1 if OK - */ -static iks *rayo_call_command_ok(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg) -{ - iks *node = msg->payload; - iks *response = NULL; - int bad = zstr(iks_find_attrib(node, "id")); - - if (bad) { - response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST); - } else if (!take_call_control(call, session, msg)) { - response = iks_new_error(node, STANZA_ERROR_CONFLICT); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, %s conflict\n", msg->from_jid, RAYO_JID(call)); - } - - return response; -} - -/** - * Check Rayo component command for errors. - * @param component the component - * @param msg the command - * @return 0 if error - */ -static iks *rayo_component_command_ok(struct rayo_component *component, struct rayo_message *msg) -{ - iks *node = msg->payload; - iks *response = NULL; - char *from = iks_find_attrib(node, "from"); - int bad = zstr(iks_find_attrib(node, "id")); - - if (bad) { - response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, %s bad request\n", msg->from_jid, RAYO_JID(component)); - } else if (strcmp(component->client_jid, from) && !is_admin_client_message(msg) && !is_internal_message(msg)) { - /* does not have control of this component */ - response = iks_new_error(node, STANZA_ERROR_CONFLICT); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, %s conflict\n", msg->from_jid, RAYO_JID(component)); - } - - return response; -} - -/** - * Handle server message - */ -void rayo_server_send(struct rayo_actor *server, struct rayo_message *msg) -{ - iks *response = NULL; - rayo_actor_xmpp_handler handler = NULL; - iks *iq = msg->payload; - - if (!strcmp("presence", iks_name(iq))) { - /* this is a hack - message from internal console */ - struct rayo_actor *client = RAYO_LOCATE(msg->from_jid); - if (client) { - if (!strcmp(RAT_CLIENT, client->type)) { - on_client_presence(RAYO_CLIENT(client), iq); - } - RAYO_RELEASE(client); - } - return; - } - - /* is this a command a server supports? */ - handler = rayo_actor_command_handler_find(server, msg); - if (!handler) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no handler function for command to %s\n", msg->from_jid, RAYO_JID(server)); - if (!msg->is_reply) { - RAYO_SEND_REPLY(server, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED)); - } - return; - } - - /* is the command valid? */ - if (!(response = rayo_server_command_ok(server, msg))) { - response = handler(server, msg, NULL); - } - - if (response) { - if (!msg->is_reply) { - RAYO_SEND_REPLY(server, msg->from_jid, response); - } else { - iks_delete(response); - } - } -} - -/** - * Handle call message - */ -void rayo_call_send(struct rayo_actor *call, struct rayo_message *msg) -{ - rayo_actor_xmpp_handler handler = NULL; - iks *stanza = msg->payload; - switch_core_session_t *session; - iks *response = NULL; - - if (!strcmp("message", iks_name(stanza))) { - const char *type = iks_find_attrib_soft(stanza, "type"); - - if (!strcmp("normal", type)) { - const char *body = iks_find_cdata(stanza, "body"); - if (!zstr(body)) { - switch_event_t *event; - if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "content-type", "text/plain"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "uuid", rayo_call_get_uuid(RAYO_CALL(call))); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", iks_find_cdata(stanza, "subject")); - switch_event_add_body(event, "%s", body); - switch_event_fire(&event); - } - } else if (!msg->is_reply) { - RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error_detailed(stanza, STANZA_ERROR_BAD_REQUEST, "missing body")); - } - } else if (!msg->is_reply) { - RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(stanza, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED)); - } - return; - } - - /* is this a command a call supports? */ - handler = rayo_actor_command_handler_find(call, msg); - if (!handler) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no handler function for command\n", RAYO_JID(call)); - if (!msg->is_reply) { - RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(stanza, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED)); - } - return; - } - - /* is the session still available? */ - session = switch_core_session_locate(rayo_call_get_uuid(RAYO_CALL(call))); - if (!session) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, session not found\n", RAYO_JID(call)); - if (!msg->is_reply) { - RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(stanza, STANZA_ERROR_ITEM_NOT_FOUND)); - } - return; - } - - /* is the command valid? */ - if (!(response = rayo_call_command_ok(RAYO_CALL(call), session, msg))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, executing command\n", RAYO_JID(call)); - response = handler(call, msg, session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, done executing command\n", RAYO_JID(call)); - } - switch_core_session_rwunlock(session); - - if (response) { - if (!msg->is_reply) { - RAYO_SEND_REPLY(call, msg->from_jid, response); - } else { - iks_delete(response); - } - } -} - -/** - * Handle mixer message - */ -void rayo_mixer_send(struct rayo_actor *mixer, struct rayo_message *msg) -{ - rayo_actor_xmpp_handler handler = NULL; - iks *iq = msg->payload; - iks *response = NULL; - - /* is this a command a mixer supports? */ - handler = rayo_actor_command_handler_find(mixer, msg); - if (!handler) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no handler function for command\n", RAYO_JID(mixer)); - if (!msg->is_reply) { - RAYO_SEND_REPLY(mixer, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED)); - } - return; - } - - /* execute the command */ - response = handler(mixer, msg, NULL); - if (response) { - if (!msg->is_reply) { - RAYO_SEND_REPLY(mixer, msg->from_jid, response); - } else { - iks_delete(response); - } - } -} - -/** - * Handle mixer message - */ -void rayo_component_send(struct rayo_actor *component, struct rayo_message *msg) -{ - rayo_actor_xmpp_handler handler = NULL; - iks *xml_msg = msg->payload; - iks *response = NULL; - - if (!strcmp("iq", iks_name(xml_msg))) { - /* is this a command a component supports? */ - handler = rayo_actor_command_handler_find(component, msg); - if (!handler) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no component handler function for command\n", RAYO_JID(component)); - if (!msg->is_reply) { - RAYO_SEND_REPLY(component, msg->from_jid, iks_new_error(xml_msg, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED)); - } - return; - } - - /* is the command valid? */ - if (!(response = rayo_component_command_ok(RAYO_COMPONENT(component), msg))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, executing command\n", RAYO_JID(component)); - response = handler(component, msg, NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, done executing command\n", RAYO_JID(component)); - } - - if (response) { - if (!msg->is_reply) { - RAYO_SEND_REPLY(component, msg->from_jid, response); - } else { - iks_delete(response); - } - return; - } - } else if (!strcmp("presence", iks_name(xml_msg))) { - /* is this an event the component wants? */ - handler = rayo_actor_event_handler_find(component, msg); - if (!handler) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no component handler function for event\n", RAYO_JID(component)); - return; - } - - /* forward the event */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, forwarding event\n", RAYO_JID(component)); - response = handler(component, msg, NULL); - if (response) { - if (!msg->is_reply) { - RAYO_SEND_REPLY(component, msg->from_jid, response); - } else { - iks_delete(response); - } - } - } -} - -/** - * Add signaling headers to channel -- only works on SIP - * @param session the channel - * @param iq_cmd the request containing
- * @param type header type - */ -static void add_signaling_headers(switch_core_session_t *session, iks *iq_cmd, const char *type) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - iks *header = NULL; - for (header = iks_find(iq_cmd, "header"); header; header = iks_next_tag(header)) { - if (!strcmp("header", iks_name(header))) { - const char *name = iks_find_attrib_soft(header, "name"); - const char *value = iks_find_attrib_soft(header, "value"); - if (!zstr(name) && !zstr(value)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding header: %s: %s\n", name, value); - switch_channel_set_variable_name_printf(channel, value, "%s%s", type, name); - } - } - } -} - -/** - * Handle request - * @param call the Rayo call - * @param session the session - * @param node the node - */ -static iks *on_rayo_accept(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *node = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *response = NULL; - - /* send ringing */ - add_signaling_headers(session, iks_find(node, "accept"), RAYO_SIP_RESPONSE_HEADER); - switch_channel_pre_answer(switch_core_session_get_channel(session)); - response = iks_new_iq_result(node); - return response; -} - -/** - * Handle request - * @param call the Rayo call - * @param session the session - * @param node the node - */ -static iks *on_rayo_answer(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *node = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *response = NULL; - - /* send answer to call */ - add_signaling_headers(session, iks_find(node, "answer"), RAYO_SIP_RESPONSE_HEADER); - switch_channel_answer(switch_core_session_get_channel(session)); - response = iks_new_iq_result(node); - return response; -} - -/** - * Handle request - * @param call the Rayo call - * @param session the session - * @param node the node - */ -static iks *on_rayo_redirect(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *node = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - switch_channel_t *channel = switch_core_session_get_channel(session); - iks *response = NULL; - iks *redirect = iks_find(node, "redirect"); - char *redirect_to = iks_find_attrib(redirect, "to"); - - if (zstr(redirect_to)) { - response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing redirect to attrib"); - } else if (switch_channel_test_flag(channel, CF_ANSWERED)) { - /* call is answered- must deflect */ - switch_core_session_message_t msg = { 0 }; - add_signaling_headers(session, redirect, RAYO_SIP_REQUEST_HEADER); - msg.from = __FILE__; - msg.string_arg = switch_core_session_strdup(session, redirect_to); - msg.message_id = SWITCH_MESSAGE_INDICATE_DEFLECT; - switch_core_session_receive_message(session, &msg); - response = iks_new_iq_result(node); - } else if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - /* Inbound call not answered - redirect */ - switch_core_session_message_t msg = { 0 }; - add_signaling_headers(session, redirect, RAYO_SIP_RESPONSE_HEADER); - msg.from = __FILE__; - msg.string_arg = switch_core_session_strdup(session, redirect_to); - msg.message_id = SWITCH_MESSAGE_INDICATE_REDIRECT; - switch_core_session_receive_message(session, &msg); - response = iks_new_iq_result(node); - } else { - response = iks_new_error_detailed(node, STANZA_ERROR_UNEXPECTED_REQUEST, "Call must be answered"); - } - return response; -} - -/** - * Handle or request - * @param call the Rayo call - * @param session the session - * @param node the node - */ -static iks *on_rayo_hangup(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *node = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *response = NULL; - iks *hangup = iks_first_tag(node); - iks *reason = iks_first_tag(hangup); - int hangup_cause = RAYO_CAUSE_HANGUP; - - /* get hangup cause */ - if (!reason && !strcmp("hangup", iks_name(hangup))) { - /* no reason in */ - hangup_cause = RAYO_CAUSE_HANGUP; - } else if (reason && !strcmp("reject", iks_name(hangup))) { - char *reason_name = iks_name(reason); - /* reason required for */ - if (!strcmp("busy", reason_name)) { - hangup_cause = RAYO_CAUSE_BUSY; - } else if (!strcmp("decline", reason_name)) { - hangup_cause = RAYO_CAUSE_DECLINE; - } else if (!strcmp("error", reason_name)) { - hangup_cause = RAYO_CAUSE_ERROR; - } else { - response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "invalid reject reason"); - } - } else { - response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST); - } - - /* do hangup */ - if (!response) { - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_local_hangup", "true"); - add_signaling_headers(session, hangup, RAYO_SIP_REQUEST_HEADER); - add_signaling_headers(session, hangup, RAYO_SIP_RESPONSE_HEADER); - switch_ivr_kill_uuid(rayo_call_get_uuid(call), hangup_cause); - response = iks_new_iq_result(node); - } - - return response; -} - -/** - * Join calls together - * @param call the call that joins - * @param session the session - * @param msg the rayo join message - * @param call_uri to join - * @param media mode (direct/bridge) - * @return the response - */ -static iks *join_call(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg, const char *call_uri, const char *media) -{ - iks *node = msg->payload; - iks *response = NULL; - /* take call out of media path if media = "direct" */ - int do_direct = !strcmp("direct", media); - - /* check if joining to rayo call */ - struct rayo_call *b_call = RAYO_CALL_LOCATE(call_uri); - if (b_call) { - if (!call->rayo_app_started) { - /* A-leg not under rayo control yet */ - response = iks_new_error_detailed(node, STANZA_ERROR_UNEXPECTED_REQUEST, "a-leg is not ready to join"); - } else if (!b_call->rayo_app_started) { - /* B-leg not under rayo control yet */ - response = iks_new_error_detailed(node, STANZA_ERROR_UNEXPECTED_REQUEST, "b-leg is not ready to join"); - } else if (!has_call_control(b_call, msg)) { - /* not allowed to join to this call */ - response = iks_new_error(node, STANZA_ERROR_NOT_ALLOWED); - } else if (b_call->joined) { - /* don't support multiple joined calls */ - response = iks_new_error_detailed(node, STANZA_ERROR_CONFLICT, "multiple joined calls not supported"); - } else { - /* bridge this call to call-uri */ - if (do_direct) { - switch_channel_set_flag(switch_core_session_get_channel(session), CF_BYPASS_MEDIA_AFTER_BRIDGE); - } else { - switch_channel_clear_flag(switch_core_session_get_channel(session), CF_BYPASS_MEDIA_AFTER_BRIDGE); - switch_channel_pre_answer(switch_core_session_get_channel(session)); - } - call->pending_join_request = iks_copy(node); - if (switch_ivr_uuid_bridge(rayo_call_get_uuid(call), rayo_call_get_uuid(b_call)) != SWITCH_STATUS_SUCCESS) { - iks *request = call->pending_join_request; - iks *result = iks_new_error(request, STANZA_ERROR_SERVICE_UNAVAILABLE); - call->pending_join_request = NULL; - RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); - iks_delete(call->pending_join_request); - } - } - RAYO_RELEASE(b_call); - } else { - /* not a rayo call */ - response = iks_new_error_detailed(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "b-leg is gone"); - } - return response; -} - -/** - * Execute command on session's conference - * @param session to execute conference API on - * @param conf_name of conference - * @param command to send to conference - * @param node IQ request - * @return response on failure - */ -static iks *exec_conference_api(switch_core_session_t *session, const char *conf_name, const char *command, iks *node) -{ - iks *response = NULL; - switch_stream_handle_t stream = { 0 }; - const char *conf_member_id = switch_channel_get_variable(switch_core_session_get_channel(session), "conference_member_id"); - SWITCH_STANDARD_STREAM(stream); - switch_api_execute("conference", switch_core_session_sprintf(session, "%s %s %s", conf_name, command, conf_member_id), NULL, &stream); - if (!zstr(stream.data) && strncmp("+OK", stream.data, 3)) { - response = iks_new_error_detailed_printf(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "%s", stream.data); - } - switch_safe_free(stream.data); - return response; -} - -/** - * Execute conference app on session - * @param session to execute conference API on - * @param command to send to conference (conference name, member flags, etc) - * @param node IQ request - * @return response on failure - */ -static iks *exec_conference_app(switch_core_session_t *session, const char *command, iks *node) -{ - iks *response = NULL; - switch_event_t *execute_event = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - - /* conference requires local media on channel */ - if (!switch_channel_media_ready(channel) && switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { - /* shit */ - response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to start media"); - return response; - } - - /* send execute conference event to session */ - if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "conference"); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", command); - //switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event_uuid", uuid); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); - if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { - switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); - } - - if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to join mixer (queue event failed)"); - if (execute_event) { - switch_event_destroy(&execute_event); - } - return response; - } - } - return response; -} - -/** - * Join call to a mixer - * @param call the call that joins - * @param session the session - * @param msg the join request - * @param mixer_name the mixer to join - * @param direction the media direction - * @return the response - */ -static iks *join_mixer(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg, const char *mixer_name, const char *direction) -{ - iks *node = msg->payload; - iks *response = NULL; - - if (!call->rayo_app_started) { - /* A-leg not under rayo control yet */ - response = iks_new_error_detailed(node, STANZA_ERROR_UNEXPECTED_REQUEST, "call is not ready to join"); - } else if (call->joined_id) { - /* adjust join conference params */ - if (!strcmp("duplex", direction)) { - if ((response = exec_conference_api(session, mixer_name, "unmute", node)) || - (response = exec_conference_api(session, mixer_name, "undeaf", node))) { - return response; - } - } else if (!strcmp("recv", direction)) { - if ((response = exec_conference_api(session, mixer_name, "mute", node)) || - (response = exec_conference_api(session, mixer_name, "undeaf", node))) { - return response; - } - } else { - if ((response = exec_conference_api(session, mixer_name, "unmute", node)) || - (response = exec_conference_api(session, mixer_name, "deaf", node))) { - return response; - } - } - response = iks_new_iq_result(node); - } else { - /* join new conference */ - const char *conf_args = switch_core_session_sprintf(session, "%s@%s", mixer_name, globals.mixer_conf_profile); - if (!strcmp("send", direction)) { - conf_args = switch_core_session_sprintf(session, "%s+flags{deaf}", conf_args); - } else if (!strcmp("recv", direction)) { - conf_args = switch_core_session_sprintf(session, "%s+flags{mute}", conf_args); - } - - call->pending_join_request = iks_copy(node); - response = exec_conference_app(session, conf_args, node); - if (response) { - iks_delete(call->pending_join_request); - call->pending_join_request = NULL; - } - } - return response; -} - -/** - * Handle request - * @param call the Rayo call - * @param session the session - * @param msg the rayo join message - */ -static iks *on_rayo_join(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *response = NULL; - iks *join = iks_find(msg->payload, "join"); - const char *join_id; - const char *mixer_name; - const char *call_uri; - - /* validate input attributes */ - if (!VALIDATE_RAYO_JOIN(join)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad join attrib\n"); - response = iks_new_error(msg->payload, STANZA_ERROR_BAD_REQUEST); - goto done; - } - mixer_name = iks_find_attrib(join, "mixer-name"); - call_uri = iks_find_attrib(join, "call-uri"); - - if (!zstr(mixer_name)) { - join_id = mixer_name; - } else { - join_id = call_uri; - } - - /* can't join both mixer and call */ - if (!zstr(mixer_name) && !zstr(call_uri)) { - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_BAD_REQUEST, "mixer-name and call-uri are mutually exclusive"); - goto done; - } - - /* need to join *something* */ - if (zstr(mixer_name) && zstr(call_uri)) { - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_BAD_REQUEST, "mixer-name or call-uri is required"); - goto done; - } - - if ((RAYO_CALL(call)->joined == JOINED_CALL) || - (RAYO_CALL(call)->joined == JOINED_MIXER && strcmp(RAYO_CALL(call)->joined_id, join_id))) { - /* already joined */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_CONFLICT, "call is already joined"); - goto done; - } - - if (rayo_call_is_faxing(RAYO_CALL(call))) { - /* can't join a call while it's faxing */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_UNEXPECTED_REQUEST, "fax is in progress"); - goto done; - } - - if (RAYO_CALL(call)->pending_join_request) { - /* don't allow concurrent join requests */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_UNEXPECTED_REQUEST, "(un)join request is pending"); - goto done; - } - - if (!zstr(mixer_name)) { - /* join conference */ - response = join_mixer(RAYO_CALL(call), session, msg, mixer_name, iks_find_attrib(join, "direction")); - } else { - /* bridge calls */ - response = join_call(RAYO_CALL(call), session, msg, call_uri, iks_find_attrib(join, "media")); - } - -done: - return response; -} - -/** - * unjoin call to a bridge - * @param call the call that unjoined - * @param session the session - * @param msg the unjoin request - * @param call_uri the b-leg xmpp URI - * @return the response - */ -static iks *unjoin_call(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg, const char *call_uri) -{ - iks *node = msg->payload; - iks *response = NULL; - - if (!strcmp(call_uri, call->joined_id)) { - /* unbridge call */ - call->pending_join_request = iks_copy(node); - switch_ivr_park_session(session); - } else { - /* not bridged or wrong b-leg URI */ - response = iks_new_error_detailed_printf(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "expected URI: %s", call->joined_id); - } - - return response; -} - -/** - * unjoin call to a mixer - * @param call the call that unjoined - * @param session the session - * @param msg the unjoin request - * @param mixer_name the mixer name - * @return the response - */ -static iks *unjoin_mixer(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg, const char *mixer_name) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *conf_member_id = switch_channel_get_variable(channel, "conference_member_id"); - const char *conf_name = switch_channel_get_variable(channel, "conference_name"); - iks *node = msg->payload; - iks *response = NULL; - - /* not conferenced, or wrong conference */ - if (zstr(conf_name) || strcmp(mixer_name, conf_name)) { - response = iks_new_error_detailed_printf(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "not joined to %s", mixer_name); - goto done; - } else if (zstr(conf_member_id)) { - /* shouldn't happen */ - response = iks_new_error_detailed(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "channel doesn't have conference member ID"); - goto done; - } - - /* kick the member */ - response = exec_conference_api(session, mixer_name, "hup", node); - if (!response) { - /* ack command */ - response = iks_new_iq_result(node); - } - -done: - - return response; -} - -/** - * Handle request - * @param call the Rayo call - * @param session the session - * @param node the node - */ -static iks *on_rayo_unjoin(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *response = NULL; - iks *unjoin = iks_find(msg->payload, "unjoin"); - const char *call_uri = iks_find_attrib(unjoin, "call-uri"); - const char *mixer_name = iks_find_attrib(unjoin, "mixer-name"); - - if (!zstr(call_uri) && !zstr(mixer_name)) { - response = iks_new_error(msg->payload, STANZA_ERROR_BAD_REQUEST); - } else if (RAYO_CALL(call)->pending_join_request) { - /* need to let pending request finish first */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_UNEXPECTED_REQUEST, "(un)join request is pending"); - } else if (!RAYO_CALL(call)->joined) { - /* not joined to anything */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_SERVICE_UNAVAILABLE, "not joined to anything"); - } else if (RAYO_CALL(call)->joined == JOINED_MIXER && !zstr(call_uri)) { - /* joined to mixer, not call */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_SERVICE_UNAVAILABLE, "not joined to call"); - } else if (RAYO_CALL(call)->joined == JOINED_CALL && !zstr(mixer_name)) { - /* joined to call, not mixer */ - response = iks_new_error_detailed(msg->payload, STANZA_ERROR_SERVICE_UNAVAILABLE, "not joined to mixer"); - } else if (!zstr(call_uri)) { - response = unjoin_call(RAYO_CALL(call), session, msg, call_uri); - } else if (!zstr(mixer_name)) { - response = unjoin_mixer(RAYO_CALL(call), session, msg, mixer_name); - } else { - /* unjoin everything */ - if (RAYO_CALL(call)->joined == JOINED_MIXER) { - response = unjoin_mixer(RAYO_CALL(call), session, msg, RAYO_CALL(call)->joined_id); - } else if (RAYO_CALL(call)->joined == JOINED_CALL) { - response = unjoin_call(RAYO_CALL(call), session, msg, RAYO_CALL(call)->joined_id); - } else { - /* shouldn't happen */ - response = iks_new_error(msg->payload, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - } - - return response; -} - -/** - * @return 1 if display name is valid - */ -static int is_valid_display_name(char *display) -{ - if (zstr(display)) { - return 0; - } - return 1; -} - -/** - * @return 1 if SIP URI is valid - */ -static int is_valid_sip_uri(char *uri) -{ - /* just some basic checks to prevent failure when passing URI as caller ID */ - if (zstr(uri) || strchr(uri, '<') || strchr(uri, '>')) { - return 0; - } - return 1; -} - -#define RAYO_URI_SCHEME_UNKNOWN 0 -#define RAYO_URI_SCHEME_TEL 1 -#define RAYO_URI_SCHEME_SIP 2 - -/** - * Parse dial "from" parameter - * @param pool to use - * @param from the parameter to parse - * @param uri the URI - * @param display the display name - * @return scheme - */ -static int parse_dial_from(switch_memory_pool_t *pool, const char *from, char **uri, char **display) -{ - if (!zstr(from)) { - char *l_display = switch_core_strdup(pool, from); - char *l_uri; - - *display = NULL; - *uri = NULL; - - /* TODO regex would be better */ - - /* split display-name and URI */ - l_uri = strrchr(l_display, ' '); - if (l_uri) { - *l_uri++ = '\0'; - if (!zstr(l_display)) { - /* remove "" from display-name */ - if (l_display[0] == '"') { - int len; - *l_display++ = '\0'; - len = strlen(l_display); - if (len < 2 || l_display[len - 1] != '"') { - return RAYO_URI_SCHEME_UNKNOWN; - } - l_display[len - 1] = '\0'; - } - if (!is_valid_display_name(l_display)) { - return RAYO_URI_SCHEME_UNKNOWN; - } - *display = l_display; - } - } else { - l_uri = l_display; - } - if (zstr(l_uri)) { - return RAYO_URI_SCHEME_UNKNOWN; - } - - /* remove <> from URI */ - if (l_uri[0] == '<') { - int len; - *l_uri++ = '\0'; - len = strlen(l_uri); - if (len < 2 || l_uri[len - 1] != '>') { - return RAYO_URI_SCHEME_UNKNOWN; - } - l_uri[len - 1] = '\0'; - if (zstr(l_uri)) { - return RAYO_URI_SCHEME_UNKNOWN; - } - } - *uri = l_uri; - - /* figure out URI scheme and validate it */ - if (!strncmp("sip:", l_uri, 4) || !strncmp("sips:", l_uri, 5)) { - /* validate SIP URI */ - if (is_valid_sip_uri(l_uri)) { - return RAYO_URI_SCHEME_SIP; - } - } else if (!strncmp("tel:", l_uri, 4)) { - l_uri += 4; - *uri = l_uri; - } - if (!zstr(l_uri)) { - return RAYO_URI_SCHEME_TEL; - } - } - return RAYO_URI_SCHEME_UNKNOWN; -} - -struct dial_thread_data { - switch_memory_pool_t *pool; - iks *node; -}; - - -/** - * Thread that handles originating new calls - * @param thread this thread - * @param obj the Rayo client - * @return NULL - */ -static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void *user) -{ - struct dial_thread_data *dtdata = (struct dial_thread_data *)user; - iks *iq = dtdata->node; - iks *dial = iks_find(iq, "dial"); - iks *response = NULL; - const char *dcp_jid = iks_find_attrib(iq, "from"); - const char *dial_to = iks_find_attrib(dial, "to"); - char *dial_to_dup = NULL; - const char *dial_from = iks_find_attrib(dial, "from"); - const char *dial_timeout_ms = iks_find_attrib(dial, "timeout"); - const char *requested_call_uri = iks_find_attrib(dial, "uri"); - const char *uuid = NULL; - switch_event_t *originate_vars = NULL; - struct dial_gateway *gateway = NULL; - struct rayo_call *call = NULL; - uint32_t dial_timeout_sec = 0; - - /* TODO dial_to needs validation */ - - /* Check if optional URI is valid. */ - if (!zstr(requested_call_uri)) { - - /* Split node and domain from URI */ - char *requested_call_uri_dup = switch_core_strdup(dtdata->pool, requested_call_uri); - char *requested_call_uri_domain = strchr(requested_call_uri_dup, '@'); - if (requested_call_uri_domain) { - *requested_call_uri_domain = '\0'; - requested_call_uri_domain++; - } - - /* is domain missing */ - if (zstr(requested_call_uri_domain)) { - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad uri"); - goto done; - } - - /* is domain correct? */ - if (strcmp(requested_call_uri_domain, RAYO_JID(globals.server))) { - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad uri (invalid domain)"); - goto done; - } - - /* is node identifier missing? */ - if (zstr(requested_call_uri_dup)) { - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad uri (missing node)"); - goto done; - } - - /* strip optional xmpp: from node identifier */ - if (!strncasecmp("xmpp:", requested_call_uri_dup, 5)) { - requested_call_uri_dup += 5; - if (zstr(requested_call_uri_dup)) { - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad uri (missing node)"); - goto done; - } - } - - /* success! */ - uuid = requested_call_uri_dup; - } - - /* create call and link to DCP */ - call = rayo_call_create(uuid); - if (!call) { - response = iks_new_error(iq, STANZA_ERROR_CONFLICT); - goto done; - } - call->dcp_jid = switch_core_strdup(RAYO_POOL(call), dcp_jid); - call->dial_request_id = switch_core_strdup(RAYO_POOL(call), iks_find_attrib_soft(iq, "id")); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s has control of call\n", dcp_jid); - uuid = switch_core_strdup(dtdata->pool, rayo_call_get_uuid(call)); - - /* create container for origination variables */ - if (switch_event_create_plain(&originate_vars, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) { - abort(); - } - - /* add dialstring vars to origination variables */ - if (*dial_to == '{') { - dial_to_dup = switch_core_strdup(dtdata->pool, dial_to); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: parsing dialstring channel variables\n"); - switch_event_create_brackets(dial_to_dup, '{', '}', ',', &originate_vars, (char **)&dial_to, SWITCH_FALSE); - } - - /* set originate channel variables */ - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "origination_uuid", rayo_call_get_uuid(call)); - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "rayo_dcp_jid", dcp_jid); - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "rayo_call_jid", RAYO_JID(call)); - - if (!zstr(dial_from)) { - char *from_uri = NULL; - char *from_display; - int scheme = parse_dial_from(dtdata->pool, dial_from, &from_uri, &from_display); - if (scheme == RAYO_URI_SCHEME_UNKNOWN) { - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad from URI"); - goto done; - } else if (scheme == RAYO_URI_SCHEME_SIP) { - /* SIP URI */ - if (!zstr(from_uri)) { - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "sip_from_uri", from_uri); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: sip_from_uri=%s\n", from_uri); - } - if (!zstr(from_display)) { - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "sip_from_display", from_display); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: sip_from_display=%s\n", from_display); - } - } - if (!zstr(from_uri)) { - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "origination_caller_id_number", from_uri); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: origination_caller_id_number=%s\n", from_uri); - } - if (!zstr(from_display)) { - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "origination_caller_id_name", from_display); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: origination_caller_id_name=%s\n", from_display); - } else if (scheme == RAYO_URI_SCHEME_TEL && !zstr(from_uri)) { - /* set caller ID name to same as number if telephone number and a name wasn't specified */ - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, "origination_caller_id_name", from_uri); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: origination_caller_id_name=%s\n", from_uri); - } - } - if (!zstr(dial_timeout_ms) && switch_is_number(dial_timeout_ms)) { - dial_timeout_sec = round((double)atoi(dial_timeout_ms) / 1000.0); - } - - /* set outbound signaling headers - only works on SIP */ - { - iks *header = NULL; - for (header = iks_find(dial, "header"); header; header = iks_next_tag(header)) { - if (!strcmp("header", iks_name(header))) { - const char *name = iks_find_attrib_soft(header, "name"); - const char *value = iks_find_attrib_soft(header, "value"); - if (!zstr(name) && !zstr(value)) { - char *header_name = switch_core_sprintf(dtdata->pool, "%s%s", RAYO_SIP_REQUEST_HEADER, name); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: Adding SIP header: %s: %s\n", name, value); - switch_event_add_header_string(originate_vars, SWITCH_STACK_BOTTOM, header_name, value); - } - } - } - } - - /* build dialstring and dial call */ - gateway = dial_gateway_find(dial_to); - if (gateway) { - iks *join = iks_find(dial, "join"); - const char *dial_to_stripped = dial_to + gateway->strip; - switch_core_session_t *called_session = NULL; - switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; - const char *dialstring = NULL; - - if (join) { - /* check join args */ - const char *call_uri = iks_find_attrib(join, "call-uri"); - const char *mixer_name = iks_find_attrib(join, "mixer-name"); - - if (!zstr(call_uri) && !zstr(mixer_name)) { - /* can't join both */ - response = iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - goto done; - } else if (zstr(call_uri) && zstr(mixer_name)) { - /* nobody to join to? */ - response = iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - goto done; - } else if (!zstr(call_uri)) { - /* bridge */ - struct rayo_call *peer_call = RAYO_CALL_LOCATE(call_uri); - /* is peer call available? */ - if (!peer_call) { - response = iks_new_error_detailed(iq, STANZA_ERROR_SERVICE_UNAVAILABLE, "peer call not found"); - goto done; - } else if (peer_call->joined) { - response = iks_new_error_detailed(iq, STANZA_ERROR_SERVICE_UNAVAILABLE, "peer call already joined"); - RAYO_RELEASE(peer_call); - goto done; - } - switch_event_add_header(originate_vars, SWITCH_STACK_BOTTOM, "rayo_origination_args", "bridge %s", rayo_call_get_uuid(peer_call)); - RAYO_RELEASE(peer_call); - } else { - /* conference */ - switch_event_add_header(originate_vars, SWITCH_STACK_BOTTOM, "rayo_origination_args", "conference %s@%s", mixer_name, globals.mixer_conf_profile); - } - } - - dialstring = switch_core_sprintf(dtdata->pool, "%s%s", gateway->dial_prefix, dial_to_stripped); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "dial: Using dialstring: %s\n", dialstring); - - /* response will be sent when originate event is received- otherwise error is returned */ - if (switch_ivr_originate(NULL, &called_session, &cause, dialstring, dial_timeout_sec, NULL, NULL, NULL, NULL, originate_vars, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS && called_session) { - /* start APP */ - switch_caller_extension_t *extension = NULL; - switch_channel_t *called_channel = switch_core_session_get_channel(called_session); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "dial: Call originated\n"); - if ((extension = switch_caller_extension_new(called_session, "rayo", NULL)) == 0) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_CRIT, "Memory Error!\n"); - abort(); - } - switch_caller_extension_add_application(called_session, extension, "rayo", NULL); - switch_channel_set_caller_extension(called_channel, extension); - switch_channel_set_state(called_channel, CS_EXECUTE); - switch_core_session_rwunlock(called_session); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "dial: Failed to originate call: %s\n", switch_channel_cause2str(cause)); - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - if (!zstr(call->dial_request_id)) { - call->dial_request_failed = 1; - call->dial_request_id = NULL; - - /* map failure reason to iq error */ - switch (cause) { - case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER: - /* out of sessions, typically */ - response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, "DESTINATION_OUT_OF_ORDER"); - break; - case SWITCH_CAUSE_SUBSCRIBER_ABSENT: - case SWITCH_CAUSE_USER_NOT_REGISTERED: { - /* call session was never created, so we must fake it so that a call error is sent and - not a dial error */ - /* send ref response to DCP immediately followed with failure */ - iks *ref; - iks *ref_response = iks_new("iq"); - iks_insert_attrib(ref_response, "from", RAYO_JID(globals.server)); - iks_insert_attrib(ref_response, "to", dcp_jid); - iks_insert_attrib(ref_response, "id", iks_find_attrib_soft(iq, "id")); - iks_insert_attrib(ref_response, "type", "result"); - ref = iks_insert(ref_response, "ref"); - iks_insert_attrib(ref, "xmlns", RAYO_NS); - iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call)); - RAYO_SEND_MESSAGE(globals.server, dcp_jid, ref_response); - - /* send subscriber-absent call hangup reason */ - rayo_call_send_end(call, NULL, 0, "SUBSCRIBER_ABSENT", "20"); - - /* destroy call */ - RAYO_DESTROY(call); - RAYO_RELEASE(call); - break; - } - case SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR: - /* max forwards */ - response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, "EXCHANGE_ROUTING_ERROR"); - break; - case SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED: - /* unsupported endpoint type */ - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "CHAN_NOT_IMPLEMENTED"); - break; - case SWITCH_CAUSE_INVALID_URL: - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "INVALID_URL"); - break; - case SWITCH_CAUSE_INVALID_GATEWAY: - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "INVALID_GATEWAY"); - break; - case SWITCH_CAUSE_INVALID_PROFILE: - response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "INVALID_PROFILE"); - break; - case SWITCH_CAUSE_SYSTEM_SHUTDOWN: - response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, "SYSTEM_SHUTDOWN"); - break; - case SWITCH_CAUSE_GATEWAY_DOWN: - response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, "GATEWAY_DOWN"); - break; - case SWITCH_CAUSE_INVALID_NUMBER_FORMAT: - response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, "INVALID_NUMBER_FORMAT"); - break; - default: - response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, switch_channel_cause2str(cause)); - break; - } - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - } - } else { - /* will only happen if misconfigured */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_CRIT, "dial: No dial gateway found for %s!\n", dial_to); - call->dial_request_failed = 1; - call->dial_request_id = NULL; - response = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "dial: No dial gateway found for %s!\n", dial_to); - goto done; - } - -done: - - /* response when error */ - if (response) { - /* send response to client */ - RAYO_SEND_REPLY(globals.server, iks_find_attrib(response, "to"), response); - - /* destroy call */ - if (call) { - RAYO_DESTROY(call); - RAYO_RELEASE(call); - } - } - - iks_delete(iq); - - if (originate_vars) { - switch_event_destroy(&originate_vars); - } - - { - switch_memory_pool_t *pool = dtdata->pool; - switch_core_destroy_memory_pool(&pool); - } - - return NULL; -} - -/** - * Dial a new call - * @param server handling the call - * @param msg the request - */ -static iks *on_rayo_dial(struct rayo_actor *server, struct rayo_message *msg, void *data) -{ - iks *node = msg->payload; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - iks *dial = iks_find(node, "dial"); - iks *response = NULL; - const char *dial_to = iks_find_attrib(dial, "to"); - - if (zstr(dial_to)) { - response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "missing dial to attribute"); - } else if (strchr(dial_to, ' ')) { - response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "malformed dial string"); - } else { - switch_memory_pool_t *pool; - struct dial_thread_data *dtdata = NULL; - switch_core_new_memory_pool(&pool); - dtdata = switch_core_alloc(pool, sizeof(*dtdata)); - dtdata->pool = pool; - dtdata->node = iks_copy(node); - - iks_insert_attrib(dtdata->node, "from", msg->from_jid); /* save DCP jid in case it isn't specified */ - - /* start dial thread */ - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, rayo_dial_thread, dtdata, pool); - } - - return response; -} - -struct exec_thread_data { - switch_memory_pool_t *pool; - iks *node; -}; - -/** - * Thread that handles executing server APIs - * @param thread this thread - * @param user the API request - * @return NULL - */ -static void *SWITCH_THREAD_FUNC rayo_exec_thread(switch_thread_t *thread, void *user) -{ - struct exec_thread_data *etdata = (struct exec_thread_data *)user; - iks *response = NULL; - iks *exec = iks_find(etdata->node, "exec"); - const char *api = iks_find_attrib(exec, "api"); - const char *args = iks_find_attrib_soft(exec, "args"); - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BGAPI EXEC: %s %s\n", api, args); - if (switch_api_execute(api, args, NULL, &stream) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BGAPI EXEC FAILURE\n"); - response = iks_new_error_detailed(etdata->node, STANZA_ERROR_BAD_REQUEST, "Failed to execute API"); - } else { - iks *api_result = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BGAPI EXEC RESULT: %s\n", (char *)stream.data); - response = iks_new_iq_result(etdata->node); - api_result = iks_insert(response, "response"); - iks_insert_attrib(api_result, "xmlns", RAYO_NS); - iks_insert_attrib(api_result, "response", zstr((char *)stream.data) ? "" : (char *)stream.data); - } - - RAYO_SEND_REPLY(globals.server, iks_find_attrib(response, "to"), response); - - switch_safe_free(stream.data); - { - switch_memory_pool_t *pool = etdata->pool; - switch_core_destroy_memory_pool(&pool); - } - return NULL; -} - -/** - * Execute an API on the server - * @param server handling the call - * @param msg the request - */ -static iks *on_rayo_exec(struct rayo_actor *server, struct rayo_message *msg, void *data) -{ - iks *node = msg->payload; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - iks *exec = iks_find(node, "exec"); - iks *response = NULL; - const char *api = iks_find_attrib_soft(exec, "api"); - - if (zstr(api)) { - response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "missing api attribute"); - } else { - struct exec_thread_data *etdata = NULL; - switch_memory_pool_t *pool = NULL; - switch_core_new_memory_pool(&pool); - etdata = switch_core_alloc(pool, sizeof(*etdata)); - etdata->pool = pool; - etdata->node = iks_copy(node); - - /* start exec thread */ - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, rayo_exec_thread, etdata, pool); - } - return response; -} - -/** - * Handle request - * @param rclient the Rayo client - * @param server the Rayo server - * @param node the node - * @return NULL - */ -static iks *on_iq_xmpp_ping(struct rayo_actor *server, struct rayo_message *msg, void *data) -{ - iks *node = msg->payload; - iks *pong = iks_new("iq"); - char *from = iks_find_attrib(node, "from"); - char *to = iks_find_attrib(node, "to"); - - if (zstr(from)) { - from = msg->from_jid; - } - - if (zstr(to)) { - to = RAYO_JID(server); - } - - iks_insert_attrib(pong, "type", "result"); - iks_insert_attrib(pong, "from", to); - iks_insert_attrib(pong, "to", from); - iks_insert_attrib(pong, "id", iks_find_attrib(node, "id")); - - return pong; -} - -/** - * Handle service discovery request - * @param rclient the Rayo client - * @param server the Rayo server - * @param node the node - * @return NULL - */ -static iks *on_iq_get_xmpp_disco(struct rayo_actor *server, struct rayo_message *msg, void *data) -{ - iks *node = msg->payload; - iks *response = NULL; - iks *x; - iks *feature; - iks *identity; - int i = 0; - const char *feature_string; - response = iks_new_iq_result(node); - x = iks_insert(response, "query"); - iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_DISCO); - identity = iks_insert(x, "identity"); - iks_insert_attrib(identity, "category", rayo_server_identity.category); - iks_insert_attrib(identity, "type", rayo_server_identity.type); - i = 0; - while((feature_string = rayo_server_features[i++])) { - feature = iks_insert(x, "feature"); - iks_insert_attrib(feature, "var", feature_string); - } - - /* TODO The response MUST also include features for the application formats and transport methods supported by - * the responding entity, as described in the relevant specifications. - */ - - return response; -} - -/** - * Handle message from client - * @param rclient that sent the command - * @param message the message - */ -static void on_client_message(struct rayo_client *rclient, iks *message) -{ - const char *to = iks_find_attrib(message, "to"); - - /* must be directed to a client */ - if (zstr(to)) { - return; - } - - /* assume client source */ - if (zstr(iks_find_attrib(message, "from"))) { - iks_insert_attrib(message, "from", RAYO_JID(rclient)); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, recv message, availability = %s\n", RAYO_JID(rclient), presence_status_to_string(rclient->availability)); - - RAYO_SEND_MESSAGE_DUP(rclient, to, message); -} - -/** - * Handle message from a client - * @param rclient the client - * @param node the presence message - */ -static void on_client_presence(struct rayo_client *rclient, iks *node) -{ - char *type = iks_find_attrib(node, "type"); - enum presence_status status = PS_UNKNOWN; - - /* - From RFC-6121: - Entity is available when received. - Entity is unavailable when is received. - - From Rayo-XEP: - Entity is available when chat is received. - Entity is unavailable when dnd is received. - */ - - /* figure out if online/offline */ - if (zstr(type)) { - /* chat */ - char *status_str = iks_find_cdata(node, "show"); - if (!zstr(status_str)) { - if (!strcmp("chat", status_str)) { - status = PS_ONLINE; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s got chat presence\n", RAYO_JID(rclient)); - } else if (!strcmp("dnd", status_str)) { - status = PS_OFFLINE; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s got dnd presence\n", RAYO_JID(rclient)); - } - } else { - /* */ - status = PS_ONLINE; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s got empty presence\n", RAYO_JID(rclient)); - } - } else if (!strcmp("unavailable", type)) { - status = PS_OFFLINE; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s got unavailable presence\n", RAYO_JID(rclient)); - } else if (!strcmp("error", type)) { - /* TODO presence error */ - } else if (!strcmp("probe", type)) { - /* TODO presence probe */ - } else if (!strcmp("subscribe", type)) { - /* TODO presence subscribe */ - } else if (!strcmp("subscribed", type)) { - /* TODO presence subscribed */ - } else if (!strcmp("unsubscribe", type)) { - /* TODO presence unsubscribe */ - } else if (!strcmp("unsubscribed", type)) { - /* TODO presence unsubscribed */ - } - - if (status == PS_ONLINE && rclient->availability != PS_ONLINE) { - rclient->availability = PS_ONLINE; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s is ONLINE\n", RAYO_JID(rclient)); - } else if (status == PS_OFFLINE && rclient->availability != PS_OFFLINE) { - rclient->availability = PS_OFFLINE; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s is OFFLINE\n", RAYO_JID(rclient)); - } - - /* destroy if not a local client (connected via peer_server) and is OFFLINE */ - if (rclient->peer_server && rclient->availability == PS_OFFLINE) { - RAYO_DESTROY(rclient); - RAYO_RELEASE(rclient); - } - - pause_when_offline(); -} - -/** - * Handle command from client - * @param rclient that sent the command - * @param iq the command - */ -static void rayo_client_command_recv(struct rayo_client *rclient, iks *iq) -{ - iks *command = iks_first_tag(iq); - const char *to = iks_find_attrib(iq, "to"); - - /* assume server destination */ - if (zstr(to)) { - to = RAYO_JID(globals.server); - iks_insert_attrib(iq, "to", to); - } - - /* assume client source */ - if (zstr(iks_find_attrib(iq, "from"))) { - iks_insert_attrib(iq, "from", RAYO_JID(rclient)); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, recv iq, availability = %s\n", RAYO_JID(rclient), presence_status_to_string(rclient->availability)); - - if (command) { - RAYO_SEND_MESSAGE_DUP(rclient, to, iq); - } else { - const char *type = iks_find_attrib_soft(iq, "type"); - if (strcmp("error", type) && strcmp("result", type)) { - RAYO_SEND_REPLY(globals.server, RAYO_JID(rclient), iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "empty IQ request")); - } - } -} - -/** - * Send event to mixer subscribers - * @param mixer the mixer - * @param rayo_event the event to send - */ -static void broadcast_mixer_event(struct rayo_mixer *mixer, iks *rayo_event) -{ - switch_hash_index_t *hi = NULL; - switch_mutex_lock(RAYO_ACTOR(mixer)->mutex); - for (hi = switch_core_hash_first(mixer->subscribers); hi; hi = switch_core_hash_next(&hi)) { - const void *key; - void *val; - struct rayo_mixer_subscriber *subscriber; - switch_core_hash_this(hi, &key, NULL, &val); - subscriber = (struct rayo_mixer_subscriber *)val; - switch_assert(subscriber); - iks_insert_attrib(rayo_event, "to", subscriber->jid); - RAYO_SEND_MESSAGE_DUP(mixer, subscriber->jid, rayo_event); - } - switch_mutex_unlock(RAYO_ACTOR(mixer)->mutex); -} - -/** - * Handle mixer delete member event - */ -static void on_mixer_delete_member_event(struct rayo_mixer *mixer, switch_event_t *event) -{ - iks *delete_member_event, *x; - const char *uuid = switch_event_get_header(event, "Unique-ID"); - struct rayo_call *call; - struct rayo_mixer_member *member; - struct rayo_mixer_subscriber *subscriber; - - /* not a rayo mixer */ - if (!mixer) { - return; - } - - /* remove member from mixer */ - switch_mutex_lock(RAYO_ACTOR(mixer)->mutex); - member = (struct rayo_mixer_member *)switch_core_hash_find(mixer->members, uuid); - if (!member) { - /* not a member */ - switch_mutex_unlock(RAYO_ACTOR(mixer)->mutex); - return; - } - switch_core_hash_delete(mixer->members, uuid); - switch_mutex_unlock(RAYO_ACTOR(mixer)->mutex); - - /* flag call as available to join another mixer */ - call = RAYO_CALL_LOCATE_BY_ID(uuid); - if (call) { - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - call->joined = 0; - call->joined_id = NULL; - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - RAYO_RELEASE(call); - } - - /* send mixer unjoined event to member DCP */ - delete_member_event = iks_new_presence("unjoined", RAYO_NS, member->jid, member->dcp_jid); - x = iks_find(delete_member_event, "unjoined"); - iks_insert_attrib(x, "mixer-name", rayo_mixer_get_name(mixer)); - RAYO_SEND_MESSAGE(mixer, member->dcp_jid, delete_member_event); - - /* broadcast member unjoined event to subscribers */ - delete_member_event = iks_new_presence("unjoined", RAYO_NS, RAYO_JID(mixer), ""); - x = iks_find(delete_member_event, "unjoined"); - iks_insert_attrib_printf(x, "call-uri", "xmpp:%s@%s", uuid, RAYO_JID(globals.server)); - broadcast_mixer_event(mixer, delete_member_event); - iks_delete(delete_member_event); - - /* remove member DCP as subscriber to mixer */ - switch_mutex_lock(RAYO_ACTOR(mixer)->mutex); - subscriber = (struct rayo_mixer_subscriber *)switch_core_hash_find(mixer->subscribers, member->dcp_jid); - if (subscriber) { - subscriber->ref_count--; - if (subscriber->ref_count <= 0) { - switch_core_hash_delete(mixer->subscribers, member->dcp_jid); - } - } - switch_mutex_unlock(RAYO_ACTOR(mixer)->mutex); -} - -/** - * Handle mixer destroy event - */ -static void on_mixer_destroy_event(struct rayo_mixer *mixer, switch_event_t *event) -{ - if (mixer) { - iks *presence; - - /* notify online clients of mixer destruction */ - presence = iks_new("presence"); - iks_insert_attrib(presence, "from", RAYO_JID(mixer)); - iks_insert_attrib(presence, "type", "unavailable"); - broadcast_event(RAYO_ACTOR(mixer), presence, 1); - iks_delete(presence); - - /* remove from hash and destroy */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, destroying mixer: %s\n", RAYO_JID(mixer), rayo_mixer_get_name(mixer)); - RAYO_RELEASE(mixer); /* release original lock */ - RAYO_DESTROY(mixer); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "destroy: NULL mixer\n"); - } -} - -/** - * Handle mixer add member event - */ -static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t *event) -{ - iks *add_member_event = NULL, *x; - const char *uuid = switch_event_get_header(event, "Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(uuid); - struct rayo_mixer *lmixer = NULL; - - if (!mixer) { - char *ver; - iks *presence, *c; - - /* new mixer */ - const char *mixer_name = switch_event_get_header(event, "Conference-Name"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "creating mixer: %s\n", mixer_name); - mixer = rayo_mixer_create(mixer_name); - if (mixer) { - /* notify online clients of mixer presence */ - ver = calculate_entity_sha1_ver(&rayo_mixer_identity, rayo_mixer_features); - - presence = iks_new_presence("c", IKS_NS_XMPP_ENTITY_CAPABILITIES, RAYO_JID(mixer), ""); - c = iks_find(presence, "c"); - iks_insert_attrib(c, "hash", "sha-1"); - iks_insert_attrib(c, "node", RAYO_MIXER_NS); - iks_insert_attrib(c, "ver", ver); - free(ver); - - broadcast_event(RAYO_ACTOR(mixer), presence, 1); - } else { - /* must have lost the race to another add member event... there should be a mixer with mixer_name already */ - mixer = lmixer = RAYO_MIXER_LOCATE(mixer_name); - if (!mixer) { - /* this is unexpected */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to find mixer: %s\n", mixer_name); - return; - } - } - } - - if (call) { - struct rayo_mixer_member *member = NULL; - /* add member DCP as subscriber to mixer */ - struct rayo_mixer_subscriber *subscriber; - switch_mutex_lock(RAYO_ACTOR(mixer)->mutex); - subscriber = (struct rayo_mixer_subscriber *)switch_core_hash_find(mixer->subscribers, call->dcp_jid); - if (!subscriber) { - subscriber = switch_core_alloc(RAYO_POOL(mixer), sizeof(*subscriber)); - subscriber->ref_count = 0; - subscriber->jid = switch_core_strdup(RAYO_POOL(mixer), call->dcp_jid); - switch_core_hash_insert(mixer->subscribers, call->dcp_jid, subscriber); - } - subscriber->ref_count++; - - /* add call as member of mixer */ - member = switch_core_alloc(RAYO_POOL(mixer), sizeof(*member)); - member->jid = switch_core_strdup(RAYO_POOL(mixer), RAYO_JID(call)); - member->dcp_jid = subscriber->jid; - switch_core_hash_insert(mixer->members, uuid, member); - - switch_mutex_unlock(RAYO_ACTOR(mixer)->mutex); - - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - call->joined = JOINED_MIXER; - call->joined_id = switch_core_strdup(RAYO_POOL(call), rayo_mixer_get_name(mixer)); - - /* send IQ result to client now. */ - if (call->pending_join_request) { - iks *request = call->pending_join_request; - iks *result = iks_new_iq_result(request); - iks *ref = iks_insert(result, "ref"); - iks_insert_attrib(ref, "xmlns", RAYO_NS); - iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(mixer)); - call->pending_join_request = NULL; - RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); - iks_delete(request); - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - - /* send mixer joined event to member DCP */ - add_member_event = iks_new_presence("joined", RAYO_NS, RAYO_JID(call), call->dcp_jid); - x = iks_find(add_member_event, "joined"); - iks_insert_attrib(x, "mixer-name", rayo_mixer_get_name(mixer)); - RAYO_SEND_MESSAGE(call, call->dcp_jid, add_member_event); - - RAYO_RELEASE(call); - } - - /* broadcast member joined event to subscribers */ - add_member_event = iks_new_presence("joined", RAYO_NS, RAYO_JID(mixer), ""); - x = iks_find(add_member_event, "joined"); - iks_insert_attrib_printf(x, "call-uri", "xmpp:%s@%s", uuid, RAYO_JID(globals.server)); - broadcast_mixer_event(mixer, add_member_event); - iks_delete(add_member_event); - - if (lmixer) { - RAYO_RELEASE(lmixer); - } -} - -/** - * Receives mixer events from FreeSWITCH core and routes them to the proper Rayo client(s). - * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. - */ -static void route_mixer_event(switch_event_t *event) -{ - const char *action = switch_event_get_header(event, "Action"); - const char *profile = switch_event_get_header(event, "Conference-Profile-Name"); - const char *mixer_name = switch_event_get_header(event, "Conference-Name"); - struct rayo_mixer *mixer = NULL; - - if (strcmp(profile, globals.mixer_conf_profile)) { - /* don't care about other conferences */ - goto done; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "looking for mixer: %s\n", mixer_name); - mixer = RAYO_MIXER_LOCATE(mixer_name); - - if (!strcmp("add-member", action)) { - on_mixer_add_member_event(mixer, event); - } else if (!strcmp("conference-destroy", action)) { - on_mixer_destroy_event(mixer, event); - } else if (!strcmp("del-member", action)) { - on_mixer_delete_member_event(mixer, event); - } - /* TODO speaking events */ - -done: - RAYO_RELEASE(mixer); -} - -/** - * Handle call originate event - create rayo call and send to client. - * @param rclient The Rayo client - * @param event the originate event - */ -static void on_call_originate_event(struct rayo_client *rclient, switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(uuid); - - if (call) { - iks *response, *ref; - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Got originate event\n"); - - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - if (!zstr(call->dial_request_id)) { - /* send response to DCP */ - response = iks_new("iq"); - iks_insert_attrib(response, "from", RAYO_JID(globals.server)); - iks_insert_attrib(response, "to", rayo_call_get_dcp_jid(call)); - iks_insert_attrib(response, "id", call->dial_request_id); - iks_insert_attrib(response, "type", "result"); - ref = iks_insert(response, "ref"); - iks_insert_attrib(ref, "xmlns", RAYO_NS); - - iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call)); - RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), response); - call->dial_request_id = NULL; - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - } - RAYO_RELEASE(call); -} - -/** - * Handle call end event - * @param event the hangup event - */ -static void on_call_end_event(switch_event_t *event) -{ - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); - - if (call) { -#if 0 - char *event_str; - if (switch_event_serialize(event, &event_str, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_DEBUG, "%s\n", event_str); - switch_safe_free(event_str); - } -#endif - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Got channel destroy event\n"); - - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - if (zstr(call->dial_request_id) && !call->dial_request_failed) { - switch_event_dup(&call->end_event, event); - RAYO_DESTROY(call); - RAYO_RELEASE(call); /* decrement ref from creation */ - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - RAYO_RELEASE(call); /* decrement this ref */ - } -} - -/** - * Handle call answer event - * @param rclient the Rayo client - * @param event the answer event - */ -static void on_call_answer_event(struct rayo_client *rclient, switch_event_t *event) -{ - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); - if (call) { - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - if (call->rayo_app_started) { - iks *revent = iks_new_presence("answered", RAYO_NS, - switch_event_get_header(event, "variable_rayo_call_jid"), - switch_event_get_header(event, "variable_rayo_dcp_jid")); - add_headers_to_event(iks_find(revent, "answered"), event, globals.add_variables_to_events); - RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); - } else if (!call->answer_event) { - /* delay sending this event until the rayo APP has started */ - switch_event_dup(&call->answer_event, event); - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - RAYO_RELEASE(call); - } -} - -/** - * Handle call ringing event - * @param rclient the Rayo client - * @param event the ringing event - */ -static void on_call_ringing_event(struct rayo_client *rclient, switch_event_t *event) -{ - const char *call_direction = switch_event_get_header(event, "Call-Direction"); - if (call_direction && !strcmp(call_direction, "outbound")) { - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); - if (call) { - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - if (!call->ringing_sent) { - iks *revent = iks_new_presence("ringing", RAYO_NS, - switch_event_get_header(event, "variable_rayo_call_jid"), - switch_event_get_header(event, "variable_rayo_dcp_jid")); - add_headers_to_event(iks_find(revent, "ringing"), event, globals.add_variables_to_events); - call->ringing_sent = 1; - RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - RAYO_RELEASE(call); - } - } -} - -/** - * Handle call bridge event - * @param rclient the Rayo client - * @param event the bridge event - */ -static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *event) -{ - const char *a_uuid = switch_event_get_header(event, "Unique-ID"); - const char *b_uuid = switch_event_get_header(event, "Bridge-B-Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(a_uuid); - struct rayo_call *b_call; - - if (call) { - iks *revent; - iks *joined; - - call->joined = JOINED_CALL; - call->joined_id = switch_core_sprintf(RAYO_POOL(call), "xmpp:%s@%s", b_uuid, RAYO_JID(globals.server)); - - /* send IQ result to client now. */ - if (call->pending_join_request) { - iks *request = call->pending_join_request; - iks *result = iks_new_iq_result(request); - call->pending_join_request = NULL; - RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); - iks_delete(request); - } - - b_call = RAYO_CALL_LOCATE_BY_ID(b_uuid); - if (b_call) { - b_call->joined = JOINED_CALL; - b_call->joined_id = switch_core_sprintf(RAYO_POOL(b_call), "xmpp:%s@%s", a_uuid, RAYO_JID(globals.server)); - - /* send IQ result to client now. */ - if (b_call->pending_join_request) { - iks *request = b_call->pending_join_request; - iks *result = iks_new_iq_result(request); - b_call->pending_join_request = NULL; - RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); - iks_delete(request); - } - - /* send B-leg event */ - revent = iks_new_presence("joined", RAYO_NS, RAYO_JID(b_call), rayo_call_get_dcp_jid(b_call)); - joined = iks_find(revent, "joined"); - iks_insert_attrib_printf(joined, "call-uri", "%s", b_call->joined_id); - - RAYO_SEND_MESSAGE(b_call, rayo_call_get_dcp_jid(b_call), revent); - RAYO_RELEASE(b_call); - } - - /* send A-leg event */ - revent = iks_new_presence("joined", RAYO_NS, - switch_event_get_header(event, "variable_rayo_call_jid"), - switch_event_get_header(event, "variable_rayo_dcp_jid")); - joined = iks_find(revent, "joined"); - iks_insert_attrib_printf(joined, "call-uri", "%s", call->joined_id); - - RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); - - RAYO_RELEASE(call); - } -} - -/** - * Handle call park event - this is fired after unjoining a call - * @param rclient the Rayo client - * @param event the unbridge event - */ -static void on_call_park_event(struct rayo_client *rclient, switch_event_t *event) -{ - const char *a_uuid = switch_event_get_header(event, "Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(a_uuid); - - if (call) { - if (call->joined) { - iks *revent; - iks *unjoined; - const char *joined_id = call->joined_id; - - call->joined = 0; - call->joined_id = NULL; - - /* send IQ result to client now. */ - if (call->pending_join_request) { - iks *request = call->pending_join_request; - iks *result = iks_new_iq_result(request); - call->pending_join_request = NULL; - RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); - iks_delete(request); - } - - /* send A-leg event */ - revent = iks_new_presence("unjoined", RAYO_NS, - switch_event_get_header(event, "variable_rayo_call_jid"), - switch_event_get_header(event, "variable_rayo_dcp_jid")); - unjoined = iks_find(revent, "unjoined"); - iks_insert_attrib_printf(unjoined, "call-uri", "%s", joined_id); - RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); - } - RAYO_RELEASE(call); - } -} - -/** - * Handle call execute application event - * @param rclient the Rayo client - * @param event the execute event - */ -static void on_call_execute_event(struct rayo_client *rclient, switch_event_t *event) -{ - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); - if (call) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Application %s execute\n", switch_event_get_header(event, "Application")); - RAYO_RELEASE(call); - } -} - -/** - * Handle call execute application complete event - * @param rclient the Rayo client - * @param event the execute complete event - */ -static void on_call_execute_complete_event(struct rayo_client *rclient, switch_event_t *event) -{ - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); - if (call) { - const char *app = switch_event_get_header(event, "Application"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Application %s execute complete: %s \n", - app, - switch_event_get_header(event, "Application-Response")); - RAYO_RELEASE(call); - } -} - -/** - * Handle events to deliver to client connection - * @param rclient the Rayo client connection to receive the event - * @param event the event. - */ -static void rayo_client_handle_event(struct rayo_client *rclient, switch_event_t *event) -{ - if (event) { - switch (event->event_id) { - case SWITCH_EVENT_CHANNEL_ORIGINATE: - on_call_originate_event(rclient, event); - break; - case SWITCH_EVENT_CHANNEL_PROGRESS: - case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA: - on_call_ringing_event(rclient, event); - break; - case SWITCH_EVENT_CHANNEL_ANSWER: - on_call_answer_event(rclient, event); - break; - case SWITCH_EVENT_CHANNEL_BRIDGE: - on_call_bridge_event(rclient, event); - break; - case SWITCH_EVENT_CHANNEL_PARK: - on_call_park_event(rclient, event); - break; - case SWITCH_EVENT_CHANNEL_EXECUTE: - on_call_execute_event(rclient, event); - break; - case SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE: - on_call_execute_complete_event(rclient, event); - break; - default: - /* don't care */ - break; - } - } -} - -/** - * Receives events from FreeSWITCH core and routes them to the proper Rayo client. - * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. - */ -static void route_call_event(switch_event_t *event) -{ - char *uuid = switch_event_get_header(event, "unique-id"); - char *dcp_jid = switch_event_get_header(event, "variable_rayo_dcp_jid"); - char *event_subclass = switch_event_get_header(event, "Event-Subclass"); - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "got event %s %s\n", switch_event_name(event->event_id), zstr(event_subclass) ? "" : event_subclass); - - /* this event is for a rayo client */ - if (!zstr(dcp_jid)) { - struct rayo_actor *actor; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "%s rayo event %s\n", dcp_jid, switch_event_name(event->event_id)); - - actor = RAYO_LOCATE(dcp_jid); - if (actor && !strcmp(RAT_CLIENT, actor->type)) { - /* route to client */ - rayo_client_handle_event(RAYO_CLIENT(actor), event); - } else { - /* TODO orphaned call... maybe allow events to queue so they can be delivered on reconnect? */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Orphaned call event %s to %s\n", switch_event_name(event->event_id), dcp_jid); - } - RAYO_RELEASE(actor); - } -} - -/** - * Create server. - * @param domain the domain name - * @return the domain - */ -static struct rayo_actor *rayo_server_create(const char *domain) -{ - switch_memory_pool_t *pool; - struct rayo_actor *new_server = NULL; - - switch_core_new_memory_pool(&pool); - new_server = switch_core_alloc(pool, sizeof(*new_server)); - RAYO_ACTOR_INIT(RAYO_ACTOR(new_server), pool, RAT_SERVER, "", domain, domain, NULL, rayo_server_send); - - return new_server; -} - -/** - * Create an offer for a call - * @param call the call - * @param session the session - * @return the offer - */ -static iks *rayo_create_offer(struct rayo_call *call, switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); - iks *presence = iks_new("presence"); - iks *c = iks_insert(presence, "c"); - iks *offer = iks_insert(presence, "offer"); - const char *val; - char *ver; - - /* */ - iks_insert_attrib(presence, "from", RAYO_JID(call)); - - /* */ - ver = calculate_entity_sha1_ver(&rayo_call_identity, rayo_call_features); - iks_insert_attrib(c, "xmlns", IKS_NS_XMPP_ENTITY_CAPABILITIES); - iks_insert_attrib(c, "hash", "sha-1"); - iks_insert_attrib(c, "node", RAYO_CALL_NS); - iks_insert_attrib(c, "ver", ver); - free(ver); - - /* */ - iks_insert_attrib(offer, "xmlns", RAYO_NS); - if (globals.offer_uri && (val = switch_channel_get_variable(channel, "sip_from_uri"))) { - /* is a SIP call - pass the URI */ - if (!strchr(val, ':')) { - iks_insert_attrib_printf(offer, "from", "sip:%s", val); - } else { - iks_insert_attrib(offer, "from", val); - } - } else { - /* pass caller ID */ - iks_insert_attrib(offer, "from", profile->caller_id_number); - } - - if (globals.offer_uri && (val = switch_channel_get_variable(channel, "sip_to_uri"))) { - /* is a SIP call - pass the URI */ - if (!strchr(val, ':')) { - iks_insert_attrib_printf(offer, "to", "sip:%s", val); - } else { - iks_insert_attrib(offer, "to", val); - } - } else { - /* pass dialed number */ - iks_insert_attrib(offer, "to", profile->destination_number); - } - - add_header(offer, "from", switch_channel_get_variable(channel, "sip_full_from")); - add_header(offer, "to", switch_channel_get_variable(channel, "sip_full_to")); - add_header(offer, "via", switch_channel_get_variable(channel, "sip_full_via")); - add_channel_headers_to_event(offer, channel, globals.add_variables_to_offer); - - return presence; -} - -/** - * Monitor rayo call activity - detect idle - */ -static switch_status_t rayo_call_on_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int i) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - struct rayo_call *call = (struct rayo_call *)switch_channel_get_private(channel, "rayo_call_private"); - if (call) { - switch_time_t now = switch_micro_time_now(); - switch_time_t idle_start = call->idle_start_time; - int idle_duration_ms = (now - idle_start) / 1000; - /* detect idle session (rayo-client has stopped controlling call) and terminate call */ - if (rayo_call_is_joined(call) || rayo_call_is_faxing(call) || RAYO_ACTOR(call)->ref_count > 1) { - call->idle_start_time = now; - } else if (idle_duration_ms > globals.max_idle_ms) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ending abandoned call. idle_duration_ms = %i ms\n", idle_duration_ms); - switch_channel_hangup(channel, RAYO_CAUSE_HANGUP); - } - } - return SWITCH_STATUS_SUCCESS; -} - -/** - * @param rclient to check - * @param offer_filters optional list of username or username@server to match with client JID. - * @param offer_filter_count - * @return 1 if client is online and optional filter(s) match the client. 0 otherwise. - */ -static int should_offer_to_client(struct rayo_client *rclient, char **offer_filters, int offer_filter_count) -{ - if (rclient->availability != PS_ONLINE) { - return 0; - } - - if (offer_filter_count == 0) { - /* online and no filters to match */ - return 1; - } else { - /* check if one of the filters matches the client */ - int i; - const char *client_jid = RAYO_JID(rclient); - size_t client_jid_len = strlen(client_jid); - for (i = 0; i < offer_filter_count; i++) { - char *offer_filter = offer_filters[i]; - if (!zstr(offer_filter)) { - size_t offer_filter_len = strlen(offer_filter); - if (strchr(offer_filter, '@')) { - if (offer_filter_len <= client_jid_len && !strncmp(offer_filter, client_jid, offer_filter_len)) { - /* username + server match */ - return 1; - } - } else if (offer_filter_len < client_jid_len && !strncmp(offer_filter, client_jid, offer_filter_len) && client_jid[offer_filter_len] == '@') { - /* username match */ - return 1; - } - } - } - } - return 0; -} - -/** - * Offered call information - */ -struct offered_call_info { - /** Call JID */ - char *call_jid; - /** Time this offer expires */ - switch_time_t offer_time; -}; - -/** - * Deliver offer message to next available client(s) - */ -static int send_offer_to_clients(struct rayo_call *from_call, switch_core_session_t *session) -{ - int i = 0; - int selection = 0; - int sent = 0; - switch_hash_index_t *hi = NULL; - iks *offer = NULL; - - if (from_call->num_acps <= 0) { - return 0; - } - - if (globals.offer_algorithm == OFFER_RANDOM) { - /* pick client at (not really) random */ - selection = rand() % from_call->num_acps; - } else if (globals.offer_algorithm == OFFER_FIRST) { - /* send to first client */ - selection = 0; - } else { - /* send to all clients */ - selection = -1; - } - - for (hi = switch_core_hash_first(from_call->acps); hi; hi = switch_core_hash_next(&hi)) { - if (i++ == selection || selection == -1) { - const char *to_client_jid = NULL; - const void *key; - void *val; - - /* get client jid to send to */ - switch_core_hash_this(hi, &key, NULL, &val); - to_client_jid = (const char *)key; - switch_assert(to_client_jid); - - /* send offer to client, remembering jid as PCP */ - if (!offer) { - offer = rayo_create_offer(from_call, session); - } - switch_core_hash_insert(from_call->pcps, to_client_jid, "1"); - iks_insert_attrib(offer, "to", to_client_jid); - RAYO_SEND_MESSAGE_DUP(from_call, to_client_jid, offer); - - sent = 1; - from_call->num_acps--; - - if (selection != -1) { - break; - } - } - } - switch_safe_free(hi); - - if (sent) { - /* remove offered client JID(s) from list of available clients */ - hi = NULL; - for (hi = switch_core_hash_first(from_call->pcps); hi; hi = switch_core_hash_next(&hi)) { - const char *to_client_jid = NULL; - const void *key; - void *val; - - /* get client jid that was sent offer */ - switch_core_hash_this(hi, &key, NULL, &val); - to_client_jid = (const char *)key; - switch_assert(to_client_jid); - - /* remove client jid from available controlling parties */ - switch_core_hash_delete(from_call->acps, to_client_jid); - } - switch_safe_free(hi); - - /* remember when offer was sent for this call to track timeouts */ - if (globals.offer_timeout_us > 0) { - struct offered_call_info *offered_call; - switch_zmalloc(offered_call, sizeof(*offered_call)); - offered_call->offer_time = switch_micro_time_now(); - offered_call->call_jid = strdup(RAYO_JID(from_call)); - if (switch_queue_trypush(globals.offer_queue, offered_call) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to queue offered call info! Offer timeout won't work on this call\n"); - switch_safe_free(offered_call->call_jid); - switch_safe_free(offered_call); - } - } - } - - if (offer) { - iks_delete(offer); - } - - return sent; -} - -/** - * Thread that monitors for timed out offers - * @param thread this thread - * @param obj unused - * @return NULL - */ -static void *SWITCH_THREAD_FUNC offer_timeout_thread(switch_thread_t *thread, void *obj) -{ - struct offered_call_info *next_offer; - switch_thread_rwlock_rdlock(globals.shutdown_rwlock); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "New offer timeout thread\n"); - while (!globals.shutdown) { - if (switch_queue_pop(globals.offer_queue, (void *)&next_offer) == SWITCH_STATUS_SUCCESS) { - switch_time_t now = switch_micro_time_now(); - switch_time_t offer_timeout = next_offer->offer_time + globals.offer_timeout_us; - - /* wait for timeout */ - while (offer_timeout > now && !globals.shutdown) { - switch_time_t remain = offer_timeout - now; - remain = remain > 500000 ? 500000 : remain; - switch_sleep(remain); - now = switch_micro_time_now(); - } - - /* check if offer was accepted - it is accepted if the call has a DCP (definitive controlling party) */ - if (!globals.shutdown) { - struct rayo_call *call = RAYO_CALL_LOCATE(next_offer->call_jid); - if (call) { - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - if (zstr(rayo_call_get_dcp_jid(call))) { - switch_core_session_t *session = switch_core_session_locate(rayo_call_get_uuid(call)); - if (session) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, offer timeout\n", RAYO_JID(call)); - if (!send_offer_to_clients(call, session)) { - /* nobody to offer to, end call */ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no more clients to offer, ending call\n", RAYO_JID(call)); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE); - } - switch_core_session_rwunlock(session); - } - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - RAYO_RELEASE(call); - } - } - - switch_safe_free(next_offer->call_jid); - switch_safe_free(next_offer); - } - } - - /* clean up queue */ - while(switch_queue_trypop(globals.offer_queue, (void *)&next_offer) == SWITCH_STATUS_SUCCESS) { - switch_safe_free(next_offer->call_jid); - switch_safe_free(next_offer); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Offer timeout thread finished\n"); - switch_thread_rwlock_unlock(globals.shutdown_rwlock); - - return NULL; -} - -/** - * Create a new offer timeout thread - * @param pool to use - */ -static void start_offer_timeout_thread(switch_memory_pool_t *pool) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, offer_timeout_thread, NULL, pool); -} - -#define RAYO_USAGE "[client username 1,client username n]" -/** - * Offer call and park channel - */ -SWITCH_STANDARD_APP(rayo_app) -{ - int ok = 0; - switch_channel_t *channel = switch_core_session_get_channel(session); - struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_core_session_get_uuid(session)); - const char *app = ""; /* optional app to execute */ - const char *app_args = ""; /* app args */ - - /* don't need to keep call reference count incremented in session- call is destroyed after all apps finish */ - if (call) { - RAYO_RELEASE(call); - } - - /* is outbound call already under control? */ - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - const char *origination_args = switch_channel_get_variable(channel, "rayo_origination_args"); - /* check origination args */ - if (!zstr(origination_args)) { - char *argv[2] = { 0 }; - char *args = switch_core_session_strdup(session, origination_args); - int argc = switch_separate_string(args, ' ', argv, sizeof(argv) / sizeof(argv[0])); - if (argc) { - if (!strcmp("conference", argv[0])) { - app = "conference"; - app_args = argv[1]; - } else if (!strcmp("bridge", argv[0])) { - app = "intercept"; - app_args = argv[1]; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Invalid rayo args: %s\n", data); - goto done; - } - } - } - if (!call) { - /* this scenario can only happen if a call was originated through a mechanism other than - and then the rayo APP was executed to offer control */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Outbound call that wasn't created with , will try to offer control\n"); - } - ok = 1; - } - - if (!call) { - /* offer control */ - switch_hash_index_t *hi = NULL; - char *clients_to_offer[16] = { 0 }; - int clients_to_offer_count = 0; - - call = rayo_call_create(switch_core_session_get_uuid(session)); - if (!call) { - /* nothing that can be done to recover... */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to create call entity!\n"); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE); - return; - } - - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_call_jid", RAYO_JID(call)); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Offering call for Rayo 3PCC\n"); - - if (!zstr(data)) { - char *data_dup = switch_core_session_strdup(session, data); - clients_to_offer_count = switch_separate_string(data_dup, ',', clients_to_offer, sizeof(clients_to_offer) / sizeof(clients_to_offer[0])); - } - - /* It is now safe for inbound call to be fully controlled by rayo client */ - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - call->rayo_app_started = 1; - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - } - - /* Offer call to all (or specified) ONLINE clients */ - switch_mutex_lock(globals.clients_mutex); - for (hi = switch_core_hash_first(globals.clients_roster); hi; hi = switch_core_hash_next(&hi)) { - struct rayo_client *rclient; - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - rclient = (struct rayo_client *)val; - switch_assert(rclient); - - /* find clients available to take calls */ - if (should_offer_to_client(rclient, clients_to_offer, clients_to_offer_count)) { - switch_core_hash_insert(call->acps, RAYO_JID(rclient), "1"); - call->num_acps++; - } - } - ok = send_offer_to_clients(call, session); - - switch_mutex_unlock(globals.clients_mutex); - - /* nobody to offer to */ - if (!ok) { - pause_when_offline(); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Rejecting rayo call - there are no online rayo clients to offer call to\n"); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE); - } - } - -done: - - if (ok) { - switch_channel_set_private(switch_core_session_get_channel(session), "rayo_call_private", call); - switch_channel_set_variable(channel, "hangup_after_bridge", "false"); - switch_channel_set_variable(channel, "transfer_after_bridge", ""); - switch_channel_set_variable(channel, "park_after_bridge", "true"); - switch_channel_set_variable(channel, "hold_hangup_xfer_exten", "park:inline:"); - switch_channel_set_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE, "-1"); /* required so that output mixing works */ - switch_core_event_hook_add_read_frame(session, rayo_call_on_read_frame); - - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - /* At this point, this outbound call might already be under control of a rayo client that is waiting for answer before sending - commands. The answered event might have been sent before we are ready to execute commands, so we delayed sending - those events if the rayo APP hadn't started yet. This delay would have only been a few milliseconds. - */ - switch_mutex_lock(RAYO_ACTOR(call)->mutex); - call->rayo_app_started = 1; - if (call->answer_event) { - struct rayo_client *rclient = RAYO_CLIENT(RAYO_LOCATE(rayo_call_get_dcp_jid(call))); - if (rclient) { - on_call_answer_event(rclient, call->answer_event); - switch_event_destroy(&call->answer_event); - RAYO_RELEASE(rclient); - } - } - switch_mutex_unlock(RAYO_ACTOR(call)->mutex); - - /* Outbound calls might have a nested join to another call or conference - do that now */ - if (!zstr(app)) { - switch_core_session_execute_application(session, app, app_args); - } - } - - /* Ready for remote control */ - switch_ivr_park(session, NULL); - } -} - -/** - * Stream locates client - */ -static struct rayo_actor *xmpp_stream_client_locate(struct xmpp_stream *stream, const char *jid) -{ - struct rayo_actor *actor = NULL; - if (xmpp_stream_is_s2s(stream)) { - actor = RAYO_LOCATE(jid); - if (!actor) { - /* previously unknown client - add it */ - struct rayo_peer_server *rserver = RAYO_PEER_SERVER(xmpp_stream_get_private(stream)); - actor = RAYO_ACTOR(rayo_client_create(jid, xmpp_stream_get_jid(stream), PS_UNKNOWN, rayo_client_send, rserver)); - RAYO_RETAIN(actor); - } else if (strcmp(RAT_CLIENT, actor->type)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, not a client: %s\n", xmpp_stream_get_jid(stream), jid); - RAYO_RELEASE(actor); - actor = NULL; - } - } else { - actor = RAYO_ACTOR(xmpp_stream_get_private(stream)); - RAYO_RETAIN(actor); - } - return actor; -} - -/** - * Handle stream resource binding - * @param stream the new stream - */ -static int on_xmpp_stream_bind(struct xmpp_stream *stream) -{ - if (!xmpp_stream_is_s2s(stream)) { - /* client belongs to stream */ - struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL); - if (client) { - xmpp_stream_set_private(stream, client); - } else { - /* this went really bad... */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n"); - return 0; - } - } - return 1; -} - -/** - * Handle new stream creation - * @param stream the new stream - */ -static int on_xmpp_stream_ready(struct xmpp_stream *stream) -{ - if (xmpp_stream_is_s2s(stream)) { - if (xmpp_stream_is_incoming(stream)) { - /* peer server belongs to a s2s inbound stream */ - struct rayo_peer_server *peer = rayo_peer_server_create(xmpp_stream_get_jid(stream)); - if (peer) { - xmpp_stream_set_private(stream, peer); - } else { - /* this went really bad... */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create peer server entity!\n"); - return 0; - } - } else { - /* send directed presence to domain */ - iks *presence = iks_new("presence"); - iks *x; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "sending server presence\n"); - - iks_insert_attrib(presence, "from", RAYO_JID(globals.server)); - iks_insert_attrib(presence, "to", xmpp_stream_get_jid(stream)); - x = iks_insert(presence, "show"); - iks_insert_cdata(x, "chat", 4); - RAYO_SEND_MESSAGE(globals.server, xmpp_stream_get_jid(stream), presence); - } - } - return 1; -} - -/** - * Checks client availability. If unknown, client presence is probed. - * @param rclient to check - */ -static void rayo_client_presence_check(struct rayo_client *rclient) -{ - if (rclient->availability == PS_UNKNOWN) { - /* for now, set online */ - rclient->availability = PS_ONLINE; - } -} - -/** - * Handle stream stanza - * @param stream the stream - * @param stanza the stanza to process - */ -static void on_xmpp_stream_recv(struct xmpp_stream *stream, iks *stanza) -{ - const char *name = iks_name(stanza); - if (!strcmp("iq", name)) { - const char *from = iks_find_attrib_soft(stanza, "from"); - struct rayo_actor *actor = xmpp_stream_client_locate(stream, from); - if (actor) { - rayo_client_presence_check(RAYO_CLIENT(actor)); - rayo_client_command_recv(RAYO_CLIENT(actor), stanza); - RAYO_RELEASE(actor); - } - } else if (!strcmp("presence", name)) { - const char *from = iks_find_attrib_soft(stanza, "from"); - struct rayo_actor *actor = xmpp_stream_client_locate(stream, from); - if (actor) { - on_client_presence(RAYO_CLIENT(actor), stanza); - RAYO_RELEASE(actor); - } - } else if (!strcmp("message", name)) { - const char *from = iks_find_attrib_soft(stanza, "from"); - struct rayo_actor *actor = xmpp_stream_client_locate(stream, from); - if (actor) { - rayo_client_presence_check(RAYO_CLIENT(actor)); - on_client_message(RAYO_CLIENT(actor), stanza); - RAYO_RELEASE(actor); - } - } -} - -/** - * Handle stream destruction - */ -static void on_xmpp_stream_destroy(struct xmpp_stream *stream) -{ - /* destroy peer server / client associated with this stream */ - void *actor = xmpp_stream_get_private(stream); - if (actor) { - RAYO_RELEASE(actor); - RAYO_DESTROY(actor); - } -} - -/** - * A command alias - */ -struct rayo_cmd_alias { - /** number of additional arguments for alias */ - int args; - /** the alias template */ - const char *cmd; -}; - -/** - * Add an alias to an API command - * @param alias_name - * @param alias_target - * @param alias_cmd - * @param alias_args - */ -static void rayo_add_cmd_alias(const char *alias_name, const char *alias_target, const char *alias_cmd, const char *alias_args) -{ - struct rayo_cmd_alias *alias = switch_core_alloc(globals.pool, sizeof(*alias)); - alias->args = 0; - if (switch_is_number(alias_args)) { - alias->args = atoi(alias_args); - if (alias->args < 0) { - alias->args = 0; - } - } - alias->cmd = alias_cmd; - switch_core_hash_insert(globals.cmd_aliases, alias_name, alias); - - /* set up autocomplete of alias */ - if (zstr(alias_target)) { - alias_target = "all"; - } - switch_console_set_complete(switch_core_sprintf(globals.pool, "add rayo %s ::rayo::list_%s", alias_name, alias_target)); -} - -/** - * Process module XML configuration - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS on successful configuration - */ -static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) -{ - switch_xml_t cfg, xml; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Configuring module\n"); - if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); - return SWITCH_STATUS_TERM; - } - - /* set defaults */ - globals.max_idle_ms = 30000; - globals.mixer_conf_profile = "sla"; - globals.num_message_threads = 8; - globals.offer_uri = 1; - globals.pause_when_offline = 0; - globals.add_variables_to_offer = 0; - globals.add_variables_to_events = 0; - globals.offer_timeout_us = 5000000; - globals.offer_algorithm = OFFER_ALL; - - /* get params */ - { - switch_xml_t settings = switch_xml_child(cfg, "settings"); - if (settings) { - switch_xml_t param; - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); - if (!strcasecmp(var, "max-idle-sec")) { - if (switch_is_number(val)) { - int max_idle_sec = atoi(val); - if (max_idle_sec > 0) { - globals.max_idle_ms = max_idle_sec * 1000; - } - } - } else if (!strcasecmp(var, "mixer-conf-profile")) { - if (!zstr(val)) { - globals.mixer_conf_profile = switch_core_strdup(pool, val); - } - } else if (!strcasecmp(var, "message-threads")) { - if (switch_is_number(val)) { - int num_message_threads = atoi(val); - if (num_message_threads > 0) { - globals.num_message_threads = num_message_threads; - } - } - } else if (!strcasecmp(var, "offer-uri")) { - if (switch_false(val)) { - globals.offer_uri = 0; - } - } else if (!strcasecmp(var, "pause-when-offline")) { - if (switch_true(val)) { - globals.pause_when_offline = 1; - } - } else if (!strcasecmp(var, "add-variables-to-offer")) { - if (switch_true(val)) { - globals.add_variables_to_offer = 1; - } - } else if (!strcasecmp(var, "add-variables-to-events")) { - if (switch_true(val)) { - globals.add_variables_to_offer = 1; - globals.add_variables_to_events = 1; - } - } else if (!strcasecmp(var, "offer-timeout-ms")) { - int offer_timeout_ms = 0; - if (switch_is_number(val) && (offer_timeout_ms = atoi(val)) >= 0 && offer_timeout_ms < 120000) { - globals.offer_timeout_us = offer_timeout_ms * 1000; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring invalid value for offer-timeout-ms \"%s\"\n", val); - } - } else if (!strcasecmp(var, "offer-algorithm")) { - if (zstr(val)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No value for offer-algorithm\n"); - } else if (!strcasecmp(val, "all")) { - globals.offer_algorithm = OFFER_ALL; - } else if (!strcasecmp(val, "first")) { - globals.offer_algorithm = OFFER_FIRST; - } else if (!strcasecmp(val, "random")) { - globals.offer_algorithm = OFFER_RANDOM; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring invalid value for offer-algorithm \"%s\"\n", val); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); - } - } - } - } - - /* configure dial gateways */ - { - switch_xml_t dial_gateways = switch_xml_child(cfg, "dial-gateways"); - - /* set defaults */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting default dial-gateways\n"); - dial_gateway_add("default", "sofia/gateway/outbound/", 0); - dial_gateway_add("tel:", "sofia/gateway/outbound/", 4); - dial_gateway_add("user", "", 0); - dial_gateway_add("sofia", "", 0); - - if (dial_gateways) { - switch_xml_t dg; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting configured dial-gateways\n"); - for (dg = switch_xml_child(dial_gateways, "dial-gateway"); dg; dg = dg->next) { - const char *uri_prefix = switch_xml_attr_soft(dg, "uriprefix"); - const char *dial_prefix = switch_xml_attr_soft(dg, "dialprefix"); - const char *strip_str = switch_xml_attr_soft(dg, "strip"); - int strip = 0; - - if (!zstr(strip_str) && switch_is_number(strip_str)) { - strip = atoi(strip_str); - if (strip < 0) { - strip = 0; - } - } - if (!zstr(uri_prefix)) { - dial_gateway_add(uri_prefix, dial_prefix, strip); - } - } - } - } - - /* configure domain */ - { - switch_xml_t domain = switch_xml_child(cfg, "domain"); - if (domain) { - switch_xml_t l; - const char *shared_secret = switch_xml_attr_soft(domain, "shared-secret"); - const char *name = switch_xml_attr_soft(domain, "name"); - const char *cert = switch_xml_attr_soft(domain, "cert"); - const char *key = switch_xml_attr_soft(domain, "key"); - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing next) { - const char *user = switch_xml_attr_soft(u, "name"); - const char *password = switch_xml_attr_soft(u, "password"); - xmpp_stream_context_add_user(globals.xmpp_context, user, password); - } - } - - /* get listeners for this domain */ - for (l = switch_xml_child(domain, "listen"); l; l = l->next) { - const char *address = switch_xml_attr_soft(l, "address"); - const char *port = switch_xml_attr_soft(l, "port"); - const char *type = switch_xml_attr_soft(l, "type"); - const char *acl = switch_xml_attr_soft(l, "acl"); - int is_s2s = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s listener: %s:%s\n", type, address, port); - is_s2s = !strcmp("s2s", type); - if (!is_s2s && strcmp("c2s", type)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Type must be \"c2s\" or \"s2s\"!\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - if (zstr(address)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing address!\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - if (!zstr(port) && !switch_is_number(port)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Port must be an integer!\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - if (xmpp_stream_context_listen(globals.xmpp_context, address, atoi(port), is_s2s, acl) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to create %s listener: %s:%s\n", type, address, port); - } - } - - /* get outbound server connections */ - for (l = switch_xml_child(domain, "connect"); l; l = l->next) { - const char *domain = switch_xml_attr_soft(l, "domain"); - const char *address = switch_xml_attr_soft(l, "address"); - const char *port = switch_xml_attr_soft(l, "port"); - if (!zstr(port) && !switch_is_number(port)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Outbound server port must be an integer!\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - if (zstr(address) && zstr(domain)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing outbound server address!\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - xmpp_stream_context_connect(globals.xmpp_context, domain, address, atoi(port)); - } - } - } - - /* get aliases */ - { - switch_xml_t aliases = switch_xml_child(cfg, "aliases"); - if (aliases) { - switch_xml_t alias; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting configured aliases\n"); - for (alias = switch_xml_child(aliases, "alias"); alias; alias = alias->next) { - const char *alias_name = switch_xml_attr_soft(alias, "name"); - const char *alias_target = switch_xml_attr_soft(alias, "target"); - const char *alias_args = switch_xml_attr_soft(alias, "args"); - if (!zstr(alias_name) && !zstr(alias->txt)) { - rayo_add_cmd_alias(alias_name, switch_core_strdup(pool, alias_target), switch_core_strdup(pool, alias->txt), switch_core_strdup(pool, alias_args)); - } - } - } - } - -done: - switch_xml_free(xml); - - return status; -} - -/** - * Dump rayo actor stats - */ -static void rayo_actor_dump(struct rayo_actor *actor, switch_stream_handle_t *stream) -{ - if (!strcmp(RAT_CLIENT, actor->type)) { - stream->write_function(stream, "TYPE='%s',SUBTYPE='%s',ID='%s',JID='%s',DOMAIN='%s',REFS=%i,STATUS='%s'", actor->type, actor->subtype, actor->id, RAYO_JID(actor), RAYO_DOMAIN(actor), actor->ref_count, presence_status_to_string(RAYO_CLIENT(actor)->availability)); - } else { - stream->write_function(stream, "TYPE='%s',SUBTYPE='%s',ID='%s',JID='%s',DOMAIN='%s',REFS=%i", actor->type, actor->subtype, actor->id, RAYO_JID(actor), RAYO_DOMAIN(actor), actor->ref_count); - } -} - -/** - * Dump rayo actors - */ -static int dump_api(const char *cmd, switch_stream_handle_t *stream) -{ - switch_hash_index_t *hi; - if (!zstr(cmd)) { - return 0; - } - - stream->write_function(stream, "\nENTITIES\n"); - switch_mutex_lock(globals.actors_mutex); - for (hi = switch_core_hash_first(globals.actors); hi; hi = switch_core_hash_next(&hi)) { - struct rayo_actor *actor = NULL; - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - actor = (struct rayo_actor *)val; - switch_assert(actor); - stream->write_function(stream, " "); - rayo_actor_dump(actor, stream); - stream->write_function(stream, "\n"); - } - - for (hi = switch_core_hash_first(globals.destroy_actors); hi; hi = switch_core_hash_next(&hi)) { - struct rayo_actor *actor = NULL; - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - actor = (struct rayo_actor *)val; - switch_assert(actor); - stream->write_function(stream, "(DEAD) "); - rayo_actor_dump(actor, stream); - stream->write_function(stream, "\n"); - } - switch_mutex_unlock(globals.actors_mutex); - - xmpp_stream_context_dump(globals.xmpp_context, stream); - - return 1; -} - -/** - * Process response to console command_api - */ -void rayo_console_client_send(struct rayo_actor *actor, struct rayo_message *msg) -{ - iks *response = msg->payload; - - if (response) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nRECV: from %s, %s\n", msg->from_jid, iks_string(iks_stack(response), response)); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nRECV: (null) from %s\n", msg->from_jid); - } -} - -/** - * Create a new Rayo console client - * @return the new client or NULL - */ -static struct rayo_client *rayo_console_client_create(void) -{ - struct rayo_client *client = NULL; - char *jid = NULL; - char id[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - switch_uuid_str(id, sizeof(id)); - jid = switch_mprintf("%s@%s/console", id, RAYO_JID(globals.server)); - client = rayo_client_create(jid, NULL, PS_OFFLINE, rayo_console_client_send, NULL); - free(jid); - return client; -} - -/** - * Send command from console - */ -static void send_console_command(struct rayo_client *client, const char *to, const char *command_str) -{ - iks *command = NULL; - iksparser *p = iks_dom_new(&command); - - if (p && iks_parse(p, command_str, 0, 1) == IKS_OK && command) { - char *str; - iks *iq = NULL; - - /* is command already wrapped in IQ? */ - if (!strcmp(iks_name(command), "iq")) { - /* command already IQ */ - iq = command; - } else { - /* create IQ to wrap command */ - iq = iks_new_within("iq", iks_stack(command)); - iks_insert_node(iq, command); - } - - /* fill in command attribs */ - iks_insert_attrib(iq, "to", to); - if (!iks_find_attrib(iq, "type")) { - iks_insert_attrib(iq, "type", "set"); - } - - if (!iks_find_attrib(iq, "id")) { - iks_insert_attrib_printf(iq, "id", "console-%i", RAYO_SEQ_NEXT(client)); - } - - iks_insert_attrib(iq, "from", RAYO_JID(client)); - - /* send command */ - str = iks_string(iks_stack(iq), iq); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nSEND: to %s, %s\n", to, str); - rayo_client_command_recv(client, iq); - iks_delete(command); - iks_parser_delete(p); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "bad request xml\n"); - if (p) { - iks_parser_delete(p); - } - } -} - -/** - * Send command to rayo actor - */ -static int command_api(char *cmd, switch_stream_handle_t *stream) -{ - char *argv[2] = { 0 }; - if (!zstr(cmd)) { - int argc = switch_separate_string(cmd, ' ', argv, sizeof(argv) / sizeof(argv[0])); - if (argc != 2) { - return 0; - } - } else { - return 0; - } - - /* send command */ - send_console_command(globals.console, argv[0], argv[1]); - stream->write_function(stream, "+OK\n"); - - return 1; -} - -/** - * Send command to rayo actor - */ -static int alias_api(struct rayo_cmd_alias *alias, char *args, switch_stream_handle_t *stream) -{ - char *argv[10] = { 0 }; - int argc, i; - char *cmd; - char *jid; - - if (zstr(alias->cmd)) { - stream->write_function(stream, "-ERR missing alias template. Check configuration.\n"); - } - - if (zstr(args)) { - stream->write_function(stream, "-ERR no args\n"); - return 1; - } - - /* check args */ - argc = switch_separate_string(args, ' ', argv, sizeof(argv) / sizeof(argv[0])); - if (argc != alias->args + 1) { - stream->write_function(stream, "-ERR wrong number of args (%i/%i)\n", argc, alias->args + 1); - return 1; - } - - jid = argv[0]; - - /* build command from args */ - cmd = strdup(alias->cmd); - for (i = 1; i < argc; i++) { - char *cmd_new; - char to_replace[12] = { 0 }; - sprintf(to_replace, "$%i", i); - cmd_new = switch_string_replace(cmd, to_replace, argv[i]); - free(cmd); - cmd = cmd_new; - } - - /* send command */ - send_console_command(globals.console, jid, cmd); - stream->write_function(stream, "+OK\n"); - free(cmd); - - return 1; -} - -/** - * Send message from console - */ -static void send_console_message(struct rayo_client *client, const char *to, const char *type, const char *message_str) -{ - iks *message = NULL, *x; - message = iks_new("message"); - iks_insert_attrib(message, "to", to); - iks_insert_attrib(message, "from", RAYO_JID(client)); - iks_insert_attrib_printf(message, "id", "console-%i", RAYO_SEQ_NEXT(client)); - iks_insert_attrib(message, "type", type); - x = iks_insert(message, "body"); - iks_insert_cdata(x, message_str, strlen(message_str)); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nSEND: to %s, %s\n", to, iks_string(iks_stack(message), message)); - RAYO_SEND_MESSAGE(client, to, message); -} - -/** - * Send message to rayo actor - */ -static int message_api(char *cmd, switch_stream_handle_t *stream) -{ - char *argv[3] = { 0 }; - if (!zstr(cmd)) { - int argc = switch_separate_string(cmd, ' ', argv, sizeof(argv) / sizeof(argv[0])); - if (argc != 3) { - return 0; - } - } else { - return 0; - } - - /* send message */ - send_console_message(globals.console, argv[0], argv[1], argv[2]); - stream->write_function(stream, "+OK\n"); - - return 1; -} - -/** - * Send presence from console - */ -static void send_console_presence(struct rayo_client *client, const char *to, int is_online) -{ - iks *presence = NULL, *x; - presence = iks_new("presence"); - iks_insert_attrib(presence, "to", to); - iks_insert_attrib(presence, "from", RAYO_JID(client)); - iks_insert_attrib_printf(presence, "id", "console-%i", RAYO_SEQ_NEXT(client)); - if (!is_online) { - iks_insert_attrib(presence, "type", "unavailable"); - } - x = iks_insert(presence, "show"); - iks_insert_cdata(x, is_online ? "chat" : "dnd", 0); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nSEND: to %s, %s\n", to, iks_string(iks_stack(presence), presence)); - RAYO_SEND_MESSAGE(client, to, presence); -} - -/** - * Send console presence - */ -static int presence_api(char *cmd, switch_stream_handle_t *stream) -{ - int is_online = 0; - char *argv[2] = { 0 }; - if (!zstr(cmd)) { - int argc = switch_separate_string(cmd, ' ', argv, sizeof(argv) / sizeof(argv[0])); - if (argc != 2) { - return 0; - } - } else { - return 0; - } - - if (!strcmp("online", argv[1])) { - is_online = 1; - } else if (strcmp("offline", argv[1])) { - return 0; - } - - /* send presence */ - send_console_presence(globals.console, argv[0], is_online); - stream->write_function(stream, "+OK\n"); - return 1; -} - -#define RAYO_API_SYNTAX "status | ( ) | (cmd ) | (msg ) | (presence )" -SWITCH_STANDARD_API(rayo_api) -{ - struct rayo_cmd_alias *alias; - char *cmd_dup = NULL; - char *argv[2] = { 0 }; - int success = 0; - - if (zstr(cmd) ) { - goto done; - } - - cmd_dup = strdup(cmd); - switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); - - /* check if a command alias */ - alias = switch_core_hash_find(globals.cmd_aliases, argv[0]); - - if (alias) { - success = alias_api(alias, argv[1], stream); - } else if (!strcmp("cmd", argv[0])) { - success = command_api(argv[1], stream); - } else if (!strcmp("status", argv[0])) { - success = dump_api(argv[1], stream); - } else if (!strcmp("msg", argv[0])) { - success = message_api(argv[1], stream); - } else if (!strcmp("presence", argv[0])) { - success = presence_api(argv[1], stream); - } - -done: - if (!success) { - stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_API_SYNTAX); - } - - switch_safe_free(cmd_dup); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Console auto-completion for actors given validation function - */ -static switch_status_t list_actors(const char *line, const char *cursor, switch_console_callback_match_t **matches, rayo_actor_match_fn match) -{ - switch_hash_index_t *hi; - void *val; - const void *vvar; - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - struct rayo_actor *actor; - - switch_mutex_lock(globals.actors_mutex); - for (hi = switch_core_hash_first(globals.actors); hi; hi = switch_core_hash_next(&hi)) { - switch_core_hash_this(hi, &vvar, NULL, &val); - - actor = (struct rayo_actor *) val; - if (match(actor)) { - switch_console_push_match(&my_matches, (const char *) vvar); - } - } - switch_mutex_unlock(globals.actors_mutex); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -/** - * @return true if internal actor - */ -static switch_bool_t is_internal_actor(struct rayo_actor *actor) -{ - return strcmp(RAT_CLIENT, actor->type) && strcmp(RAT_PEER_SERVER, actor->type); -} - -/** - * Console auto-completion for all internal actors - */ -static switch_status_t list_internal(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_internal_actor); -} - -/** - * @return true if external actor - */ -static switch_bool_t is_external_actor(struct rayo_actor *actor) -{ - return !strcmp(RAT_CLIENT, actor->type) || !strcmp(RAT_PEER_SERVER, actor->type); -} - -/** - * Console auto-completion for all external actors - */ -static switch_status_t list_external(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_external_actor); -} - -/** - * @return true - */ -static switch_bool_t is_any_actor(struct rayo_actor *actor) -{ - return SWITCH_TRUE; -} - -/** - * Console auto-completion for all actors - */ -static switch_status_t list_all(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_any_actor); -} - -/** - * @return true if a server - */ -static switch_bool_t is_server_actor(struct rayo_actor *actor) -{ - return !strcmp(RAT_SERVER, actor->type); -} - -/** - * Console auto-completion for all servers - */ -static switch_status_t list_server(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_server_actor); -} - -/** - * @return true if a call - */ -static switch_bool_t is_call_actor(struct rayo_actor *actor) -{ - return !strcmp(RAT_CALL, actor->type); -} - -/** - * Console auto-completion for all calls - */ -static switch_status_t list_call(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_call_actor); -} - -/** - * @return true if a component - */ -switch_bool_t is_component_actor(struct rayo_actor *actor) -{ - return !strncmp(RAT_COMPONENT, actor->type, strlen(RAT_COMPONENT)); -} - -/** - * Console auto-completion for all components - */ -static switch_status_t list_component(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_component_actor); -} - -/** - * @return true if a record component - */ -static switch_bool_t is_record_actor(struct rayo_actor *actor) -{ - return is_component_actor(actor) && !strcmp(actor->subtype, "record"); -} - -/** - * Console auto-completion for all components - */ -static switch_status_t list_record(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_record_actor); -} - -/** - * @return true if an output component - */ -static switch_bool_t is_output_actor(struct rayo_actor *actor) -{ - return is_component_actor(actor) && !strcmp(actor->subtype, "output"); -} - -/** - * Console auto-completion for all components - */ -static switch_status_t list_output(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_output_actor); -} - -/** - * @return true if an input component - */ -static switch_bool_t is_input_actor(struct rayo_actor *actor) -{ - return is_component_actor(actor) && !strcmp(actor->subtype, "input"); -} - -/** - * Console auto-completion for all components - */ -static switch_status_t list_input(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - return list_actors(line, cursor, matches, is_input_actor); -} - -/** - * Shutdown module on load failure or shutdown from FreeSWITCH core - */ -static switch_status_t do_shutdown(void) -{ - switch_console_del_complete_func("::rayo::list_all"); - switch_console_del_complete_func("::rayo::list_internal"); - switch_console_del_complete_func("::rayo::list_external"); - switch_console_del_complete_func("::rayo::list_server"); - switch_console_del_complete_func("::rayo::list_call"); - switch_console_del_complete_func("::rayo::list_component"); - switch_console_del_complete_func("::rayo::list_record"); - switch_console_del_complete_func("::rayo::list_output"); - switch_console_del_complete_func("::rayo::list_input"); - switch_console_set_complete("del rayo"); - - /* stop XMPP streams */ - if (globals.xmpp_context) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for XMPP threads to stop\n"); - xmpp_stream_context_destroy(globals.xmpp_context); - } - - /* stop threads */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for message and offer timeout threads to stop\n"); - stop_all_threads(); - - if (globals.console) { - RAYO_RELEASE(globals.console); - RAYO_DESTROY(globals.console); - globals.console = NULL; - } - - if (globals.server) { - RAYO_RELEASE(globals.server); - RAYO_DESTROY(globals.server); - globals.server = NULL; - } - - rayo_components_shutdown(); - - switch_event_unbind_callback(route_call_event); - switch_event_unbind_callback(on_call_end_event); - switch_event_unbind_callback(route_mixer_event); - - if (globals.command_handlers) { - switch_core_hash_destroy(&globals.command_handlers); - } - if (globals.event_handlers) { - switch_core_hash_destroy(&globals.event_handlers); - } - if (globals.clients_roster) { - switch_core_hash_destroy(&globals.clients_roster); - } - if (globals.actors) { - switch_core_hash_destroy(&globals.actors); - } - if (globals.destroy_actors) { - switch_core_hash_destroy(&globals.destroy_actors); - } - if (globals.actors_by_id) { - switch_core_hash_destroy(&globals.actors_by_id); - } - if (globals.dial_gateways) { - switch_core_hash_destroy(&globals.dial_gateways); - } - if (globals.cmd_aliases) { - switch_core_hash_destroy(&globals.cmd_aliases); - } - - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Load module - */ -SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load) -{ - switch_api_interface_t *api_interface; - switch_application_interface_t *app_interface; - - - if (switch_event_reserve_subclass("rayo::cpa") != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", "rayo::cpa"); - return SWITCH_STATUS_TERM; - } - - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading module\n"); - - memset(&globals, 0, sizeof(globals)); - globals.pool = pool; - switch_core_hash_init(&globals.command_handlers); - switch_core_hash_init(&globals.event_handlers); - switch_core_hash_init(&globals.clients_roster); - switch_mutex_init(&globals.clients_mutex, SWITCH_MUTEX_NESTED, pool); - switch_core_hash_init(&globals.actors); - switch_core_hash_init(&globals.destroy_actors); - switch_core_hash_init(&globals.actors_by_id); - switch_mutex_init(&globals.actors_mutex, SWITCH_MUTEX_NESTED, pool); - switch_core_hash_init(&globals.dial_gateways); - switch_mutex_init(&globals.dial_gateways_mutex, SWITCH_MUTEX_NESTED, pool); - switch_core_hash_init(&globals.cmd_aliases); - switch_thread_rwlock_create(&globals.shutdown_rwlock, pool); - switch_queue_create(&globals.msg_queue, 25000, pool); - switch_queue_create(&globals.offer_queue, 25000, pool); - globals.offline_logged = 1; - - /* server commands */ - rayo_actor_command_handler_add(RAT_SERVER, "", "get:"IKS_NS_XMPP_PING":ping", on_iq_xmpp_ping); - rayo_actor_command_handler_add(RAT_SERVER, "", "get:"IKS_NS_XMPP_DISCO":query", on_iq_get_xmpp_disco); - rayo_actor_command_handler_add(RAT_SERVER, "", "set:"RAYO_NS":dial", on_rayo_dial); - rayo_actor_command_handler_add(RAT_SERVER, "", "set:"RAYO_NS":exec", on_rayo_exec); - - /* Rayo call commands */ - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":accept", on_rayo_accept); - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":answer", on_rayo_answer); - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":redirect", on_rayo_redirect); - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":reject", on_rayo_hangup); /* handles both reject and hangup */ - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":hangup", on_rayo_hangup); /* handles both reject and hangup */ - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":join", on_rayo_join); - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_NS":unjoin", on_rayo_unjoin); - - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_ORIGINATE, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_PROGRESS, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_ANSWER, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_BRIDGE, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_PARK, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_EXECUTE, NULL, route_call_event, NULL); - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, route_call_event, NULL); - - switch_event_bind(modname, SWITCH_EVENT_CHANNEL_DESTROY, NULL, on_call_end_event, NULL); - - switch_event_bind(modname, SWITCH_EVENT_CUSTOM, "conference::maintenance", route_mixer_event, NULL); - - SWITCH_ADD_APP(app_interface, "rayo", "Offer call control to Rayo client(s)", "", rayo_app, RAYO_USAGE, SAF_SUPPORT_NOMEDIA); - SWITCH_ADD_API(api_interface, "rayo", "Query rayo status", rayo_api, RAYO_API_SYNTAX); - - /* set up rayo components */ - if (rayo_components_load(module_interface, pool, RAYO_CONFIG_FILE) != SWITCH_STATUS_SUCCESS) { - goto error; - } - - /* configure / open sockets */ - if(do_config(globals.pool, RAYO_CONFIG_FILE) != SWITCH_STATUS_SUCCESS) { - goto error; - } - - /* create admin client */ - globals.console = rayo_console_client_create(); - if (!globals.console) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to create console client entity!\n"); - goto error; - } - - /* start up message threads */ - { - int i; - for (i = 0; i < globals.num_message_threads; i++) { - start_deliver_message_thread(pool); - } - } - start_offer_timeout_thread(pool); - - switch_console_set_complete("add rayo status"); - switch_console_set_complete("add rayo msg ::rayo::list_all"); - switch_console_set_complete("add rayo msg ::rayo::list_all chat"); - switch_console_set_complete("add rayo msg ::rayo::list_all groupchat"); - switch_console_set_complete("add rayo msg ::rayo::list_all headline"); - switch_console_set_complete("add rayo msg ::rayo::list_all normal"); - switch_console_set_complete("add rayo presence ::rayo::list_server online"); - switch_console_set_complete("add rayo presence ::rayo::list_server offline"); - switch_console_add_complete_func("::rayo::list_all", list_all); - switch_console_add_complete_func("::rayo::list_internal", list_internal); - switch_console_add_complete_func("::rayo::list_external", list_external); - switch_console_add_complete_func("::rayo::list_server", list_server); - switch_console_add_complete_func("::rayo::list_call", list_call); - switch_console_add_complete_func("::rayo::list_component", list_component); - switch_console_add_complete_func("::rayo::list_record", list_record); - switch_console_add_complete_func("::rayo::list_output", list_output); - switch_console_add_complete_func("::rayo::list_input", list_input); - - return SWITCH_STATUS_SUCCESS; - - error: - switch_event_free_subclass("rayo::cpa"); - do_shutdown(); - return SWITCH_STATUS_TERM; - -} - -/** - * Shutdown module. Notifies threads to stop. - */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rayo_shutdown) -{ - switch_status_t result; - - switch_event_free_subclass("rayo::cpa"); - result = do_shutdown(); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Module shutdown\n"); - return result; -} - -/** - * Checks status of connected clients - */ -SWITCH_MODULE_RUNTIME_FUNCTION(mod_rayo_runtime) -{ - if (globals.pause_when_offline) { - switch_thread_rwlock_rdlock(globals.shutdown_rwlock); - while (!globals.shutdown) { - switch_sleep(1000 * 1000); /* 1 second */ - pause_when_offline(); - } - switch_thread_rwlock_unlock(globals.shutdown_rwlock); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Runtime thread is done\n"); - } - return SWITCH_STATUS_TERM; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h deleted file mode 100644 index 2d066c4e21..0000000000 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * mod_rayo.h -- Rayo server / node implementation. Allows MxN clustering of FreeSWITCH and Rayo Clients (like Adhearsion) - * - */ -#ifndef MOD_RAYO_H -#define MOD_RAYO_H - -#include -#include - -#include "iks_helpers.h" - -#define RAYO_VERSION "1" -#define RAYO_BASE "urn:xmpp:rayo:" - -#define RAYO_NS RAYO_BASE RAYO_VERSION -#define RAYO_CLIENT_NS RAYO_BASE "client:" RAYO_VERSION -#define RAYO_CALL_NS RAYO_BASE "call:" RAYO_VERSION -#define RAYO_MIXER_NS RAYO_BASE "mixer:" RAYO_VERSION - -#define RAYO_CPA_BASE RAYO_BASE "cpa:" -#define RAYO_CPA_NS RAYO_CPA_BASE RAYO_VERSION - -#define RAT_CALL "CALL" -#define RAT_COMPONENT "COMPONENT" -#define RAT_CALL_COMPONENT RAT_COMPONENT"_CALL" -#define RAT_MIXER "MIXER" -#define RAT_MIXER_COMPONENT RAT_COMPONENT"_MIXER" -#define RAT_SERVER "SERVER" -#define RAT_PEER_SERVER "PEER_SERVER" -#define RAT_CLIENT "CLIENT" - -struct rayo_actor; -struct rayo_call; -struct rayo_mixer; -struct rayo_component; - -/** - * A message sent to an actor - */ -struct rayo_message { - iks *payload; - char *to_jid; - iksid *to; - char *from_jid; - iksid *from; - char *from_type; - char *from_subtype; - int is_reply; - char *file; - int line; -}; - -typedef void (* rayo_actor_cleanup_fn)(struct rayo_actor *); -typedef void (* rayo_actor_send_fn)(struct rayo_actor *, struct rayo_message *); - -/** - * A rayo actor - this is an entity that can be controlled by a rayo client - */ -struct rayo_actor { - /** Type of actor */ - char *type; - /** Sub-type of actor */ - char *subtype; - /** domain part of JID */ - char *domain; - /** Internal ID */ - char *id; - /** actor JID */ - char *jid; - /** Actor pool */ - switch_memory_pool_t *pool; - /** synchronizes access to this actor */ - switch_mutex_t *mutex; - /** an atomically incrementing sequence for this actor */ - int seq; - /** number of users of this actor */ - int ref_count; - /** destroy flag */ - int destroy; - /** XMPP message handling function */ - rayo_actor_send_fn send_fn; - /** optional cleanup */ - rayo_actor_cleanup_fn cleanup_fn; - /** optional parent */ - struct rayo_actor *parent; -}; - -/** - * A Rayo component - */ -struct rayo_component { - /** base actor class */ - struct rayo_actor base; - /** owning client JID */ - const char *client_jid; - /** external ref */ - const char *ref; - /** true if component has completed */ - int complete; -}; - -#define RAYO_ACTOR(x) ((struct rayo_actor *)x) -#define RAYO_COMPONENT(x) ((struct rayo_component *)x) -#define RAYO_CALL(x) ((struct rayo_call *)x) -#define RAYO_MIXER(x) ((struct rayo_mixer *)x) - -SWITCH_DECLARE(void) rayo_message_send(struct rayo_actor *from, const char *to, iks *payload, int dup, int reply, const char *file, int line); -SWITCH_DECLARE(void) rayo_message_destroy(struct rayo_message *msg); -SWITCH_DECLARE(iks *) rayo_message_remove_payload(struct rayo_message *msg); -#define RAYO_SEND_MESSAGE(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 0, 0, __FILE__, __LINE__) -#define RAYO_SEND_MESSAGE_DUP(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 1, 0, __FILE__, __LINE__) -#define RAYO_SEND_REPLY(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 0, 1, __FILE__, __LINE__) -#define RAYO_SEND_REPLY_DUP(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 1, 1, __FILE__, __LINE__) - -SWITCH_DECLARE(struct rayo_actor *) rayo_actor_locate(const char *jid, const char *file, int line); -SWITCH_DECLARE(struct rayo_actor *) rayo_actor_locate_by_id(const char *id, const char *file, int line); -SWITCH_DECLARE(int) rayo_actor_seq_next(struct rayo_actor *actor); -SWITCH_DECLARE(void) rayo_actor_retain(struct rayo_actor *actor, const char *file, int line); -SWITCH_DECLARE(void) rayo_actor_release(struct rayo_actor *actor, const char *file, int line); -SWITCH_DECLARE(void) rayo_actor_destroy(struct rayo_actor *actor, const char *file, int line); - -#define RAYO_LOCATE(jid) rayo_actor_locate(jid, __FILE__, __LINE__) -#define RAYO_LOCATE_BY_ID(id) rayo_actor_locate_by_id(id, __FILE__, __LINE__) -#define RAYO_SET_EVENT_FN(actor, event) rayo_actor_set_event_fn(RAYO_ACTOR(actor), event) -#define RAYO_DOMAIN(x) RAYO_ACTOR(x)->domain -#define RAYO_JID(x) RAYO_ACTOR(x)->jid -#define RAYO_ID(x) RAYO_ACTOR(x)->id -#define RAYO_POOL(x) RAYO_ACTOR(x)->pool -#define RAYO_RETAIN(x) rayo_actor_retain(RAYO_ACTOR(x), __FILE__, __LINE__) -#define RAYO_RELEASE(x) rayo_actor_release(RAYO_ACTOR(x), __FILE__, __LINE__) -#define RAYO_DESTROY(x) rayo_actor_destroy(RAYO_ACTOR(x), __FILE__, __LINE__) -#define RAYO_SEQ_NEXT(x) rayo_actor_seq_next(RAYO_ACTOR(x)) - -SWITCH_DECLARE(int) rayo_call_is_joined(struct rayo_call *call); -SWITCH_DECLARE(int) rayo_call_is_faxing(struct rayo_call *call); -SWITCH_DECLARE(void) rayo_call_set_faxing(struct rayo_call *call, int faxing); -SWITCH_DECLARE(const char *) rayo_call_get_dcp_jid(struct rayo_call *call); - -#define rayo_mixer_get_name(mixer) RAYO_ID(mixer) - -#define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, NULL, __FILE__, __LINE__) -#define rayo_component_init_cleanup(component, pool, type, subtype, id, parent, client_jid, cleanup) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, cleanup, __FILE__, __LINE__) -SWITCH_DECLARE(struct rayo_component *) _rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line); -SWITCH_DECLARE(switch_bool_t) is_component_actor(struct rayo_actor *); - -typedef iks *(*rayo_actor_xmpp_handler)(struct rayo_actor *, struct rayo_message *, void *); -SWITCH_DECLARE(void) rayo_actor_command_handler_add(const char *type, const char *subtype, const char *name, rayo_actor_xmpp_handler fn); -SWITCH_DECLARE(void) rayo_actor_event_handler_add(const char *from_type, const char *from_subtype, const char *to_type, const char *to_subtype, const char *name, rayo_actor_xmpp_handler fn); - -#endif - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/nlsml.c b/src/mod/event_handlers/mod_rayo/nlsml.c deleted file mode 100644 index 61730127c4..0000000000 --- a/src/mod/event_handlers/mod_rayo/nlsml.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * nlsml.c -- Parses / creates NLSML results - * - */ -#include -#include - -#include "nlsml.h" -#include "iks_helpers.h" - -struct nlsml_parser; - -/** function to handle tag attributes */ -typedef int (* tag_attribs_fn)(struct nlsml_parser *, char **); -/** function to handle tag CDATA */ -typedef int (* tag_cdata_fn)(struct nlsml_parser *, char *, size_t); - -/** - * Tag definition - */ -struct tag_def { - tag_attribs_fn attribs_fn; - tag_cdata_fn cdata_fn; - switch_bool_t is_root; - switch_hash_t *children_tags; -}; - -/** - * library configuration - */ -typedef struct { - /** true if initialized */ - switch_bool_t init; - /** Mapping of tag name to definition */ - switch_hash_t *tag_defs; - /** library memory pool */ - switch_memory_pool_t *pool; -} nlsml_globals; -static nlsml_globals globals = { 0 }; - -/** - * The node in the XML tree - */ -struct nlsml_node { - /** tag name */ - const char *name; - /** tag definition */ - struct tag_def *tag_def; - /** parent to this node */ - struct nlsml_node *parent; -}; - -/** - * The SAX parser state - */ -struct nlsml_parser { - /** current node */ - struct nlsml_node *cur; - /** optional UUID for logging */ - const char *uuid; - /** true if a match exists */ - int match; - /** true if noinput */ - int noinput; - /** true if nomatch */ - int nomatch; -}; - -/** - * Tag def destructor - */ -static void destroy_tag_def(void *ptr) -{ - struct tag_def *tag = (struct tag_def *) ptr; - if (tag->children_tags) { - switch_core_hash_destroy(&tag->children_tags); - } -} - -/** - * Add a definition for a tag - * @param tag the name - * @param attribs_fn the function to handle the tag attributes - * @param cdata_fn the function to handler the tag CDATA - * @param children_tags comma-separated list of valid child tag names - * @return the definition - */ -static struct tag_def *add_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) -{ - struct tag_def *def = switch_core_alloc(globals.pool, sizeof(*def)); - switch_core_hash_init(&def->children_tags); - if (!zstr(children_tags)) { - char *children_tags_dup = switch_core_strdup(globals.pool, children_tags); - char *tags[32] = { 0 }; - int tag_count = switch_separate_string(children_tags_dup, ',', tags, sizeof(tags) / sizeof(tags[0])); - if (tag_count) { - int i; - for (i = 0; i < tag_count; i++) { - switch_core_hash_insert(def->children_tags, tags[i], tags[i]); - } - } - } - def->attribs_fn = attribs_fn; - def->cdata_fn = cdata_fn; - def->is_root = SWITCH_FALSE; - switch_core_hash_insert_destructor(globals.tag_defs, tag, def, destroy_tag_def); - return def; -} - -/** - * Add a definition for a root tag - * @param tag the name - * @param attribs_fn the function to handle the tag attributes - * @param cdata_fn the function to handler the tag CDATA - * @param children_tags comma-separated list of valid child tag names - * @return the definition - */ -static struct tag_def *add_root_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) -{ - struct tag_def *def = add_tag_def(tag, attribs_fn, cdata_fn, children_tags); - def->is_root = SWITCH_TRUE; - return def; -} - -/** - * Handle tag attributes - * @param parser the parser - * @param name the tag name - * @param atts the attributes - * @return IKS_OK if OK IKS_BADXML on parse failure - */ -static int process_tag(struct nlsml_parser *parser, const char *name, char **atts) -{ - struct nlsml_node *cur = parser->cur; - if (cur->tag_def->is_root && cur->parent == NULL) { - /* no parent for ROOT tags */ - return cur->tag_def->attribs_fn(parser, atts); - } else if (!cur->tag_def->is_root && cur->parent) { - /* check if this child is allowed by parent node */ - struct tag_def *parent_def = cur->parent->tag_def; - if (switch_core_hash_find(parent_def->children_tags, "ANY") || - switch_core_hash_find(parent_def->children_tags, name)) { - return cur->tag_def->attribs_fn(parser, atts); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "<%s> cannot be a child of <%s>\n", name, cur->parent->name); - } - } else if (cur->tag_def->is_root && cur->parent != NULL) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "<%s> must be the root element\n", name); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "<%s> cannot be a root element\n", name); - } - return IKS_BADXML; -} - -/** - * Handle tag attributes that are ignored - * @param parser the parser - * @param atts the attributes - * @return IKS_OK - */ -static int process_attribs_ignore(struct nlsml_parser *parser, char **atts) -{ - return IKS_OK; -} - -/** - * Handle CDATA that is ignored - * @param parser the parser - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int process_cdata_ignore(struct nlsml_parser *parser, char *data, size_t len) -{ - return IKS_OK; -} - -/** - * Handle CDATA that is not allowed - * @param parser the parser - * @param data the CDATA - * @param len the CDATA length - * @return IKS_BADXML if any printable characters - */ -static int process_cdata_bad(struct nlsml_parser *parser, char *data, size_t len) -{ - int i; - for (i = 0; i < len; i++) { - if (isgraph(data[i])) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "Unexpected CDATA for <%s>\n", parser->cur->name); - return IKS_BADXML; - } - } - return IKS_OK; -} - -/** - * Handle CDATA with match text - * @param parser the parser - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int process_cdata_match(struct nlsml_parser *parser, char *data, size_t len) -{ - int i; - for (i = 0; i < len; i++) { - if (isgraph(data[i])) { - parser->match++; - return IKS_OK; - } - } - return IKS_OK; -} - -/** - * Handle nomatch - * @param parser the parser - * @param atts the attributes - * @return IKS_OK - */ -static int process_nomatch(struct nlsml_parser *parser, char **atts) -{ - parser->nomatch++; - return IKS_OK; -} - -/** - * Handle noinput - * @param parser the parser - * @param atts the attributes - * @return IKS_OK - */ -static int process_noinput(struct nlsml_parser *parser, char **atts) -{ - parser->noinput++; - return IKS_OK; -} - -/** - * Process a tag - */ -static int tag_hook(void *user_data, char *name, char **atts, int type) -{ - int result = IKS_OK; - struct nlsml_parser *parser = (struct nlsml_parser *)user_data; - - if (type == IKS_OPEN || type == IKS_SINGLE) { - struct nlsml_node *child_node = malloc(sizeof(*child_node)); - switch_assert(child_node); - child_node->name = name; - child_node->tag_def = switch_core_hash_find(globals.tag_defs, name); - if (!child_node->tag_def) { - child_node->tag_def = switch_core_hash_find(globals.tag_defs, "ANY"); - } - child_node->parent = parser->cur; - parser->cur = child_node; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_DEBUG1, "<%s>\n", name); - result = process_tag(parser, name, atts); - } - - if (type == IKS_CLOSE || type == IKS_SINGLE) { - struct nlsml_node *node = parser->cur; - parser->cur = node->parent; - free(node); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_DEBUG1, "\n", name); - } - - return result; -} - -/** - * Process cdata - * @param user_data the parser - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int cdata_hook(void *user_data, char *data, size_t len) -{ - struct nlsml_parser *parser = (struct nlsml_parser *)user_data; - if (!parser) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing parser\n"); - return IKS_BADXML; - } - if (parser->cur) { - struct tag_def *def = parser->cur->tag_def; - if (def) { - return def->cdata_fn(parser, data, len); - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "Missing definition for <%s>\n", parser->cur->name); - return IKS_BADXML; - } - return IKS_OK; -} - -/** - * Parse the result, looking for noinput/nomatch/match - * @param nlsml_result the NLSML result to parse - * @param uuid optional UUID for logging - * @return true if successful - */ -enum nlsml_match_type nlsml_parse(const char *nlsml_result, const char *uuid) -{ - struct nlsml_parser parser = { 0 }; - int result = NMT_BAD_XML; - iksparser *p = NULL; - parser.uuid = uuid; - - if (!zstr(nlsml_result)) { - p = iks_sax_new(&parser, tag_hook, cdata_hook); - if (iks_parse(p, nlsml_result, 0, 1) == IKS_OK) { - /* check result */ - if (parser.match) { - result = NMT_MATCH; - goto end; - } - if (parser.nomatch) { - result = NMT_NOMATCH; - goto end; - } - if (parser.noinput) { - result = NMT_NOINPUT; - goto end; - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser.uuid), SWITCH_LOG_INFO, "NLSML result does not have match/noinput/nomatch!\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser.uuid), SWITCH_LOG_INFO, "Failed to parse NLSML!\n"); - } - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser.uuid), SWITCH_LOG_INFO, "Missing NLSML result\n"); - } - end: - - while (parser.cur) { - struct nlsml_node *node = parser.cur; - parser.cur = node->parent; - free(node); - } - - if ( p ) { - iks_parser_delete(p); - } - return result; -} - -#define NLSML_NS "http://www.ietf.org/xml/ns/mrcpv2" - -/** - * Makes NLSML result to conform to mrcpv2 - * @param result the potentially non-conforming result - * @return the conforming result - */ -iks *nlsml_normalize(const char *result) -{ - iks *result_xml = NULL; - iksparser *p = iks_dom_new(&result_xml); - if (iks_parse(p, result, 0, 1) == IKS_OK && result_xml) { - /* for now, all that is needed is to set the proper namespace */ - iks_insert_attrib(result_xml, "xmlns", NLSML_NS); - } else { - /* unexpected ... */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to normalize NLSML result: %s\n", result); - if (result_xml) { - iks_delete(result_xml); - } - } - iks_parser_delete(p); - return result_xml; -} - -/** - * @return true if digit is a DTMF - */ -static int isdtmf(const char digit) -{ - switch(digit) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '*': - case '#': - case 'a': - case 'A': - case 'b': - case 'B': - case 'c': - case 'C': - case 'd': - case 'D': - return 1; - } - return 0; -} - -/** - * Construct an NLSML result for match - * @param match the matching digits or text - * @param interpretation the optional digit interpretation - * @param mode dtmf or speech - * @param confidence 0-100 - * @return the NLSML - */ -iks *nlsml_create_match(const char *match, const char *interpretation, const char *mode, int confidence) -{ - iks *result = iks_new("result"); - iks_insert_attrib(result, "xmlns", NLSML_NS); - iks_insert_attrib(result, "xmlns:xf", "http://www.w3.org/2000/xforms"); - if (!zstr(match)) { - iks *interpretation_node = iks_insert(result, "interpretation"); - iks *input_node = iks_insert(interpretation_node, "input"); - iks *instance_node = iks_insert(interpretation_node, "instance"); - iks_insert_attrib(input_node, "mode", mode); - iks_insert_attrib_printf(input_node, "confidence", "%d", confidence); - iks_insert_cdata(input_node, match, strlen(match)); - if (zstr(interpretation)) { - iks_insert_cdata(instance_node, match, strlen(match)); - } else { - iks_insert_cdata(instance_node, interpretation, strlen(interpretation)); - } - } - return result; -} - -/** - * Construct an NLSML result for match - * @param match the matching digits or text - * @param interpretation the optional digit interpretation - * @return the NLSML - */ -iks *nlsml_create_dtmf_match(const char *digits, const char *interpretation) -{ - iks *result = NULL; - int first = 1; - int i; - int num_digits = strlen(digits); - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - for (i = 0; i < num_digits; i++) { - if (isdtmf(digits[i])) { - if (first) { - stream.write_function(&stream, "%c", digits[i]); - first = 0; - } else { - stream.write_function(&stream, " %c", digits[i]); - } - } - } - result = nlsml_create_match((const char *)stream.data, interpretation, "dtmf", 100); - switch_safe_free(stream.data); - return result; -} - -/** - * Initialize NLSML parser. This function is not thread safe. - */ -int nlsml_init(void) -{ - if (globals.init) { - return 1; - } - - globals.init = SWITCH_TRUE; - switch_core_new_memory_pool(&globals.pool); - switch_core_hash_init(&globals.tag_defs); - - add_root_tag_def("result", process_attribs_ignore, process_cdata_ignore, "interpretation"); - add_tag_def("interpretation", process_attribs_ignore, process_cdata_ignore, "input,model,xf:model,instance,xf:instance"); - add_tag_def("input", process_attribs_ignore, process_cdata_match, "input,nomatch,noinput"); - add_tag_def("noinput", process_noinput, process_cdata_bad, ""); - add_tag_def("nomatch", process_nomatch, process_cdata_ignore, ""); - add_tag_def("model", process_attribs_ignore, process_cdata_ignore, "ANY"); - add_tag_def("xf:model", process_attribs_ignore, process_cdata_ignore, "ANY"); - add_tag_def("instance", process_attribs_ignore, process_cdata_ignore, "ANY"); - add_tag_def("xf:instance", process_attribs_ignore, process_cdata_ignore, "ANY"); - add_tag_def("ANY", process_attribs_ignore, process_cdata_ignore, "ANY"); - - return 1; -} - -/** - * Destruction of NLSML parser environment - */ -void nlsml_destroy(void) -{ - if (globals.init) { - if (globals.tag_defs) { - switch_core_hash_destroy(&globals.tag_defs); - globals.tag_defs = NULL; - } - if (globals.pool) { - switch_core_destroy_memory_pool(&globals.pool); - globals.pool = NULL; - } - globals.init = SWITCH_FALSE; - } -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/nlsml.h b/src/mod/event_handlers/mod_rayo/nlsml.h deleted file mode 100644 index 35f79adc26..0000000000 --- a/src/mod/event_handlers/mod_rayo/nlsml.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * nlsml.h -- Parses / creates NLSML results - * - */ -#ifndef NLSML_H -#define NLSML_H - -#include -#include - -enum nlsml_match_type { - NMT_BAD_XML, - NMT_MATCH, - NMT_NOINPUT, - NMT_NOMATCH -}; - -SWITCH_DECLARE(int) nlsml_init(void); -SWITCH_DECLARE(void) nlsml_destroy(void); -SWITCH_DECLARE(enum nlsml_match_type) nlsml_parse(const char *result, const char *uuid); -SWITCH_DECLARE(iks *) nlsml_normalize(const char *result); -SWITCH_DECLARE(iks *) nlsml_create_dtmf_match(const char *digits, const char *interpretation); -SWITCH_DECLARE(iks *) nlsml_create_match(const char *digits, const char *interpretation, const char *mode, int confidence); - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c deleted file mode 100644 index 2d303fe3bb..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_components.c -- Rayo component interface - * - */ -#include "rayo_components.h" - -#include -#include "mod_rayo.h" -#include "iks_helpers.h" - -/** - * Get access to Rayo component data. - * @param id the component internal ID - * @return the component or NULL. Call rayo_component_unlock() when done with component pointer. - */ -struct rayo_component *rayo_component_locate(const char *id, const char *file, int line) -{ - struct rayo_actor *actor = rayo_actor_locate_by_id(id, file, line); - if (actor && is_component_actor(actor)) { - return RAYO_COMPONENT(actor); - } else if (actor) { - RAYO_RELEASE(actor); - } - return NULL; -} - -/** - * Send component start reply - * @param component the component - * @param iq the start request - */ -void rayo_component_send_start(struct rayo_component *component, iks *iq) -{ - iks *response = iks_new_iq_result(iq); - iks *ref = iks_insert(response, "ref"); - iks_insert_attrib(ref, "xmlns", RAYO_NS); - iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(component)); - RAYO_SEND_REPLY(component, iks_find_attrib(response, "to"), response); -} - -/** - * Create component complete event - * @param component the component - * @param reason_str the completion reason - * @param reason_namespace the completion reason namespace - * @param meta metadata to add as child - * @param child_of_complete if true metadata is child of complete instead of reason - * @return the event - */ -iks *rayo_component_create_complete_event_with_metadata(struct rayo_component *component, const char *reason_str, const char *reason_namespace, iks *meta, int child_of_complete) -{ - iks *response = iks_new("presence"); - iks *complete; - iks *reason; - iks_insert_attrib(response, "from", RAYO_JID(component)); - iks_insert_attrib(response, "to", component->client_jid); - iks_insert_attrib(response, "type", "unavailable"); - complete = iks_insert(response, "complete"); - iks_insert_attrib(complete, "xmlns", RAYO_EXT_NS); - reason = iks_insert(complete, reason_str); - iks_insert_attrib(reason, "xmlns", reason_namespace); - if (meta) { - meta = iks_copy_within(meta, iks_stack(response)); - if (child_of_complete) { - iks_insert_node(complete, meta); - } else { - iks_insert_node(reason, meta); - } - } - - return response; -} - -/** - * Create component complete event - * @param component the component - * @param reason the completion reason - * @param reason_namespace the completion reason namespace - * @return the event - */ -iks *rayo_component_create_complete_event(struct rayo_component *component, const char *reason, const char *reason_namespace) -{ - return rayo_component_create_complete_event_with_metadata(component, reason, reason_namespace, NULL, 0); -} - -/** - * Send rayo component complete event - */ -void rayo_component_send_complete_event(struct rayo_component *component, iks *response) -{ - component->complete = 1; - RAYO_SEND_REPLY(component, iks_find_attrib(response, "to"), response); - RAYO_RELEASE(component); - RAYO_DESTROY(component); -} - -/** - * Send rayo complete - */ -void rayo_component_send_complete(struct rayo_component *component, const char *reason, const char *reason_namespace) -{ - rayo_component_send_complete_event(component, rayo_component_create_complete_event(component, reason, reason_namespace)); -} - -/** - * Send rayo complete - */ -void rayo_component_send_complete_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete) -{ - rayo_component_send_complete_event(component, rayo_component_create_complete_event_with_metadata(component, reason, reason_namespace, meta, child_of_complete)); -} - -/** - * Send rayo complete - */ -void rayo_component_send_complete_with_metadata_string(struct rayo_component *component, const char *reason, const char *reason_namespace, const char *meta, int child_of_complete) -{ - iks *meta_xml = NULL; - iksparser *p = iks_dom_new(&meta_xml); - if (iks_parse(p, meta, 0, 1) != IKS_OK) { - /* unexpected ... */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s Failed to parse metadata for complete event: %s\n", - RAYO_JID(component), meta); - /* send without... */ - rayo_component_send_complete(component, reason, reason_namespace); - } else { - rayo_component_send_complete_with_metadata(component, reason, reason_namespace, meta_xml, child_of_complete); - } - if (meta_xml) { - iks_delete(meta_xml); - } - iks_parser_delete(p); -} - -/** - * Background API data - */ -struct component_bg_api_cmd { - const char *cmd; - const char *args; - switch_memory_pool_t *pool; - struct rayo_component *component; -}; - -/** - * Thread that outputs to component - * @param thread this thread - * @param obj the Rayo mixer context - * @return NULL - */ -static void *SWITCH_THREAD_FUNC component_bg_api_thread(switch_thread_t *thread, void *obj) -{ - struct component_bg_api_cmd *cmd = (struct component_bg_api_cmd *)obj; - switch_stream_handle_t stream = { 0 }; - switch_memory_pool_t *pool = cmd->pool; - SWITCH_STANDARD_STREAM(stream); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BGAPI EXEC: %s %s\n", cmd->cmd, cmd->args); - if (switch_api_execute(cmd->cmd, cmd->args, NULL, &stream) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BGAPI EXEC FAILURE\n"); - rayo_component_send_complete(cmd->component, COMPONENT_COMPLETE_ERROR); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BGAPI EXEC RESULT: %s\n", (char *)stream.data); - } - switch_safe_free(stream.data); - switch_core_destroy_memory_pool(&pool); - return NULL; -} - -/** - * Run a background API command - * @param cmd API command - * @param args API args - */ -void rayo_component_api_execute_async(struct rayo_component *component, const char *cmd, const char *args) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - struct component_bg_api_cmd *bg_cmd = NULL; - switch_memory_pool_t *pool; - - /* set up command */ - switch_core_new_memory_pool(&pool); - bg_cmd = switch_core_alloc(pool, sizeof(*bg_cmd)); - bg_cmd->pool = pool; - bg_cmd->cmd = switch_core_strdup(pool, cmd); - bg_cmd->args = switch_core_strdup(pool, args); - bg_cmd->component = component; - - /* create thread */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s BGAPI START\n", RAYO_JID(component)); - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, component_bg_api_thread, bg_cmd, pool); -} - -/** - * Handle configuration - */ -switch_status_t rayo_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - if (rayo_input_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_output_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_prompt_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_record_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_fax_components_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_exec_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - return SWITCH_STATUS_SUCCESS; -} - -/** - * Handle shutdown - */ -switch_status_t rayo_components_shutdown(void) -{ - rayo_input_component_shutdown(); - rayo_output_component_shutdown(); - rayo_prompt_component_shutdown(); - rayo_record_component_shutdown(); - rayo_fax_components_shutdown(); - rayo_exec_component_shutdown(); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.h b/src/mod/event_handlers/mod_rayo/rayo_components.h deleted file mode 100644 index 9be7881a4e..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_components.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * components.c -- Rayo component implementations - * - */ -#ifndef RAYO_COMPONENTS_H -#define RAYO_COMPONENTS_H - -#include -#include - -#include "mod_rayo.h" - -#define RAYO_EXT_NS RAYO_BASE "ext:" RAYO_VERSION -#define RAYO_EXT_COMPLETE_NS RAYO_BASE "ext:complete:" RAYO_VERSION - -#define RAYO_OUTPUT_NS RAYO_BASE "output:" RAYO_VERSION -#define RAYO_OUTPUT_COMPLETE_NS RAYO_BASE "output:complete:" RAYO_VERSION - -#define RAYO_INPUT_NS RAYO_BASE "input:" RAYO_VERSION -#define RAYO_INPUT_COMPLETE_NS RAYO_BASE "input:complete:" RAYO_VERSION - -#define RAYO_RECORD_NS RAYO_BASE "record:" RAYO_VERSION -#define RAYO_RECORD_COMPLETE_NS RAYO_BASE "record:complete:" RAYO_VERSION - -#define RAYO_PROMPT_NS RAYO_BASE "prompt:" RAYO_VERSION -#define RAYO_PROMPT_COMPLETE_NS RAYO_BASE "prompt:complete:" RAYO_VERSION - -#define RAYO_FAX_NS RAYO_BASE "fax:" RAYO_VERSION -#define RAYO_FAX_COMPLETE_NS RAYO_BASE "fax:complete:" RAYO_VERSION - -#define RAYO_EXEC_NS RAYO_BASE "exec:" RAYO_VERSION -#define RAYO_EXEC_COMPLETE_NS RAYO_BASE "exec:complete:" RAYO_VERSION - -#define COMPONENT_COMPLETE_STOP "stop", RAYO_EXT_COMPLETE_NS -#define COMPONENT_COMPLETE_ERROR "error", RAYO_EXT_COMPLETE_NS -#define COMPONENT_COMPLETE_HANGUP "hangup", RAYO_EXT_COMPLETE_NS -#define COMPONENT_COMPLETE_DONE "done", RAYO_EXT_COMPLETE_NS - -SWITCH_DECLARE(switch_status_t) rayo_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(switch_status_t) rayo_input_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(switch_status_t) rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(switch_status_t) rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(switch_status_t) rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(switch_status_t) rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(switch_status_t) rayo_exec_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); - -SWITCH_DECLARE(switch_status_t) rayo_components_shutdown(void); -SWITCH_DECLARE(switch_status_t) rayo_input_component_shutdown(void); -SWITCH_DECLARE(switch_status_t) rayo_output_component_shutdown(void); -SWITCH_DECLARE(switch_status_t) rayo_prompt_component_shutdown(void); -SWITCH_DECLARE(switch_status_t) rayo_record_component_shutdown(void); -SWITCH_DECLARE(switch_status_t) rayo_fax_components_shutdown(void); -SWITCH_DECLARE(switch_status_t) rayo_exec_component_shutdown(void); - -SWITCH_DECLARE(void) rayo_component_send_start(struct rayo_component *component, iks *iq); -SWITCH_DECLARE(void) rayo_component_send_iq_error(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type); -SWITCH_DECLARE(void) rayo_component_send_iq_error_detailed(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type, const char *detail); -SWITCH_DECLARE(void) rayo_component_send_complete(struct rayo_component *component, const char *reason, const char *reason_namespace); -SWITCH_DECLARE(void) rayo_component_send_complete_event(struct rayo_component *component, iks *response); -SWITCH_DECLARE(void) rayo_component_send_complete_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete); -SWITCH_DECLARE(void) rayo_component_send_complete_with_metadata_string(struct rayo_component *component, const char *reason, const char *reason_namespace, const char *meta, int child_of_complete); - -SWITCH_DECLARE(iks *) rayo_component_create_complete_event(struct rayo_component *component, const char *reason, const char *reason_namespace); -SWITCH_DECLARE(iks *) rayo_component_create_complete_event_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete); - -SWITCH_DECLARE(void) rayo_component_api_execute_async(struct rayo_component *component, const char *cmd, const char *args); - -#define RAYO_COMPONENT_LOCATE(id) rayo_component_locate(id, __FILE__, __LINE__) -SWITCH_DECLARE(struct rayo_component *) rayo_component_locate(const char *id, const char *file, int line); - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_component.c b/src/mod/event_handlers/mod_rayo/rayo_cpa_component.c deleted file mode 100644 index 15dcd74aa7..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_component.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2014, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_cpa_component.c -- input component "cpa" mode implementation - */ -#include - -#include "rayo_cpa_component.h" -#include "mod_rayo.h" -#include "rayo_components.h" -#include "rayo_cpa_detector.h" - -/** - * Module globals - */ -static struct { - /** signal subscribers */ - switch_hash_t *subscribers; - /** synchronizes access to subscribers */ - switch_mutex_t *subscribers_mutex; - /** module pool */ - switch_memory_pool_t *pool; -} globals; - -/** - * A CPA signal monitored by this component - */ -struct cpa_signal { - /** name of this signal */ - const char *name; - /** true if signal causes component termination */ - int terminate; -}; - -/** - * CPA component state - */ -struct cpa_component { - /** component base class */ - struct rayo_component base; - /** true if ready to forward detector events */ - int ready; - /** signals this component wants */ - switch_hash_t *signals; -}; - -#define CPA_COMPONENT(x) ((struct cpa_component *)x) - -typedef void (* subscriber_execute_fn)(const char *jid, void *user_data); - -/** - * Request signals - */ -static void subscribe(const char *uuid, const char *signal_type, const char *jid) -{ - char *key = switch_mprintf("%s:%s", uuid, signal_type); - switch_mutex_lock(globals.subscribers_mutex); - { - switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Subscribe %s => %s\n", signal_type, jid); - if (!signal_subscribers) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Create %s subscriber hash\n", signal_type); - switch_core_hash_init(&signal_subscribers); - switch_core_hash_insert(globals.subscribers, key, signal_subscribers); - } - switch_core_hash_insert(signal_subscribers, jid, "1"); - } - switch_mutex_unlock(globals.subscribers_mutex); - switch_safe_free(key); -} - -/** - * Stop receiving signals - */ -static void unsubscribe(const char *uuid, const char *signal_type, const char *jid) -{ - char *key = switch_mprintf("%s:%s", uuid, signal_type); - switch_mutex_lock(globals.subscribers_mutex); - { - switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); - if (signal_subscribers) { - switch_core_hash_delete(signal_subscribers, jid); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Unsubscribe %s => %s\n", signal_type, jid); - - /* clean up hash if empty */ - if (switch_core_hash_empty(signal_subscribers)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Destroy %s subscriber hash\n", signal_type); - switch_core_hash_destroy(&signal_subscribers); - switch_core_hash_delete(globals.subscribers, key); - } - } - } - switch_mutex_unlock(globals.subscribers_mutex); - switch_safe_free(key); -} - -/** - * Execute function for each subscriber - */ -static void subscriber_execute(const char *uuid, const char *signal_type, subscriber_execute_fn callback, void *user_data) -{ - switch_event_t *subscriber_list = NULL; - switch_event_header_t *subscriber = NULL; - - /* fetch list of subscribers */ - char *key = switch_mprintf("%s:%s", uuid, signal_type); - switch_event_create_subclass(&subscriber_list, SWITCH_EVENT_CLONE, NULL); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Subscriber execute %s\n", signal_type); - switch_mutex_lock(globals.subscribers_mutex); - { - switch_hash_index_t *hi = NULL; - switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); - if (signal_subscribers) { - for (hi = switch_core_hash_first(signal_subscribers); hi; hi = switch_core_hash_next(&hi)) { - const void *jid; - void *dont_care; - switch_core_hash_this(hi, &jid, NULL, &dont_care); - switch_event_add_header_string(subscriber_list, SWITCH_STACK_BOTTOM, "execute", (const char *)jid); - } - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "No subscribers for %s\n", signal_type); - } - } - switch_mutex_unlock(globals.subscribers_mutex); - switch_safe_free(key); - - /* execute function for each subscriber */ - for (subscriber = subscriber_list->headers; subscriber; subscriber = subscriber->next) { - callback(subscriber->value, user_data); - } - - switch_event_destroy(&subscriber_list); -} - -/** - * Stop all CPA detectors - */ -static void stop_cpa_detectors(struct cpa_component *cpa) -{ - if (cpa->signals) { - switch_hash_index_t *hi = NULL; - for (hi = switch_core_hash_first(cpa->signals); hi; hi = switch_core_hash_next(&hi)) { - const void *signal_type; - void *cpa_signal = NULL; - switch_core_hash_this(hi, &signal_type, NULL, &cpa_signal); - if (cpa_signal) { - rayo_cpa_detector_stop(RAYO_ACTOR(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name); - unsubscribe(RAYO_ACTOR(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name, RAYO_JID(cpa)); - } - } - switch_core_hash_destroy(&cpa->signals); - cpa->signals = NULL; - } - unsubscribe(RAYO_ACTOR(cpa)->parent->id, "hangup", RAYO_JID(cpa)); -} - -/** - * Stop execution of CPA component - */ -static iks *stop_cpa_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - stop_cpa_detectors(CPA_COMPONENT(component)); - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); - return iks_new_iq_result(msg->payload); -} - -/** - * Forward CPA signal to client - */ -static void rayo_cpa_detector_event(const char *jid, void *user_data) -{ - struct rayo_actor *component = RAYO_LOCATE(jid); - if (component) { - if (CPA_COMPONENT(component)->ready) { - switch_event_t *event = (switch_event_t *)user_data; - const char *signal_type = switch_event_get_header(event, "signal-type"); - struct cpa_signal *cpa_signal = switch_core_hash_find(CPA_COMPONENT(component)->signals, signal_type); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(component->parent->id), SWITCH_LOG_DEBUG, "Handling CPA event\n"); - if (cpa_signal) { - const char *value = switch_event_get_header(event, "value"); - const char *duration = switch_event_get_header(event, "duration"); - if (cpa_signal->terminate) { - iks *complete_event; - iks *signal_xml; - - stop_cpa_detectors(CPA_COMPONENT(component)); - - /* send complete event to client */ - complete_event = rayo_component_create_complete_event(RAYO_COMPONENT(component), "signal", RAYO_CPA_NS); - signal_xml = iks_find(complete_event, "complete"); - signal_xml = iks_find(signal_xml, "signal"); - iks_insert_attrib(signal_xml, "type", signal_type); - if (!zstr(value)) { - iks_insert_attrib(signal_xml, "value", value); - } - if (!zstr(duration)) { - iks_insert_attrib(signal_xml, "duration", duration); - } - rayo_component_send_complete_event(RAYO_COMPONENT(component), complete_event); - } else { - /* send event to client */ - iks *signal_event = iks_new_presence("signal", RAYO_CPA_NS, RAYO_JID(component), RAYO_COMPONENT(component)->client_jid); - iks *signal_xml = iks_find(signal_event, "signal"); - iks_insert_attrib(signal_xml, "type", signal_type); - if (!zstr(value)) { - iks_insert_attrib(signal_xml, "value", value); - } - if (!zstr(duration)) { - iks_insert_attrib(signal_xml, "duration", duration); - } - RAYO_SEND_REPLY(component, RAYO_COMPONENT(component)->client_jid, signal_event); - } - } - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(component->parent->id), SWITCH_LOG_DEBUG, "Skipping CPA event\n"); - } - RAYO_RELEASE(component); - } -} - -/** - * Handle CPA signal-type event - */ -static void on_rayo_cpa_detector_event(switch_event_t *event) -{ - subscriber_execute(switch_event_get_header(event, "Unique-ID"), switch_event_get_header(event, "signal-type"), rayo_cpa_detector_event, event); -} - -/** - * Handle CPA completion because of hangup - */ -static void rayo_cpa_component_hangup(const char *jid, void *user_data) -{ - struct rayo_actor *component = RAYO_LOCATE(jid); - if (component) { - stop_cpa_detectors(CPA_COMPONENT(component)); - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_HANGUP); - RAYO_RELEASE(component); - } -} - -/** - * Handle hungup call event - */ -static void on_channel_hangup_complete_event(switch_event_t *event) -{ - subscriber_execute(switch_event_get_header(event, "Unique-ID"), "hangup", rayo_cpa_component_hangup, event); -} - -/** - * Start CPA - */ -iks *rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *input = iks_find(iq, "input"); - switch_memory_pool_t *pool = NULL; - struct cpa_component *component = NULL; - int have_grammar = 0; - iks *grammar = NULL; - - /* create CPA component */ - switch_core_new_memory_pool(&pool); - component = switch_core_alloc(pool, sizeof(*component)); - component = CPA_COMPONENT(rayo_component_init((struct rayo_component *)component, pool, RAT_CALL_COMPONENT, "cpa", NULL, call, iks_find_attrib(iq, "from"))); - if (!component) { - switch_core_destroy_memory_pool(&pool); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create CPA entity"); - } - - switch_core_hash_init(&component->signals); - - /* start CPA detectors */ - for (grammar = iks_find(input, "grammar"); grammar; grammar = iks_next_tag(grammar)) { - if (!strcmp("grammar", iks_name(grammar))) { - const char *error_str = ""; - const char *url = iks_find_attrib_soft(grammar, "url"); - char *url_dup; - char *url_params; - - if (zstr(url)) { - stop_cpa_detectors(component); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing grammar URL"); - } - have_grammar = 1; - - url_dup = strdup(url); - switch_assert(url_dup); - if ((url_params = strchr(url_dup, '?'))) { - *url_params = '\0'; - url_params++; - } - - if (switch_core_hash_find(component->signals, url)) { - free(url_dup); - stop_cpa_detectors(component); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Duplicate URL"); - } - - /* start detector */ - /* TODO return better reasons... */ - if (rayo_cpa_detector_start(switch_core_session_get_uuid(session), url_dup, &error_str)) { - struct cpa_signal *cpa_signal = switch_core_alloc(pool, sizeof(*cpa_signal)); - cpa_signal->terminate = !zstr(url_params) && strstr(url_params, "terminate=true"); - cpa_signal->name = switch_core_strdup(pool, url_dup); - switch_core_hash_insert(component->signals, cpa_signal->name, cpa_signal); - subscribe(switch_core_session_get_uuid(session), cpa_signal->name, RAYO_JID(component)); - } else { - free(url_dup); - stop_cpa_detectors(component); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, error_str); - } - - free(url_dup); - } - } - - if (!have_grammar) { - stop_cpa_detectors(component); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "No grammar defined"); - } - - /* acknowledge command */ - rayo_component_send_start(RAYO_COMPONENT(component), iq); - - /* TODO hangup race condition */ - subscribe(switch_core_session_get_uuid(session), "hangup", RAYO_JID(component)); - - /* ready to forward detector events */ - component->ready = 1; - - return NULL; -} - -/** - * Load input CPA - * @param module_interface - * @param pool memory pool - * @param config_file - * @return SWITCH_STATUS_SUCCESS if successfully loaded - */ -switch_status_t rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "cpa", "set:"RAYO_EXT_NS":stop", stop_cpa_component); - switch_event_bind("rayo_cpa_component", SWITCH_EVENT_CUSTOM, "rayo::cpa", on_rayo_cpa_detector_event, NULL); - switch_event_bind("rayo_cpa_component", SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE, NULL, on_channel_hangup_complete_event, NULL); - - globals.pool = pool; - switch_core_hash_init(&globals.subscribers); - switch_mutex_init(&globals.subscribers_mutex, SWITCH_MUTEX_NESTED, pool); - - return rayo_cpa_detector_load(module_interface, pool, config_file); -} - -/** - * Stop input CPA - */ -void rayo_cpa_component_shutdown(void) -{ - switch_event_unbind_callback(on_rayo_cpa_detector_event); - switch_event_unbind_callback(on_channel_hangup_complete_event); - rayo_cpa_detector_shutdown(); - if (globals.subscribers) { - switch_core_hash_destroy(&globals.subscribers); - } -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_component.h b/src/mod/event_handlers/mod_rayo/rayo_cpa_component.h deleted file mode 100644 index 442ec1f4c8..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_component.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2014, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_cpa_component.h -- Rayo call progress analysis component - * - */ -#ifndef RAYO_CPA_COMPONENT_H -#define RAYO_CPA_COMPONENT_H - -#include -#include - -#include "mod_rayo.h" - -SWITCH_DECLARE(switch_status_t) rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(void) rayo_cpa_component_shutdown(void); -SWITCH_DECLARE(iks *) rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data); - -#endif - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c deleted file mode 100644 index 6a85db561b..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2014-2015, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_cpa_detector.c -- Glue to normalize events from and to allow multiple instantiation of various detectors in FreeSWITCH - */ - -#include "rayo_cpa_detector.h" - -static struct { - /** detectors supported by this module mapped by signal-type */ - switch_hash_t *detectors; - /** synchronizes access to detectors */ - switch_mutex_t *detectors_mutex; -} globals; - -struct rayo_cpa_detector; - -/** - * Detector definition - */ -struct rayo_cpa_detector { - /** unique internal name of this detector */ - const char *name; - /** detector ID */ - const char *uuid; - /** start detection APP */ - const char *start_app; - /** args to pass to start detection app */ - const char *start_app_args; - /** stop detection APP */ - const char *stop_app; - /** args to pass to stop detection app */ - const char *stop_app_args; - /** (optional) name of header to get the signal type from */ - const char *signal_type_header; - /** (optional) where to get the signal value from the event */ - const char *signal_value_header; - /** (optional) where to get the signal duration from the event */ - const char *signal_duration_header; - /** detector event to signal type mapping */ - switch_hash_t *signal_type_map; -}; - -/** - * Detection state - */ -struct rayo_cpa_detector_state { - /** reference count */ - int refs; -}; - -/** - * Start detecting - * @param call_uuid call to detect signal on - * @param signal_ns namespace of signal to detect - * @param error_detail on failure, describes the error - * @return 1 if successful, 0 if failed - */ -int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail) -{ - struct rayo_cpa_detector *detector = switch_core_hash_find(globals.detectors, signal_ns); - switch_core_session_t *session; - if (detector) { - if (zstr(detector->start_app)) { - /* nothing to do */ - return 1; - } - session = switch_core_session_locate(call_uuid); - if (session) { - struct rayo_cpa_detector_state *detector_state = switch_channel_get_private(switch_core_session_get_channel(session), detector->uuid); - if (detector_state) { - /* detector is already running */ - detector_state->refs++; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Start detector %s, refs = %d\n", detector->name, detector_state->refs); - switch_core_session_rwunlock(session); - return 1; - } - detector_state = switch_core_session_alloc(session, sizeof(*detector_state)); - detector_state->refs = 1; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Starting detector %s, refs = 1\n", detector->name); - switch_channel_set_private(switch_core_session_get_channel(session), detector->uuid, detector_state); - switch_core_session_execute_application_async(session, detector->start_app, zstr(detector->start_app_args) ? NULL : detector->start_app_args); - switch_core_session_rwunlock(session); - return 1; - } else { - *error_detail = "session gone"; - return 0; - } - } - *error_detail = "detector not supported"; - return 0; -} - -/** - * Stop detecting - * @param call_uuid call to stop detecting signal on - * @param signal_ns name of signal to stop detecting - */ -void rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns) -{ - struct rayo_cpa_detector *detector = switch_core_hash_find(globals.detectors, signal_ns); - switch_core_session_t *session; - if (detector) { - if (zstr(detector->stop_app)) { - /* nothing to do */ - return; - } - session = switch_core_session_locate(call_uuid); - if (session) { - struct rayo_cpa_detector_state *detector_state = switch_channel_get_private(switch_core_session_get_channel(session), detector->uuid); - if (detector_state) { - detector_state->refs--; - if (detector_state->refs < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Stop detector %s refs = %d\n", detector->name, detector_state->refs); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stop detector %s refs = %d\n", detector->name, detector_state->refs); - } - if (detector_state->refs == 0) { - /* nobody interested in detector events- shut it down */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stopping detector %s\n", detector->name); - switch_core_session_execute_application_async(session, detector->stop_app, zstr(detector->stop_app_args) ? NULL : detector->stop_app_args); - switch_channel_set_private(switch_core_session_get_channel(session), detector->uuid, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Detector %s is already stopped\n", detector->name); - } - switch_core_session_rwunlock(session); - } - } -} - -/** - * Handle event from detector - */ -static void rayo_cpa_detector_event(switch_event_t *event) -{ - struct rayo_cpa_detector *detector = (struct rayo_cpa_detector *)event->bind_user_data; - if (detector) { - const char *signal_type = "rayo_default"; - if (!zstr(detector->signal_type_header)) { - signal_type = switch_event_get_header(event, detector->signal_type_header); - } - if (!zstr(signal_type)) { - signal_type = switch_core_hash_find(detector->signal_type_map, signal_type); - } - if (!zstr(signal_type)) { - switch_event_t *cpa_event; - const char *uuid = switch_event_get_header(event, "Unique-ID"); - if (zstr(uuid)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s %s event is missing call UUID!\n", detector->name, signal_type); - return; - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got Rayo CPA event %s\n", signal_type); - if (switch_event_create_subclass(&cpa_event, SWITCH_EVENT_CUSTOM, "rayo::cpa") == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "Unique-ID", uuid); - switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "detector-name", detector->name); - switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "detector-uuid", detector->uuid); - switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "signal-type", "%s%s:%s", RAYO_CPA_BASE, signal_type, RAYO_VERSION); - if (!zstr(detector->signal_value_header)) { - const char *value = switch_event_get_header(event, detector->signal_value_header); - if (!zstr(value)) { - switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "value", value); - } - } - if (!zstr(detector->signal_duration_header)) { - const char *duration = switch_event_get_header(event, detector->signal_duration_header); - if (!zstr(duration)) { - switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "duration", duration); - } - } - switch_event_fire(&cpa_event); - } - } else { - /* couldn't map event to Rayo signal-type */ - const char *event_name = switch_event_get_header(event, "Event-Name"); - const char *event_subclass = switch_event_get_header(event, "Event-Subclass"); - if (zstr(event_subclass)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to find Rayo signal-type for event %s\n", event_name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to find Rayo signal-type for event %s %s\n", event_name, event_subclass); - } - } - } -} - -#define RAYO_CPA_DETECTOR_SYNTAX "rayo_cpa " -SWITCH_STANDARD_API(rayo_cpa_detector_api) -{ - char *cmd_dup = NULL; - char *argv[4] = { 0 }; - int argc = 0; - - if (zstr(cmd)) { - stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_CPA_DETECTOR_SYNTAX); - goto done; - } - - cmd_dup = strdup(cmd); - argc = switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); - - if (argc != 3) { - stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_CPA_DETECTOR_SYNTAX); - } else { - const char *err_reason = NULL; - if (!strcmp(argv[2], "stop")) { - rayo_cpa_detector_stop(argv[0], argv[1]); - stream->write_function(stream, "+OK\n"); - } else if (!strcmp(argv[2], "start")) { - if (!rayo_cpa_detector_start(argv[0], argv[1], &err_reason)) { - if (err_reason) { - stream->write_function(stream, "-ERR: %s\n", err_reason); - } else { - stream->write_function(stream, "-ERR\n"); - } - } else { - stream->write_function(stream, "+OK\n"); - } - } else { - stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_CPA_DETECTOR_SYNTAX); - } - } - -done: - switch_safe_free(cmd_dup); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Detector definition destructor - */ -static void destroy_detector(void *ptr) -{ - struct rayo_cpa_detector *detector = (struct rayo_cpa_detector *) ptr; - if (detector->signal_type_map) { - switch_core_hash_destroy(&detector->signal_type_map); - } -} - -/** - * Configure CPA - */ -static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) -{ - switch_xml_t cfg, xml, cpa_xml; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_hash_t *bound_events; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Configuring CPA\n"); - if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); - return SWITCH_STATUS_TERM; - } - - switch_core_hash_init(&bound_events); - - cpa_xml = switch_xml_child(cfg, "cpa"); - if (cpa_xml) { - switch_xml_t detector_xml; - - for (detector_xml = switch_xml_child(cpa_xml, "detector"); detector_xml; detector_xml = detector_xml->next) { - switch_xml_t start_xml, stop_xml, event_xml; - struct rayo_cpa_detector *detector; - char id[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - const char *name = switch_xml_attr_soft(detector_xml, "name"); - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing name of CPA detector!\n"); - status = SWITCH_STATUS_TERM; - goto done; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CPA detector: %s\n", name); - detector = switch_core_alloc(pool, sizeof(*detector)); - switch_core_hash_init(&detector->signal_type_map); - detector->name = switch_core_strdup(pool, name); - switch_uuid_str(id, sizeof(id)); - detector->uuid = switch_core_strdup(pool, id); - - start_xml = switch_xml_child(detector_xml, "start"); - if (start_xml) { - detector->start_app = switch_core_strdup(pool, switch_xml_attr_soft(start_xml, "application")); - detector->start_app_args = switch_core_strdup(pool, switch_xml_attr_soft(start_xml, "data")); - } - - stop_xml = switch_xml_child(detector_xml, "stop"); - if (stop_xml) { - detector->stop_app = switch_core_strdup(pool, switch_xml_attr_soft(stop_xml, "application")); - detector->stop_app_args = switch_core_strdup(pool, switch_xml_attr_soft(stop_xml, "data")); - } - - event_xml = switch_xml_child(detector_xml, "event"); - if (event_xml) { - int event_ok = 0; - switch_xml_t signal_type_xml; - const char *event_class = switch_xml_attr_soft(event_xml, "class"); - const char *event_subclass = switch_xml_attr_soft(event_xml, "subclass"); - switch_event_types_t event_type; - if (zstr(event_class)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing event class for CPA detector: %s\n", detector->name); - status = SWITCH_STATUS_TERM; - goto done; - } - - if (switch_name_event(event_class, &event_type) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event class %s for CPA detector: %s\n", event_class, detector->name); - status = SWITCH_STATUS_TERM; - goto done; - } - - /* bind detector to event if not already done... */ - { - struct rayo_cpa_detector *bound_detector; - const char *event_name = switch_core_sprintf(pool, "%s %s", event_class, event_subclass); - if (!(bound_detector = switch_core_hash_find(bound_events, event_name))) { - /* not yet bound */ - if (zstr(event_subclass)) { - event_subclass = NULL; - } - switch_event_bind("rayo_cpa_detector", event_type, event_subclass, rayo_cpa_detector_event, detector); - switch_core_hash_insert(bound_events, event_name, detector); /* mark as bound */ - } else if (bound_detector != detector) { - /* can't have multiple detectors generating the same event! */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s attempted to bind to event %s that is already bound by %s\n", detector->name, event_name, bound_detector->name); - status = SWITCH_STATUS_TERM; - goto done; - } - } - - /* configure native event -> rayo CPA event mapping */ - detector->signal_type_header = switch_core_strdup(pool, switch_xml_attr_soft(event_xml, "type-header")); - detector->signal_value_header = switch_core_strdup(pool, switch_xml_attr_soft(event_xml, "value-header")); - detector->signal_duration_header = switch_core_strdup(pool, switch_xml_attr_soft(event_xml, "duration-header")); - - /* configure native event type -> rayo CPA signal type mapping */ - for (signal_type_xml = switch_xml_child(event_xml, "signal-type"); signal_type_xml; signal_type_xml = signal_type_xml->next) { - const char *header_value = switch_core_strdup(pool, switch_xml_attr_soft(signal_type_xml, "header-value")); - const char *signal_type = switch_core_strdup(pool, switch_xml_attr_soft(signal_type_xml, "value")); - if (zstr(signal_type)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s missing signal-type value!\n", detector->name); - status = SWITCH_STATUS_TERM; - goto done; - } else { - /* add signal-type to detector mapping if not already done for this detector */ - const char *signal_type_ns = switch_core_sprintf(pool, "%s%s:%s", RAYO_CPA_BASE, signal_type, RAYO_VERSION); - struct rayo_cpa_detector *bound_detector = switch_core_hash_find(globals.detectors, signal_type_ns); - if (!bound_detector) { - switch_core_hash_insert_destructor(globals.detectors, signal_type_ns, detector, destroy_detector); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding CPA %s => %s\n", signal_type_ns, detector->name); - event_ok = 1; - } else if (bound_detector == detector) { - /* detector has multiple signal-type configs w/ same value */ - event_ok = 1; - } else { - /* multiple detectors with same signal-type value */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s configured to handle signal-type %s that is already handled by %s\n", detector->name, signal_type, bound_detector->name); - status = SWITCH_STATUS_TERM; - goto done; - } - } - - /* map event value to signal-type */ - if (zstr(header_value)) { - switch_core_hash_insert(detector->signal_type_map, "rayo_default", signal_type); - } else { - switch_core_hash_insert(detector->signal_type_map, header_value, signal_type); - } - } - - if (!event_ok) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s is missing Rayo signal-type for event\n", detector->name); - status = SWITCH_STATUS_TERM; - goto done; - } - } - } - } - -done: - switch_core_hash_destroy(&bound_events); - switch_xml_free(xml); - - return status; -} - -/** - * Console auto-completion for signal types - */ -static switch_status_t rayo_cpa_detector_signal_types(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - switch_status_t status = SWITCH_STATUS_FALSE; - switch_hash_index_t *hi; - void *val; - const void *vvar; - switch_console_callback_match_t *my_matches = NULL; - - switch_mutex_lock(globals.detectors_mutex); - for (hi = switch_core_hash_first(globals.detectors); hi; hi = switch_core_hash_next(&hi)) { - switch_core_hash_this(hi, &vvar, NULL, &val); - switch_console_push_match(&my_matches, (const char *) vvar); - } - switch_mutex_unlock(globals.detectors_mutex); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -/** - * Load CPA signal detection features - * @param module_interface - * @param pool memory pool - * @param config_file - * @return SWITCH_STATUS_SUCCESS if successfully loaded - */ -switch_status_t rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - switch_api_interface_t *api_interface; - - switch_core_hash_init(&globals.detectors); - switch_mutex_init(&globals.detectors_mutex, SWITCH_MUTEX_NESTED, pool); - - if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - - SWITCH_ADD_API(api_interface, "rayo_cpa", "Query rayo status", rayo_cpa_detector_api, RAYO_CPA_DETECTOR_SYNTAX); - - switch_console_set_complete("add rayo_cpa ::console::list_uuid ::rayo_cpa::list_signal_types start"); - switch_console_set_complete("add rayo_cpa ::console::list_uuid ::rayo_cpa::list_signal_types stop"); - switch_console_add_complete_func("::rayo_cpa::list_signal_types", rayo_cpa_detector_signal_types); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Disable CPA signal detection features - */ -void rayo_cpa_detector_shutdown(void) -{ - switch_console_set_complete("del rayo_cpa"); - switch_console_del_complete_func("::rayo_cpa::list_signal_types"); - if (globals.detectors) { - switch_core_hash_destroy(&globals.detectors); - } - switch_event_unbind_callback(rayo_cpa_detector_event); -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h deleted file mode 100644 index fec720dadf..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2014, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_cpa_detector.h -- Rayo call progress analysis - * - */ -#ifndef RAYO_CPA_DETECTOR_H -#define RAYO_CPA_DETECTOR_H - -#include - -#include "mod_rayo.h" - -SWITCH_DECLARE(switch_status_t) rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -SWITCH_DECLARE(void) rayo_cpa_detector_shutdown(void); -SWITCH_DECLARE(int) rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail); -SWITCH_DECLARE(void) rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns); - -#endif - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c deleted file mode 100644 index 14e9c61c55..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_elements.c -- Rayo XML element definition - * - */ -#include "rayo_elements.h" - -/** - * component validation - */ -ELEMENT(RAYO_INPUT) - ATTRIB(xmlns,, any) - STRING_ATTRIB(mode, any, "any,dtmf,voice,cpa") - OPTIONAL_ATTRIB(terminator,, dtmf_digit) - ATTRIB(recognizer,, any) - ATTRIB(language, en-US, any) - ATTRIB(initial-timeout, -1, positive_or_neg_one) - ATTRIB(inter-digit-timeout, -1, positive_or_neg_one) - ATTRIB(sensitivity, 0.5, decimal_between_zero_and_one) - ATTRIB(min-confidence, 0, decimal_between_zero_and_one) - ATTRIB(max-silence, -1, positive_or_neg_one) - STRING_ATTRIB(match-content-type, application/nlsml+xml, "application/nlsml+xml") - /* internal attribs for prompt support */ - ATTRIB(barge-event, false, bool) - ATTRIB(start-timers, true, bool) -ELEMENT_END - -/** - * command validation - */ -ELEMENT(RAYO_JOIN) - ATTRIB(xmlns,, any) - STRING_ATTRIB(direction, duplex, "send,recv,duplex") - STRING_ATTRIB(media, bridge, "bridge,direct") - ATTRIB(call-uri,, any) - ATTRIB(mixer-name,, any) -ELEMENT_END - -/** - * component validation - */ -ELEMENT(RAYO_OUTPUT) - ATTRIB(xmlns,, any) - ATTRIB(start-offset, 0, not_negative) - ATTRIB(start-paused, false, bool) - ATTRIB(repeat-interval, 0, not_negative) - ATTRIB(repeat-times, 1, not_negative) - ATTRIB(max-time, -1, positive_or_neg_one) - ATTRIB(renderer,, any) - ATTRIB(voice,, any) - STRING_ATTRIB(direction, out, "out,in") -ELEMENT_END - -/** - * validation - */ -ELEMENT(RAYO_OUTPUT_SEEK) - ATTRIB(xmlns,, any) - STRING_ATTRIB(direction,, "forward,back") - ATTRIB(amount,-1, positive) -ELEMENT_END - -/** - * component validation - */ -ELEMENT(RAYO_PROMPT) - ATTRIB(xmlns,, any) - ATTRIB(barge-in, true, bool) -ELEMENT_END - -/** - * command validation - */ -ELEMENT(RAYO_RECEIVEFAX) - ATTRIB(xmlns,, any) -ELEMENT_END - -/** - * component validation - */ -ELEMENT(RAYO_RECORD) - ATTRIB(xmlns,, any) - ATTRIB(format, wav, any) - ATTRIB(start-beep, false, bool) - ATTRIB(stop-beep, false, bool) - ATTRIB(start-paused, false, bool) - ATTRIB(max-duration, -1, positive_or_neg_one) - ATTRIB(initial-timeout, -1, positive_or_neg_one) - ATTRIB(final-timeout, -1, positive_or_neg_one) - STRING_ATTRIB(direction, duplex, "duplex,send,recv") - ATTRIB(mix, false, bool) -ELEMENT_END - -/** - * command validation - */ -ELEMENT(RAYO_SENDFAX) - ATTRIB(xmlns,, any) -ELEMENT_END - -/** - * command validation - */ -ELEMENT(RAYO_APP) - ATTRIB(xmlns,, any) - ATTRIB(app,, any) - OPTIONAL_ATTRIB(args,, any) -ELEMENT_END - - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.h b/src/mod/event_handlers/mod_rayo/rayo_elements.h deleted file mode 100644 index dc67a9fa4b..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_elements.h -- Rayo XML elements - * - */ -#ifndef RAYO_ELEMENTS_H -#define RAYO_ELEMENTS_H - -#include "iks_helpers.h" - -ELEMENT_DECL(RAYO_INPUT) -ELEMENT_DECL(RAYO_JOIN) -ELEMENT_DECL(RAYO_OUTPUT) -ELEMENT_DECL(RAYO_OUTPUT_SEEK) -ELEMENT_DECL(RAYO_PROMPT) -ELEMENT_DECL(RAYO_RECEIVEFAX) -ELEMENT_DECL(RAYO_RECORD) -ELEMENT_DECL(RAYO_SENDFAX) -ELEMENT_DECL(RAYO_APP) - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_exec_component.c b/src/mod/event_handlers/mod_rayo/rayo_exec_component.c deleted file mode 100644 index a918f0136d..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_exec_component.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_exec_component.c -- Rayo call application execution component - * - */ -#include "rayo_components.h" -#include "rayo_elements.h" - - -/** - * An exec component - */ -struct exec_component { - /** component base class */ - struct rayo_component base; - /** Dialplan app */ - const char *app; - /** Dialplan app args */ - char *args; -}; - -#define EXEC_COMPONENT(x) ((struct exec_component *)x) - -/** - * Wrapper for executing dialplan app - */ -SWITCH_STANDARD_APP(rayo_app_exec) -{ - if (!zstr(data)) { - struct rayo_component *component = RAYO_COMPONENT_LOCATE(data); - if (component) { - switch_status_t status; - switch_channel_set_variable(switch_core_session_get_channel(session), SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, ""); - status = switch_core_session_execute_application(session, EXEC_COMPONENT(component)->app, EXEC_COMPONENT(component)->args); - if (status != SWITCH_STATUS_SUCCESS) { - rayo_component_send_complete(component, COMPONENT_COMPLETE_ERROR); - } else { - const char *resp = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE); - if (zstr(resp)) { - rayo_component_send_complete(component, COMPONENT_COMPLETE_DONE); - } else { - /* send complete event to client */ - iks *response = iks_new("app"); - iks_insert_attrib(response, "xmlns", RAYO_EXEC_COMPLETE_NS); - iks_insert_attrib(response, "response", resp); - rayo_component_send_complete_with_metadata(component, COMPONENT_COMPLETE_DONE, response, 1); - iks_delete(response); - } - } - RAYO_RELEASE(component); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Missing rayo exec component JID\n"); - } - switch_channel_set_variable(switch_core_session_get_channel(session), SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, ""); -} - -/** - * Create a record component - */ -static struct rayo_component *exec_component_create(struct rayo_actor *call, const char *client_jid, iks *exec) -{ - switch_memory_pool_t *pool; - struct exec_component *exec_component = NULL; - - switch_core_new_memory_pool(&pool); - exec_component = switch_core_alloc(pool, sizeof(*exec_component)); - exec_component = EXEC_COMPONENT(rayo_component_init(RAYO_COMPONENT(exec_component), pool, RAT_CALL_COMPONENT, "exec", NULL, call, client_jid)); - if (exec_component) { - exec_component->app = switch_core_strdup(pool, iks_find_attrib_soft(exec, "app")); - exec_component->args = switch_core_strdup(pool, iks_find_attrib_soft(exec, "args")); - } else { - switch_core_destroy_memory_pool(&pool); - return NULL; - } - - return RAYO_COMPONENT(exec_component); -} - -/** - * Execute dialplan APP on rayo call - */ -static iks *start_exec_app_component(struct rayo_actor *call, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *exec = iks_find(iq, "app"); - struct rayo_component *exec_component = NULL; - switch_core_session_t *session = NULL; - - /* validate record attributes */ - if (!VALIDATE_RAYO_APP(exec)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - exec_component = exec_component_create(call, iks_find_attrib(iq, "from"), exec); - if (!exec_component) { - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create exec entity"); - } - - session = switch_core_session_locate(call->id); - if (session) { - if (switch_core_session_execute_application_async(session, switch_core_session_strdup(session, "rayo-app-exec"), switch_core_session_strdup(session, RAYO_JID(exec_component))) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - RAYO_RELEASE(exec_component); - RAYO_DESTROY(exec_component); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to execute app"); - } - switch_core_session_rwunlock(session); - } else { - RAYO_RELEASE(exec_component); - RAYO_DESTROY(exec_component); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Call is gone"); - } - - rayo_component_send_start(exec_component, iq); - - return NULL; -} - -/** - * Initialize exec component - * @param module_interface - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_exec_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - switch_application_interface_t *app_interface; - SWITCH_ADD_APP(app_interface, "rayo-app-exec", "Wrapper dialplan app for internal use only", "", rayo_app_exec, "", SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC); - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_EXEC_NS":app", start_exec_app_component); - return SWITCH_STATUS_SUCCESS; -} - -/** - * Shutdown exec component - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_exec_component_shutdown(void) -{ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c deleted file mode 100644 index b605702005..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2014, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_fax_components.c -- Rayo receivefax and sendfax components implementation - * - */ -#include "rayo_components.h" -#include "rayo_elements.h" - -/** - * settings - */ -static struct { - const char *file_prefix; -} globals; - -struct fax_component { - /** component base class */ - struct rayo_component base; - /** Flag to stop fax */ - int stop; -}; - -#define FAX_COMPONENT(x) ((struct fax_component *)x) - -struct receivefax_component { - /** fax component base class */ - struct fax_component base; - /** true if HTTP PUT needs to be done after fax is received */ - int http_put_after_receive; - /** fax stored on local filesystem */ - const char *local_filename; - /** fax final target (may be same as local filename) */ - const char *filename; -}; - -#define RECEIVEFAX_COMPONENT(x) ((struct receivefax_component *)x) - -#define FAX_FINISH "finish", RAYO_FAX_COMPLETE_NS - -/** - * Start execution of call sendfax component - * @param call the call to send fax to - * @param msg the original request - * @param session_data the call's session - */ -static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - struct fax_component *sendfax_component = NULL; - iks *sendfax = iks_find(iq, "sendfax"); - iks *response = NULL; - switch_event_t *execute_event = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_memory_pool_t *pool; - iks *document; - const char *fax_document; - const char *fax_header; - const char *fax_identity; - const char *pages; - - /* validate attributes */ - if (!VALIDATE_RAYO_SENDFAX(sendfax)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - /* fax is only allowed if the call is not currently joined */ - if (rayo_call_is_joined(RAYO_CALL(call))) { - return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't send fax on a joined call"); - } - - if (rayo_call_is_faxing(RAYO_CALL(call))) { - return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress"); - } - - /* get fax document */ - document = iks_find(sendfax, "document"); - if (!document) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "missing document"); - } - fax_document = iks_find_attrib_soft(document, "url"); - if (zstr(fax_document)) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "missing document url"); - } - - /* is valid URL type? */ - if (!strncasecmp(fax_document, "http://", 7) || !strncasecmp(fax_document, "https://", 8)) { - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - /* need to fetch document from server... */ - switch_api_execute("http_get", fax_document, session, &stream); - if (!zstr(stream.data) && !strncmp(fax_document, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { - fax_document = switch_core_session_strdup(session, stream.data); - } else { - switch_safe_free(stream.data); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to fetch document"); - } - switch_safe_free(stream.data); - } else if (!strncasecmp(fax_document, "file://", 7)) { - fax_document = fax_document + 7; - if (zstr(fax_document)) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid file:// url"); - } - } else if (strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "unsupported url type"); - } - - /* does document exist? */ - if (switch_file_exists(fax_document, NULL) != SWITCH_STATUS_SUCCESS) { - return iks_new_error_detailed_printf(iq, STANZA_ERROR_BAD_REQUEST, "file not found: %s", fax_document); - } - - /* get fax identity and header */ - fax_identity = iks_find_attrib_soft(document, "identity"); - if (!zstr(fax_identity)) { - switch_channel_set_variable(channel, "fax_ident", fax_identity); - } else { - switch_channel_set_variable(channel, "fax_ident", NULL); - } - fax_header = iks_find_attrib_soft(document, "header"); - if (!zstr(fax_header)) { - switch_channel_set_variable(channel, "fax_header", fax_header); - } else { - switch_channel_set_variable(channel, "fax_header", NULL); - } - - /* get pages to send */ - pages = iks_find_attrib_soft(document, "pages"); - if (!zstr(pages)) { - if (switch_regex_match(pages, "[1-9][0-9]*(-[1-9][0-9]*)?") == SWITCH_STATUS_FALSE) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid pages value"); - } else { - int start = 0; - int end = 0; - char *pages_dup = switch_core_session_strdup(session, pages); - char *sep = strchr(pages_dup, '-'); - if (sep) { - *sep = '\0'; - sep++; - end = atoi(sep); - } - start = atoi(pages_dup); - if (end && end < start) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid pages value"); - } - switch_channel_set_variable(channel, "fax_start_page", pages_dup); - switch_channel_set_variable(channel, "fax_end_page", sep); - } - } else { - switch_channel_set_variable(channel, "fax_start_page", NULL); - switch_channel_set_variable(channel, "fax_end_page", NULL); - } - - /* create sendfax component */ - switch_core_new_memory_pool(&pool); - sendfax_component = switch_core_alloc(pool, sizeof(*sendfax_component)); - sendfax_component = FAX_COMPONENT(rayo_component_init((struct rayo_component *)sendfax_component, pool, RAT_CALL_COMPONENT, "sendfax", NULL, call, iks_find_attrib(iq, "from"))); - if (!sendfax_component) { - switch_core_destroy_memory_pool(&pool); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create sendfax entity"); - } - - /* add channel variable so that fax component can be located from fax events */ - switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(sendfax_component)); - - /* clear fax result variables */ - switch_channel_set_variable(channel, "fax_success", NULL); - switch_channel_set_variable(channel, "fax_result_code", NULL); - switch_channel_set_variable(channel, "fax_result_text", NULL); - switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL); - switch_channel_set_variable(channel, "fax_document_total_pages", NULL); - switch_channel_set_variable(channel, "fax_image_resolution", NULL); - switch_channel_set_variable(channel, "fax_image_size", NULL); - switch_channel_set_variable(channel, "fax_bad_rows", NULL); - switch_channel_set_variable(channel, "fax_transfer_rate", NULL); - switch_channel_set_variable(channel, "fax_ecm_used", NULL); - switch_channel_set_variable(channel, "fax_local_station_id", NULL); - switch_channel_set_variable(channel, "fax_remote_station_id", NULL); - - rayo_call_set_faxing(RAYO_CALL(call), 1); - - /* execute txfax APP */ - if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "txfax"); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", fax_document); - if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { - switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); - } - - if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to txfax (queue event failed)"); - if (execute_event) { - switch_event_destroy(&execute_event); - } - rayo_call_set_faxing(RAYO_CALL(call), 0); - RAYO_RELEASE(sendfax_component); - } else { - /* component starting... */ - rayo_component_send_start(RAYO_COMPONENT(sendfax_component), iq); - } - } else { - response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create txfax event"); - rayo_call_set_faxing(RAYO_CALL(call), 0); - RAYO_RELEASE(sendfax_component); - } - - return response; -} - -/** - * Start execution of call receivefax component - * @param call the call to receive fax from - * @param msg the original request - * @param session_data the call's session - */ -static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - struct receivefax_component *receivefax_component = NULL; - iks *receivefax = iks_find(iq, "receivefax"); - iks *response = NULL; - switch_event_t *execute_event = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_memory_pool_t *pool; - int file_no; - - /* validate attributes */ - if (!VALIDATE_RAYO_RECEIVEFAX(receivefax)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - /* fax is only allowed if the call is not currently joined */ - if (rayo_call_is_joined(RAYO_CALL(call))) { - return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't receive fax on a joined call"); - } - - if (rayo_call_is_faxing(RAYO_CALL(call))) { - return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress"); - } - - /* create receivefax component */ - switch_core_new_memory_pool(&pool); - receivefax_component = switch_core_alloc(pool, sizeof(*receivefax_component)); - receivefax_component = RECEIVEFAX_COMPONENT(rayo_component_init((struct rayo_component *)receivefax_component, pool, RAT_CALL_COMPONENT, "receivefax", NULL, call, iks_find_attrib(iq, "from"))); - if (!receivefax_component) { - switch_core_destroy_memory_pool(&pool); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create sendfax entity"); - } - file_no = rayo_actor_seq_next(call); - receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d.tif", - globals.file_prefix, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); - if (!strncmp(receivefax_component->filename, "http://", 7) || !strncmp(receivefax_component->filename, "https://", 8)) { - /* This is an HTTP URL, need to PUT after fax is received */ - receivefax_component->local_filename = switch_core_sprintf(pool, "%s%s%s-%d", - SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); - receivefax_component->http_put_after_receive = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to HTTP URL\n", RAYO_JID(receivefax_component)); - } else { - /* assume file.. */ - receivefax_component->local_filename = receivefax_component->filename; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to local file\n", RAYO_JID(receivefax_component)); - } - - /* add channel variable so that fax component can be located from fax events */ - switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(receivefax_component)); - - /* clear fax result variables */ - switch_channel_set_variable(channel, "fax_success", NULL); - switch_channel_set_variable(channel, "fax_result_code", NULL); - switch_channel_set_variable(channel, "fax_result_text", NULL); - switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL); - switch_channel_set_variable(channel, "fax_document_total_pages", NULL); - switch_channel_set_variable(channel, "fax_image_resolution", NULL); - switch_channel_set_variable(channel, "fax_image_size", NULL); - switch_channel_set_variable(channel, "fax_bad_rows", NULL); - switch_channel_set_variable(channel, "fax_transfer_rate", NULL); - switch_channel_set_variable(channel, "fax_ecm_used", NULL); - switch_channel_set_variable(channel, "fax_local_station_id", NULL); - switch_channel_set_variable(channel, "fax_remote_station_id", NULL); - - rayo_call_set_faxing(RAYO_CALL(call), 1); - - /* execute rxfax APP */ - if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "rxfax"); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", receivefax_component->local_filename); - if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { - switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); - } - - if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to rxfax (queue event failed)"); - if (execute_event) { - switch_event_destroy(&execute_event); - } - rayo_call_set_faxing(RAYO_CALL(call), 0); - RAYO_RELEASE(receivefax_component); - } else { - /* component starting... */ - rayo_component_send_start(RAYO_COMPONENT(receivefax_component), iq); - } - } else { - response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create rxfax event"); - rayo_call_set_faxing(RAYO_CALL(call), 0); - RAYO_RELEASE(receivefax_component); - } - - return response; -} - -/** - * Stop execution of fax component - */ -static iks *stop_fax_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = switch_core_session_locate(component->parent->id); - FAX_COMPONENT(component)->stop = 1; - if (session) { - switch_core_session_execute_application_async(session, "stopfax", ""); - switch_core_session_rwunlock(session); - } - return iks_new_iq_result(iq); -} - -/** - * Add fax metadata to result - * @param event source of metadata - * @param name of metadata - * @param result to add metadata to - */ -static void insert_fax_metadata(switch_event_t *event, const char *name, iks *result) -{ - char actual_name[256]; - const char *value; - snprintf(actual_name, sizeof(actual_name), "variable_%s", name); - actual_name[sizeof(actual_name) - 1] = '\0'; - value = switch_event_get_header(event, actual_name); - if (!zstr(value)) { - iks *metadata = iks_insert(result, "metadata"); - iks_insert_attrib(metadata, "xmlns", RAYO_FAX_COMPLETE_NS); - iks_insert_attrib(metadata, "name", name); - iks_insert_attrib(metadata, "value", value); - } -} - -/** - * Handle fax completion event from FreeSWITCH core - * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. - */ -static void on_execute_complete_event(switch_event_t *event) -{ - const char *application = switch_event_get_header(event, "Application"); - - if (!zstr(application) && (!strcmp(application, "rxfax") || !strcmp(application, "txfax"))) { - int is_rxfax = !strcmp(application, "rxfax"); - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *fax_jid = switch_event_get_header(event, "variable_rayo_fax_jid"); - struct rayo_actor *component; - if (!zstr(fax_jid) && (component = RAYO_LOCATE(fax_jid))) { - iks *result; - iks *complete; - iks *fax; - int have_fax_document = 1; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid); - - /* RX only: transfer HTTP document and delete local copy */ - if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { - char *cmd = switch_core_sprintf(RAYO_POOL(component), "%s %s", RECEIVEFAX_COMPONENT(component)->filename, RECEIVEFAX_COMPONENT(component)->local_filename); - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename); - switch_api_execute("http_put", cmd, NULL, &stream); - /* check if successful */ - if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) { - /* PUT failed */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s PUT fax %s to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->local_filename, RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data); - have_fax_document = 0; - } - switch_safe_free(stream.data) - switch_file_remove(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)); - } - - /* successful fax? */ - if (have_fax_document && switch_true(switch_event_get_header(event, "variable_fax_success"))) { - result = rayo_component_create_complete_event(RAYO_COMPONENT(component), FAX_FINISH); - } else if (have_fax_document && FAX_COMPONENT(component)->stop) { - result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); - } else { - result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); - } - complete = iks_find(result, "complete"); - - /* RX only: add fax document information */ - if (is_rxfax && have_fax_document) { - const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages"); - if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) { - const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution"); - const char *size = switch_event_get_header(event, "variable_fax_image_size"); - - fax = iks_insert(complete, "fax"); - iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS); - - if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) { - iks_insert_attrib(fax, "url", RECEIVEFAX_COMPONENT(component)->filename); - } else { - /* convert absolute path to file:// URI */ - iks_insert_attrib_printf(fax, "url", "file://%s", RECEIVEFAX_COMPONENT(component)->filename); - } - - if (!zstr(resolution)) { - iks_insert_attrib(fax, "resolution", resolution); - } - if (!zstr(size)) { - iks_insert_attrib(fax, "size", size); - } - iks_insert_attrib(fax, "pages", pages); - } - } - - /* add metadata from event */ - insert_fax_metadata(event, "fax_success", complete); - insert_fax_metadata(event, "fax_result_code", complete); - insert_fax_metadata(event, "fax_result_text", complete); - insert_fax_metadata(event, "fax_document_transferred_pages", complete); - insert_fax_metadata(event, "fax_document_total_pages", complete); - insert_fax_metadata(event, "fax_image_resolution", complete); - insert_fax_metadata(event, "fax_image_size", complete); - insert_fax_metadata(event, "fax_bad_rows", complete); - insert_fax_metadata(event, "fax_transfer_rate", complete); - insert_fax_metadata(event, "fax_ecm_used", complete); - insert_fax_metadata(event, "fax_local_station_id", complete); - insert_fax_metadata(event, "fax_remote_station_id", complete); - - /* flag faxing as done */ - rayo_call_set_faxing(RAYO_CALL(component->parent), 0); - - rayo_component_send_complete_event(RAYO_COMPONENT(component), result); - - RAYO_RELEASE(component); - } - } -} - -/** - * Process module XML configuration - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS on successful configuration - */ -static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) -{ - switch_xml_t cfg, xml; - - /* set defaults */ - globals.file_prefix = switch_core_sprintf(pool, "%s%s", SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_PATH_SEPARATOR); - - if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); - return SWITCH_STATUS_TERM; - } - - /* get params */ - { - switch_xml_t settings = switch_xml_child(cfg, "fax"); - if (settings) { - switch_xml_t param; - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); - if (!strcasecmp(var, "receivefax-file-prefix")) { - if (!zstr(val)) { - globals.file_prefix = switch_core_strdup(pool, val); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); - } - } - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax-file-prefix = %s\n", globals.file_prefix); - - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Initialize fax components - * @param module_interface - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - - switch_event_bind("rayo_fax_components", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); - - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":receivefax", start_receivefax_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_fax_component); - - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":sendfax", start_sendfax_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "sendfax", "set:"RAYO_EXT_NS":stop", stop_fax_component); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Shutdown fax components - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_fax_components_shutdown(void) -{ - switch_event_unbind_callback(on_execute_complete_event); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c deleted file mode 100644 index 84a8e745cc..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2015, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_input_component.c -- Rayo input component implementation - * - */ -#include "rayo_components.h" -#include "rayo_cpa_component.h" -#include "rayo_elements.h" -#include "srgs.h" -#include "nlsml.h" - -#define MAX_DTMF 256 - -#define INPUT_MATCH_TAG "match" -#define INPUT_MATCH INPUT_MATCH_TAG, RAYO_INPUT_COMPLETE_NS -#define INPUT_NOINPUT "noinput", RAYO_INPUT_COMPLETE_NS -#define INPUT_NOMATCH "nomatch", RAYO_INPUT_COMPLETE_NS - -#define RAYO_INPUT_COMPONENT_PRIVATE_VAR "__rayo_input_component" - -struct input_handler; - -static struct { - /** grammar parser */ - struct srgs_parser *parser; - /** default recognizer to use if none specified */ - const char *default_recognizer; -} globals; - -/** - * Input component state - */ -struct input_component { - /** component base class */ - struct rayo_component base; - /** true if speech detection */ - int speech_mode; - /** Number of collected digits */ - int num_digits; - /** Terminating digit */ - char term_digit; - /** The collected digits */ - char digits[MAX_DTMF + 1]; - /** grammar to match */ - struct srgs_grammar *grammar; - /** time when last digit was received */ - switch_time_t last_digit_time; - /** timeout before first digit is received */ - int initial_timeout; - /** maximum silence allowed */ - int max_silence; - /** minimum speech detection confidence */ - double min_confidence; - /** sensitivity to background noise */ - double sensitivity; - /** timeout after first digit is received */ - int inter_digit_timeout; - /** stop flag */ - int stop; - /** true if input timers started */ - int start_timers; - /** true if event fired for first digit / start of speech */ - int barge_event; - /** optional language to use */ - const char *language; - /** optional recognizer to use */ - const char *recognizer; - /** global data */ - struct input_handler *handler; -}; - -#define INPUT_COMPONENT(x) ((struct input_component *)x) - -/** - * Call input state - */ -struct input_handler { - /** media bug to monitor frames / control input lifecycle */ - switch_media_bug_t *bug; - /** active voice input component */ - struct input_component *voice_component; - /** active dtmf input components */ - switch_hash_t *dtmf_components; - /** synchronizes media bug and dtmf callbacks */ - switch_mutex_t *mutex; - /** last recognizer used */ - const char *last_recognizer; -}; - -/** - * @param digit1 to match - * @param digit2 to match - * @return true if matching - */ -static int digit_test(char digit1, char digit2) -{ - return digit1 && digit2 && tolower(digit1) == tolower(digit2); -} - -/** - * Send match event to client - */ -static void send_match_event(struct rayo_component *component, iks *result) -{ - iks *event = rayo_component_create_complete_event(RAYO_COMPONENT(component), INPUT_MATCH); - iks *match = iks_find(iks_find(event, "complete"), INPUT_MATCH_TAG); - iks_insert_attrib(match, "content-type", "application/nlsml+xml"); - iks_insert_cdata(match, iks_string(iks_stack(result), result), 0); - rayo_component_send_complete_event(component, event); -} - -/** - * Send barge-in event to client - */ -static void send_barge_event(struct rayo_component *component) -{ - iks *event = iks_new("presence"); - iks *x; - iks_insert_attrib(event, "from", RAYO_JID(component)); - iks_insert_attrib(event, "to", component->client_jid); - x = iks_insert(event, "start-of-input"); - iks_insert_attrib(x, "xmlns", RAYO_INPUT_NS); - RAYO_SEND_REPLY(component, component->client_jid, event); -} - -/** - * Check if dtmf component has timed out - */ -static switch_status_t dtmf_component_check_timeout(struct input_component *component, switch_core_session_t *session) -{ - /* check for stopped component */ - if (component->stop) { - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); - - /* let handler know component is done */ - return SWITCH_STATUS_FALSE; - } - - /* check for timeout */ - if (component->start_timers) { - int elapsed_ms = (switch_micro_time_now() - component->last_digit_time) / 1000; - if (component->num_digits && component->inter_digit_timeout > 0 && elapsed_ms > component->inter_digit_timeout) { - enum srgs_match_type match; - const char *interpretation = NULL; - - /* we got some input, check for match */ - match = srgs_grammar_match(component->grammar, component->digits, &interpretation); - if (match == SMT_MATCH || match == SMT_MATCH_END) { - iks *result = nlsml_create_dtmf_match(component->digits, interpretation); - /* notify of match */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MATCH = %s\n", component->digits); - send_match_event(RAYO_COMPONENT(component), result); - iks_delete(result); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "inter-digit-timeout\n"); - rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOMATCH); - } - - /* let handler know component is done */ - return SWITCH_STATUS_FALSE; - } else if (!component->num_digits && component->initial_timeout > 0 && elapsed_ms > component->initial_timeout) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "initial-timeout\n"); - rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOINPUT); - - /* let handler know component is done */ - return SWITCH_STATUS_FALSE; - } - } - return SWITCH_STATUS_SUCCESS; -} - -/** - * Process DTMF press for a specific component - * @param component to receive DTMF - * @param session - * @param dtmf - * @param direction - * @return SWITCH_STATUS_FALSE if component is done - */ -static switch_status_t dtmf_component_on_dtmf(struct input_component *component, switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction) -{ - int is_term_digit = 0; - enum srgs_match_type match; - const char *interpretation = NULL; - - is_term_digit = digit_test(component->term_digit, dtmf->digit); - - if (!is_term_digit) { - component->digits[component->num_digits] = dtmf->digit; - component->num_digits++; - component->digits[component->num_digits] = '\0'; - component->last_digit_time = switch_micro_time_now(); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Collected digits = \"%s\"\n", component->digits); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Collected term digit = \"%c\"\n", dtmf->digit); - } - - match = srgs_grammar_match(component->grammar, component->digits, &interpretation); - - if (is_term_digit) { - /* finalize result if terminating digit was pressed */ - if (match == SMT_MATCH_PARTIAL) { - match = SMT_NO_MATCH; - } else if (match == SMT_MATCH) { - match = SMT_MATCH_END; - } - } else if (component->num_digits >= MAX_DTMF) { - /* maximum digits collected and still not a definitive match */ - if (match != SMT_MATCH_END) { - match = SMT_NO_MATCH; - } - } - - switch (match) { - case SMT_MATCH: - case SMT_MATCH_PARTIAL: { - /* need more digits */ - if (component->num_digits == 1) { - send_barge_event(RAYO_COMPONENT(component)); - } - break; - } - case SMT_NO_MATCH: { - /* notify of no-match and remove input component */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO MATCH = %s\n", component->digits); - rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOMATCH); - - /* let handler know component is done */ - return SWITCH_STATUS_FALSE; - } - case SMT_MATCH_END: { - iks *result = nlsml_create_dtmf_match(component->digits, interpretation); - /* notify of match and remove input component */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MATCH = %s\n", component->digits); - send_match_event(RAYO_COMPONENT(component), result); - iks_delete(result); - - /* let handler know component is done */ - return SWITCH_STATUS_FALSE; - } - } - - /* still need more input */ - return SWITCH_STATUS_SUCCESS; -} - -/** - * Process DTMF press on call - */ -static switch_status_t input_handler_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - struct input_handler *handler = (struct input_handler *)switch_channel_get_private(channel, RAYO_INPUT_COMPONENT_PRIVATE_VAR); - - if (handler) { - switch_event_t *components_to_remove = NULL; - switch_hash_index_t *hi; - - switch_mutex_lock(handler->mutex); - - /* check input on each component */ - for (hi = switch_core_hash_first(handler->dtmf_components); hi; hi = switch_core_hash_next(&hi)) { - const void *jid; - void *component; - switch_core_hash_this(hi, &jid, NULL, &component); - if (dtmf_component_on_dtmf(INPUT_COMPONENT(component), session, dtmf, direction) != SWITCH_STATUS_SUCCESS) { - if (!components_to_remove) { - switch_event_create_subclass(&components_to_remove, SWITCH_EVENT_CLONE, NULL); - } - switch_event_add_header_string(components_to_remove, SWITCH_STACK_BOTTOM, "done", RAYO_JID(component)); - } - } - - /* remove any finished components */ - if (components_to_remove) { - switch_event_header_t *component_to_remove = NULL; - for (component_to_remove = components_to_remove->headers; component_to_remove; component_to_remove = component_to_remove->next) { - switch_core_hash_delete(handler->dtmf_components, component_to_remove->value); - } - switch_event_destroy(&components_to_remove); - } - - switch_mutex_unlock(handler->mutex); - } - return SWITCH_STATUS_SUCCESS; -} - -/** - * Monitor for input - */ -static switch_bool_t input_handler_bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) -{ - switch_core_session_t *session = switch_core_media_bug_get_session(bug); - struct input_handler *handler = (struct input_handler *)user_data; - switch_hash_index_t *hi; - - switch_mutex_lock(handler->mutex); - - switch(type) { - case SWITCH_ABC_TYPE_INIT: { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding DTMF callback\n"); - switch_core_event_hook_add_recv_dtmf(session, input_handler_on_dtmf); - break; - } - case SWITCH_ABC_TYPE_READ_REPLACE: { - switch_frame_t *rframe = switch_core_media_bug_get_read_replace_frame(bug); - switch_event_t *components_to_remove = NULL; - - /* check timeout/stop on each component */ - for (hi = switch_core_hash_first(handler->dtmf_components); hi; hi = switch_core_hash_next(&hi)) { - const void *jid; - void *component; - switch_core_hash_this(hi, &jid, NULL, &component); - if (dtmf_component_check_timeout(INPUT_COMPONENT(component), session) != SWITCH_STATUS_SUCCESS) { - if (!components_to_remove) { - switch_event_create_subclass(&components_to_remove, SWITCH_EVENT_CLONE, NULL); - } - switch_event_add_header_string(components_to_remove, SWITCH_STACK_BOTTOM, "done", RAYO_JID(component)); - } - } - - /* remove any finished components */ - if (components_to_remove) { - switch_event_header_t *component_to_remove = NULL; - for (component_to_remove = components_to_remove->headers; component_to_remove; component_to_remove = component_to_remove->next) { - switch_core_hash_delete(handler->dtmf_components, component_to_remove->value); - } - switch_event_destroy(&components_to_remove); - } - - switch_core_media_bug_set_read_replace_frame(bug, rframe); - break; - } - case SWITCH_ABC_TYPE_CLOSE: - /* complete all components */ - for (hi = switch_core_hash_first(handler->dtmf_components); hi; hi = switch_core_hash_next(&hi)) { - const void *jid; - void *component; - switch_core_hash_this(hi, &jid, NULL, &component); - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_HANGUP); - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Removing DTMF callback\n"); - switch_core_event_hook_remove_recv_dtmf(session, input_handler_on_dtmf); - switch_core_hash_destroy(&handler->dtmf_components); - break; - default: - break; - } - switch_mutex_unlock(handler->mutex); - return SWITCH_TRUE; -} - -/** - * Validate input request - * @param input request to validate - * @param error message - * @return 0 if error, 1 if valid - */ -static int validate_call_input(iks *input, const char **error) -{ - iks *grammar; - const char *content_type; - int has_grammar = 0; - int use_mrcp = 0; - - /* validate input attributes */ - if (!VALIDATE_RAYO_INPUT(input)) { - *error = "Bad attrib value"; - return 0; - } - - use_mrcp = !strncmp("unimrcp", iks_find_attrib(input, "recognizer") ? iks_find_attrib(input, "recognizer") : globals.default_recognizer, 7); - - /* validate grammar elements */ - for (grammar = iks_find(input, "grammar"); grammar; grammar = iks_next_tag(grammar)) { - /* is this a grammar? */ - if (strcmp("grammar", iks_name(grammar))) { - continue; - } - content_type = iks_find_attrib(grammar, "content-type"); - if (zstr(content_type)) { - /* grammar URL */ - if (zstr(iks_find_attrib(grammar, "url"))) { - *error = "url or content-type must be set"; - return 0; - } else if (!use_mrcp) { - *error = "url only supported with unimrcp recognizer"; - return 0; - } - } else { - /* inline grammar / only support srgs */ - if (!zstr(iks_find_attrib(grammar, "url"))) { - *error = "url not allowed with content-type"; - return 0; - } else if (strcmp("application/srgs+xml", content_type) && strcmp("text/plain", content_type)) { - *error = "Unsupported content type"; - return 0; - } - - /* missing inline grammar body */ - if (zstr(iks_find_cdata(input, "grammar"))) { - *error = "Grammar content is missing"; - return 0; - } - } - has_grammar = 1; - } - - if (!has_grammar) { - *error = "Missing "; - return 0; - } - - return 1; -} - -static char *setup_grammars_pocketsphinx(struct input_component *component, switch_core_session_t *session, iks *input, const struct xmpp_error **stanza_error, const char **error_detail) -{ - const char *jsgf_path; - switch_stream_handle_t grammar = { 0 }; - SWITCH_STANDARD_STREAM(grammar); - - /* transform SRGS grammar to JSGF */ - if (!(component->grammar = srgs_parse(globals.parser, iks_find_cdata(input, "grammar")))) { - *stanza_error = STANZA_ERROR_BAD_REQUEST; - *error_detail = "Failed to parse grammar body"; - switch_safe_free(grammar.data); - return NULL; - } - - jsgf_path = srgs_grammar_to_jsgf_file(component->grammar, SWITCH_GLOBAL_dirs.grammar_dir, "gram"); - if (!jsgf_path) { - *stanza_error = STANZA_ERROR_BAD_REQUEST; - *error_detail = "Grammar conversion to JSGF error"; - switch_safe_free(grammar.data); - return NULL; - } - - /* build pocketsphinx grammar string */ - grammar.write_function(&grammar, - "{start-input-timers=%s,no-input-timeout=%d,speech-timeout=%d,confidence-threshold=%d}%s", - component->start_timers ? "true" : "false", - component->initial_timeout, - component->max_silence, - (int)ceil(component->min_confidence * 100.0), - jsgf_path); - - return (char *)grammar.data; -} - -static char *setup_grammars_unimrcp(struct input_component *component, switch_core_session_t *session, iks *input, const struct xmpp_error **stanza_error, const char **error_detail) -{ - iks *grammar_tag; - switch_asr_handle_t *ah; - switch_stream_handle_t grammar_uri_list = { 0 }; - SWITCH_STANDARD_STREAM(grammar_uri_list); - - /* unlock handler mutex, otherwise deadlock will happen when switch_ivr_detect_speech_init adds a new media bug */ - switch_mutex_unlock(component->handler->mutex); - ah = switch_core_session_alloc(session, sizeof(*ah)); - if (switch_ivr_detect_speech_init(session, component->recognizer, "", ah) != SWITCH_STATUS_SUCCESS) { - switch_mutex_lock(component->handler->mutex); - *stanza_error = STANZA_ERROR_INTERNAL_SERVER_ERROR; - *error_detail = "Failed to initialize recognizer"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } - switch_mutex_lock(component->handler->mutex); - - /* handle input config */ - switch_core_asr_text_param(ah, "start-input-timers", component->start_timers ? "true" : "false"); - switch_core_asr_text_param(ah, "confidence-threshold", switch_core_sprintf(RAYO_POOL(component), "%f", component->min_confidence)); - switch_core_asr_text_param(ah, "sensitivity-level", switch_core_sprintf(RAYO_POOL(component), "%f", component->sensitivity)); - if (component->initial_timeout > 0) { - switch_core_asr_text_param(ah, "no-input-timeout", switch_core_sprintf(RAYO_POOL(component), "%d", component->initial_timeout)); - } - if (component->max_silence > 0) { - switch_core_asr_text_param(ah, "speech-complete-timeout", switch_core_sprintf(RAYO_POOL(component), "%d", component->max_silence)); - switch_core_asr_text_param(ah, "speech-incomplete-timeout", switch_core_sprintf(RAYO_POOL(component), "%d", component->max_silence)); - } - if (!zstr(component->language)) { - switch_core_asr_text_param(ah, "speech-language", component->language); - } - if (!strcmp(iks_find_attrib_soft(input, "mode"), "any") || !strcmp(iks_find_attrib_soft(input, "mode"), "dtmf")) { - /* set dtmf params */ - if (component->inter_digit_timeout > 0) { - switch_core_asr_text_param(ah, "dtmf-interdigit-timeout", switch_core_sprintf(RAYO_POOL(component), "%d", component->inter_digit_timeout)); - } - if (component->term_digit) { - switch_core_asr_text_param(ah, "dtmf-term-char", switch_core_sprintf(RAYO_POOL(component), "%c", component->term_digit)); - } - } - - /* override input configs w/ custom headers */ - { - iks *header = NULL; - for (header = iks_find(input, "header"); header; header = iks_next_tag(header)) { - if (!strcmp("header", iks_name(header))) { - const char *name = iks_find_attrib_soft(header, "name"); - const char *value = iks_find_attrib_soft(header, "value"); - if (!zstr(name) && !zstr(value)) { - switch_core_asr_text_param(ah, (char *)name, value); - } - } - } - } - - switch_core_asr_text_param(ah, "start-recognize", "false"); - switch_core_asr_text_param(ah, "define-grammar", "true"); - for (grammar_tag = iks_find(input, "grammar"); grammar_tag; grammar_tag = iks_next_tag(grammar_tag)) { - const char *grammar_name; - iks *grammar_cdata; - const char *grammar; - - /* is this a grammar? */ - if (strcmp("grammar", iks_name(grammar_tag))) { - continue; - } - - if (!zstr(iks_find_attrib_soft(grammar_tag, "content-type"))) { - /* get the srgs contained in this grammar */ - if (!(grammar_cdata = iks_child(grammar_tag)) || iks_type(grammar_cdata) != IKS_CDATA) { - *stanza_error = STANZA_ERROR_BAD_REQUEST; - *error_detail = "Missing grammar"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } - grammar = switch_core_sprintf(RAYO_POOL(component), "inline:%s", iks_cdata(grammar_cdata)); - } else { - /* Grammar is at a URL */ - grammar = iks_find_attrib_soft(grammar_tag, "url"); - if (zstr(grammar)) { - *stanza_error = STANZA_ERROR_BAD_REQUEST; - *error_detail = "Missing grammar"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } - if (strncasecmp(grammar, "http", 4) && strncasecmp(grammar, "file", 4)) { - *stanza_error = STANZA_ERROR_BAD_REQUEST; - *error_detail = "Bad URL"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } - } - grammar_name = switch_core_sprintf(RAYO_POOL(component), "grammar-%d", rayo_actor_seq_next(RAYO_ACTOR(component))); - - /* DEFINE-GRAMMAR */ - /* unlock handler mutex, otherwise deadlock will happen if switch_ivr_detect_speech_load_grammar removes the media bug */ - switch_mutex_unlock(component->handler->mutex); - if (switch_ivr_detect_speech_load_grammar(session, grammar, grammar_name) != SWITCH_STATUS_SUCCESS) { - switch_mutex_lock(component->handler->mutex); - *stanza_error = STANZA_ERROR_INTERNAL_SERVER_ERROR; - *error_detail = "Failed to load grammar"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } - switch_mutex_lock(component->handler->mutex); - - /* add grammar to uri-list */ - grammar_uri_list.write_function(&grammar_uri_list, "session:%s\r\n", grammar_name); - } - switch_core_asr_text_param(ah, "start-recognize", "true"); - switch_core_asr_text_param(ah, "define-grammar", "false"); - - return (char *)grammar_uri_list.data; -} - -static char *setup_grammars_unknown(struct input_component *component, switch_core_session_t *session, iks *input, const struct xmpp_error **stanza_error, const char **error_detail) -{ - switch_stream_handle_t grammar = { 0 }; - SWITCH_STANDARD_STREAM(grammar); - grammar.write_function(&grammar, "%s", iks_find_cdata(input, "grammar")); - return (char *)grammar.data; -} - -/** - * Start call input on voice resource - */ -static iks *start_call_voice_input(struct input_component *component, switch_core_session_t *session, iks *input, iks *iq, int barge_in) -{ - struct input_handler *handler = component->handler; - char *grammar = NULL; - const struct xmpp_error *stanza_error = NULL; - const char *error_detail = NULL; - - if (component->speech_mode && handler->voice_component) { - /* don't allow multi voice input */ - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple voice input is not allowed"); - } - - handler->voice_component = component; - - if (zstr(component->recognizer)) { - component->recognizer = globals.default_recognizer; - } - - /* if recognition engine is different, we can't handle this request */ - if (!zstr(handler->last_recognizer) && strcmp(component->recognizer, handler->last_recognizer)) { - handler->voice_component = NULL; - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Must use the same recognizer for the entire call"); - } else if (zstr(handler->last_recognizer)) { - handler->last_recognizer = switch_core_session_strdup(session, component->recognizer); - } - - if (!strcmp(component->recognizer, "pocketsphinx")) { - grammar = setup_grammars_pocketsphinx(component, session, input, &stanza_error, &error_detail); - } else if (!strncmp(component->recognizer, "unimrcp", strlen("unimrcp"))) { - grammar = setup_grammars_unimrcp(component, session, input, &stanza_error, &error_detail); - } else { - grammar = setup_grammars_unknown(component, session, input, &stanza_error, &error_detail); - } - - if (!grammar) { - handler->voice_component = NULL; - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, stanza_error, error_detail); - } - - /* acknowledge command */ - rayo_component_send_start(RAYO_COMPONENT(component), iq); - - /* start speech detection */ - switch_channel_set_variable(switch_core_session_get_channel(session), "fire_asr_events", "true"); - /* unlock handler mutex, otherwise deadlock will happen if switch_ivr_detect_speech adds a media bug */ - switch_mutex_unlock(handler->mutex); - if (switch_ivr_detect_speech(session, component->recognizer, grammar, "mod_rayo_grammar", "", NULL) != SWITCH_STATUS_SUCCESS) { - switch_mutex_lock(handler->mutex); - handler->voice_component = NULL; - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); - } else { - switch_mutex_lock(handler->mutex); - } - switch_safe_free(grammar); - - return NULL; -} - -/** - * Start call input on DTMF resource - */ -static iks *start_call_dtmf_input(struct input_component *component, switch_core_session_t *session, iks *input, iks *iq, int barge_in) -{ - /* parse the grammar */ - if (!(component->grammar = srgs_parse(globals.parser, iks_find_cdata(input, "grammar")))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Failed to parse grammar body\n"); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Failed to parse grammar body"); - } - - component->last_digit_time = switch_micro_time_now(); - - /* acknowledge command */ - rayo_component_send_start(RAYO_COMPONENT(component), iq); - - /* start dtmf input detection */ - switch_core_hash_insert(component->handler->dtmf_components, RAYO_JID(component), component); - - return NULL; -} - -/** - * Start call input for the given component - * @param component the input or prompt component - * @param session the session - * @param input the input request - * @param iq the original input/prompt request - */ -static iks *start_call_input(struct input_component *component, switch_core_session_t *session, iks *input, iks *iq, int barge_in) -{ - iks *result = NULL; - - /* set up input component for new detection */ - struct input_handler *handler = (struct input_handler *)switch_channel_get_private(switch_core_session_get_channel(session), RAYO_INPUT_COMPONENT_PRIVATE_VAR); - if (!handler) { - /* create input component */ - handler = switch_core_session_alloc(session, sizeof(*handler)); - switch_mutex_init(&handler->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_core_hash_init(&handler->dtmf_components); - switch_channel_set_private(switch_core_session_get_channel(session), RAYO_INPUT_COMPONENT_PRIVATE_VAR, handler); - handler->last_recognizer = ""; - - /* fire up media bug to monitor lifecycle */ - if (switch_core_media_bug_add(session, "rayo_input_component", NULL, input_handler_bug_callback, handler, 0, SMBF_READ_REPLACE, &handler->bug) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Failed to create input handler media bug\n"); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create input handler media bug"); - } - } - - switch_mutex_lock(handler->mutex); - - if (!handler->dtmf_components) { - /* handler bug was destroyed */ - switch_mutex_unlock(handler->mutex); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Input handler media bug is closed\n"); - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Input handler media bug is closed\n"); - } - - component->grammar = NULL; - component->num_digits = 0; - component->digits[0] = '\0'; - component->stop = 0; - component->initial_timeout = iks_find_int_attrib(input, "initial-timeout"); - component->inter_digit_timeout = iks_find_int_attrib(input, "inter-digit-timeout"); - component->max_silence = iks_find_int_attrib(input, "max-silence"); - component->min_confidence = iks_find_decimal_attrib(input, "min-confidence"); - component->sensitivity = iks_find_decimal_attrib(input, "sensitivity"); - component->barge_event = iks_find_bool_attrib(input, "barge-event"); - component->start_timers = iks_find_bool_attrib(input, "start-timers"); - component->term_digit = iks_find_char_attrib(input, "terminator"); - component->recognizer = switch_core_strdup(RAYO_POOL(component), iks_find_attrib_soft(input, "recognizer")); - component->language = switch_core_strdup(RAYO_POOL(component), iks_find_attrib_soft(input, "language")); - component->handler = handler; - component->speech_mode = strcmp(iks_find_attrib_soft(input, "mode"), "dtmf"); - - if (component->speech_mode) { - result = start_call_voice_input(component, session, input, iq, barge_in); - } else { - result = start_call_dtmf_input(component, session, input, iq, barge_in); - } - - switch_mutex_unlock(handler->mutex); - - return result; -} - -/** - * Create input component id for session. - * @param session requesting component - * @param input request - * @return the ID - */ -static char *create_input_component_id(switch_core_session_t *session, iks *input) -{ - const char *mode = "unk"; - if (input) { - mode = iks_find_attrib_soft(input, "mode"); - if (!strcmp(mode, "dtmf")) { - return NULL; - } - if (!strcmp(mode, "any")) { - mode = "voice"; - } - } - return switch_core_session_sprintf(session, "%s-input-%s", switch_core_session_get_uuid(session), mode); -} - -/** - * Release any resources consumed by this input component - */ -static void input_component_cleanup(struct rayo_actor *component) -{ - if (INPUT_COMPONENT(component)->speech_mode) { - switch_core_session_t *session = switch_core_session_locate(component->parent->id); - if (session) { - switch_ivr_stop_detect_speech(session); - switch_core_session_rwunlock(session); - } - } -} - -/** - * Start execution of input component - */ -static iks *start_call_input_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - iks *input = iks_find(iq, "input"); - char *component_id = create_input_component_id(session, input); - switch_memory_pool_t *pool = NULL; - struct input_component *input_component = NULL; - const char *error = NULL; - - /* Start CPA */ - if (!strcmp(iks_find_attrib_soft(input, "mode"), "cpa")) { - return rayo_cpa_component_start(call, msg, session_data); - } - - /* start input */ - if (!validate_call_input(input, &error)) { - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, error); - } - - switch_core_new_memory_pool(&pool); - input_component = switch_core_alloc(pool, sizeof(*input_component)); - input_component = INPUT_COMPONENT(rayo_component_init_cleanup(RAYO_COMPONENT(input_component), pool, RAT_CALL_COMPONENT, "input", component_id, call, iks_find_attrib(iq, "from"), input_component_cleanup)); - if (!input_component) { - switch_core_destroy_memory_pool(&pool); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create input entity"); - } - return start_call_input(input_component, session, input, iq, 0); -} - -/** - * Stop execution of input component - */ -static iks *stop_call_input_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - struct input_component *input_component = INPUT_COMPONENT(component); - - if (input_component && !input_component->stop) { - switch_core_session_t *session = switch_core_session_locate(component->parent->id); - if (session) { - switch_mutex_lock(input_component->handler->mutex); - input_component->stop = 1; - if (input_component->speech_mode) { - switch_mutex_unlock(input_component->handler->mutex); - switch_ivr_stop_detect_speech(session); - switch_mutex_lock(input_component->handler->mutex); - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); - } - switch_mutex_unlock(input_component->handler->mutex); - switch_core_session_rwunlock(session); - } - } - return iks_new_iq_result(iq); -} - -/** - * Start input component timers - */ -static iks *start_timers_call_input_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - struct input_component *input_component = INPUT_COMPONENT(component); - if (input_component) { - switch_core_session_t *session = switch_core_session_locate(component->parent->id); - if (session) { - switch_mutex_lock(input_component->handler->mutex); - if (input_component->speech_mode) { - switch_mutex_unlock(input_component->handler->mutex); - switch_ivr_detect_speech_start_input_timers(session); - switch_mutex_lock(input_component->handler->mutex); - } else { - input_component->last_digit_time = switch_micro_time_now(); - input_component->start_timers = 1; - } - switch_mutex_unlock(input_component->handler->mutex); - switch_core_session_rwunlock(session); - } - } - return iks_new_iq_result(iq); -} - -/** - * Get text / error from result - */ -static const char *get_detected_speech_result_text(cJSON *result_json, double *confidence, const char **error_text) -{ - const char *result_text = NULL; - const char *text = cJSON_GetObjectCstr(result_json, "text"); - if (confidence) { - *confidence = 0.0; - } - if (!zstr(text)) { - cJSON *json_confidence = cJSON_GetObjectItem(result_json, "confidence"); - if (json_confidence && json_confidence->valuedouble > 0.0) { - *confidence = json_confidence->valuedouble; - } else { - *confidence = 0.99; - } - result_text = text; - } else if (error_text) { - *error_text = cJSON_GetObjectCstr(result_json, "error"); - } - return result_text; -} - -/** - * Handle speech detection event - */ -static void on_detected_speech_event(switch_event_t *event) -{ - const char *speech_type = switch_event_get_header(event, "Speech-Type"); - char *event_str = NULL; - const char *uuid = switch_event_get_header(event, "Unique-ID"); - switch_event_serialize(event, &event_str, SWITCH_FALSE); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", event_str); - if (!speech_type || !uuid) { - return; - } - - if (!strcasecmp("detected-speech", speech_type)) { - char *component_id = switch_mprintf("%s-input-voice", uuid); - struct rayo_component *component = RAYO_COMPONENT_LOCATE(component_id); - - switch_safe_free(component_id); - if (component) { - const char *result = switch_event_get_body(event); - - switch_mutex_lock(INPUT_COMPONENT(component)->handler->mutex); - INPUT_COMPONENT(component)->handler->voice_component = NULL; - switch_mutex_unlock(INPUT_COMPONENT(component)->handler->mutex); - - if (zstr(result)) { - rayo_component_send_complete(component, INPUT_NOMATCH); - } else { - if (result[0] == '{') { - // internal FS JSON format - cJSON *json_result = cJSON_Parse(result); - if (json_result) { - // examine result to determine what happened - double confidence = 0.0; - const char *error_text = NULL; - const char *result_text = NULL; - result_text = get_detected_speech_result_text(json_result, &confidence, &error_text); - if (!zstr(result_text)) { - // got result... send as NLSML - iks *result = nlsml_create_match(result_text, NULL, "speech", (int)(confidence * 100.0)); - /* notify of match */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "MATCH = %s\n", result_text); - send_match_event(RAYO_COMPONENT(component), result); - iks_delete(result); - } else if (zstr(error_text)) { - // unknown error - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "No matching text nor error in result: %s!\n", result); - rayo_component_send_complete(component, INPUT_NOMATCH); - } else if (!strcmp(error_text, "no_input")) { - // no input error - rayo_component_send_complete(component, INPUT_NOINPUT); - } else if (!strcmp(error_text, "no_match")) { - // no match error - rayo_component_send_complete(component, INPUT_NOMATCH); - } else { - // generic error - iks *response = rayo_component_create_complete_event(component, COMPONENT_COMPLETE_ERROR); - iks *error = NULL; - if ((error = iks_find(response, "complete"))) { - if ((error = iks_find(error, "error"))) { - iks_insert_cdata(error, error_text, strlen(error_text)); - } - } - rayo_component_send_complete_event(component, response); - } - cJSON_Delete(json_result); - } else { - // failed to parse JSON result - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "Failed to parse JSON result: %s!\n", result); - rayo_component_send_complete(component, INPUT_NOMATCH); - } - } else if (strchr(result, '<')) { - /* got an XML result */ - enum nlsml_match_type match_type = nlsml_parse(result, uuid); - switch (match_type) { - case NMT_NOINPUT: - rayo_component_send_complete(component, INPUT_NOINPUT); - break; - case NMT_MATCH: { - iks *result_xml = nlsml_normalize(result); - send_match_event(RAYO_COMPONENT(component), result_xml); - iks_delete(result_xml); - break; - } - case NMT_BAD_XML: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "Failed to parse NLSML result: %s!\n", result); - rayo_component_send_complete(component, INPUT_NOMATCH); - break; - case NMT_NOMATCH: - rayo_component_send_complete(component, INPUT_NOMATCH); - break; - default: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_CRIT, "Unknown NLSML match type: %i, %s!\n", match_type, result); - rayo_component_send_complete(component, INPUT_NOMATCH); - break; - } - } else if (strstr(result, "002")) { - /* Completion-Cause: 002 no-input-timeout */ - rayo_component_send_complete(component, INPUT_NOINPUT); - } else if (strstr(result, "004") || strstr(result, "005") || strstr(result, "006") || strstr(result, "009") || strstr(result, "010")) { - /* Completion-Cause: 004 gram-load-failure */ - /* Completion-Cause: 005 gram-comp-failure */ - /* Completion-Cause: 006 error */ - /* Completion-Cause: 009 uri-failure */ - /* Completion-Cause: 010 language-unsupported */ - iks *response = rayo_component_create_complete_event(component, COMPONENT_COMPLETE_ERROR); - const char *error_reason = switch_event_get_header(event, "ASR-Completion-Reason"); - if (!zstr(error_reason)) { - iks *error; - if ((error = iks_find(response, "complete"))) { - if ((error = iks_find(error, "error"))) { - iks_insert_cdata(error, error_reason, strlen(error_reason)); - } - } - } - rayo_component_send_complete_event(component, response); - } else { - /* assume no match */ - /* Completion-Cause: 001 no-match */ - /* Completion-Cause: 003 recognition-timeout */ - /* Completion-Cause: 007 speech-too-early */ - /* Completion-Cause: 008 too-much-speech-timeout */ - rayo_component_send_complete(component, INPUT_NOMATCH); - } - } - RAYO_RELEASE(component); - } - } else if (!strcasecmp("begin-speaking", speech_type)) { - char *component_id = switch_mprintf("%s-input-voice", uuid); - struct rayo_component *component = RAYO_COMPONENT_LOCATE(component_id); - switch_safe_free(component_id); - if (component && INPUT_COMPONENT(component)->barge_event) { - send_barge_event(component); - } - RAYO_RELEASE(component); - } else if (!strcasecmp("closed", speech_type)) { - char *component_id = switch_mprintf("%s-input-voice", uuid); - struct rayo_component *component = RAYO_COMPONENT_LOCATE(component_id); - switch_safe_free(component_id); - if (component) { - char *channel_state = switch_event_get_header(event, "Channel-State"); - switch_mutex_lock(INPUT_COMPONENT(component)->handler->mutex); - INPUT_COMPONENT(component)->handler->voice_component = NULL; - switch_mutex_unlock(INPUT_COMPONENT(component)->handler->mutex); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Recognizer closed\n"); - if (channel_state && !strcmp("CS_HANGUP", channel_state)) { - rayo_component_send_complete(component, COMPONENT_COMPLETE_HANGUP); - } else { - /* shouldn't get here... */ - rayo_component_send_complete(component, COMPONENT_COMPLETE_ERROR); - } - RAYO_RELEASE(component); - } - } - switch_safe_free(event_str); -} - -/** - * Process module XML configuration - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS on successful configuration - */ -static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) -{ - switch_xml_t cfg, xml; - - /* set defaults */ - globals.default_recognizer = "pocketsphinx"; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Configuring module\n"); - if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); - return SWITCH_STATUS_TERM; - } - - /* get params */ - { - switch_xml_t settings = switch_xml_child(cfg, "input"); - if (settings) { - switch_xml_t param; - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); - if (!strcasecmp(var, "default-recognizer")) { - if (!zstr(val)) { - globals.default_recognizer = switch_core_strdup(pool, val); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); - } - } - } - } - - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Initialize input component - * @param module_interface - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - - srgs_init(); - nlsml_init(); - - globals.parser = srgs_parser_new(NULL); - - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_INPUT_NS":input", start_call_input_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "input", "set:"RAYO_EXT_NS":stop", stop_call_input_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "input", "set:"RAYO_INPUT_NS":start-timers", start_timers_call_input_component); - switch_event_bind("rayo_input_component", SWITCH_EVENT_DETECTED_SPEECH, SWITCH_EVENT_SUBCLASS_ANY, on_detected_speech_event, NULL); - - return rayo_cpa_component_load(module_interface, pool, config_file); -} - -/** - * Shutdown input component - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_input_component_shutdown(void) -{ - switch_event_unbind_callback(on_detected_speech_event); - - if (globals.parser) { - srgs_parser_destroy(globals.parser); - } - srgs_destroy(); - nlsml_destroy(); - - rayo_cpa_component_shutdown(); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_output_component.c b/src/mod/event_handlers/mod_rayo/rayo_output_component.c deleted file mode 100644 index 6ea607e33b..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_output_component.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * output_component.c -- Rayo output component implementation - * - */ -#include "rayo_components.h" -#include "rayo_elements.h" - -/** - * An output component - */ -struct output_component { - /** component base class */ - struct rayo_component base; - /** document to play */ - iks *document; - /** where to start playing in document */ - int start_offset_ms; - /** maximum time to play */ - int max_time_ms; - /** silence between repeats */ - int repeat_interval_ms; - /** number of times to repeat */ - int repeat_times; - /** true if started paused */ - switch_bool_t start_paused; - /** true if stopped */ - int stop; - /** output renderer to use */ - const char *renderer; - /** optional headers to pass to renderer */ - const char *headers; - /** audio direction */ - const char *direction; -}; - -#define OUTPUT_FINISH "finish", RAYO_OUTPUT_COMPLETE_NS -#define OUTPUT_MAX_TIME "max-time", RAYO_OUTPUT_COMPLETE_NS - -#define OUTPUT_COMPONENT(x) ((struct output_component *)x) - -/** - * Create new output component - */ -static struct rayo_component *create_output_component(struct rayo_actor *actor, const char *type, iks *output, const char *client_jid) -{ - switch_memory_pool_t *pool; - struct output_component *output_component = NULL; - - switch_core_new_memory_pool(&pool); - output_component = switch_core_alloc(pool, sizeof(*output_component)); - output_component = OUTPUT_COMPONENT(rayo_component_init((struct rayo_component *)output_component, pool, type, "output", NULL, actor, client_jid)); - if (output_component) { - output_component->document = iks_copy(output); - output_component->start_offset_ms = iks_find_int_attrib(output, "start-offset"); - output_component->repeat_interval_ms = iks_find_int_attrib(output, "repeat-interval"); - output_component->repeat_times = iks_find_int_attrib(output, "repeat-times"); - output_component->max_time_ms = iks_find_int_attrib(output, "max-time"); - output_component->start_paused = iks_find_bool_attrib(output, "start-paused"); - output_component->renderer = switch_core_strdup(RAYO_POOL(output_component), iks_find_attrib_soft(output, "renderer")); - output_component->direction = strcmp(iks_find_attrib_soft(output, "direction"), "in") ? "m" : "mr"; - output_component->headers = NULL; - /* get custom headers */ - { - switch_stream_handle_t headers = { 0 }; - iks *header = NULL; - int first = 1; - SWITCH_STANDARD_STREAM(headers); - for (header = iks_find(output, "header"); header; header = iks_next_tag(header)) { - if (!strcmp("header", iks_name(header))) { - const char *name = iks_find_attrib_soft(header, "name"); - const char *value = iks_find_attrib_soft(header, "value"); - if (!zstr(name) && !zstr(value)) { - headers.write_function(&headers, "%s%s=%s", first ? "{" : ",", name, value); - first = 0; - } - } - } - if (headers.data && !first) { - headers.write_function(&headers, "}"); - output_component->headers = switch_core_strdup(RAYO_POOL(output_component), (char *)headers.data); - } - switch_safe_free(headers.data); - } - } else { - switch_core_destroy_memory_pool(&pool); - } - - return RAYO_COMPONENT(output_component); -} - -/** - * Start execution of call output component - * @param component to start - * @param session the session to output to - * @param output the output request - * @param iq the original request - */ -static iks *start_call_output(struct rayo_component *component, switch_core_session_t *session, iks *output, iks *iq) -{ - switch_stream_handle_t stream = { 0 }; - - /* acknowledge command */ - rayo_component_send_start(component, iq); - - /* build playback command */ - SWITCH_STANDARD_STREAM(stream); - stream.write_function(&stream, "{id=%s,session=%s,pause=%s", - RAYO_JID(component), switch_core_session_get_uuid(session), - OUTPUT_COMPONENT(component)->start_paused ? "true" : "false"); - if (OUTPUT_COMPONENT(component)->max_time_ms > 0) { - stream.write_function(&stream, ",timeout=%i", OUTPUT_COMPONENT(component)->max_time_ms); - } - if (OUTPUT_COMPONENT(component)->start_offset_ms > 0) { - stream.write_function(&stream, ",start_offset_ms=%i", OUTPUT_COMPONENT(component)->start_offset_ms); - } - stream.write_function(&stream, "}fileman://rayo://%s", RAYO_JID(component)); - - if (switch_ivr_displace_session(session, stream.data, 0, OUTPUT_COMPONENT(component)->direction) == SWITCH_STATUS_SUCCESS) { - RAYO_RELEASE(component); - } else { - if (component->complete) { - /* component is already destroyed */ - RAYO_RELEASE(component); - } else { - /* need to destroy component */ - if (OUTPUT_COMPONENT(component)->document) { - iks_delete(OUTPUT_COMPONENT(component)->document); - } - if (switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - rayo_component_send_complete(component, COMPONENT_COMPLETE_HANGUP); - } else { - rayo_component_send_complete(component, COMPONENT_COMPLETE_ERROR); - } - } - } - switch_safe_free(stream.data); - return NULL; -} - -/** - * Start execution of call output component - */ -static iks *start_call_output_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - struct rayo_component *output_component = NULL; - iks *output = iks_find(iq, "output"); - iks *document = NULL; - - /* validate output attributes */ - if (!VALIDATE_RAYO_OUTPUT(output)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - /* check if exists */ - document = iks_find(output, "document"); - if (!document) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - output_component = create_output_component(call, RAT_CALL_COMPONENT, output, iks_find_attrib(iq, "from")); - if (!output_component) { - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create output entity"); - } - return start_call_output(output_component, session, output, iq); -} - -/** - * Start execution of mixer output component - */ -static iks *start_mixer_output_component(struct rayo_actor *mixer, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - struct rayo_component *component = NULL; - iks *output = iks_find(iq, "output"); - iks *document = NULL; - switch_stream_handle_t stream = { 0 }; - - /* validate output attributes */ - if (!VALIDATE_RAYO_OUTPUT(output)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - /* check if exists */ - document = iks_find(output, "document"); - if (!document) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - component = create_output_component(mixer, RAT_MIXER_COMPONENT, output, iks_find_attrib(iq, "from")); - if (!component) { - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create output entity"); - } - - /* build conference command */ - SWITCH_STANDARD_STREAM(stream); - stream.write_function(&stream, "%s play ", rayo_mixer_get_name(RAYO_MIXER(mixer)), RAYO_ID(component)); - - stream.write_function(&stream, "{id=%s,pause=%s", - RAYO_JID(component), - OUTPUT_COMPONENT(component)->start_paused ? "true" : "false"); - if (OUTPUT_COMPONENT(component)->max_time_ms > 0) { - stream.write_function(&stream, ",timeout=%i", OUTPUT_COMPONENT(component)->max_time_ms); - } - if (OUTPUT_COMPONENT(component)->start_offset_ms > 0) { - stream.write_function(&stream, ",start_offset_ms=%i", OUTPUT_COMPONENT(component)->start_offset_ms); - } - stream.write_function(&stream, "}fileman://rayo://%s", RAYO_JID(component)); - - /* acknowledge command */ - rayo_component_send_start(component, iq); - - rayo_component_api_execute_async(component, "conference", stream.data); - - switch_safe_free(stream.data); - RAYO_RELEASE(component); - - return NULL; -} - -/** - * Stop execution of output component - */ -static iks *stop_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s stop", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - OUTPUT_COMPONENT(component)->stop = 1; - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s stopping\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Pause execution of output component - */ -static iks *pause_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s pause", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s pausing\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Resume execution of output component - */ -static iks *resume_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s resume", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s resuming\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Speed up execution of output component - */ -static iks *speed_up_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s speed:+", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s speeding up\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Slow down execution of output component - */ -static iks *speed_down_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s speed:-", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s slowing down\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Increase volume of output component - */ -static iks *volume_up_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s volume:+", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s increasing volume\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Lower volume of output component - */ -static iks *volume_down_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *result = NULL; - switch_core_session_t *session = NULL; - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s volume:-", RAYO_JID(component)); - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s lowering volume\n", RAYO_JID(component)); - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - return result; -} - -/** - * Seek output component - */ -static iks *seek_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *seek = iks_find(iq, "seek"); - - if (VALIDATE_RAYO_OUTPUT_SEEK(seek)) { - iks *result = NULL; - switch_core_session_t *session = NULL; - int is_forward = !strcmp("forward", iks_find_attrib(seek, "direction")); - int amount_ms = iks_find_int_attrib(seek, "amount"); - char *command = switch_mprintf("%s seek:%s%i", RAYO_JID(component), - is_forward ? "+" : "-", amount_ms); - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - if (!strcmp(RAYO_ACTOR(component)->type, RAT_CALL_COMPONENT)) { - session = (switch_core_session_t *)data; - } - - switch_api_execute("fileman", command, NULL, &stream); - if (!zstr((char *)stream.data) && !strncmp((char *)stream.data, "+OK", 3)) { - result = iks_new_iq_result(iq); - } else if (session && switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - result = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "call has ended"); - } else if (!zstr((char *)stream.data)) { - result = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", (char *)stream.data); - } else { - result = iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - switch_safe_free(stream.data); - switch_safe_free(command); - - return result; - } - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); -} - -/** - * Rayo document playback state - */ -struct rayo_file_context { - /** handle to current file */ - switch_file_handle_t fh; - /** current document being played */ - iks *cur_doc; - /** current file string being played */ - char *ssml; - /** The component */ - struct rayo_component *component; - /** number of times played */ - int play_count; - /** have any files successfully opened? */ - int could_open; -}; - -/** - * open next file for reading - * @param handle the file handle - */ -static switch_status_t next_file(switch_file_handle_t *handle) -{ - int loops = 0; - struct rayo_file_context *context = handle->private_info; - struct output_component *output = context->component ? OUTPUT_COMPONENT(context->component) : NULL; - - if (!output) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing output component!\n"); - return SWITCH_STATUS_FALSE; - } - - top: - - if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { - switch_core_file_close(&context->fh); - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - /* unsupported */ - return SWITCH_STATUS_FALSE; - } - - if (!context->cur_doc) { - context->cur_doc = iks_find(output->document, "document"); - if (!context->cur_doc) { - iks_delete(output->document); - output->document = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing \n"); - return SWITCH_STATUS_FALSE; - } - } else { - context->cur_doc = iks_next_tag(context->cur_doc); - } - - /* done? */ - if (!context->cur_doc) { - if (context->could_open && ++loops < 2 && (output->repeat_times == 0 || ++context->play_count < output->repeat_times)) { - /* repeat all document(s) */ - if (!output->repeat_interval_ms) { - goto top; - } - } else { - /* no more files to play */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Done playing\n"); - return SWITCH_STATUS_FALSE; - } - } - - if (!context->cur_doc) { - /* play silence between repeats */ - switch_safe_free(context->ssml); - context->ssml = switch_mprintf("silence_stream://%i", output->repeat_interval_ms); - } else { - /* play next document */ - iks *speak = NULL; - - switch_safe_free(context->ssml); - context->ssml = NULL; - speak = iks_find(context->cur_doc, "speak"); - if (speak) { - /* is child node */ - char *ssml_str = iks_string(NULL, speak); - if (zstr(output->renderer)) { - /* FS must parse the SSML */ - context->ssml = switch_mprintf("ssml://%s", ssml_str); - } else { - /* renderer will parse the SSML */ - if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { - /* pass MRCP headers */ - context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); - } else { - context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); - } - } - iks_free(ssml_str); - } else if (iks_has_children(context->cur_doc)) { - /* check if is in CDATA */ - const char *ssml_str = NULL; - iks *ssml = iks_child(context->cur_doc); - if (ssml && iks_type(ssml) == IKS_CDATA) { - ssml_str = iks_cdata(ssml); - } - if (zstr(ssml_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing CDATA\n"); - return SWITCH_STATUS_FALSE; - } - if (zstr(output->renderer)) { - /* FS must parse the SSML */ - context->ssml = switch_mprintf("ssml://%s", ssml_str); - } else { - /* renderer will parse the SSML */ - if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { - /* pass MRCP headers */ - context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); - } else { - context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); - } - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing \n"); - return SWITCH_STATUS_FALSE; - } - } - if (switch_core_file_open(&context->fh, context->ssml, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to open %s\n", context->ssml); - goto top; - } else { - context->could_open = 1; - } - - handle->samples = context->fh.samples; - handle->format = context->fh.format; - handle->sections = context->fh.sections; - handle->seekable = context->fh.seekable; - handle->speed = context->fh.speed; - handle->vol = context->fh.vol; - handle->offset_pos = context->fh.offset_pos; - handle->interval = context->fh.interval; - - if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { - switch_set_flag_locked(handle, SWITCH_FILE_NATIVE); - } else { - switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE); - } - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Transforms Rayo document into sub-format and opens file_string. - * @param handle - * @param path the inline Rayo document - * @return SWITCH_STATUS_SUCCESS if opened - */ -static switch_status_t rayo_file_open(switch_file_handle_t *handle, const char *path) -{ - switch_status_t status = SWITCH_STATUS_FALSE; - struct rayo_file_context *context = switch_core_alloc(handle->memory_pool, sizeof(*context)); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got path %s\n", path); - - context->component = RAYO_COMPONENT_LOCATE(path); - - if (context->component) { - handle->private_info = context; - context->cur_doc = NULL; - context->play_count = 0; - context->could_open = 0; - status = next_file(handle); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "File error! %s\n", path); - return SWITCH_STATUS_FALSE; - } - - if (status != SWITCH_STATUS_SUCCESS && context->component) { - /* complete error event will be sent by calling thread */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Status = %i\n", status); - RAYO_RELEASE(context->component); - } - - return status; -} - -/** - * Close SSML document. - * @param handle - * @return SWITCH_STATUS_SUCCESS - */ -static switch_status_t rayo_file_close(switch_file_handle_t *handle) -{ - struct rayo_file_context *context = (struct rayo_file_context *)handle->private_info; - - if (context && context->component) { - struct output_component *output = OUTPUT_COMPONENT(context->component); - - /* send completion and destroy */ - if (!strcmp(RAYO_ACTOR(context->component)->type, RAT_CALL_COMPONENT)) { - /* call output... check for hangup */ - switch_core_session_t *session = switch_core_session_locate(RAYO_ACTOR(context->component)->parent->id); - if (session) { - if (switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { - rayo_component_send_complete(context->component, COMPONENT_COMPLETE_HANGUP); - } else if (output->stop) { - rayo_component_send_complete(context->component, COMPONENT_COMPLETE_STOP); - } else { - rayo_component_send_complete(context->component, OUTPUT_FINISH); - } - switch_core_session_rwunlock(session); - } else { - /* session is gone */ - rayo_component_send_complete(context->component, COMPONENT_COMPLETE_HANGUP); - } - } else if (output->stop) { - rayo_component_send_complete(context->component, COMPONENT_COMPLETE_STOP); - } else { - /* mixer output... finished */ - rayo_component_send_complete(context->component, OUTPUT_FINISH); - } - /* TODO timed out */ - - /* cleanup internals */ - switch_safe_free(context->ssml); - context->ssml = NULL; - if (output->document) { - iks_delete(output->document); - output->document = NULL; - } - - /* close SSML file */ - if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { - return switch_core_file_close(&context->fh); - } - } - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Read from SSML document - * @param handle - * @param data - * @param len - * @return - */ -static switch_status_t rayo_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - switch_status_t status; - struct rayo_file_context *context = (struct rayo_file_context *)handle->private_info; - size_t llen = *len; - - if (OUTPUT_COMPONENT(context->component)->stop) { - return SWITCH_STATUS_FALSE; - } else { - status = switch_core_file_read(&context->fh, data, len); - if (status != SWITCH_STATUS_SUCCESS) { - if ((status = next_file(handle)) != SWITCH_STATUS_SUCCESS) { - return status; - } - *len = llen; - status = switch_core_file_read(&context->fh, data, len); - } - } - - return status; -} - -/** - * Seek file - */ -static switch_status_t rayo_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence) -{ - struct rayo_file_context *context = handle->private_info; - - if (samples == 0 && whence == SWITCH_SEEK_SET) { - /* restart from beginning */ - context->cur_doc = NULL; - context->play_count = 0; - return next_file(handle); - } - - if (!handle->seekable) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File is not seekable\n"); - return SWITCH_STATUS_NOTIMPL; - } - - return switch_core_file_seek(&context->fh, cur_sample, samples, whence); -} - -/** - * Manages access to fileman controls - */ -struct { - /** synchronizes access to fileman hash */ - switch_mutex_t *mutex; - /** fileman mapped by id */ - switch_hash_t *hash; -} fileman_globals; - -#define FILE_STARTBYTES 1024 * 32 -#define FILE_BLOCKSIZE 1024 * 8 -#define FILE_BUFSIZE 1024 * 64 - -/** - * Fileman playback state - */ -struct fileman_file_context { - /** handle to current file */ - switch_file_handle_t fh; - /** file buffer */ - int16_t *abuf; - /** end of file */ - int eof; - /** maximum size of a packet in 2-byte samples */ - switch_size_t max_frame_len; - /** optional session UUID */ - const char *uuid; - /** fileman control ID */ - const char *id; - /** done flag */ - int done; -}; - -/** - * Wraps file with interface that can be controlled by fileman flags - * @param handle - * @param path the file to play - * @return SWITCH_STATUS_SUCCESS if opened - */ -static switch_status_t fileman_file_open(switch_file_handle_t *handle, const char *path) -{ - int start_offset_ms = 0; - switch_status_t status = SWITCH_STATUS_FALSE; - struct fileman_file_context *context = switch_core_alloc(handle->memory_pool, sizeof(*context)); - handle->private_info = context; - - if (handle->params) { - const char *id = switch_event_get_header(handle->params, "id"); - const char *uuid = switch_event_get_header(handle->params, "session"); - const char *start_offset_ms_str = switch_event_get_header(handle->params, "start_offset_ms"); - if (!zstr(id)) { - context->id = switch_core_strdup(handle->memory_pool, id); - } - if (!zstr(uuid)) { - context->uuid = switch_core_strdup(handle->memory_pool, uuid); - } - if (!zstr(start_offset_ms_str) && switch_is_number(start_offset_ms_str)) { - start_offset_ms = atoi(start_offset_ms_str); - if (start_offset_ms < 0) { - start_offset_ms = 0; - } - } - } - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Got path %s\n", path); - - if ((status = switch_core_file_open(&context->fh, path, handle->channels, handle->samplerate, handle->flags, NULL)) != SWITCH_STATUS_SUCCESS) { - return status; - } - - /* set up handle for external control */ - if (!context->id) { - /* use filename as ID */ - context->id = switch_core_strdup(handle->memory_pool, path); - } - switch_mutex_lock(fileman_globals.mutex); - if (!switch_core_hash_find(fileman_globals.hash, context->id)) { - switch_core_hash_insert(fileman_globals.hash, context->id, handle); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_WARNING, "Duplicate fileman ID: %s\n", context->id); - return SWITCH_STATUS_FALSE; - } - switch_mutex_unlock(fileman_globals.mutex); - - context->max_frame_len = (handle->samplerate / 1000 * SWITCH_MAX_INTERVAL); - switch_zmalloc(context->abuf, FILE_STARTBYTES * sizeof(*context->abuf)); - - if (!context->fh.audio_buffer) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Create audio buffer\n"); - switch_buffer_create_dynamic(&context->fh.audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0); - switch_assert(context->fh.audio_buffer); - } - - handle->samples = context->fh.samples; - handle->format = context->fh.format; - handle->sections = context->fh.sections; - handle->seekable = context->fh.seekable; - handle->speed = context->fh.speed; - handle->vol = context->fh.vol; - handle->offset_pos = context->fh.offset_pos; - handle->interval = context->fh.interval; - - if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { - switch_set_flag_locked(handle, SWITCH_FILE_NATIVE); - } else { - switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE); - } - - if (handle->params && switch_true(switch_event_get_header(handle->params, "pause"))) { - switch_set_flag_locked(handle, SWITCH_FILE_PAUSE); - } - - if (handle->seekable && start_offset_ms) { - unsigned int pos = 0; - int32_t target = start_offset_ms * (handle->samplerate / 1000); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target); - switch_core_file_seek(&context->fh, &pos, target, SEEK_SET); - } - - return status; -} - -/** - * Close file. - * @param handle - * @return SWITCH_STATUS_SUCCESS - */ -static switch_status_t fileman_file_close(switch_file_handle_t *handle) -{ - struct fileman_file_context *context = (struct fileman_file_context *)handle->private_info; - switch_file_handle_t *fh = &context->fh; - - if (context->id) { - switch_mutex_lock(fileman_globals.mutex); - switch_core_hash_delete(fileman_globals.hash, context->id); - switch_mutex_unlock(fileman_globals.mutex); - } - - if (switch_test_flag(fh, SWITCH_FILE_OPEN)) { - free(context->abuf); - - if (fh->audio_buffer) { - switch_buffer_destroy(&fh->audio_buffer); - } - - if (fh->sp_audio_buffer) { - switch_buffer_destroy(&fh->sp_audio_buffer); - } - return switch_core_file_close(fh); - } - return SWITCH_STATUS_SUCCESS; -} - -/** - * Write to file - * @param handle - * @param data - * @param len - * @return - */ -static switch_status_t fileman_file_write(switch_file_handle_t *handle, void *data, size_t *len) -{ - struct fileman_file_context *context = (struct fileman_file_context *)handle->private_info; - switch_file_handle_t *fh = &context->fh; - if (!switch_test_flag(handle, SWITCH_FILE_PAUSE)) { - return switch_core_file_write(fh, data, len); - } - return SWITCH_STATUS_SUCCESS; -} - -/** - * Read from file - * @param handle - * @param data - * @param len - * @return - */ -static switch_status_t fileman_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - struct fileman_file_context *context = (struct fileman_file_context *)handle->private_info; - switch_file_handle_t *fh = &context->fh; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_size_t o_len = 0; - - /* anything called "_len" is measured in 2-byte samples */ - - if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) { - return switch_core_file_read(fh, data, len); - } - - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "len = %"SWITCH_SIZE_T_FMT"\n", *len); - if (*len > context->max_frame_len) { - *len = context->max_frame_len; - } - - for (;;) { - int do_speed = 1; - size_t read_bytes = 0; - - if (context->done) { - /* done with this file */ - status = SWITCH_STATUS_FALSE; - goto done; - } else if (switch_test_flag(handle, SWITCH_FILE_PAUSE)) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Read pause frame\n"); - memset(context->abuf, 255, *len * 2); - do_speed = 0; - o_len = *len; - } else if (fh->sp_audio_buffer && (context->eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (*len * 2)))) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Read speed frame\n"); - /* get next speed frame */ - if (!(read_bytes = switch_buffer_read(fh->sp_audio_buffer, context->abuf, *len * 2))) { - /* This is the reverse of what happens in switch_ivr_play_file... i think that implementation is wrong */ - if (context->eof) { - /* done with file */ - status = SWITCH_STATUS_FALSE; - goto done; - } else { - /* try again to fetch frame */ - continue; - } - } - - /* pad short frame with silence */ - if (read_bytes < *len * 2) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Padding speed frame %"SWITCH_SIZE_T_FMT" bytes\n", (context->frame_len * 2) - read_bytes); - memset(context->abuf + read_bytes, 255, (*len * 2) - read_bytes); - } - o_len = *len; - do_speed = 0; - } else if (fh->audio_buffer && (context->eof || (switch_buffer_inuse(fh->audio_buffer) > (switch_size_t) (*len * 2)))) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "(2) Read audio frame\n"); - /* get next file frame */ - if (!(read_bytes = switch_buffer_read(fh->audio_buffer, context->abuf, *len * 2))) { - if (context->eof) { - /* done with file */ - status = SWITCH_STATUS_FALSE; - goto done; - } else { - /* try again to fetch frame */ - continue; - } - } - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "(2) Read audio frame %"SWITCH_SIZE_T_FMT" bytes\n", read_bytes); - fh->offset_pos += read_bytes / 2; - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "(2) file pos = %i\n", fh->offset_pos); - - /* pad short frame with silence */ - if (read_bytes < (*len * 2)) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Padding audio frame %"SWITCH_SIZE_T_FMT" bytes\n", (context->frame_len * 2) - read_bytes); - memset(context->abuf + read_bytes, 255, (*len * 2) - read_bytes); - } - - o_len = *len; - } else { - if (context->eof) { - /* done with file */ - status = SWITCH_STATUS_FALSE; - goto done; - } - o_len = FILE_STARTBYTES / 2; - if (switch_core_file_read(fh, context->abuf, &o_len) != SWITCH_STATUS_SUCCESS) { - context->eof++; - /* at end of file... need to clear buffers before giving up */ - continue; - } - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Read file %"SWITCH_SIZE_T_FMT" bytes\n", o_len * 2); - - /* add file data to audio bufer */ - switch_buffer_write(fh->audio_buffer, context->abuf, o_len * 2); - - read_bytes = switch_buffer_read(fh->audio_buffer, context->abuf, *len * 2); - o_len = read_bytes / 2; - fh->offset_pos += o_len; - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Read audio frame %"SWITCH_SIZE_T_FMT" bytes\n", read_bytes); - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "file pos = %i\n", fh->offset_pos); - } - - if (o_len <= 0) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "o_len <= 0 (%"SWITCH_SIZE_T_FMT")\n", o_len); - status = SWITCH_STATUS_FALSE; - goto done; - } - - /* limit speed... there is a .25 factor change in packet size relative to original packet size for each increment. - Too many increments and we cause badness when (factor * speed * o_len) > o_len */ - if (handle->speed > 2) { - handle->speed = 2; - } else if (handle->speed < -2) { - handle->speed = -2; - } - - if (switch_test_flag(fh, SWITCH_FILE_SEEK)) { - /* file position has changed flush the buffer */ - switch_buffer_zero(fh->audio_buffer); - switch_clear_flag_locked(fh, SWITCH_FILE_SEEK); - } - - /* generate speed frames */ - if (handle->speed && do_speed) { - float factor = 0.25f * abs(handle->speed); - switch_size_t new_len, supplement_len, step_len; - short *bp = context->abuf; - switch_size_t wrote_len = 0; - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Generate speed frame (%i)\n", handle->speed); - - supplement_len = (int) (factor * o_len); - if (!supplement_len) { - supplement_len = 1; - } - new_len = (handle->speed > 0) ? o_len - supplement_len : o_len + supplement_len; - - step_len = (handle->speed > 0) ? (new_len / supplement_len) : (o_len / supplement_len); - - if (!fh->sp_audio_buffer) { - switch_buffer_create_dynamic(&fh->sp_audio_buffer, 1024, 1024, 0); - } - - while ((wrote_len + step_len) < new_len) { - switch_buffer_write(fh->sp_audio_buffer, bp, step_len * 2); - wrote_len += step_len; - bp += step_len; - if (handle->speed > 0) { - bp++; - } else { - float f; - short s; - f = (float) (*bp + *(bp + 1) + *(bp - 1)); - f /= 3; - s = (short) f; - switch_buffer_write(fh->sp_audio_buffer, &s, 2); - wrote_len++; - } - } - if (wrote_len < new_len) { - switch_size_t r_len = new_len - wrote_len; - switch_buffer_write(fh->sp_audio_buffer, bp, r_len * 2); - } - continue; - } - - /* adjust volume on frame */ - if (handle->vol) { - //switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Adjust volume to = %i\n", handle->vol); - switch_change_sln_volume(context->abuf, *len, handle->vol); - } - break; - } - -done: - - /* copy frame over to return to caller */ - memcpy(data, context->abuf, *len * 2); - handle->offset_pos = context->fh.offset_pos; - - return status; -} - -/** - * Seek file - */ -static switch_status_t fileman_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence) -{ - struct fileman_file_context *context = handle->private_info; - - if (!handle->seekable) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_WARNING, "File is not seekable\n"); - return SWITCH_STATUS_NOTIMPL; - } - return switch_core_file_seek(&context->fh, cur_sample, samples, whence); -} - -/** - * Process fileman command - */ -static switch_status_t fileman_process_cmd(const char *cmd, switch_file_handle_t *fhp) -{ - if (zstr(cmd)) { - return SWITCH_STATUS_SUCCESS; - } - - if (fhp) { - struct fileman_file_context *context = (struct fileman_file_context *)fhp->private_info; - if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) { - return SWITCH_STATUS_FALSE; - } - - if (!strncasecmp(cmd, "speed", 5)) { - char *p; - - if ((p = strchr(cmd, ':'))) { - p++; - if (*p == '+' || *p == '-') { - int step; - if (!(step = atoi(p))) { - if (*p == '+') { - step = 1; - } else { - step = -1; - } - } - fhp->speed += step; - } else { - int speed = atoi(p); - fhp->speed = speed; - } - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; - - } else if (!strncasecmp(cmd, "volume", 6)) { - char *p; - - if ((p = strchr(cmd, ':'))) { - p++; - if (*p == '+' || *p == '-') { - int step; - if (!(step = atoi(p))) { - if (*p == '+') { - step = 1; - } else { - step = -1; - } - } - fhp->vol += step; - } else { - int vol = atoi(p); - fhp->vol = vol; - } - return SWITCH_STATUS_SUCCESS; - } - - if (fhp->vol) { - switch_normalize_volume(fhp->vol); - } - - return SWITCH_STATUS_FALSE; - } else if (!strcasecmp(cmd, "pause")) { - switch_set_flag_locked(fhp, SWITCH_FILE_PAUSE); - return SWITCH_STATUS_SUCCESS; - } else if (!strcasecmp(cmd, "resume")) { - switch_clear_flag_locked(fhp, SWITCH_FILE_PAUSE); - return SWITCH_STATUS_SUCCESS; - } else if (!strcasecmp(cmd, "stop")) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Stopping file\n"); - context->done = 1; - switch_set_flag_locked(fhp, SWITCH_FILE_DONE); - return SWITCH_STATUS_SUCCESS; - } else if (!strcasecmp(cmd, "truncate")) { - switch_core_file_truncate(fhp, 0); - } else if (!strcasecmp(cmd, "restart")) { - unsigned int pos = 0; - fhp->speed = 0; - switch_core_file_seek(fhp, &pos, 0, SEEK_SET); - return SWITCH_STATUS_SUCCESS; - } else if (!strncasecmp(cmd, "seek", 4)) { - unsigned int samps = 0; - unsigned int pos = 0; - char *p; - - if ((p = strchr(cmd, ':'))) { - p++; - if (*p == '+' || *p == '-') { - int step; - int32_t target; - if (!(step = atoi(p))) { - if (*p == '+') { - step = 1000; - } else { - step = -1000; - } - } - - samps = step * (fhp->samplerate / 1000); - target = (int32_t)fhp->pos + samps; - - if (target < 0) { - target = 0; - } - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target); - switch_core_file_seek(fhp, &pos, target, SEEK_SET); - - } else { - samps = switch_atoui(p) * (fhp->samplerate / 1000); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", samps); - switch_core_file_seek(fhp, &pos, samps, SEEK_SET); - } - } - - return SWITCH_STATUS_SUCCESS; - } - } - - if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) { - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; -} - -#define FILEMAN_SYNTAX " :" -SWITCH_STANDARD_API(fileman_api) -{ - char *mycmd = NULL, *argv[4] = { 0 }; - int argc = 0; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (argc >= 2 && !zstr(argv[0])) { - char *id = argv[0]; - char *cmd = argv[1]; - switch_file_handle_t *fh = NULL; - switch_mutex_lock(fileman_globals.mutex); - fh = (switch_file_handle_t *)switch_core_hash_find(fileman_globals.hash, id); - if (fh) { - if (fileman_process_cmd(cmd, fh) == SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "+OK\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "fileman API failed for file %s\n", zstr(fh->file_path) ? "" : fh->file_path); - stream->write_function(stream, "-ERR API call failed"); - } - switch_mutex_unlock(fileman_globals.mutex); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "fileman API failed for ID %s\n", zstr(id) ? "" : id); - switch_mutex_unlock(fileman_globals.mutex); - stream->write_function(stream, "-ERR file handle not found\n"); - } - goto done; - } - } - - stream->write_function(stream, "-USAGE: %s\n", FILEMAN_SYNTAX); - - done: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -static char *rayo_supported_formats[] = { "rayo", NULL }; -static char *fileman_supported_formats[] = { "fileman", NULL }; - -/** - * Initialize output component - * @param module_interface - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - switch_api_interface_t *api_interface; - switch_file_interface_t *file_interface; - - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_OUTPUT_NS":output", start_call_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_EXT_NS":stop", stop_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":pause", pause_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":resume", resume_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":speed-up", speed_up_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":speed-down", speed_down_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":volume-up", volume_up_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":volume-down", volume_down_output_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":seek", seek_output_component); - - rayo_actor_command_handler_add(RAT_MIXER, "", "set:"RAYO_OUTPUT_NS":output", start_mixer_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_EXT_NS":stop", stop_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":pause", pause_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":resume", resume_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":speed-up", speed_up_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":speed-down", speed_down_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":volume-up", volume_up_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":volume-down", volume_down_output_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "output", "set:"RAYO_OUTPUT_NS":seek", seek_output_component); - - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = "mod_rayo"; - file_interface->extens = rayo_supported_formats; - file_interface->file_open = rayo_file_open; - file_interface->file_close = rayo_file_close; - file_interface->file_read = rayo_file_read; - file_interface->file_seek = rayo_file_seek; - - switch_mutex_init(&fileman_globals.mutex, SWITCH_MUTEX_NESTED, pool); - switch_core_hash_init(&fileman_globals.hash); - - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = "mod_rayo"; - file_interface->extens = fileman_supported_formats; - file_interface->file_open = fileman_file_open; - file_interface->file_close = fileman_file_close; - file_interface->file_write = fileman_file_write; - file_interface->file_read = fileman_file_read; - file_interface->file_seek = fileman_file_seek; - - SWITCH_ADD_API(api_interface, "fileman", "Manage file audio", fileman_api, FILEMAN_SYNTAX); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Shutdown output component - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_output_component_shutdown(void) -{ - if (fileman_globals.hash) { - switch_core_hash_destroy(&fileman_globals.hash); - } - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c deleted file mode 100644 index 15add81d79..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2015, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * rayo_prompt_component.c -- Rayo prompt component implementation - * - */ -#include "rayo_components.h" -#include "rayo_elements.h" - -enum prompt_component_state { - /* initial state - no barge */ - PCS_START_OUTPUT, - /* playing prompt */ - PCS_OUTPUT, - /* start input - no barge */ - PCS_START_INPUT, - /* input starting - start timers needed */ - PCS_START_INPUT_TIMERS, - /* initial state - barge in */ - PCS_START_OUTPUT_BARGE, - /* start input for barge-in */ - PCS_START_INPUT_OUTPUT, - /* playing and detecting */ - PCS_INPUT_OUTPUT, - /* barge in on output */ - PCS_STOP_OUTPUT, - /* detecting */ - PCS_INPUT, - /* finishing, stop output */ - PCS_DONE_STOP_OUTPUT, - /* finished */ - PCS_DONE -}; - -/** - * Prompt state - */ -struct prompt_component { - struct rayo_component base; - enum prompt_component_state state; - iks *iq; - iks *complete; - const char *input_jid; - const char *output_jid; - const char *start_timers_request_id; -}; - -#define PROMPT_COMPONENT(x) ((struct prompt_component *)x) - -static const char *prompt_component_state_to_string(enum prompt_component_state state) -{ - switch(state) { - case PCS_START_OUTPUT_BARGE: return "START_OUTPUT_BARGE"; - case PCS_START_OUTPUT: return "START_OUTPUT"; - case PCS_START_INPUT_OUTPUT: return "START_INPUT_OUTPUT"; - case PCS_START_INPUT: return "START_INPUT"; - case PCS_START_INPUT_TIMERS: return "START_INPUT_TIMERS"; - case PCS_INPUT_OUTPUT: return "INPUT_OUTPUT"; - case PCS_STOP_OUTPUT: return "STOP_OUTPUT"; - case PCS_INPUT: return "INPUT"; - case PCS_OUTPUT: return "OUTPUT"; - case PCS_DONE_STOP_OUTPUT: return "DONE_STOP_OUTPUT"; - case PCS_DONE: return "DONE"; - } - return "UNKNOWN"; -} - -/** - * Send input-timers-started event - */ -void rayo_component_send_input_timers_started_event(struct rayo_component *component) -{ - iks *event = iks_new("presence"); - iks *x; - iks_insert_attrib(event, "from", RAYO_JID(component)); - iks_insert_attrib(event, "to", component->client_jid); - x = iks_insert(event, "input-timers-started"); - iks_insert_attrib(x, "xmlns", RAYO_PROMPT_NS); - RAYO_SEND_REPLY(component, component->client_jid, event); -} - -/** - * Send stop to component - */ -static void rayo_component_send_stop(struct rayo_actor *from, const char *to) -{ - iks *stop = iks_new("iq"); - iks *x; - iks_insert_attrib(stop, "from", RAYO_JID(from)); - iks_insert_attrib(stop, "to", to); - iks_insert_attrib(stop, "type", "set"); - iks_insert_attrib_printf(stop, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(from)); - x = iks_insert(stop, "stop"); - iks_insert_attrib(x, "xmlns", RAYO_EXT_NS); - RAYO_SEND_MESSAGE(from, to, stop); -} - -/** - * Start input component - */ -static void start_input(struct prompt_component *prompt, int start_timers, int barge_event) -{ - iks *iq = iks_new("iq"); - iks *input = iks_find(PROMPT_COMPONENT(prompt)->iq, "prompt"); - input = iks_find(input, "input"); - iks_insert_attrib(iq, "from", RAYO_JID(prompt)); - iks_insert_attrib(iq, "to", RAYO_JID(RAYO_ACTOR(prompt)->parent)); - iks_insert_attrib_printf(iq, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt)); - iks_insert_attrib(iq, "type", "set"); - input = iks_copy_within(input, iks_stack(iq)); - iks_insert_attrib(input, "start-timers", start_timers ? "true" : "false"); - iks_insert_attrib(input, "barge-event", barge_event ? "true" : "false"); - iks_insert_node(iq, input); - RAYO_SEND_MESSAGE(prompt, RAYO_JID(RAYO_ACTOR(prompt)->parent), iq); -} - -/** - * Start input component timers - */ -static void start_input_timers(struct prompt_component *prompt) -{ - iks *x; - iks *iq = iks_new("iq"); - iks_insert_attrib(iq, "from", RAYO_JID(prompt)); - iks_insert_attrib(iq, "to", prompt->input_jid); - iks_insert_attrib(iq, "type", "set"); - prompt->start_timers_request_id = switch_core_sprintf(RAYO_POOL(prompt), "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt)); - iks_insert_attrib(iq, "id", prompt->start_timers_request_id); - x = iks_insert(iq, "start-timers"); - iks_insert_attrib(x, "xmlns", RAYO_INPUT_NS); - RAYO_SEND_MESSAGE(prompt, prompt->input_jid, iq); -} - -/** - * Handle start of output. - */ -static iks *prompt_component_handle_output_start(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) output start\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_START_OUTPUT: - PROMPT_COMPONENT(prompt)->output_jid = switch_core_strdup(RAYO_POOL(prompt), msg->from_jid); - PROMPT_COMPONENT(prompt)->state = PCS_OUTPUT; - /* send ref to client */ - rayo_component_send_start(RAYO_COMPONENT(prompt), PROMPT_COMPONENT(prompt)->iq); - break; - case PCS_START_OUTPUT_BARGE: - PROMPT_COMPONENT(prompt)->output_jid = switch_core_strdup(RAYO_POOL(prompt), msg->from_jid); - PROMPT_COMPONENT(prompt)->state = PCS_START_INPUT_OUTPUT; - /* start input without timers and with barge events */ - start_input(PROMPT_COMPONENT(prompt), 0, 1); - break; - case PCS_OUTPUT: - case PCS_START_INPUT_OUTPUT: - case PCS_START_INPUT: - case PCS_START_INPUT_TIMERS: - case PCS_INPUT_OUTPUT: - case PCS_STOP_OUTPUT: - case PCS_INPUT: - case PCS_DONE_STOP_OUTPUT: - case PCS_DONE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start output event\n", RAYO_JID(prompt)); - break; - } - - return NULL; -} - -/** - * Handle start of input. - */ -static iks *prompt_component_handle_input_start(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) input start\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_START_INPUT: - PROMPT_COMPONENT(prompt)->input_jid = switch_core_strdup(RAYO_POOL(prompt), msg->from_jid); - PROMPT_COMPONENT(prompt)->state = PCS_INPUT; - rayo_component_send_input_timers_started_event(RAYO_COMPONENT(prompt)); - break; - case PCS_START_INPUT_OUTPUT: - PROMPT_COMPONENT(prompt)->input_jid = switch_core_strdup(RAYO_POOL(prompt), msg->from_jid); - PROMPT_COMPONENT(prompt)->state = PCS_INPUT_OUTPUT; - /* send ref to client */ - rayo_component_send_start(RAYO_COMPONENT(prompt), PROMPT_COMPONENT(prompt)->iq); - break; - case PCS_START_INPUT_TIMERS: - PROMPT_COMPONENT(prompt)->input_jid = switch_core_strdup(RAYO_POOL(prompt), msg->from_jid); - PROMPT_COMPONENT(prompt)->state = PCS_INPUT; - /* send ref to client */ - rayo_component_send_start(RAYO_COMPONENT(prompt), PROMPT_COMPONENT(prompt)->iq); - start_input_timers(PROMPT_COMPONENT(prompt)); - break; - case PCS_DONE: - /* stopped by client */ - PROMPT_COMPONENT(prompt)->input_jid = switch_core_strdup(RAYO_POOL(prompt), msg->from_jid); - rayo_component_send_stop(prompt, msg->from_jid); - break; - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - case PCS_INPUT_OUTPUT: - case PCS_INPUT: - case PCS_STOP_OUTPUT: - case PCS_OUTPUT: - case PCS_DONE_STOP_OUTPUT: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start input event\n", RAYO_JID(prompt)); - break; - } - return NULL; -} - -/** - * Handle start of input/output. - */ -static iks *prompt_component_handle_io_start(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, got from %s: %s\n", - RAYO_JID(prompt), msg->from_jid, iks_string(iks_stack(iq), iq)); - if (!strcmp("input", msg->from_subtype)) { - return prompt_component_handle_input_start(prompt, msg, data); - } else if (!strcmp("output", msg->from_subtype)) { - return prompt_component_handle_output_start(prompt, msg, data); - } - return NULL; -} - -/** - * Handle failure to start timers - */ -static iks *prompt_component_handle_input_start_timers_error(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - /* this is only expected if input component is gone */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) start timers error\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - return NULL; -} - -/** - * Handle input failure. - */ -static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *error = iks_find(iq, "error"); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) input error\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_START_INPUT_TIMERS: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, error: %s\n", RAYO_JID(prompt), iks_string(iks_stack(iq), iq)); - PROMPT_COMPONENT(prompt)->state = PCS_DONE; - - /* forward IQ error to client */ - iq = PROMPT_COMPONENT(prompt)->iq; - iks_insert_attrib(iq, "from", RAYO_JID(prompt->parent)); - iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); - iks_insert_attrib(iq, "type", "error"); - iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); - RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); - - /* done */ - PROMPT_COMPONENT(prompt)->iq = NULL; - RAYO_RELEASE(prompt); - RAYO_DESTROY(prompt); - - break; - - case PCS_START_INPUT: - PROMPT_COMPONENT(prompt)->state = PCS_DONE; - iks_delete(PROMPT_COMPONENT(prompt)->iq); - if (iks_find(error, "item-not-found")) { - /* call is gone (hangup) */ - rayo_component_send_complete(RAYO_COMPONENT(prompt), COMPONENT_COMPLETE_HANGUP); - } else { - /* send presence error to client */ - rayo_component_send_complete(RAYO_COMPONENT(prompt), COMPONENT_COMPLETE_ERROR); - } - break; - case PCS_START_INPUT_OUTPUT: - PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; - - /* forward IQ error to client */ - iq = PROMPT_COMPONENT(prompt)->iq; - iks_insert_attrib(iq, "from", RAYO_JID(prompt->parent)); - iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); - iks_insert_attrib(iq, "type", "error"); - iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); - PROMPT_COMPONENT(prompt)->complete = iks_copy(iq); - - rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->output_jid); - break; - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - case PCS_INPUT_OUTPUT: - case PCS_STOP_OUTPUT: - case PCS_INPUT: - case PCS_OUTPUT: - case PCS_DONE_STOP_OUTPUT: - case PCS_DONE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start input error event\n", RAYO_JID(prompt)); - break; - } - - return NULL; -} - -/** - * Handle output failure. - */ -static iks *prompt_component_handle_output_error(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *error = iks_find(iq, "error"); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) output error\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, error: %s\n", RAYO_JID(prompt), iks_string(iks_stack(iq), iq)); - PROMPT_COMPONENT(prompt)->state = PCS_DONE; - - /* forward IQ error to client */ - iq = PROMPT_COMPONENT(prompt)->iq; - iks_insert_attrib(iq, "from", RAYO_JID(prompt->parent)); - iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); - iks_insert_attrib(iq, "type", "error"); - iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); - RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); - - /* done */ - PROMPT_COMPONENT(prompt)->iq = NULL; - RAYO_RELEASE(prompt); - RAYO_DESTROY(prompt); - - break; - case PCS_START_INPUT_OUTPUT: - case PCS_START_INPUT_TIMERS: - case PCS_START_INPUT: - case PCS_INPUT_OUTPUT: - case PCS_STOP_OUTPUT: - case PCS_INPUT: - case PCS_OUTPUT: - case PCS_DONE_STOP_OUTPUT: - case PCS_DONE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start output error event\n", RAYO_JID(prompt)); - break; - } - - return NULL; -} - -/** - * Handle barge event - */ -static iks *prompt_component_handle_input_barge(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *presence = msg->payload; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) input barge\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_INPUT_OUTPUT: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, got from %s: %s\n", - RAYO_JID(prompt), msg->from_jid, iks_string(iks_stack(presence), presence)); - PROMPT_COMPONENT(prompt)->state = PCS_STOP_OUTPUT; - rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->output_jid); - break; - case PCS_STOP_OUTPUT: - case PCS_INPUT: - /* don't care */ - break; - case PCS_OUTPUT: - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - case PCS_START_INPUT: - case PCS_START_INPUT_OUTPUT: - case PCS_START_INPUT_TIMERS: - case PCS_DONE_STOP_OUTPUT: - case PCS_DONE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start output error event\n", RAYO_JID(prompt)); - break; - } - return NULL; -} - -/** - * Handle completion event - */ -static iks *prompt_component_handle_input_complete(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *presence = msg->payload; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) input complete\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_INPUT_OUTPUT: - PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; - presence = iks_copy(presence); - iks_insert_attrib(presence, "from", RAYO_JID(prompt)); - iks_insert_attrib(presence, "to", RAYO_COMPONENT(prompt)->client_jid); - PROMPT_COMPONENT(prompt)->complete = presence; - rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->output_jid); - break; - case PCS_STOP_OUTPUT: - PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; - presence = iks_copy(presence); - iks_insert_attrib(presence, "from", RAYO_JID(prompt)); - iks_insert_attrib(presence, "to", RAYO_COMPONENT(prompt)->client_jid); - PROMPT_COMPONENT(prompt)->complete = presence; - break; - case PCS_INPUT: - PROMPT_COMPONENT(prompt)->state = PCS_DONE; - /* pass through */ - case PCS_DONE: - presence = iks_copy(presence); - iks_insert_attrib(presence, "from", RAYO_JID(prompt)); - iks_insert_attrib(presence, "to", RAYO_COMPONENT(prompt)->client_jid); - iks_delete(PROMPT_COMPONENT(prompt)->iq); - rayo_component_send_complete_event(RAYO_COMPONENT(prompt), presence); - break; - case PCS_OUTPUT: - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - case PCS_START_INPUT: - case PCS_START_INPUT_OUTPUT: - case PCS_START_INPUT_TIMERS: - case PCS_DONE_STOP_OUTPUT: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s, unexpected start output error event\n", RAYO_JID(prompt)); - break; - } - - return NULL; -} - -/** - * Forward result - */ -static iks *prompt_component_handle_result(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - - /* forward all results, except for internal ones... */ - const char *id = iks_find_attrib_soft(iq, "id"); - if (strncmp("mod_rayo-prompt", id, 15)) { - iks_insert_attrib(iq, "from", RAYO_JID(prompt)); - iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); - RAYO_SEND_REPLY_DUP(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); - } else if (!zstr(PROMPT_COMPONENT(prompt)->start_timers_request_id) && !strcmp(PROMPT_COMPONENT(prompt)->start_timers_request_id, id)) { - rayo_component_send_input_timers_started_event(RAYO_COMPONENT(prompt)); - } - - return NULL; -} - -/** - * Handle completion event - */ -static iks *prompt_component_handle_output_complete(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) output complete\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_OUTPUT: - PROMPT_COMPONENT(prompt)->state = PCS_START_INPUT; - /* start input with timers enabled and barge events disabled */ - start_input(PROMPT_COMPONENT(prompt), 1, 0); - break; - case PCS_START_INPUT_OUTPUT: - /* output finished before input started */ - PROMPT_COMPONENT(prompt)->state = PCS_START_INPUT_TIMERS; - break; - case PCS_INPUT_OUTPUT: - PROMPT_COMPONENT(prompt)->state = PCS_INPUT; - start_input_timers(PROMPT_COMPONENT(prompt)); - break; - case PCS_STOP_OUTPUT: - PROMPT_COMPONENT(prompt)->state = PCS_INPUT; - start_input_timers(PROMPT_COMPONENT(prompt)); - break; - case PCS_DONE_STOP_OUTPUT: - if (PROMPT_COMPONENT(prompt)->complete) { - iks_delete(PROMPT_COMPONENT(prompt)->iq); - rayo_component_send_complete_event(RAYO_COMPONENT(prompt), PROMPT_COMPONENT(prompt)->complete); - } - break; - case PCS_INPUT: - break; - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - /* output most likely failed w/ error */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s, prompt output finished way too quickly (possible failure), continuing w/ input\n", RAYO_JID(prompt)); - /* start input with timers enabled and barge events disabled */ - rayo_component_send_start(RAYO_COMPONENT(prompt), PROMPT_COMPONENT(prompt)->iq); - PROMPT_COMPONENT(prompt)->state = PCS_START_INPUT; - start_input(PROMPT_COMPONENT(prompt), 1, 0); - break; - case PCS_START_INPUT: - case PCS_START_INPUT_TIMERS: - case PCS_DONE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s, unexpected start output complete event\n", RAYO_JID(prompt)); - break; - } - - return NULL; -} - -/** - * Start execution of prompt component - */ -static iks *start_call_prompt_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - switch_memory_pool_t *pool; - struct prompt_component *prompt_component = NULL; - iks *prompt = iks_find(iq, "prompt"); - iks *input; - iks *output; - iks *cmd; - - if (!VALIDATE_RAYO_PROMPT(prompt)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Bad attrib\n"); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad attrib value"); - } - - output = iks_find(prompt, "output"); - if (!output) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Missing \n"); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing "); - } - - input = iks_find(prompt, "input"); - if (!input) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Missing \n"); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing "); - } - - /* create prompt component, linked to call */ - switch_core_new_memory_pool(&pool); - prompt_component = switch_core_alloc(pool, sizeof(*prompt_component)); - prompt_component = PROMPT_COMPONENT(rayo_component_init(RAYO_COMPONENT(prompt_component), pool, RAT_CALL_COMPONENT, "prompt", NULL, call, iks_find_attrib(iq, "from"))); - if (!prompt_component) { - switch_core_destroy_memory_pool(&pool); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create prompt entity"); - } - prompt_component->iq = iks_copy(iq); - - /* start output */ - if (iks_find_bool_attrib(prompt, "barge-in")) { - prompt_component->state = PCS_START_OUTPUT_BARGE; - } else { - prompt_component->state = PCS_START_OUTPUT; - } - cmd = iks_new("iq"); - iks_insert_attrib(cmd, "from", RAYO_JID(prompt_component)); - iks_insert_attrib(cmd, "to", RAYO_JID(call)); - iks_insert_attrib(cmd, "id", iks_find_attrib(iq, "id")); - iks_insert_attrib(cmd, "type", "set"); - output = iks_copy_within(output, iks_stack(cmd)); - iks_insert_node(cmd, output); - RAYO_SEND_MESSAGE(prompt_component, RAYO_JID(call), cmd); - - return NULL; -} - -/** - * Stop execution of prompt component - */ -static iks *stop_call_prompt_component(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - iks *reply = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) stop prompt\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_OUTPUT: - /* input hasn't started yet */ - PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; - PROMPT_COMPONENT(prompt)->complete = rayo_component_create_complete_event(RAYO_COMPONENT(prompt), COMPONENT_COMPLETE_STOP); - rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->output_jid); - break; - case PCS_INPUT_OUTPUT: - case PCS_INPUT: - case PCS_STOP_OUTPUT: - /* stopping input will trigger completion */ - rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->input_jid); - break; - case PCS_START_INPUT: - /* stop input as soon as it starts */ - PROMPT_COMPONENT(prompt)->state = PCS_DONE; - break; - case PCS_DONE_STOP_OUTPUT: - case PCS_DONE: - /* already done */ - break; - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - case PCS_START_INPUT_OUTPUT: - case PCS_START_INPUT_TIMERS: - /* ref hasn't been sent yet */ - reply = iks_new_error(iq, STANZA_ERROR_UNEXPECTED_REQUEST); - break; - } - - if (!reply) { - reply = iks_new_iq_result(iq); - } - return reply; -} - -/** - * Pass output component command - */ -static iks *forward_output_component_request(struct rayo_actor *prompt, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) %s prompt\n", - RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state), iks_name(iks_first_tag(iq))); - - switch (PROMPT_COMPONENT(prompt)->state) { - case PCS_OUTPUT: - case PCS_START_INPUT_OUTPUT: - case PCS_INPUT_OUTPUT: { - /* forward request to output component */ - iks_insert_attrib(iq, "from", RAYO_JID(prompt)); - iks_insert_attrib(iq, "to", PROMPT_COMPONENT(prompt)->output_jid); - RAYO_SEND_MESSAGE_DUP(prompt, PROMPT_COMPONENT(prompt)->output_jid, iq); - return NULL; - } - case PCS_START_INPUT_TIMERS: - case PCS_START_OUTPUT: - case PCS_START_OUTPUT_BARGE: - /* ref hasn't been sent yet */ - return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "too soon"); - break; - case PCS_START_INPUT: - case PCS_STOP_OUTPUT: - case PCS_DONE_STOP_OUTPUT: - case PCS_INPUT: - case PCS_DONE: - return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "output is finished"); - } - return NULL; -} - -/** - * Initialize prompt component - * @param module_interface - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - /* Prompt is a convenience component that wraps and */ - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_PROMPT_NS":prompt", start_call_prompt_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_EXT_NS":stop", stop_call_prompt_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "result:"RAYO_NS":ref", prompt_component_handle_io_start); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "result::", prompt_component_handle_result); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "error:"RAYO_OUTPUT_NS":output", prompt_component_handle_output_error); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "error:"RAYO_INPUT_NS":input", prompt_component_handle_input_error); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "error:"RAYO_INPUT_NS":start-timers", prompt_component_handle_input_start_timers_error); - rayo_actor_event_handler_add(RAT_CALL_COMPONENT, "input", RAT_CALL_COMPONENT, "prompt", ":"RAYO_INPUT_NS":start-of-input", prompt_component_handle_input_barge); - rayo_actor_event_handler_add(RAT_CALL_COMPONENT, "input", RAT_CALL_COMPONENT, "prompt", "unavailable:"RAYO_EXT_NS":complete", prompt_component_handle_input_complete); - rayo_actor_event_handler_add(RAT_CALL_COMPONENT, "output", RAT_CALL_COMPONENT, "prompt", "unavailable:"RAYO_EXT_NS":complete", prompt_component_handle_output_complete); - - /* wrap output commands */ - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":pause", forward_output_component_request); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":resume", forward_output_component_request); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":speed-up", forward_output_component_request); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":speed-down", forward_output_component_request); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":volume-up", forward_output_component_request); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":volume-down", forward_output_component_request); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_OUTPUT_NS":seek", forward_output_component_request); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Shutdown prompt component - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_prompt_component_shutdown(void) -{ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/rayo_record_component.c b/src/mod/event_handlers/mod_rayo/rayo_record_component.c deleted file mode 100644 index 82a36d79b8..0000000000 --- a/src/mod/event_handlers/mod_rayo/rayo_record_component.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2014, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * record_component.c -- Rayo record component implementation - * - */ -#include "rayo_components.h" -#include "rayo_elements.h" - -/* TODO timeouts / durations are affected by pause/resume */ - -/** - * settings - */ -static struct { - const char *record_file_prefix; - const char *record_file_format; -} globals; - -/** - * A record component - */ -struct record_component { - /** component base class */ - struct rayo_component base; - /** maximum duration allowed */ - int max_duration; - /** timeout for total silence */ - int initial_timeout; - /** timeout for silence after initial utterance */ - int final_timeout; - /** duplex/send/recv */ - const char *direction; - /** true if mixed (mono) */ - int mix; - /** true if start beep to be played */ - int start_beep; - /** true if stop beep to be played */ - int stop_beep; - /** time recording started */ - switch_time_t start_time; - /** duration of this recording */ - int duration_ms; - /** path on local filesystem */ - char *local_file_path; - /** true if recording was stopped */ - int stop; -}; - -#define RECORD_COMPONENT(x) ((struct record_component *)x) - -/* 1000 Hz beep for 250ms */ -#define RECORD_BEEP "tone_stream://%(250,0,1000)" - -#define RECORD_COMPLETE_MAX_DURATION "max-duration", RAYO_RECORD_COMPLETE_NS -#define RECORD_COMPLETE_INITIAL_TIMEOUT "initial-timeout", RAYO_RECORD_COMPLETE_NS -#define RECORD_COMPLETE_FINAL_TIMEOUT "final-timeout", RAYO_RECORD_COMPLETE_NS - -/** - * Notify completion of record component - */ -static void complete_record(struct rayo_component *component, const char *reason, const char *reason_namespace) -{ - switch_core_session_t *session = NULL; - const char *uuid = RAYO_ACTOR(component)->parent->id; - const char *uri = RECORD_COMPONENT(component)->local_file_path; - iks *recording; - switch_size_t file_size = 0; - - /* TODO this doesn't work with HTTP, improve core RECORD_STOP event so that file size and duration is reported */ -#if 0 - switch_file_t *file; - - if (switch_file_open(&file, uri, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { - file_size = switch_file_get_size(file); - switch_file_close(file); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_INFO, "Failed to open %s.\n", uri); - } -#endif - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Recording %s done.\n", uri); - - if (RECORD_COMPONENT(component)->stop_beep && (session = switch_core_session_locate(uuid))) { - switch_ivr_displace_session(session, RECORD_BEEP, 0, ""); - switch_core_session_rwunlock(session); - } - - /* send complete event to client */ - recording = iks_new("recording"); - iks_insert_attrib(recording, "xmlns", RAYO_RECORD_COMPLETE_NS); - if (strlen(uri) > strlen(SWITCH_PATH_SEPARATOR) && !strncmp(uri, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { - /* convert absolute path to file:// URI */ - iks_insert_attrib_printf(recording, "uri", "file://%s", uri); - } else { - /* is already a URI (hopefully) */ - iks_insert_attrib(recording, "uri", uri); - } - iks_insert_attrib_printf(recording, "duration", "%i", RECORD_COMPONENT(component)->duration_ms); - iks_insert_attrib_printf(recording, "size", "%"SWITCH_SIZE_T_FMT, file_size); - rayo_component_send_complete_with_metadata(component, reason, reason_namespace, recording, 1); - iks_delete(recording); -} - -/** - * Handle RECORD_STOP event from FreeSWITCH. - * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. - */ -static void on_call_record_stop_event(switch_event_t *event) -{ - const char *file_path = switch_event_get_header(event, "Record-File-Path"); - struct rayo_component *component = RAYO_COMPONENT_LOCATE(file_path); - - if (component) { - const char *completion_cause = switch_event_get_header(event, "Record-Completion-Cause"); - completion_cause = zstr(completion_cause) ? "" : completion_cause; - RECORD_COMPONENT(component)->duration_ms += (switch_micro_time_now() - RECORD_COMPONENT(component)->start_time) / 1000; - if (RECORD_COMPONENT(component)->stop) { - complete_record(component, COMPONENT_COMPLETE_STOP); - } else if (!strcmp(completion_cause, "no-input-timeout")) { - complete_record(component, RECORD_COMPLETE_INITIAL_TIMEOUT); - } else if (!strcmp(completion_cause, "success-maxtime")) { - complete_record(component, RECORD_COMPLETE_MAX_DURATION); - } else { - /* assume final timeout */ - complete_record(component, RECORD_COMPLETE_FINAL_TIMEOUT); - } - RAYO_RELEASE(component); - } -} - -/** - * Create a record component - */ -static struct rayo_component *record_component_create(struct rayo_actor *actor, const char *type, const char *client_jid, iks *record) -{ - switch_memory_pool_t *pool; - struct record_component *record_component = NULL; - char *local_file_path; - char *fs_file_path; - switch_bool_t start_paused; - - start_paused = iks_find_bool_attrib(record, "start-paused"); - - /* create record filename from session UUID and ref */ - /* for example: prefix/1234-1234-1234-1234-30.wav */ - local_file_path = switch_mprintf("%s%s-%i.%s", - globals.record_file_prefix, - actor->id, rayo_actor_seq_next(actor), iks_find_attrib(record, "format")); - - fs_file_path = switch_mprintf("{pause=%s}fileman://%s", - start_paused ? "true" : "false", - local_file_path); - - switch_core_new_memory_pool(&pool); - record_component = switch_core_alloc(pool, sizeof(*record_component)); - record_component = RECORD_COMPONENT(rayo_component_init(RAYO_COMPONENT(record_component), pool, type, "record", fs_file_path, actor, client_jid)); - if (record_component) { - record_component->max_duration = iks_find_int_attrib(record, "max-duration"); - record_component->initial_timeout = iks_find_int_attrib(record, "initial-timeout"); - record_component->final_timeout = iks_find_int_attrib(record, "final-timeout"); - record_component->direction = switch_core_strdup(RAYO_POOL(record_component), iks_find_attrib_soft(record, "direction")); - record_component->mix = iks_find_bool_attrib(record, "mix"); - record_component->start_beep = iks_find_bool_attrib(record, "start-beep"); - record_component->stop_beep = iks_find_bool_attrib(record, "stop-beep"); - record_component->start_time = start_paused ? 0 : switch_micro_time_now(); - record_component->local_file_path = switch_core_strdup(RAYO_POOL(record_component), local_file_path); - } else { - switch_core_destroy_memory_pool(&pool); - } - - switch_safe_free(local_file_path); - switch_safe_free(fs_file_path); - - return RAYO_COMPONENT(record_component); -} - -/** - * Start recording call - * @param session the session to record - * @param record the record component - */ -static int start_call_record(switch_core_session_t *session, struct rayo_component *component) -{ - struct record_component *record_component = RECORD_COMPONENT(component); - switch_channel_t *channel = switch_core_session_get_channel(session); - int max_duration_sec = 0; - - switch_channel_set_variable(channel, "RECORD_HANGUP_ON_ERROR", "false"); - switch_channel_set_variable(channel, "RECORD_TOGGLE_ON_REPEAT", ""); - switch_channel_set_variable(channel, "RECORD_CHECK_BRIDGE", ""); - switch_channel_set_variable(channel, "RECORD_MIN_SEC", "0"); - switch_channel_set_variable(channel, "RECORD_STEREO", ""); - switch_channel_set_variable(channel, "RECORD_READ_ONLY", ""); - switch_channel_set_variable(channel, "RECORD_WRITE_ONLY", ""); - switch_channel_set_variable(channel, "RECORD_APPEND", ""); - switch_channel_set_variable(channel, "RECORD_WRITE_OVER", "true"); - switch_channel_set_variable(channel, "RECORD_ANSWER_REQ", ""); - switch_channel_set_variable(channel, "RECORD_SILENCE_THRESHOLD", "200"); - if (record_component->initial_timeout > 0) { - switch_channel_set_variable_printf(channel, "RECORD_INITIAL_TIMEOUT_MS", "%i", record_component->initial_timeout); - } else { - switch_channel_set_variable(channel, "RECORD_INITIAL_TIMEOUT_MS", ""); - } - if (record_component->final_timeout > 0) { - switch_channel_set_variable_printf(channel, "RECORD_FINAL_TIMEOUT_MS", "%i", record_component->final_timeout); - } else { - switch_channel_set_variable(channel, "RECORD_FINAL_TIMEOUT_MS", ""); - } - /* allow dialplan override for these variables */ - //switch_channel_set_variable(channel, "RECORD_PRE_BUFFER_FRAMES", ""); - //switch_channel_set_variable(channel, "record_sample_rate", ""); - //switch_channel_set_variable(channel, "enable_file_write_buffering", ""); - - /* max duration attribute is in milliseconds- convert to seconds */ - if (record_component->max_duration > 0) { - max_duration_sec = ceil((double)(record_component->max_duration - record_component->duration_ms) / 1000.0); - } - - if (!strcmp(record_component->direction, "duplex")) { - if (!record_component->mix) { - /* STEREO */ - switch_channel_set_variable(channel, "RECORD_STEREO", "true"); - } /* else MONO (default) */ - } else if (!strcmp(record_component->direction, "send")) { - /* record audio sent from the caller */ - switch_channel_set_variable(channel, "RECORD_READ_ONLY", "true"); - } else if (!strcmp(record_component->direction, "recv")) { - /* record audio received by the caller */ - switch_channel_set_variable(channel, "RECORD_WRITE_ONLY", "true"); - }; - - if (record_component->start_beep) { - switch_ivr_displace_session(session, RECORD_BEEP, 0, ""); - record_component->start_time = switch_micro_time_now(); - } - - if (switch_ivr_record_session(session, (char *)RAYO_ID(component), max_duration_sec, NULL) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Recording started: file = %s\n", RAYO_ID(component)); - return 1; - } - - return 0; -} - -/** - * Start execution of call record component - */ -static iks *start_call_record_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = (switch_core_session_t *)session_data; - struct rayo_component *component = NULL; - iks *record = iks_find(iq, "record"); - - /* validate record attributes */ - if (!VALIDATE_RAYO_RECORD(record)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - component = record_component_create(call, RAT_CALL_COMPONENT, iks_find_attrib(iq, "from"), record); - if (!component) { - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create record entity"); - } - - if (start_call_record(session, component)) { - rayo_component_send_start(component, iq); - } else { - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - - return NULL; -} - -/** - * Stop execution of record component - */ -static iks *stop_call_record_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - switch_core_session_t *session = switch_core_session_locate(component->parent->id); - if (session) { - RECORD_COMPONENT(component)->stop = 1; - switch_ivr_stop_record_session(session, RAYO_ID(component)); - switch_core_session_rwunlock(session); - } - return iks_new_iq_result(iq); -} - -/** - * Pause execution of record component - */ -static iks *pause_record_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - struct record_component *record = RECORD_COMPONENT(component); - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s pause", record->local_file_path); - SWITCH_STANDARD_STREAM(stream); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s pausing\n", RAYO_ID(component)); - if (record->start_time) { - record->duration_ms += (switch_micro_time_now() - record->start_time) / 1000; - record->start_time = 0; - } - switch_api_execute("fileman", command, NULL, &stream); - switch_safe_free(stream.data); - switch_safe_free(command); - - return iks_new_iq_result(iq); -} - -/** - * Resume execution of record component - */ -static iks *resume_record_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - struct record_component *record = RECORD_COMPONENT(component); - switch_stream_handle_t stream = { 0 }; - char *command = switch_mprintf("%s resume", record->local_file_path); - SWITCH_STANDARD_STREAM(stream); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s resuming\n", RAYO_ID(component)); - if (!record->start_time) { - record->start_time = switch_micro_time_now(); - } - switch_api_execute("fileman", command, NULL, &stream); - switch_safe_free(stream.data); - switch_safe_free(command); - - return iks_new_iq_result(iq); -} - -/** - * Handle conference events from FreeSWITCH. - * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. - */ -static void on_mixer_record_event(switch_event_t *event) -{ - const char *file_path = switch_event_get_header(event, "Path"); - const char *action = switch_event_get_header(event, "Action"); - struct rayo_component *component = RAYO_COMPONENT_LOCATE(file_path); - - if (component) { - struct record_component *record = RECORD_COMPONENT(component); - if (!strcmp("stop-recording", action)) { - record->duration_ms += (switch_micro_time_now() - record->start_time) / 1000; - if (record->stop) { - complete_record(component, COMPONENT_COMPLETE_STOP); - } else { - /* TODO assume final timeout, for now */ - complete_record(component, RECORD_COMPLETE_FINAL_TIMEOUT); - } - } - RAYO_RELEASE(component); - } -} - -/** - * Start recording mixer - * @param record the record component - */ -static int start_mixer_record(struct rayo_component *component) -{ - switch_stream_handle_t stream = { 0 }; - char *args; - SWITCH_STANDARD_STREAM(stream); - - args = switch_mprintf("%s recording start %s", RAYO_ACTOR(component)->parent->id, RAYO_ID(component)); - switch_api_execute("conference", args, NULL, &stream); - switch_safe_free(args); - switch_safe_free(stream.data); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recording started: file = %s\n", RAYO_ID(component)); - return 1; -} - -/** - * Start execution of mixer record component - */ -static iks *start_mixer_record_component(struct rayo_actor *mixer, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - struct rayo_component *component = NULL; - iks *record = iks_find(iq, "record"); - - /* validate record attributes */ - if (!VALIDATE_RAYO_RECORD(record)) { - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - component = record_component_create(mixer, RAT_MIXER_COMPONENT, iks_find_attrib(iq, "from"), record); - if (!component) { - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create record entity"); - } - - /* mixer doesn't allow "send" */ - if (!strcmp("send", iks_find_attrib_soft(record, "direction"))) { - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); - } - - if (start_mixer_record(component)) { - rayo_component_send_start(component, iq); - } else { - RAYO_RELEASE(component); - RAYO_DESTROY(component); - return iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR); - } - - return NULL; -} - -/** - * Stop execution of record component - */ -static iks *stop_mixer_record_component(struct rayo_actor *component, struct rayo_message *msg, void *data) -{ - iks *iq = msg->payload; - char *args; - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - - RECORD_COMPONENT(component)->stop = 1; - args = switch_mprintf("%s recording stop %s", component->parent->id, RAYO_ID(component)); - switch_api_execute("conference", args, NULL, &stream); - switch_safe_free(args); - switch_safe_free(stream.data); - - return iks_new_iq_result(iq); -} - -/** - * Process module XML configuration - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS on successful configuration - */ -static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) -{ - switch_xml_t cfg, xml; - - /* set defaults */ - globals.record_file_prefix = switch_core_sprintf(pool, "%s%s", SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_PATH_SEPARATOR); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Configuring module\n"); - if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); - return SWITCH_STATUS_TERM; - } - - /* get params */ - { - switch_xml_t settings = switch_xml_child(cfg, "record"); - if (settings) { - switch_xml_t param; - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); - if (!strcasecmp(var, "record-file-prefix")) { - if (!zstr(val)) { - globals.record_file_prefix = switch_core_strdup(pool, val); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); - } - } - } - } - - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Initialize record component - * @param module_interface - * @param pool memory pool to allocate from - * @param config_file to use - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) -{ - if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - - switch_event_bind("rayo_record_component", SWITCH_EVENT_RECORD_STOP, NULL, on_call_record_stop_event, NULL); - rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_RECORD_NS":record", start_call_record_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "record", "set:"RAYO_RECORD_NS":pause", pause_record_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "record", "set:"RAYO_RECORD_NS":resume", resume_record_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "record", "set:"RAYO_EXT_NS":stop", stop_call_record_component); - - switch_event_bind("rayo_record_component", SWITCH_EVENT_CUSTOM, "conference::maintenance", on_mixer_record_event, NULL); - rayo_actor_command_handler_add(RAT_MIXER, "", "set:"RAYO_RECORD_NS":record", start_mixer_record_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "record", "set:"RAYO_RECORD_NS":pause", pause_record_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "record", "set:"RAYO_RECORD_NS":resume", resume_record_component); - rayo_actor_command_handler_add(RAT_MIXER_COMPONENT, "record", "set:"RAYO_EXT_NS":stop", stop_mixer_record_component); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Shutdown record component - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t rayo_record_component_shutdown(void) -{ - switch_event_unbind_callback(on_call_record_stop_event); - switch_event_unbind_callback(on_mixer_record_event); - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ - diff --git a/src/mod/event_handlers/mod_rayo/sasl.c b/src/mod/event_handlers/mod_rayo/sasl.c deleted file mode 100644 index 4277ea305b..0000000000 --- a/src/mod/event_handlers/mod_rayo/sasl.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * sasl.c -- SASL functions - * - */ -#include -#include -#include "sasl.h" - -/** - * Parse authzid, authcid, and password tokens from base64 PLAIN auth message. - * @param message the base-64 encoded authentication message - * @param authzid the authorization id in the message - free this string when done with parsed message - * @param authcid the authentication id in the message - * @param password the password in the message - */ -void parse_plain_auth_message(const char *message, char **authzid, char **authcid, char **password) -{ - char *decoded = iks_base64_decode(message); - int maxlen = strlen(message) * 6 / 8 + 1; - int pos = 0; - *authzid = NULL; - *authcid = NULL; - *password = NULL; - if (decoded == NULL) { - goto end; - } - pos = strlen(decoded) + 1; - if (pos >= maxlen) { - goto end; - } - *authcid = strdup(decoded + pos); - pos += strlen(*authcid) + 1; - if (pos >= maxlen) { - goto end; - } - *password = strdup(decoded + pos); - if (zstr(decoded)) { - *authzid = strdup(*authcid); - } else { - *authzid = strdup(decoded); - } - - end: - switch_safe_free(decoded); -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/sasl.h b/src/mod/event_handlers/mod_rayo/sasl.h deleted file mode 100644 index 641bcfa064..0000000000 --- a/src/mod/event_handlers/mod_rayo/sasl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * sasl.h -- SASL - * - */ -#ifndef SASL_H -#define SASL_H - -SWITCH_DECLARE(void) parse_plain_auth_message(const char *message, char **authzid, char **authcid, char **password); - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/srgs.c b/src/mod/event_handlers/mod_rayo/srgs.c deleted file mode 100644 index 7981c24ef2..0000000000 --- a/src/mod/event_handlers/mod_rayo/srgs.c +++ /dev/null @@ -1,1683 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2015, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * srgs.c -- Parses / converts / matches SRGS grammars - * - */ -#include -#include -#include - -#include "srgs.h" - -#define MAX_RECURSION 100 -#define MAX_TAGS 1024 - -/** function to handle tag attributes */ -typedef int (* tag_attribs_fn)(struct srgs_grammar *, char **); -/** function to handle tag CDATA */ -typedef int (* tag_cdata_fn)(struct srgs_grammar *, char *, size_t); - -/** - * Tag definition - */ -struct tag_def { - tag_attribs_fn attribs_fn; - tag_cdata_fn cdata_fn; - switch_bool_t is_root; - switch_hash_t *children_tags; -}; - -/** - * library configuration - */ -typedef struct { - /** true if initialized */ - switch_bool_t init; - /** Mapping of tag name to definition */ - switch_hash_t *tag_defs; - /** library memory pool */ - switch_memory_pool_t *pool; -} srgs_globals; -static srgs_globals globals = { 0 }; - -/** - * SRGS node types - */ -enum srgs_node_type { - /** anything */ - SNT_ANY, - /** */ - SNT_GRAMMAR, - /** */ - SNT_RULE, - /** */ - SNT_ONE_OF, - /** */ - SNT_ITEM, - /** unresolved reference to node */ - SNT_UNRESOLVED_REF, - /** resolved reference to node */ - SNT_REF, - /** string */ - SNT_STRING, - /** */ - SNT_TAG, - /** */ - SNT_LEXICON, - /** */ - SNT_EXAMPLE, - /** */ - SNT_TOKEN, - /** */ - SNT_META, - /** */ - SNT_METADATA -}; - -/** - * value - */ -struct rule_value { - char is_public; - char *id; - char *regex; -}; - -/** - * value - */ -struct item_value { - int repeat_min; - int repeat_max; - const char *weight; - int tag; -}; - -/** - * value - */ -union ref_value { - struct srgs_node *node; - char *uri; -}; - -/** - * A node in the SRGS parse tree - */ -struct srgs_node { - /** Name of node */ - const char *name; - /** Type of node */ - enum srgs_node_type type; - /** True if node has been inspected for loops */ - char visited; - /** Node value */ - union { - char *root; - const char *string; - union ref_value ref; - struct rule_value rule; - struct item_value item; - } value; - /** parent node */ - struct srgs_node *parent; - /** child node */ - struct srgs_node *child; - /** sibling node */ - struct srgs_node *next; - /** number of child nodes */ - int num_children; - /** tag handling data */ - struct tag_def *tag_def; -}; - -/** - * A parsed grammar - */ -struct srgs_grammar { - /** grammar memory pool */ - switch_memory_pool_t *pool; - /** current node being parsed */ - struct srgs_node *cur; - /** rule names mapped to node */ - switch_hash_t *rules; - /** possible matching tags */ - const char *tags[MAX_TAGS + 1]; - /** number of tags */ - int tag_count; - /** grammar encoding */ - char *encoding; - /** grammar language */ - char *language; - /** true if digit grammar */ - int digit_mode; - /** grammar parse tree root */ - struct srgs_node *root; - /** root rule */ - struct srgs_node *root_rule; - /** compiled grammar regex */ - pcre *compiled_regex; - /** grammar in regex format */ - char *regex; - /** grammar in JSGF format */ - char *jsgf; - /** grammar as JSGF file */ - char *jsgf_file_name; - /** synchronizes access to this grammar */ - switch_mutex_t *mutex; - /** optional uuid for logging */ - const char *uuid; -}; - -/** - * The SRGS SAX parser - */ -struct srgs_parser { - /** parser memory pool */ - switch_memory_pool_t *pool; - /** grammar cache */ - switch_hash_t *cache; - /** cache mutex */ - switch_mutex_t *mutex; - /** optional uuid for logging */ - const char *uuid; -}; - -/** - * Convert entity name to node type - * @param name of entity - * @return the type or ANY - */ -static enum srgs_node_type string_to_node_type(char *name) -{ - if (!strcmp("grammar", name)) { - return SNT_GRAMMAR; - } - if (!strcmp("item", name)) { - return SNT_ITEM; - } - if (!strcmp("one-of", name)) { - return SNT_ONE_OF; - } - if (!strcmp("ruleref", name)) { - return SNT_UNRESOLVED_REF; - } - if (!strcmp("rule", name)) { - return SNT_RULE; - } - if (!strcmp("tag", name)) { - return SNT_TAG; - } - if (!strcmp("lexicon", name)) { - return SNT_LEXICON; - } - if (!strcmp("example", name)) { - return SNT_EXAMPLE; - } - if (!strcmp("token", name)) { - return SNT_TOKEN; - } - if (!strcmp("meta", name)) { - return SNT_META; - } - if (!strcmp("metadata", name)) { - return SNT_METADATA; - } - return SNT_ANY; -} - -/** - * Log node - */ -static void sn_log_node_open(struct srgs_node *node) -{ - switch (node->type) { - case SNT_ANY: - case SNT_METADATA: - case SNT_META: - case SNT_TOKEN: - case SNT_EXAMPLE: - case SNT_LEXICON: - case SNT_TAG: - case SNT_ONE_OF: - case SNT_GRAMMAR: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "<%s>\n", node->name); - return; - case SNT_RULE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "\n", node->value.rule.id, node->value.rule.is_public ? "public" : "private"); - return; - case SNT_ITEM: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "\n", node->value.item.repeat_min); - return; - case SNT_UNRESOLVED_REF: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "value.ref.uri); - return; - case SNT_REF: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "\n", node->value.ref.node->value.rule.id); - return; - case SNT_STRING: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s\n", node->value.string); - return; - } -} - -/** - * Log node - */ -static void sn_log_node_close(struct srgs_node *node) -{ - switch (node->type) { - case SNT_GRAMMAR: - case SNT_RULE: - case SNT_ONE_OF: - case SNT_ITEM: - case SNT_REF: - case SNT_TAG: - case SNT_LEXICON: - case SNT_EXAMPLE: - case SNT_TOKEN: - case SNT_META: - case SNT_METADATA: - case SNT_ANY: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "\n", node->name); - return; - case SNT_UNRESOLVED_REF: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "\n"); - return; - case SNT_STRING: - return; - } -} - -/** - * Create a new node - * @param pool to use - * @param name of node - * @param type of node - * @return the node - */ -static struct srgs_node *sn_new(switch_memory_pool_t *pool, const char *name, enum srgs_node_type type) -{ - struct srgs_node *node = switch_core_alloc(pool, sizeof(*node)); - node->name = switch_core_strdup(pool, name); - node->type = type; - return node; -} - -/** - * @param node to search - * @return the last sibling of node - */ -static struct srgs_node *sn_find_last_sibling(struct srgs_node *node) -{ - if (node && node->next) { - return sn_find_last_sibling(node->next); - } - return node; -} - -/** - * Add child node - * @param pool to use - * @param parent node to add child to - * @param name the child node name - * @param type the child node type - * @return the child node - */ -static struct srgs_node *sn_insert(switch_memory_pool_t *pool, struct srgs_node *parent, const char *name, enum srgs_node_type type) -{ - struct srgs_node *sibling = parent ? sn_find_last_sibling(parent->child) : NULL; - struct srgs_node *child = sn_new(pool, name, type); - if (parent) { - parent->num_children++; - child->parent = parent; - } - if (sibling) { - sibling->next = child; - } else if (parent) { - parent->child = child; - } - return child; -} - -/** - * Add string child node - * @param pool to use - * @param parent node to add string to - * @param string to add - this function does not copy the string - * @return the string child node - */ -static struct srgs_node *sn_insert_string(switch_memory_pool_t *pool, struct srgs_node *parent, char *string) -{ - struct srgs_node *child = sn_insert(pool, parent, string, SNT_STRING); - child->value.string = string; - return child; -} - -/** - * Tag def destructor - */ -static void destroy_tag_def(void *ptr) -{ - struct tag_def *tag = (struct tag_def *) ptr; - if (tag->children_tags) { - switch_core_hash_destroy(&tag->children_tags); - } -} - -/** - * Add a definition for a tag - * @param tag the name - * @param attribs_fn the function to handle the tag attributes - * @param cdata_fn the function to handler the tag CDATA - * @param children_tags comma-separated list of valid child tag names - * @return the definition - */ -static struct tag_def *add_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) -{ - struct tag_def *def = switch_core_alloc(globals.pool, sizeof(*def)); - switch_core_hash_init(&def->children_tags); - if (!zstr(children_tags)) { - char *children_tags_dup = switch_core_strdup(globals.pool, children_tags); - char *tags[32] = { 0 }; - int tag_count = switch_separate_string(children_tags_dup, ',', tags, sizeof(tags) / sizeof(tags[0])); - if (tag_count) { - int i; - for (i = 0; i < tag_count; i++) { - switch_core_hash_insert(def->children_tags, tags[i], tags[i]); - } - } - } - def->attribs_fn = attribs_fn; - def->cdata_fn = cdata_fn; - def->is_root = SWITCH_FALSE; - switch_core_hash_insert_destructor(globals.tag_defs, tag, def, destroy_tag_def); - return def; -} - -/** - * Add a definition for a root tag - * @param tag the name - * @param attribs_fn the function to handle the tag attributes - * @param cdata_fn the function to handler the tag CDATA - * @param children_tags comma-separated list of valid child tag names - * @return the definition - */ -static struct tag_def *add_root_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) -{ - struct tag_def *def = add_tag_def(tag, attribs_fn, cdata_fn, children_tags); - def->is_root = SWITCH_TRUE; - return def; -} - -/** - * Handle tag attributes - * @param parser the parser - * @param name the tag name - * @param atts the attributes - * @return IKS_OK if OK IKS_BADXML on parse failure - */ -static int process_tag(struct srgs_grammar *grammar, const char *name, char **atts) -{ - struct srgs_node *cur = grammar->cur; - if (cur->tag_def->is_root && cur->parent == NULL) { - /* no parent for ROOT tags */ - return cur->tag_def->attribs_fn(grammar, atts); - } else if (!cur->tag_def->is_root && cur->parent) { - /* check if this child is allowed by parent node */ - struct tag_def *parent_def = cur->parent->tag_def; - if (switch_core_hash_find(parent_def->children_tags, "ANY") || - switch_core_hash_find(parent_def->children_tags, name)) { - return cur->tag_def->attribs_fn(grammar, atts); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "<%s> cannot be a child of <%s>\n", name, cur->parent->name); - } - } else if (cur->tag_def->is_root && cur->parent != NULL) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "<%s> must be the root element\n", name); - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "<%s> cannot be a root element\n", name); - } - return IKS_BADXML; -} - -/** - * Handle tag attributes that are ignored - * @param grammar the grammar - * @param atts the attributes - * @return IKS_OK - */ -static int process_attribs_ignore(struct srgs_grammar *grammar, char **atts) -{ - return IKS_OK; -} - -/** - * Handle CDATA that is ignored - * @param grammar the grammar - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int process_cdata_ignore(struct srgs_grammar *grammar, char *data, size_t len) -{ - return IKS_OK; -} - -/** - * Handle CDATA that is not allowed - * @param grammar the grammar - * @param data the CDATA - * @param len the CDATA length - * @return IKS_BADXML if any printable characters - */ -static int process_cdata_bad(struct srgs_grammar *grammar, char *data, size_t len) -{ - int i; - for (i = 0; i < len; i++) { - if (isgraph(data[i])) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Unexpected CDATA for <%s>\n", grammar->cur->name); - return IKS_BADXML; - } - } - return IKS_OK; -} - -/** - * Process attributes - * @param grammar the grammar state - * @param atts the attributes - * @return IKS_OK if ok - */ -static int process_rule(struct srgs_grammar *grammar, char **atts) -{ - struct srgs_node *rule = grammar->cur; - rule->value.rule.is_public = 0; - rule->value.rule.id = NULL; - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("scope", atts[i])) { - rule->value.rule.is_public = !zstr(atts[i + 1]) && !strcmp("public", atts[i + 1]); - } else if (!strcmp("id", atts[i])) { - if (!zstr(atts[i + 1])) { - rule->value.rule.id = switch_core_strdup(grammar->pool, atts[i + 1]); - } - } - i += 2; - } - } - - if (zstr(rule->value.rule.id)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Missing rule ID: %s\n", rule->value.rule.id); - return IKS_BADXML; - } - - if (switch_core_hash_find(grammar->rules, rule->value.rule.id)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Duplicate rule ID: %s\n", rule->value.rule.id); - return IKS_BADXML; - } - switch_core_hash_insert(grammar->rules, rule->value.rule.id, rule); - - return IKS_OK; -} - -/** - * Process attributes - * @param grammar the grammar state - * @param atts the attributes - * @return IKS_OK if ok - */ -static int process_ruleref(struct srgs_grammar *grammar, char **atts) -{ - struct srgs_node *ruleref = grammar->cur; - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("uri", atts[i])) { - char *uri = atts[i + 1]; - if (zstr(uri)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Empty uri\n"); - return IKS_BADXML; - } - /* only allow local reference */ - if (uri[0] != '#' || strlen(uri) < 2) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Only local rule refs allowed\n"); - return IKS_BADXML; - } - ruleref->value.ref.uri = switch_core_strdup(grammar->pool, uri); - return IKS_OK; - } - i += 2; - } - } - return IKS_OK; -} - -/** - * Process attributes - * @param grammar the grammar state - * @param atts the attributes - * @return IKS_OK if ok - */ -static int process_item(struct srgs_grammar *grammar, char **atts) -{ - struct srgs_node *item = grammar->cur; - item->value.item.repeat_min = 1; - item->value.item.repeat_max = 1; - item->value.item.weight = NULL; - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("repeat", atts[i])) { - /* repeats of 0 are not supported by this code */ - char *repeat = atts[i + 1]; - if (zstr(repeat)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Empty repeat atribute\n"); - return IKS_BADXML; - } - if (switch_is_number(repeat)) { - /* single number */ - int repeat_val = atoi(repeat); - if (repeat_val < 1) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " repeat must be >= 0\n"); - return IKS_BADXML; - } - item->value.item.repeat_min = repeat_val; - item->value.item.repeat_max = repeat_val; - } else { - /* range */ - char *min = switch_core_strdup(grammar->pool, repeat); - char *max = strchr(min, '-'); - if (max) { - *max = '\0'; - max++; - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " repeat must be a number or range\n"); - return IKS_BADXML; - } - if (switch_is_number(min) && (switch_is_number(max) || zstr(max))) { - int min_val = atoi(min); - int max_val = zstr(max) ? INT_MAX : atoi(max); - /* max must be >= min and > 0 - min must be >= 0 */ - if ((max_val <= 0) || (max_val < min_val) || (min_val < 0)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " repeat range invalid\n"); - return IKS_BADXML; - } - item->value.item.repeat_min = min_val; - item->value.item.repeat_max = max_val; - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " repeat range is not a number\n"); - return IKS_BADXML; - } - } - } else if (!strcmp("weight", atts[i])) { - const char *weight = atts[i + 1]; - if (zstr(weight) || !switch_is_number(weight) || atof(weight) < 0) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " weight is not a number >= 0\n"); - return IKS_BADXML; - } - item->value.item.weight = switch_core_strdup(grammar->pool, weight); - } - i += 2; - } - } - return IKS_OK; -} - -/** - * Process attributes - * @param grammar the grammar state - * @param atts the attributes - * @return IKS_OK if ok - */ -static int process_grammar(struct srgs_grammar *grammar, char **atts) -{ - if (grammar->root) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Only one tag allowed\n"); - return IKS_BADXML; - } - grammar->root = grammar->cur; - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("mode", atts[i])) { - char *mode = atts[i + 1]; - if (zstr(mode)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " mode is missing\n"); - return IKS_BADXML; - } - grammar->digit_mode = !strcasecmp(mode, "dtmf"); - } else if(!strcmp("encoding", atts[i])) { - char *encoding = atts[i + 1]; - if (zstr(encoding)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " encoding is empty\n"); - return IKS_BADXML; - } - grammar->encoding = switch_core_strdup(grammar->pool, encoding); - } else if (!strcmp("language", atts[i])) { - char *language = atts[i + 1]; - if (zstr(language)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " language is empty\n"); - return IKS_BADXML; - } - grammar->language = switch_core_strdup(grammar->pool, language); - } else if (!strcmp("root", atts[i])) { - char *root = atts[i + 1]; - if (zstr(root)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, " root is empty\n"); - return IKS_BADXML; - } - grammar->cur->value.root = switch_core_strdup(grammar->pool, root); - } - i += 2; - } - } - return IKS_OK; -} - -/** - * Process a tag - */ -static int tag_hook(void *user_data, char *name, char **atts, int type) -{ - int result = IKS_OK; - struct srgs_grammar *grammar = (struct srgs_grammar *)user_data; - - if (type == IKS_OPEN || type == IKS_SINGLE) { - enum srgs_node_type ntype = string_to_node_type(name); - grammar->cur = sn_insert(grammar->pool, grammar->cur, name, ntype); - grammar->cur->tag_def = switch_core_hash_find(globals.tag_defs, name); - if (!grammar->cur->tag_def) { - grammar->cur->tag_def = switch_core_hash_find(globals.tag_defs, "ANY"); - } - result = process_tag(grammar, name, atts); - sn_log_node_open(grammar->cur); - } - - if (type == IKS_CLOSE || type == IKS_SINGLE) { - sn_log_node_close(grammar->cur); - grammar->cur = grammar->cur->parent; - } - - return result; -} - -/** - * Process CDATA - * @param grammar the grammar - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int process_cdata_tag(struct srgs_grammar *grammar, char *data, size_t len) -{ - struct srgs_node *item = grammar->cur->parent; - if (item && item->type == SNT_ITEM) { - if (grammar->tag_count < MAX_TAGS) { - /* grammar gets the tag name, item gets the unique tag number */ - char *tag = switch_core_alloc(grammar->pool, sizeof(char) * (len + 1)); - tag[len] = '\0'; - strncpy(tag, data, len); - grammar->tags[++grammar->tag_count] = tag; - item->value.item.tag = grammar->tag_count; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "too many s\n"); - return IKS_BADXML; - } - } - return IKS_OK; -} - -/** - * Process CDATA grammar tokens - * @param grammar the grammar - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int process_cdata_tokens(struct srgs_grammar *grammar, char *data, size_t len) -{ - struct srgs_node *string = grammar->cur; - int i; - if (grammar->digit_mode) { - for (i = 0; i < len; i++) { - if (isdigit(data[i]) || data[i] == '#' || data[i] == '*') { - char *digit = switch_core_alloc(grammar->pool, sizeof(char) * 2); - digit[0] = data[i]; - digit[1] = '\0'; - string = sn_insert_string(grammar->pool, string, digit); - sn_log_node_open(string); - } - } - } else { - char *data_dup = switch_core_alloc(grammar->pool, sizeof(char) * (len + 1)); - char *start = data_dup; - char *end = start + len - 1; - memcpy(data_dup, data, len); - /* remove start whitespace */ - for (; start && *start && !isgraph(*start); start++) { - } - if (!zstr(start)) { - /* remove end whitespace */ - for (; end != start && *end && !isgraph(*end); end--) { - *end = '\0'; - } - if (!zstr(start)) { - sn_insert_string(grammar->pool, string, start); - } - } - } - return IKS_OK; -} - -/** - * Process cdata - * @param user_data the grammar - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int cdata_hook(void *user_data, char *data, size_t len) -{ - struct srgs_grammar *grammar = (struct srgs_grammar *)user_data; - if (!grammar) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing grammar\n"); - return IKS_BADXML; - } - if (grammar->cur) { - if (grammar->cur->tag_def) { - return grammar->cur->tag_def->cdata_fn(grammar, data, len); - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Missing definition for <%s>\n", grammar->cur->name); - return IKS_BADXML; - } - return IKS_OK; -} - -/** - * Create a new parsed grammar - * @param parser - * @return the grammar - */ -struct srgs_grammar *srgs_grammar_new(struct srgs_parser *parser) -{ - switch_memory_pool_t *pool = NULL; - struct srgs_grammar *grammar = NULL; - switch_core_new_memory_pool(&pool); - grammar = switch_core_alloc(pool, sizeof (*grammar)); - grammar->pool = pool; - grammar->root = NULL; - grammar->cur = NULL; - grammar->uuid = (parser && !zstr(parser->uuid)) ? switch_core_strdup(pool, parser->uuid) : ""; - switch_core_hash_init(&grammar->rules); - switch_mutex_init(&grammar->mutex, SWITCH_MUTEX_NESTED, pool); - return grammar; -} - -/** - * Destroy a parsed grammar - * @param grammar the grammar - */ -static void srgs_grammar_destroy(struct srgs_grammar *grammar) -{ - switch_memory_pool_t *pool = grammar->pool; - if (grammar->compiled_regex) { - pcre_free(grammar->compiled_regex); - } - if (grammar->jsgf_file_name) { - switch_file_remove(grammar->jsgf_file_name, pool); - } - switch_core_hash_destroy(&grammar->rules); - switch_core_destroy_memory_pool(&pool); -} - -/** - * Create a new parser. - * @param uuid optional uuid for logging - * @return the created parser - */ -struct srgs_parser *srgs_parser_new(const char *uuid) -{ - switch_memory_pool_t *pool = NULL; - struct srgs_parser *parser = NULL; - switch_core_new_memory_pool(&pool); - if (pool) { - parser = switch_core_alloc(pool, sizeof(*parser)); - parser->pool = pool; - parser->uuid = zstr(uuid) ? "" : switch_core_strdup(pool, uuid); - switch_core_hash_init(&parser->cache); - switch_mutex_init(&parser->mutex, SWITCH_MUTEX_NESTED, pool); - } - return parser; -} - -/** - * Destroy the parser. - * @param parser to destroy - */ -void srgs_parser_destroy(struct srgs_parser *parser) -{ - switch_memory_pool_t *pool = parser->pool; - switch_hash_index_t *hi = NULL; - - if (parser->cache) { - /* clean up all cached grammars */ - for (hi = switch_core_hash_first(parser->cache); hi; hi = switch_core_hash_next(&hi)) { - struct srgs_grammar *grammar = NULL; - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - grammar = (struct srgs_grammar *)val; - switch_assert(grammar); - srgs_grammar_destroy(grammar); - } - switch_core_hash_destroy(&parser->cache); - } - switch_core_destroy_memory_pool(&pool); -} - -/** - * Create regexes - * @param grammar the grammar - * @param node root node - * @param stream set to NULL - * @return 1 if successful - */ -static int create_regexes(struct srgs_grammar *grammar, struct srgs_node *node, switch_stream_handle_t *stream) -{ - sn_log_node_open(node); - switch (node->type) { - case SNT_GRAMMAR: - if (node->child) { - int num_rules = 0; - struct srgs_node *child = node->child; - if (grammar->root_rule) { - if (!create_regexes(grammar, grammar->root_rule, NULL)) { - return 0; - } - grammar->regex = switch_core_sprintf(grammar->pool, "^%s$", grammar->root_rule->value.rule.regex); - } else { - switch_stream_handle_t new_stream = { 0 }; - SWITCH_STANDARD_STREAM(new_stream); - if (node->num_children > 1) { - new_stream.write_function(&new_stream, "%s", "^(?:"); - } else { - new_stream.write_function(&new_stream, "%s", "^"); - } - for (; child; child = child->next) { - if (!create_regexes(grammar, child, &new_stream)) { - switch_safe_free(new_stream.data); - return 0; - } - if (child->type == SNT_RULE && child->value.rule.is_public) { - if (num_rules > 0) { - new_stream.write_function(&new_stream, "%s", "|"); - } - new_stream.write_function(&new_stream, "%s", child->value.rule.regex); - num_rules++; - } - } - if (node->num_children > 1) { - new_stream.write_function(&new_stream, "%s", ")$"); - } else { - new_stream.write_function(&new_stream, "%s", "$"); - } - grammar->regex = switch_core_strdup(grammar->pool, new_stream.data); - switch_safe_free(new_stream.data); - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_DEBUG, "document regex = %s\n", grammar->regex); - } - break; - case SNT_RULE: - if (node->value.rule.regex) { - return 1; - } else if (node->child) { - struct srgs_node *item = node->child; - switch_stream_handle_t new_stream = { 0 }; - SWITCH_STANDARD_STREAM(new_stream); - for (; item; item = item->next) { - if (!create_regexes(grammar, item, &new_stream)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_DEBUG, "%s regex failed = %s\n", node->value.rule.id, node->value.rule.regex); - switch_safe_free(new_stream.data); - return 0; - } - } - node->value.rule.regex = switch_core_strdup(grammar->pool, new_stream.data); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_DEBUG, "%s regex = %s\n", node->value.rule.id, node->value.rule.regex); - switch_safe_free(new_stream.data); - } - break; - case SNT_STRING: { - int i; - for (i = 0; i < strlen(node->value.string); i++) { - switch (node->value.string[i]) { - case '[': - case '\\': - case '^': - case '$': - case '.': - case '|': - case '?': - case '*': - case '+': - case '(': - case ')': - /* escape special PCRE regex characters */ - stream->write_function(stream, "\\%c", node->value.string[i]); - break; - default: - stream->write_function(stream, "%c", node->value.string[i]); - break; - } - } - if (node->child) { - if (!create_regexes(grammar, node->child, stream)) { - return 0; - } - } - break; - } - case SNT_ITEM: - if (node->child) { - struct srgs_node *item = node->child; - if (node->value.item.repeat_min != 1 || node->value.item.repeat_max != 1 || node->value.item.tag) { - if (node->value.item.tag) { - stream->write_function(stream, "(?P", node->value.item.tag); - } else { - stream->write_function(stream, "%s", "(?:"); - } - } - for(; item; item = item->next) { - if (!create_regexes(grammar, item, stream)) { - return 0; - } - } - if (node->value.item.repeat_min != 1 || node->value.item.repeat_max != 1) { - if (node->value.item.repeat_min != node->value.item.repeat_max) { - if (node->value.item.repeat_min == 0 && node->value.item.repeat_max == INT_MAX) { - stream->write_function(stream, ")*"); - } else if (node->value.item.repeat_min == 0 && node->value.item.repeat_max == 1) { - stream->write_function(stream, ")?"); - } else if (node->value.item.repeat_min == 1 && node->value.item.repeat_max == INT_MAX) { - stream->write_function(stream, ")+"); - } else if (node->value.item.repeat_max == INT_MAX) { - stream->write_function(stream, "){%i,1000}", node->value.item.repeat_min); - } else { - stream->write_function(stream, "){%i,%i}", node->value.item.repeat_min, node->value.item.repeat_max); - } - } else { - stream->write_function(stream, "){%i}", node->value.item.repeat_min); - } - } else if (node->value.item.tag) { - stream->write_function(stream, "%s", ")"); - } - } - break; - case SNT_ONE_OF: - if (node->child) { - struct srgs_node *item = node->child; - if (node->num_children > 1) { - stream->write_function(stream, "%s", "(?:"); - } - for (; item; item = item->next) { - if (item != node->child) { - stream->write_function(stream, "%s", "|"); - } - if (!create_regexes(grammar, item, stream)) { - return 0; - } - } - if (node->num_children > 1) { - stream->write_function(stream, "%s", ")"); - } - } - break; - case SNT_REF: { - struct srgs_node *rule = node->value.ref.node; - if (!rule->value.rule.regex) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_DEBUG, "ruleref: create %s regex\n", rule->value.rule.id); - if (!create_regexes(grammar, rule, NULL)) { - return 0; - } - } - if (!rule->value.rule.regex) { - return 0; - } - stream->write_function(stream, "%s", rule->value.rule.regex); - break; - } - case SNT_ANY: - default: - /* ignore */ - return 1; - } - sn_log_node_close(node); - return 1; -} - -/** - * Compile regex - */ -static pcre *get_compiled_regex(struct srgs_grammar *grammar) -{ - int erroffset = 0; - const char *errptr = ""; - int options = 0; - const char *regex; - - if (!grammar) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "grammar is NULL!\n"); - return NULL; - } - - switch_mutex_lock(grammar->mutex); - if (!grammar->compiled_regex && (regex = srgs_grammar_to_regex(grammar))) { - if (!(grammar->compiled_regex = pcre_compile(regex, options, &errptr, &erroffset, NULL))) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_WARNING, "Failed to compile grammar regex: %s\n", regex); - } - } - switch_mutex_unlock(grammar->mutex); - return grammar->compiled_regex; -} - -/** - * Resolve all unresolved references and detect loops. - * @param grammar the grammar - * @param node the current node - * @param level the recursion level - */ -static int resolve_refs(struct srgs_grammar *grammar, struct srgs_node *node, int level) -{ - sn_log_node_open(node); - if (node->visited) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Loop detected.\n"); - return 0; - } - node->visited = 1; - - if (level > MAX_RECURSION) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Recursion too deep.\n"); - return 0; - } - - if (node->type == SNT_GRAMMAR && node->value.root) { - struct srgs_node *rule = (struct srgs_node *)switch_core_hash_find(grammar->rules, node->value.root); - if (!rule) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Root rule not found: %s\n", node->value.root); - return 0; - } - grammar->root_rule = rule; - } - - if (node->type == SNT_UNRESOLVED_REF) { - /* resolve reference to local rule- drop first character # from URI */ - struct srgs_node *rule = (struct srgs_node *)switch_core_hash_find(grammar->rules, node->value.ref.uri + 1); - if (!rule) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_INFO, "Local rule not found: %s\n", node->value.ref.uri); - return 0; - } - - /* link to rule */ - node->type = SNT_REF; - node->value.ref.node = rule; - } - - /* travel through rule to detect loops */ - if (node->type == SNT_REF) { - if (!resolve_refs(grammar, node->value.ref.node, level + 1)) { - return 0; - } - } - - /* resolve children refs */ - if (node->child) { - struct srgs_node *child = node->child; - for (; child; child = child->next) { - if (!resolve_refs(grammar, child, level + 1)) { - return 0; - } - } - } - - node->visited = 0; - sn_log_node_close(node); - return 1; -} - -/** - * Parse the document into rules to match - * @param parser the parser - * @param document the document to parse - * @return the parsed grammar if successful - */ -struct srgs_grammar *srgs_parse(struct srgs_parser *parser, const char *document) -{ - struct srgs_grammar *grammar = NULL; - if (!parser) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "NULL parser!!\n"); - return NULL; - } - - if (zstr(document)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "Missing grammar document\n"); - return NULL; - } - - /* check for cached grammar */ - switch_mutex_lock(parser->mutex); - grammar = (struct srgs_grammar *)switch_core_hash_find(parser->cache, document); - if (!grammar) { - int result = 0; - iksparser *p; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_DEBUG, "Parsing new grammar\n"); - grammar = srgs_grammar_new(parser); - p = iks_sax_new(grammar, tag_hook, cdata_hook); - if (iks_parse(p, document, 0, 1) == IKS_OK) { - if (grammar->root) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_DEBUG, "Resolving references\n"); - if (resolve_refs(grammar, grammar->root, 0)) { - result = 1; - } - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "Nothing to parse!\n"); - } - } - iks_parser_delete(p); - if (result) { - switch_core_hash_insert(parser->cache, document, grammar); - } else { - if (grammar) { - srgs_grammar_destroy(grammar); - grammar = NULL; - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_INFO, "Failed to parse grammar\n"); - } - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(parser->uuid), SWITCH_LOG_DEBUG, "Using cached grammar\n"); - } - switch_mutex_unlock(parser->mutex); - - return grammar; -} - -#define MAX_INPUT_SIZE 128 -#define OVECTOR_SIZE MAX_TAGS -#define WORKSPACE_SIZE 1024 - -/** - * Check if no more digits can be added to input and match - * @param compiled_regex the regex used in the initial match - * @param input the input to check - * @return true if end of match (no more input can be added) - */ -static int is_match_end(pcre *compiled_regex, const char *input) -{ - int ovector[OVECTOR_SIZE]; - int input_size = strlen(input); - char search_input[MAX_INPUT_SIZE + 2]; - const char *search_set = "0123456789#*ABCD"; - const char *search = strchr(search_set, input[input_size - 1]); /* start with last digit in input */ - int i = 0; - - if (!search) { - return 0; - } - - /* For each digit in search_set, check if input + search_set digit is a potential match. - If so, then this is not a match end. - */ - sprintf(search_input, "%sZ", input); - for (i = 0; i < 16; i++) { - int result; - if (!*search) { - search = search_set; - } - search_input[input_size] = *search++; - result = pcre_exec(compiled_regex, NULL, search_input, input_size + 1, 0, PCRE_PARTIAL, - ovector, sizeof(ovector) / sizeof(ovector[0])); - if (result > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not match end\n"); - return 0; - } - if (result == PCRE_ERROR_PARTIAL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "partial match possible - not match end\n"); - return 0; - } - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "is match end\n"); - return 1; -} - -/** - * Find a match - * @param grammar the grammar to match - * @param input the input to compare - * @param interpretation the (optional) interpretation of the input result - * @return the match result - */ -enum srgs_match_type srgs_grammar_match(struct srgs_grammar *grammar, const char *input, const char **interpretation) -{ - int result = 0; - int ovector[OVECTOR_SIZE]; - pcre *compiled_regex; - - *interpretation = NULL; - - if (zstr(input)) { - return SMT_NO_MATCH; - } - if (strlen(input) > MAX_INPUT_SIZE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "input too large: %s\n", input); - return SMT_NO_MATCH; - } - - if (!(compiled_regex = get_compiled_regex(grammar))) { - return SMT_NO_MATCH; - } - result = pcre_exec(compiled_regex, NULL, input, strlen(input), 0, PCRE_PARTIAL, - ovector, OVECTOR_SIZE); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "match = %i\n", result); - if (result > 0) { - int i; - char buffer[MAX_INPUT_SIZE + 1]; - buffer[MAX_INPUT_SIZE] = '\0'; - - /* find matching instance... */ - for (i = 1; i <= grammar->tag_count; i++) { - char substring_name[16] = { 0 }; - buffer[0] = '\0'; - snprintf(substring_name, 16, "tag%d", i); - if (pcre_copy_named_substring(compiled_regex, input, ovector, result, substring_name, buffer, MAX_INPUT_SIZE) != PCRE_ERROR_NOSUBSTRING && !zstr_buf(buffer)) { - *interpretation = grammar->tags[i]; - break; - } - } - - if (is_match_end(compiled_regex, input)) { - return SMT_MATCH_END; - } - return SMT_MATCH; - } - if (result == PCRE_ERROR_PARTIAL) { - return SMT_MATCH_PARTIAL; - } - - return SMT_NO_MATCH; -} - -/** - * Generate regex from SRGS document. Call this after parsing SRGS document. - * @param parser the parser - * @return the regex or NULL - */ -const char *srgs_grammar_to_regex(struct srgs_grammar *grammar) -{ - if (!grammar) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "grammar is NULL!\n"); - return NULL; - } - switch_mutex_lock(grammar->mutex); - if (!grammar->regex && !create_regexes(grammar, grammar->root, NULL)) { - switch_mutex_unlock(grammar->mutex); - return NULL; - } - switch_mutex_unlock(grammar->mutex); - return grammar->regex; -} - -/** - * Create JSGF grammar - * @param parser the parser - * @param node root node - * @param stream set to NULL - * @return 1 if successful - */ -static int create_jsgf(struct srgs_grammar *grammar, struct srgs_node *node, switch_stream_handle_t *stream) -{ - sn_log_node_open(node); - switch (node->type) { - case SNT_GRAMMAR: - if (node->child) { - struct srgs_node *child; - switch_stream_handle_t new_stream = { 0 }; - SWITCH_STANDARD_STREAM(new_stream); - - new_stream.write_function(&new_stream, "#JSGF V1.0"); - if (!zstr(grammar->encoding)) { - new_stream.write_function(&new_stream, " %s", grammar->encoding); - if (!zstr(grammar->language)) { - new_stream.write_function(&new_stream, " %s", grammar->language); - } - } - - new_stream.write_function(&new_stream, - ";\ngrammar org.freeswitch.srgs_to_jsgf;\n" - "public "); - - /* output root rule */ - if (grammar->root_rule) { - if (!create_jsgf(grammar, grammar->root_rule, &new_stream)) { - switch_safe_free(new_stream.data); - return 0; - } - } else { - int num_rules = 0; - int first = 1; - - for (child = node->child; child; child = child->next) { - if (child->type == SNT_RULE && child->value.rule.is_public) { - num_rules++; - } - } - - if (num_rules > 1) { - new_stream.write_function(&new_stream, " ="); - for (child = node->child; child; child = child->next) { - if (child->type == SNT_RULE && child->value.rule.is_public) { - if (!first) { - new_stream.write_function(&new_stream, "%s", " |"); - } - first = 0; - new_stream.write_function(&new_stream, " <%s>", child->value.rule.id); - } - } - new_stream.write_function(&new_stream, ";\n"); - } else { - for (child = node->child; child; child = child->next) { - if (child->type == SNT_RULE && child->value.rule.is_public) { - grammar->root_rule = child; - if (!create_jsgf(grammar, child, &new_stream)) { - switch_safe_free(new_stream.data); - return 0; - } else { - break; - } - } - } - } - } - - /* output all rule definitions */ - for (child = node->child; child; child = child->next) { - if (child->type == SNT_RULE && child != grammar->root_rule) { - if (!create_jsgf(grammar, child, &new_stream)) { - switch_safe_free(new_stream.data); - return 0; - } - } - } - grammar->jsgf = switch_core_strdup(grammar->pool, new_stream.data); - switch_safe_free(new_stream.data); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "document jsgf = %s\n", grammar->jsgf); - } - break; - case SNT_RULE: - if (node->child) { - struct srgs_node *item = node->child; - stream->write_function(stream, "<%s> =", node->value.rule.id); - for (; item; item = item->next) { - if (!create_jsgf(grammar, item, stream)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s jsgf rule failed\n", node->value.rule.id); - return 0; - } - } - stream->write_function(stream, ";\n"); - } - break; - case SNT_STRING: { - int len = strlen(node->value.string); - int i; - stream->write_function(stream, " "); - for (i = 0; i < len; i++) { - switch (node->value.string[i]) { - case '\\': - case '*': - case '+': - case '/': - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - case '=': - case '<': - case '>': - case ';': - case '|': - stream->write_function(stream, "\\"); - break; - default: - break; - } - stream->write_function(stream, "%c", node->value.string[i]); - } - if (node->child) { - if (!create_jsgf(grammar, node->child, stream)) { - return 0; - } - } - break; - } - case SNT_ITEM: - if (node->child) { - struct srgs_node *item; - if (node->value.item.repeat_min == 0 && node->value.item.repeat_max == 1) { - /* optional item */ - stream->write_function(stream, " ["); - for(item = node->child; item; item = item->next) { - if (!create_jsgf(grammar, item, stream)) { - return 0; - } - } - stream->write_function(stream, " ]"); - } else { - /* minimum repeats */ - int i; - for (i = 0; i < node->value.item.repeat_min; i++) { - if (node->value.item.repeat_min != 1 && node->value.item.repeat_max != 1) { - stream->write_function(stream, " ("); - } - for(item = node->child; item; item = item->next) { - if (!create_jsgf(grammar, item, stream)) { - return 0; - } - } - if (node->value.item.repeat_min != 1 && node->value.item.repeat_max != 1) { - stream->write_function(stream, " )"); - } - } - if (node->value.item.repeat_max == INT_MAX) { - stream->write_function(stream, "*"); - } else { - for (;i < node->value.item.repeat_max; i++) { - stream->write_function(stream, " ["); - for(item = node->child; item; item = item->next) { - if (!create_jsgf(grammar, item, stream)) { - return 0; - } - } - stream->write_function(stream, " ]"); - } - } - } - } - break; - case SNT_ONE_OF: - if (node->child) { - struct srgs_node *item = node->child; - if (node->num_children > 1) { - stream->write_function(stream, " ("); - } - for (; item; item = item->next) { - if (item != node->child) { - stream->write_function(stream, " |"); - } - stream->write_function(stream, " ("); - if (!create_jsgf(grammar, item, stream)) { - return 0; - } - stream->write_function(stream, " )"); - } - if (node->num_children > 1) { - stream->write_function(stream, " )"); - } - } - break; - case SNT_REF: { - struct srgs_node *rule = node->value.ref.node; - stream->write_function(stream, " <%s>", rule->value.rule.id); - break; - } - case SNT_ANY: - default: - /* ignore */ - return 1; - } - sn_log_node_close(node); - return 1; -} - -/** - * Generate JSGF from SRGS document. Call this after parsing SRGS document. - * @param grammar the grammar - * @return the JSGF document or NULL - */ -const char *srgs_grammar_to_jsgf(struct srgs_grammar *grammar) -{ - if (!grammar) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "grammar is NULL!\n"); - return NULL; - } - switch_mutex_lock(grammar->mutex); - if (!grammar->jsgf && !create_jsgf(grammar, grammar->root, NULL)) { - switch_mutex_unlock(grammar->mutex); - return NULL; - } - switch_mutex_unlock(grammar->mutex); - return grammar->jsgf; -} - -/** - * Generate JSGF file from SRGS document. Call this after parsing SRGS document. - * @param grammar the grammar - * @param basedir the base path to use if file does not already exist - * @param ext the extension to use - * @return the path or NULL - */ -const char *srgs_grammar_to_jsgf_file(struct srgs_grammar *grammar, const char *basedir, const char *ext) -{ - if (!grammar) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "grammar is NULL!\n"); - return NULL; - } - switch_mutex_lock(grammar->mutex); - if (!grammar->jsgf_file_name) { - char file_name_buf[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_file_t *file; - switch_size_t len; - const char *jsgf = srgs_grammar_to_jsgf(grammar); - switch_uuid_str(file_name_buf, sizeof(file_name_buf)); - grammar->jsgf_file_name = switch_core_sprintf(grammar->pool, "%s%s%s.%s", basedir, SWITCH_PATH_SEPARATOR, file_name_buf, ext); - if (!jsgf) { - switch_mutex_unlock(grammar->mutex); - return NULL; - } - - /* write grammar to file */ - if (switch_file_open(&file, grammar->jsgf_file_name, SWITCH_FOPEN_WRITE | SWITCH_FOPEN_TRUNCATE | SWITCH_FOPEN_CREATE, SWITCH_FPROT_OS_DEFAULT, grammar->pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to create jsgf file: %s!\n", grammar->jsgf_file_name); - grammar->jsgf_file_name = NULL; - switch_mutex_unlock(grammar->mutex); - return NULL; - } - len = strlen(jsgf); - switch_file_write(file, jsgf, &len); - switch_file_close(file); - } - switch_mutex_unlock(grammar->mutex); - return grammar->jsgf_file_name; -} - -/** - * Initialize SRGS parser. This function is not thread safe. - */ -int srgs_init(void) -{ - if (globals.init) { - return 1; - } - - globals.init = SWITCH_TRUE; - switch_core_new_memory_pool(&globals.pool); - switch_core_hash_init(&globals.tag_defs); - - add_root_tag_def("grammar", process_grammar, process_cdata_bad, "meta,metadata,lexicon,tag,rule"); - add_tag_def("ruleref", process_ruleref, process_cdata_bad, ""); - add_tag_def("token", process_attribs_ignore, process_cdata_ignore, ""); - add_tag_def("tag", process_attribs_ignore, process_cdata_tag, ""); - add_tag_def("one-of", process_attribs_ignore, process_cdata_tokens, "item"); - add_tag_def("item", process_item, process_cdata_tokens, "token,ruleref,item,one-of,tag"); - add_tag_def("rule", process_rule, process_cdata_tokens, "token,ruleref,item,one-of,tag,example"); - add_tag_def("example", process_attribs_ignore, process_cdata_ignore, ""); - add_tag_def("lexicon", process_attribs_ignore, process_cdata_bad, ""); - add_tag_def("meta", process_attribs_ignore, process_cdata_bad, ""); - add_tag_def("metadata", process_attribs_ignore, process_cdata_ignore, "ANY"); - add_tag_def("ANY", process_attribs_ignore, process_cdata_ignore, "ANY"); - - return 1; -} - -/** - * Destruction of SRGS parser environment - */ -void srgs_destroy(void) -{ - if (globals.init) { - if (globals.tag_defs) { - switch_core_hash_destroy(&globals.tag_defs); - globals.tag_defs = NULL; - } - if (globals.pool) { - switch_core_destroy_memory_pool(&globals.pool); - globals.pool = NULL; - } - globals.init = SWITCH_FALSE; - } -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/srgs.h b/src/mod/event_handlers/mod_rayo/srgs.h deleted file mode 100644 index e32b522d33..0000000000 --- a/src/mod/event_handlers/mod_rayo/srgs.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * srgs.h -- Transforms SRGS into regex rules - * - */ -#ifndef SRGS_H -#define SRGS_H - -#include - -struct srgs_parser; -struct srgs_grammar; - -enum srgs_match_type { - /** invalid input */ - SMT_NO_MATCH, - /** matches, can accept more input */ - SMT_MATCH, - /** not yet a match, but valid input so far */ - SMT_MATCH_PARTIAL, - /** matches, cannot accept more input */ - SMT_MATCH_END -}; - -SWITCH_DECLARE(int) srgs_init(void); -SWITCH_DECLARE(void) srgs_destroy(void); -SWITCH_DECLARE(struct srgs_parser *) srgs_parser_new(const char *uuid); -SWITCH_DECLARE(struct srgs_grammar *) srgs_parse(struct srgs_parser *parser, const char *document); -SWITCH_DECLARE(const char *) srgs_grammar_to_regex(struct srgs_grammar *grammar); -SWITCH_DECLARE(const char *) srgs_grammar_to_jsgf(struct srgs_grammar *grammar); -SWITCH_DECLARE(const char *) srgs_grammar_to_jsgf_file(struct srgs_grammar *grammar, const char *basedir, const char *ext); -SWITCH_DECLARE(enum srgs_match_type) srgs_grammar_match(struct srgs_grammar *grammar, const char *input, const char **interpretation); -SWITCH_DECLARE(void) srgs_parser_destroy(struct srgs_parser *parser); - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/test/test_iks.c b/src/mod/event_handlers/mod_rayo/test/test_iks.c deleted file mode 100644 index 29b424afc0..0000000000 --- a/src/mod/event_handlers/mod_rayo/test/test_iks.c +++ /dev/null @@ -1,216 +0,0 @@ - - -#include -#include -#include -#include - -static const char *voxeo_grammar = - ""; - - -static const char *repeating_bracket = - "]]]]]]]]] ]] ]]>"; - - -static const char *normal_cdata = - ""; - - -static const char *empty_cdata = - ""; - -static const char *rayo_test_srgs = - "\n" - " \n" - " \n" - " \n" - " need a\n" - " i need a\n" - " \n" - " clue \n" - " \n" - " out.concept = \"clue\";\n" - " \n" - " \n" - " have an\n" - " i have an\n" - " \n" - " answer \n" - " \n" - " out.concept = \"answer\";\n" - " \n" - " \n" - " \n" - ""; - - -#define MATCH 1 -#define NO_MATCH 0 - - -/** - * main program - */ -FST_BEGIN() - -FST_SUITE_BEGIN(iks) - -FST_SETUP_BEGIN() -{ -} -FST_SETUP_END() - -FST_TEARDOWN_BEGIN() -{ -} -FST_TEARDOWN_END() - - -FST_TEST_BEGIN(iks_cdata_bug) -{ - iks *iq = NULL; - iks *input = NULL; - iksparser *p = iks_dom_new(&iq); - const char *cdata; - fst_check(IKS_OK == iks_parse(p, voxeo_grammar, 0, 1)); - iks_parser_delete(p); - fst_check((input = iks_find(iq, "input"))); - fst_check((cdata = iks_find_cdata(input, "grammar"))); - fst_check_string_equals("[1 DIGITS]", cdata); - iks_delete(iq); -} -FST_TEST_END() - -FST_TEST_BEGIN(repeating_bracket) -{ - iks *iq = NULL; - iks *input = NULL; - iksparser *p = iks_dom_new(&iq); - const char *cdata; - fst_check(IKS_OK == iks_parse(p, repeating_bracket, 0, 1)); - iks_parser_delete(p); - fst_check((input = iks_find(iq, "input"))); - fst_check((cdata = iks_find_cdata(input, "grammar"))); - fst_check_string_equals("[1 DIGITS]>]]]]]]]]] ]] ", cdata); - iks_delete(iq); -} -FST_TEST_END() - -FST_TEST_BEGIN(normal_cdata) -{ - iks *iq = NULL; - iks *input = NULL; - iksparser *p = iks_dom_new(&iq); - const char *cdata; - fst_check(IKS_OK == iks_parse(p, normal_cdata, 0, 1)); - iks_parser_delete(p); - fst_check((input = iks_find(iq, "input"))); - fst_check((cdata = iks_find_cdata(input, "grammar"))); - fst_check_string_equals("1 DIGITS", cdata); - iks_delete(iq); -} -FST_TEST_END() - -FST_TEST_BEGIN(empty_cdata) -{ - iks *iq = NULL; - iks *input = NULL; - iksparser *p = iks_dom_new(&iq); - const char *cdata; - fst_check(IKS_OK == iks_parse(p, empty_cdata, 0, 1)); - iks_parser_delete(p); - fst_check((input = iks_find(iq, "input"))); - fst_check(NULL == (cdata = iks_find_cdata(input, "grammar"))); - iks_delete(iq); -} -FST_TEST_END() - - -FST_TEST_BEGIN(rayo_test_srgs) -{ - iks *grammar = NULL; - iksparser *p = iks_dom_new(&grammar); - fst_check(IKS_OK == iks_parse(p, rayo_test_srgs, 0, 1)); - iks_parser_delete(p); - iks_delete(grammar); -} -FST_TEST_END() - -FST_TEST_BEGIN(iks_helper_value_matches) -{ - fst_check(MATCH == value_matches("1", "1,2,3")); - fst_check(MATCH == value_matches("2", "1,2,3")); - fst_check(MATCH == value_matches("3", "1,2,3")); - fst_check(NO_MATCH == value_matches("4", "1,2,3")); - fst_check(NO_MATCH == value_matches("1,2", "1,2,3")); - fst_check(NO_MATCH == value_matches(NULL, "1,2,3")); - fst_check(NO_MATCH == value_matches(NULL, NULL)); - fst_check(NO_MATCH == value_matches("1", NULL)); - fst_check(NO_MATCH == value_matches("", "1,2,3")); - fst_check(NO_MATCH == value_matches("", "")); - fst_check(NO_MATCH == value_matches("1", "")); - fst_check(MATCH == value_matches("duplex", "duplex,send,recv")); - fst_check(MATCH == value_matches("send", "duplex,send,recv")); - fst_check(MATCH == value_matches("recv", "duplex,send,recv")); - fst_check(NO_MATCH == value_matches("sendrecv", "duplex,send,recv")); - fst_check(MATCH == value_matches("duplex1", "duplex1,duplex2,duplex3")); - fst_check(MATCH == value_matches("duplex2", "duplex1,duplex2,duplex3")); - fst_check(MATCH == value_matches("duplex3", "duplex1,duplex2,duplex3")); - fst_check(NO_MATCH == value_matches("duplex4", "duplex1,duplex2,duplex3")); - fst_check(NO_MATCH == value_matches("duplex", "duplex1,duplex2,duplex3")); -} -FST_TEST_END() - -FST_TEST_BEGIN(dialback_key) -{ - char *dialback_key; - - dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", "D60000229F"); - fst_check_string_equals("37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643", dialback_key); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("", "xmpp.example.com", "example.org", "D60000229F"))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", "", "example.org", "D60000229F"))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "", "D60000229F"))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", ""))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key(NULL, "xmpp.example.com", "example.org", "D60000229F"))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", NULL, "example.org", "D60000229F"))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", NULL, "D60000229F"))); - switch_safe_free(dialback_key); - fst_check(NULL == (dialback_key = iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", NULL))); - switch_safe_free(dialback_key); -} -FST_TEST_END() - -FST_TEST_BEGIN(validate_dtmf) -{ - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("1")); - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("A")); - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("a")); - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("D")); - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("d")); - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("*")); - fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("#")); - fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit("E")); - fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit(NULL)); - fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit("")); - fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit("11")); - fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "A")); - fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "1")); - fst_check(SWITCH_FALSE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "Z")); - fst_check(SWITCH_FALSE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "11")); - fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, NULL)); - fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "")); -} -FST_TEST_END() - - -FST_SUITE_END() - -FST_END() diff --git a/src/mod/event_handlers/mod_rayo/test/test_nlsml.c b/src/mod/event_handlers/mod_rayo/test/test_nlsml.c deleted file mode 100644 index 7319a04f4c..0000000000 --- a/src/mod/event_handlers/mod_rayo/test/test_nlsml.c +++ /dev/null @@ -1,343 +0,0 @@ - - -#include -#include -#include - -static const char *nlsml_good = - "" - "" - "" - "" - "yes" - "" - "" - "ok" - "" - ""; - -static const char *nlsml_bad = - "\n" - "\n"; - -static const char *nlsml_match_with_model_instance = - "\"\n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " ddddd\n" - " \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " 123 Maple Street\n" - " Mill Valley\n" - " CA\n" - " 90952\n" - " \n" - " \n" - " \n" - " My address is 123 Maple Street,\n" - " Mill Valley, California, 90952\n" - " n" - " \n" - "\n"; - -static const char *nlsml_multi_input = - "\"\n" - " \n" - "\n" - " \n" - " fried\n" - " onions\n" - " \n" - " \n" - "\n"; - -static const char *nlsml_no_input = - "\"\n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *nlsml_multi_input_dtmf = - "\"\n" - " \n" - "\n" - " \n" - " \n" - " 1 2 3 4\n" - " \n" - " \n" - "\n"; - -static const char *nlsml_meta = - "\n" - "\n" - " \n" - " what toppings do you have?\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " toppings\n" - " \n" - " availability\n" - " \n" - " \n" - " \n" - "\n" - "\n"; - -static const char *nlsml_simple_ambiguity = - "\n" - " \n" - " \n" - " I want to go to Pittsburgh\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " Pittsburgh\n" - " \n" - " \n" - " \n" - " \n" - " I want to go to Stockholm\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " Stockholm\n" - " \n" - " \n" - " \n" - "\n"; - -const char *nlsml_mixed_initiative = - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " pepperoni\n" - " \n" - " \n" - " cheese\n" - " \n" - " \n" - " \n" - " sausage\n" - " \n" - " \n" - " \n" - " 2-liter\n" - " \n" - " to go\n" - " \n" - " \n" - " I would like 2 pizzas,\n" - " one with pepperoni and cheese, one with sausage\n" - " and a bottle of coke, to go.\n" - " \n" - " \n" - "\n"; - -static const char *nlsml_no_match = - "\"\n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"; - - -static const char *nlsml_dtmf_result = - "" - "1 2 3 4" - "1 2 3 4" - ""; - - -static const char *nlsml_good_normalized = - "" - "" - "" - "" - "yes" - "" - "" - "ok" - "" - ""; - - -static const char *nlsml_dtmf_instance_result = - "" - "1" - "foo" - ""; - - -FST_BEGIN() - -FST_SUITE_BEGIN(nlsml) - -FST_SETUP_BEGIN() -{ - fst_requires(nlsml_init()); -} -FST_SETUP_END() - -FST_TEARDOWN_BEGIN() -{ -} -FST_TEARDOWN_END() - -/** - * Test parsing NLSML example results - */ -FST_TEST_BEGIN(parse_nlsml_examples) -{ - fst_check(NMT_MATCH == nlsml_parse(nlsml_good, "1234")); - fst_check(NMT_BAD_XML == nlsml_parse(nlsml_bad, "1234")); - fst_check(NMT_MATCH == nlsml_parse(nlsml_match_with_model_instance, "1234")); - fst_check(NMT_MATCH == nlsml_parse(nlsml_multi_input, "1234")); - fst_check(NMT_NOINPUT == nlsml_parse(nlsml_no_input, "1234")); - fst_check(NMT_MATCH == nlsml_parse(nlsml_multi_input_dtmf, "1234")); - fst_check(NMT_MATCH == nlsml_parse(nlsml_meta, "1234")); - fst_check(NMT_MATCH == nlsml_parse(nlsml_simple_ambiguity, "1234")); - fst_check(NMT_MATCH == nlsml_parse(nlsml_mixed_initiative, "1234")); - fst_check(NMT_NOMATCH == nlsml_parse(nlsml_no_match, "1234")); -} -FST_TEST_END() - -/** - * Test creating DTMF match result - */ -FST_TEST_BEGIN(create_dtmf_match) -{ - iks *result = nlsml_create_dtmf_match("1234", NULL); - char *result_str; - fst_requires(result); - result_str = iks_string(NULL, result); - fst_check_string_equals(nlsml_dtmf_result, result_str); - iks_free(result_str); - iks_delete(result); -} -FST_TEST_END() - - -/** - * Test creating DTMF match result with instance interpretation - */ -FST_TEST_BEGIN(create_dtmf_instance) -{ - iks *result = nlsml_create_dtmf_match("1", "foo"); - char *result_str; - fst_requires(result); - result_str = iks_string(NULL, result); - fst_check_string_equals(nlsml_dtmf_instance_result, result_str); - iks_free(result_str); - iks_delete(result); -} -FST_TEST_END() - -/** - * Test NLSML normalization - */ -FST_TEST_BEGIN(normalize) -{ - iks *result = nlsml_normalize(nlsml_good); - char *result_str; - - fst_requires(result); - result_str = iks_string(NULL, result); - fst_check_string_equals(nlsml_good_normalized, result_str); - iks_free(result_str); - iks_delete(result); -} -FST_TEST_END() - - -FST_SUITE_END() - -FST_END() diff --git a/src/mod/event_handlers/mod_rayo/test/test_srgs.c b/src/mod/event_handlers/mod_rayo/test/test_srgs.c deleted file mode 100644 index 9bd6fc1eb5..0000000000 --- a/src/mod/event_handlers/mod_rayo/test/test_srgs.c +++ /dev/null @@ -1,1279 +0,0 @@ - - -#include -#include -#include - - -static const char *adhearsion_menu_grammar = - "" - " \n" - " \n" - " 01\n" - " 15\n" - " 77\n" - " 39\n" - " 4715\n" - " \n" - " \n" - "\n"; - -static const char *adhearsion_large_menu_grammar = - "" - " \n" - " \n" - " 01\n" - " 15\n" - " 27\n" - " 39\n" - " 4715\n" - " 5716\n" - " 6717\n" - " 7718\n" - " 8719\n" - " 9720\n" - " 10721\n" - " 11722\n" - " 12723\n" - " 13724\n" - " 14725\n" - " 15726\n" - " 16727\n" - " 17728\n" - " 18729\n" - " 19730\n" - " 20731\n" - " 21732\n" - " 22733\n" - " 23734\n" - " 24735\n" - " 25736\n" - " 26737\n" - " 27738\n" - " 28739\n" - " 29740\n" - " 30741\n" - " 31742\n" - " 32743\n" - " 33744\n" - " 34745\n" - " 35746\n" - " 36747\n" - " 37748\n" - " 38749\n" - " 39750\n" - " 40751\n" - " 41752\n" - " 42753\n" - " 43754\n" - " 44755\n" - " 45756\n" - " 46757\n" - " 47758\n" - " 48759\n" - " 49760\n" - " 50761\n" - " 51762\n" - " 52763\n" - " 53764\n" - " 54765\n" - " 55766\n" - " 56767\n" - " 57768\n" - " 58769\n" - " 59770\n" - " 60771\n" - " 61772\n" - " 62773\n" - " 63774\n" - " 64775\n" - " \n" - " \n" - "\n"; - -static const char *duplicate_tag_grammar = - "" - " \n" - " \n" - " 21\n" - " 25\n" - " 47\n" - " 49\n" - " \n" - " \n" - "\n"; - - -static const char *adhearsion_ask_grammar = - "" - " \n" - " \n" - " 0\n" - " 1\n" - " 2\n" - " 3\n" - " 4\n" - " 5\n" - " 6\n" - " 7\n" - " 8\n" - " 9\n" - " #\n" - " *\n" - " \n" - " \n" - "\n"; - - -static const char *multi_digit_grammar = - "" - " \n" - " \n" - " 01\n" - " 13\n" - " 24\n" - " 36 \n" - " 223\n" - " 5 5\n" - " 63\n" - " 76\n" - " 8 8 0\n" - " 93\n" - " # 2 \n" - " *3\n" - " 27\n" - " \n" - " \n" - "\n"; - - -static const char *multi_rule_grammar = - "" - " \n" - " \n" - " 01\n" - " 13\n" - " 24\n" - " 36 \n" - " 5 5\n" - " 63\n" - " \n" - " \n" - " \n" - " \n" - " 76\n" - " 8 8 0\n" - " 93\n" - " # 2 \n" - " *3\n" - " 27\n" - " 223\n" - " \n" - " \n" - "\n"; - - -static const char *rayo_example_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *bad_ref_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *adhearsion_ask_grammar_bad = - "" - " \n" - " \n" - " 0\n" - " 12\n" - " 3\n" - " 4\n" - " 5\n" - " 6\n" - " 7\n" - " 8\n" - " 9\n" - " #\n" - " *\n" - " \n" - " \n" - "\n"; - - -static const char *repeat_item_grammar_bad = - "\n" - "\n" - " \n" - " \n" - " 4\n" - " #\n" - " " - " \n" - "\n"; - -static const char *repeat_item_grammar_bad2 = - "\n" - "\n" - " \n" - " \n" - " 4\n" - " #\n" - " " - " \n" - "\n"; - -static const char *repeat_item_grammar_bad3 = - "\n" - "\n" - " \n" - " \n" - " 4\n" - " #\n" - " " - " \n" - "\n"; - -static const char *repeat_item_grammar_bad4 = - "\n" - "\n" - " \n" - " \n" - " 4\n" - " #\n" - " " - " \n" - "\n"; - -static const char *repeat_item_grammar_bad5 = - "\n" - "\n" - " \n" - " \n" - " 4\n" - " #\n" - " " - " \n" - "\n"; - -static const char *repeat_item_grammar_bad6 = - "\n" - "\n" - " \n" - " \n" - " 4\n" - " #\n" - " " - " \n" - "\n"; - -static const char *repeat_item_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *repeat_item_range_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *repeat_item_optional_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *repeat_item_star_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - -static const char *repeat_item_plus_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " " - " " - " * 9 \n" - " \n" - " \n" - " \n" - "\n"; - - -static const char *repeat_item_range_ambiguous_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - "\n"; - - -static const char *repeat_item_range_optional_pound_grammar = - "\n" - "\n" - " \n" - " \n" - " 0 \n" - " 1 \n" - " 2 \n" - " 3 \n" - " 4 \n" - " 5 \n" - " 6 \n" - " 7 \n" - " 8 \n" - " 9 \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " #\n" - " \n" - " \n" - " \n" - " \n" - "\n"; - - -/* - = please | kindly | oh mighty computer; -public = [ ] don't crash; -*/ -static const char *voice_srgs1 = - "\n" - "\n" - " \n" - " \n" - " please\n" - " kindly\n" - " oh mighty computer\n" - " \n" - " \n" - "\n" - " \n" - " \n" - " don't crash\n" - " \n" - "\n"; - -static const char *voice_jsgf = - "#JSGF V1.0;\n" - "grammar org.freeswitch.srgs_to_jsgf;\n" - "public = [ ] don't crash;\n" - " = ( ( please ) | ( kindly ) | ( oh mighty computer ) );\n"; - -static const char *rayo_test_srgs = - "\n" - " \n" - " \n" - " \n" - " need a\n" - " i need a\n" - " \n" - " clue \n" - " \n" - " out.concept = \"clue\";\n" - " \n" - " \n" - " have an\n" - " i have an\n" - " \n" - " answer \n" - " \n" - " out.concept = \"answer\";\n" - " \n" - " \n" - " \n" - ""; - - -/* removed the ruleref to URL from example */ -static const char *w3c_example_grammar = - "" - - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - " please move the window \n" - " open a file \n" - "\n" - " \n" - "\n" - " \n" - " \n" - "\n" - "\n" - "\n" - "\n" - " \n" - "\n" - "\n" - "\n" - " \n" - " open TAG-CONTENT-1 \n" - " close TAG-CONTENT-2 \n" - " delete TAG-CONTENT-3 \n" - " move TAG-CONTENT-4 \n" - " \n" - "\n" - "\n" - "\n" - " \n" - " \n" - " the \n" - " a \n" - " \n" - " \n" - "\n" - " \n" - " window \n" - " file \n" - " menu \n" - " \n" - "\n" - "\n" - ""; - - -static const char *metadata_grammar = - "" - - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - "\n" - "\n" - " please move the window \n" - " open a file \n" - "\n" - " \n" - "\n" - " \n" - " \n" - "\n" - "\n" - "\n" - "\n" - " \n" - "\n" - "\n" - "\n" - " \n" - " open TAG-CONTENT-1 \n" - " close TAG-CONTENT-2 \n" - " delete TAG-CONTENT-3 \n" - " move TAG-CONTENT-4 \n" - " \n" - "\n" - "\n" - "\n" - " \n" - " \n" - " the \n" - " a \n" - " \n" - " \n" - "\n" - " \n" - " window \n" - " file \n" - " menu \n" - " \n" - "\n" - "\n" - ""; - - -FST_BEGIN() - -FST_SUITE_BEGIN(srgs) - -FST_SETUP_BEGIN() -{ - fst_requires(srgs_init()); -} -FST_SETUP_END() - -FST_TEARDOWN_BEGIN() -{ -} -FST_TEARDOWN_END() - -/** - * Test matching against adhearsion menu grammar - */ -FST_TEST_BEGIN(match_adhearsion_menu_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, adhearsion_menu_grammar))); - - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check_string_equals("0", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check_string_equals("1", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check_string_equals("7", interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "715", &interpretation)); - fst_check_string_equals("4", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check_string_equals("3", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - fst_check(NULL == interpretation); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - -/** - * Test matching against adhearsion menu grammar - */ -FST_TEST_BEGIN(match_adhearsion_large_menu_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, adhearsion_large_menu_grammar))); - - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check_string_equals("0", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check_string_equals("1", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check_string_equals("2", interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "715", &interpretation)); - fst_check_string_equals("4", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check_string_equals("3", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "761", &interpretation)); - fst_check_string_equals("50", interpretation); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -/** - * Test matching with duplicate tags - */ -FST_TEST_BEGIN(match_duplicate_tag_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, duplicate_tag_grammar))); - - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check_string_equals("2", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check_string_equals("2", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check_string_equals("4", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check_string_equals("4", interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - fst_check(NULL == interpretation); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - - -/** - * Test matching against adhearsion ask grammar - */ -FST_TEST_BEGIN(match_adhearsion_ask_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, adhearsion_ask_grammar))); - - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(NULL == interpretation); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -/** - * Test matching against grammar with multiple digits per item - */ -FST_TEST_BEGIN(match_multi_digit_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, multi_digit_grammar))); - - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -FST_TEST_BEGIN(match_multi_rule_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, multi_rule_grammar))); - - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -FST_TEST_BEGIN(match_rayo_example_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, rayo_example_grammar))); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "0", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "2", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "3", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "4", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "5", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "6", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "7", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "8", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "9", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "*", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "*9", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1234#", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "2321#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "27", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "223", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "0123456789*#", &interpretation)); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - - -FST_TEST_BEGIN(parse_grammar) -{ - struct srgs_parser *parser; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - - fst_check(srgs_parse(parser, adhearsion_ask_grammar)); - fst_check(NULL == srgs_parse(parser, adhearsion_ask_grammar_bad)); - fst_check(NULL == srgs_parse(parser, NULL)); - fst_check(NULL == srgs_parse(NULL, adhearsion_ask_grammar)); - fst_check(NULL == srgs_parse(NULL, adhearsion_ask_grammar_bad)); - fst_check(NULL == srgs_parse(parser, bad_ref_grammar)); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - -FST_TEST_BEGIN(repeat_item_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_check(NULL == srgs_parse(parser, repeat_item_grammar_bad)); - fst_check(NULL == srgs_parse(parser, repeat_item_grammar_bad2)); - fst_check(NULL == srgs_parse(parser, repeat_item_grammar_bad3)); - fst_check(NULL == srgs_parse(parser, repeat_item_grammar_bad4)); - fst_check(NULL == srgs_parse(parser, repeat_item_grammar_bad5)); - fst_check(NULL == srgs_parse(parser, repeat_item_grammar_bad6)); - fst_requires((grammar = srgs_parse(parser, repeat_item_grammar))); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1111#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1111", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1234#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1234", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "11115#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "11115", &interpretation)); - fst_requires((grammar = srgs_parse(parser, repeat_item_range_grammar))); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1111#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1111", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1234#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1234", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "11115#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "11115", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "111156#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "111156", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1111567#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1111567", &interpretation)); - fst_requires((grammar = srgs_parse(parser, repeat_item_optional_grammar))); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1111#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1111", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1234#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1234", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "11115#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "11115", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "111156#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "111156", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1111567#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "1111567", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_requires((grammar = srgs_parse(parser, repeat_item_plus_grammar))); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1111#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1111", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1234#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1234", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "11115#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "11115", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "111156#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "111156", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "111157#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "111157", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - fst_requires((grammar = srgs_parse(parser, repeat_item_star_grammar))); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1111#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1111", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1234#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1234", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "11115#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "11115", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "111156#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "111156", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "111157#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "111157", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1#", &interpretation)); - fst_check(SMT_MATCH_PARTIAL == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A#", &interpretation)); - fst_check(SMT_NO_MATCH == srgs_grammar_match(grammar, "A", &interpretation)); - - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -FST_TEST_BEGIN(repeat_item_range_ambiguous_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, repeat_item_range_ambiguous_grammar))); - fst_check(SMT_MATCH == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH == srgs_grammar_match(grammar, "12", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "123", &interpretation)); - srgs_parser_destroy(parser); -} -FST_TEST_END() - -FST_TEST_BEGIN(repeat_item_range_optional_pound_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *interpretation; - - parser = srgs_parser_new("1234"); - fst_requires(parser); - fst_requires((grammar = srgs_parse(parser, repeat_item_range_optional_pound_grammar))); - fst_check(SMT_MATCH == srgs_grammar_match(grammar, "1", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "1#", &interpretation)); - fst_check(SMT_MATCH == srgs_grammar_match(grammar, "12", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "12#", &interpretation)); - fst_check(SMT_MATCH_END == srgs_grammar_match(grammar, "123", &interpretation)); - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -FST_TEST_BEGIN(jsgf) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - const char *jsgf; - parser = srgs_parser_new("1234"); - fst_requires(parser); - - fst_requires((grammar = srgs_parse(parser, adhearsion_ask_grammar))); - fst_check((jsgf = srgs_grammar_to_jsgf(grammar))); - fst_requires((grammar = srgs_parse(parser, voice_srgs1))); - fst_check((jsgf = srgs_grammar_to_jsgf(grammar))); - fst_check_string_equals(voice_jsgf, jsgf); - fst_requires((grammar = srgs_parse(parser, multi_rule_grammar))); - fst_check((jsgf = srgs_grammar_to_jsgf(grammar))); - fst_requires((grammar = srgs_parse(parser, rayo_test_srgs))); - fst_check((jsgf = srgs_grammar_to_jsgf(grammar))); - fst_check(NULL == srgs_grammar_to_jsgf(NULL)); - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -FST_TEST_BEGIN(w3c_example_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - parser = srgs_parser_new("1234"); - fst_requires(parser); - - fst_requires((grammar = srgs_parse(parser, w3c_example_grammar))); - fst_check(srgs_grammar_to_jsgf(grammar)); - srgs_parser_destroy(parser); -} -FST_TEST_END() - - -FST_TEST_BEGIN(metadata_grammar) -{ - struct srgs_parser *parser; - struct srgs_grammar *grammar; - parser = srgs_parser_new("1234"); - fst_requires(parser); - - fst_requires((grammar = srgs_parse(parser, metadata_grammar))); - fst_check(srgs_grammar_to_jsgf(grammar)); - srgs_parser_destroy(parser); -} -FST_TEST_END() - -FST_SUITE_END() - -FST_END() - diff --git a/src/mod/event_handlers/mod_rayo/xmpp_errors.def b/src/mod/event_handlers/mod_rayo/xmpp_errors.def deleted file mode 100644 index 83adcef503..0000000000 --- a/src/mod/event_handlers/mod_rayo/xmpp_errors.def +++ /dev/null @@ -1,20 +0,0 @@ -XMPP_ERROR(STANZA_ERROR_BAD_REQUEST, "bad-request", "modify") -XMPP_ERROR(STANZA_ERROR_CONFLICT, "conflict", "cancel") -XMPP_ERROR(STANZA_ERROR_FEATURE_NOT_IMPLEMENTED, "feature-not-implemented", "modify") -XMPP_ERROR(STANZA_ERROR_FORBIDDEN, "forbidden", "auth") -XMPP_ERROR(STANZA_ERROR_GONE, "gone", "modify") -XMPP_ERROR(STANZA_ERROR_INTERNAL_SERVER_ERROR, "internal-server-error", "wait") -XMPP_ERROR(STANZA_ERROR_ITEM_NOT_FOUND, "item-not-found", "cancel") -XMPP_ERROR(STANZA_ERROR_JID_MALFORMED, "jid-malformed", "modify") -XMPP_ERROR(STANZA_ERROR_NOT_ACCEPTABLE, "not-acceptable", "modify") -XMPP_ERROR(STANZA_ERROR_NOT_ALLOWED, "not-allowed", "cancel") -XMPP_ERROR(STANZA_ERROR_NOT_AUTHORIZED, "not-authorized", "auth") -XMPP_ERROR(STANZA_ERROR_RECIPIENT_UNAVAILABLE, "recipient-unavailable", "wait") -XMPP_ERROR(STANZA_ERROR_REDIRECT, "redirect", "modify") -XMPP_ERROR(STANZA_ERROR_REGISTRATION_REQUIRED, "registration-required", "auth") -XMPP_ERROR(STANZA_ERROR_REMOTE_SERVER_NOT_FOUND, "remote-server-not-found", "cancel") -XMPP_ERROR(STANZA_ERROR_REMOTE_SERVER_TIMEOUT, "remote-server-timeout", "wait") -XMPP_ERROR(STANZA_ERROR_RESOURCE_CONSTRAINT, "resource-constraint", "wait") -XMPP_ERROR(STANZA_ERROR_SERVICE_UNAVAILABLE, "service-unavailable", "cancel") -XMPP_ERROR(STANZA_ERROR_UNDEFINED_CONDITION, "undefined-condition", "wait") -XMPP_ERROR(STANZA_ERROR_UNEXPECTED_REQUEST, "unexpected-request", "wait") diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.c b/src/mod/event_handlers/mod_rayo/xmpp_streams.c deleted file mode 100644 index c78fff78e3..0000000000 --- a/src/mod/event_handlers/mod_rayo/xmpp_streams.c +++ /dev/null @@ -1,1890 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2015, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * xmpp_streams.c -- XMPP s2s and c2s streams - * - */ -#include -#include - -#include - -#include "xmpp_streams.h" -#include "iks_helpers.h" -#include "sasl.h" - -#define MAX_QUEUE_LEN 25000 - -/** - * Context for all streams - */ -struct xmpp_stream_context { - /** memory pool to use */ - switch_memory_pool_t *pool; - /** domain for this context */ - const char *domain; - /** synchronizes access to streams and routes hashes */ - switch_mutex_t *streams_mutex; - /** map of stream JID to routable stream */ - switch_hash_t *routes; - /** map of stream ID to stream */ - switch_hash_t *streams; - /** map of user ID to password */ - switch_hash_t *users; - /** shared secret for server dialback */ - const char *dialback_secret; - /** callback when a new resource is bound */ - xmpp_stream_bind_callback bind_callback; - /** callback when a new stream is ready */ - xmpp_stream_ready_callback ready_callback; - /** callback when a stream is destroyed */ - xmpp_stream_destroy_callback destroy_callback; - /** callback when a stanza is received */ - xmpp_stream_recv_callback recv_callback; - /** context shutdown flag */ - int shutdown; - /** prevents context shutdown until all threads are finished */ - switch_thread_rwlock_t *shutdown_rwlock; - /** path to cert PEM file */ - const char *cert_pem_file; - /** path to key PEM file */ - const char *key_pem_file; -}; - -/** - * State of a stream - */ -enum xmpp_stream_state { - /** new connection */ - XSS_CONNECT, - /** encrypted comms established */ - XSS_SECURE, - /** remote party authenticated */ - XSS_AUTHENTICATED, - /** client resource bound */ - XSS_RESOURCE_BOUND, - /** ready to accept requests */ - XSS_READY, - /** terminating stream */ - XSS_SHUTDOWN, - /** unrecoverable error */ - XSS_ERROR, - /** destroyed */ - XSS_DESTROY -}; - -/** - * A client/server stream connection - */ -struct xmpp_stream { - /** stream state */ - enum xmpp_stream_state state; - /** true if server-to-server connection */ - int s2s; - /** true if incoming connection */ - int incoming; - /** Jabber ID of remote party */ - char *jid; - /** stream ID */ - char *id; - /** stream pool */ - switch_memory_pool_t *pool; - /** address of this stream */ - const char *address; - /** port of this stream */ - int port; - /** synchronizes access to this stream */ - switch_mutex_t *mutex; - /** socket to remote party */ - switch_socket_t *socket; - /** socket poll descriptor */ - switch_pollfd_t *pollfd; - /** XML stream parser */ - iksparser *parser; - /** outbound message queue */ - switch_queue_t *msg_queue; - /** true if no activity last poll */ - int idle; - /** context for this stream */ - struct xmpp_stream_context *context; - /** user private data */ - void *user_private; -}; - -/** - * A socket listening for new connections - */ -struct xmpp_listener { - /** listener pool */ - switch_memory_pool_t *pool; - /** listen address */ - char *addr; - /** listen port */ - switch_port_t port; - /** access control list */ - const char *acl; - /** listen socket */ - switch_socket_t *socket; - /** pollset for listen socket */ - switch_pollfd_t *read_pollfd; - /** true if server to server connections only */ - int s2s; - /** context for new streams */ - struct xmpp_stream_context *context; -}; - -static void xmpp_stream_new_id(struct xmpp_stream *stream); -static void xmpp_stream_set_id(struct xmpp_stream *stream, const char *id); - -/** - * Convert xmpp stream state to string - * @param state the xmpp stream state - * @return the string value of state or "UNKNOWN" - */ -static const char *xmpp_stream_state_to_string(enum xmpp_stream_state state) -{ - switch(state) { - case XSS_CONNECT: return "CONNECT"; - case XSS_SECURE: return "SECURE"; - case XSS_AUTHENTICATED: return "AUTHENTICATED"; - case XSS_RESOURCE_BOUND: return "RESOURCE_BOUND"; - case XSS_READY: return "READY"; - case XSS_SHUTDOWN: return "SHUTDOWN"; - case XSS_ERROR: return "ERROR"; - case XSS_DESTROY: return "DESTROY"; - } - return "UNKNOWN"; -} - -/** - * Handle XMPP stream logging callback - * @param user_data the xmpp stream - * @param data the log message - * @param size of the log message - * @param is_incoming true if this is a log for a received message - */ -static void on_stream_log(void *user_data, const char *data, size_t size, int is_incoming) -{ - if (size > 0) { - struct xmpp_stream *stream = (struct xmpp_stream *)user_data; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, %s_%s %s %s\n", stream->jid, stream->address, stream->port, stream->s2s ? "s2s" : "c2s", - stream->incoming ? "in" : "out", is_incoming ? "RECV" : "SEND", data); - } -} - -/** - * Send stanza to stream. - */ -static void xmpp_stream_stanza_send(struct xmpp_stream *stream, iks *msg) -{ - /* send directly if client or outbound s2s stream */ - if (!stream->s2s || !stream->incoming) { - iks_send(stream->parser, msg); - iks_delete(msg); - } else { - /* route message to outbound server stream */ - xmpp_stream_context_send(stream->context, stream->jid, msg); - iks_delete(msg); - } -} - -/** - * Attach stream to connected socket - * @param stream the stream - * @param socket the connected socket - */ -static void xmpp_stream_set_socket(struct xmpp_stream *stream, switch_socket_t *socket) -{ - stream->socket = socket; - switch_socket_create_pollset(&stream->pollfd, stream->socket, SWITCH_POLLIN | SWITCH_POLLERR, stream->pool); - - /* connect XMPP stream parser to socket */ - { - switch_os_socket_t os_socket; - switch_os_sock_get(&os_socket, stream->socket); - iks_connect_fd(stream->parser, os_socket); - /* TODO connect error checking */ - } -} - -/** - * Assign a new ID to the stream - * @param stream the stream - */ -static void xmpp_stream_new_id(struct xmpp_stream *stream) -{ - char id[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - switch_uuid_str(id, sizeof(id)); - xmpp_stream_set_id(stream, id); -} - -/** - * Send session reply to server after auth is done - * @param stream the xmpp stream - */ -static void xmpp_send_server_header_features(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - char *header = switch_mprintf( - "" - "", context->domain, stream->id); - - iks_send_raw(stream->parser, header); - free(header); -} - -/** - * Send bind + session reply to client - * @param stream the xmpp stream - */ -static void xmpp_send_client_header_bind(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - char *header = switch_mprintf( - "" - "" - "" - "", context->domain, stream->id); - - iks_send_raw(stream->parser, header); - free(header); -} - -/** - * Handle message callback - * @param stream the stream - * @param node the presence message - */ -static void on_stream_presence(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - const char *from = iks_find_attrib(node, "from"); - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, presence, state = %s\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state)); - - if (!from) { - if (stream->s2s) { - /* from is required in s2s connections */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, no presence from JID\n", stream->jid, stream->address, stream->port); - return; - } - - /* use stream JID if a c2s connection */ - from = stream->jid; - if (zstr(from)) { - /* error */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, no presence from JID\n", stream->jid, stream->address, stream->port); - return; - } - iks_insert_attrib(node, "from", from); - } - if (context->recv_callback) { - context->recv_callback(stream, node); - } -} - -/** - * Send reply to xmpp stream - * @param stream the xmpp stream. - */ -static void xmpp_send_auth_success(struct xmpp_stream *stream) -{ - iks_send_raw(stream->parser, ""); -} - -/** - * Send reply to xmpp client - * @param stream the xmpp stream to use. - * @param reason the reason for failure - */ -static void xmpp_send_auth_failure(struct xmpp_stream *stream, const char *reason) -{ - char *reply = switch_mprintf("" - "<%s/>", reason); - iks_send_raw(stream->parser, reply); - free(reply); -} - -/** - * Validate username and password - * @param authzid authorization id - * @param authcid authentication id - * @param password - * @return 1 if authenticated - */ -static int verify_plain_auth(struct xmpp_stream_context *context, const char *authzid, const char *authcid, const char *password) -{ - char *correct_password; - if (zstr(authzid) || zstr(authcid) || zstr(password)) { - return 0; - } - correct_password = switch_core_hash_find(context->users, authcid); - return !zstr(correct_password) && !strcmp(correct_password, password); -} - -/** - * Send sasl reply to xmpp - * @param stream the xmpp stream - */ -static void xmpp_send_client_header_auth(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - char *header = switch_mprintf( - "" - "" - "PLAIN" - "", context->domain, stream->id); - iks_send_raw(stream->parser, header); - free(header); -} - -/** - * Send sasl + starttls reply to xmpp - * @param stream the xmpp stream - */ -static void xmpp_send_client_header_tls(struct xmpp_stream *stream) -{ - if (stream->context->key_pem_file && stream->context->cert_pem_file) { - struct xmpp_stream_context *context = stream->context; - char *header = switch_mprintf( - "" - "" - "" - "PLAIN" - "", context->domain, stream->id); - iks_send_raw(stream->parser, header); - free(header); - } else { - /* not set up for TLS, skip it */ - stream->state = XSS_SECURE; - xmpp_send_client_header_auth(stream); - } -} - -/** - * Send sasl reply to xmpp - * @param stream the xmpp stream - */ -static void xmpp_send_server_header_auth(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - char *header = switch_mprintf( - "" - "" - "", - context->domain, stream->id); - iks_send_raw(stream->parser, header); - free(header); -} - -/** - * Send dialback to receiving server - */ -static void xmpp_send_dialback_key(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - char *dialback_key = iks_server_dialback_key(context->dialback_secret, stream->jid, context->domain, stream->id); - if (dialback_key) { - char *dialback = switch_mprintf( - "%s", - context->domain, stream->jid, - dialback_key); - iks_send_raw(stream->parser, dialback); - free(dialback); - free(dialback_key); - } else { - /* TODO missing shared secret */ - } -} - -/** - * Send initial header to peer server - * @param stream the xmpp stream - */ -static void xmpp_send_outbound_server_header(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - char *header = switch_mprintf( - "", context->domain, stream->jid); - iks_send_raw(stream->parser, header); - free(header); -} - -/** - * Handle message. - * @param the xmpp stream - * @param node the packet - */ -static void on_stream_starttls(struct xmpp_stream *stream, iks *node) -{ - /* wait for handshake to start */ - if (iks_proceed_tls(stream->parser, stream->context->cert_pem_file, stream->context->key_pem_file) == IKS_OK) { - stream->state = XSS_SECURE; - } else { - stream->state = XSS_ERROR; - } -} - -/** - * Handle message. Only PLAIN supported. - * @param stream the xmpp stream - * @param node the packet - */ -static void on_stream_auth(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - const char *xmlns, *mechanism; - iks *auth_body; - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, auth, state = %s\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state)); - - /* wrong state for authentication */ - if (stream->state != XSS_SECURE) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, %s:%i, auth UNEXPECTED, state = %s\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state)); - /* on_auth unexpected error */ - stream->state = XSS_ERROR; - return; - } - - /* unsupported authentication type */ - xmlns = iks_find_attrib_soft(node, "xmlns"); - if (strcmp(IKS_NS_XMPP_SASL, xmlns)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, %s:%i, auth, state = %s, unsupported namespace: %s!\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state), xmlns); - /* on_auth namespace error */ - stream->state = XSS_ERROR; - return; - } - - /* unsupported SASL authentication mechanism */ - mechanism = iks_find_attrib_soft(node, "mechanism"); - if (strcmp("PLAIN", mechanism)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, %s:%i, auth, state = %s, unsupported SASL mechanism: %s!\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state), mechanism); - xmpp_send_auth_failure(stream, "invalid-mechanism"); - stream->state = XSS_ERROR; - return; - } - - if ((auth_body = iks_child(node)) && iks_type(auth_body) == IKS_CDATA) { - /* get user and password from auth */ - char *message = iks_cdata(auth_body); - char *authzid = NULL, *authcid, *password; - /* TODO use library for SASL! */ - parse_plain_auth_message(message, &authzid, &authcid, &password); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, auth, state = %s, SASL/PLAIN decoded authzid = \"%s\" authcid = \"%s\"\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state), authzid, authcid); - if (verify_plain_auth(context, authzid, authcid, password)) { - stream->jid = switch_core_strdup(stream->pool, authzid); - if (!stream->s2s && !strchr(stream->jid, '@')) { - /* add missing domain on client stream */ - stream->jid = switch_core_sprintf(stream->pool, "%s@%s", stream->jid, context->domain); - } - - xmpp_send_auth_success(stream); - stream->state = XSS_AUTHENTICATED; - } else { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, %s:%i, auth, state = %s, invalid user or password!\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state)); - xmpp_send_auth_failure(stream, "not-authorized"); - stream->state = XSS_ERROR; - } - switch_safe_free(authzid); - switch_safe_free(authcid); - switch_safe_free(password); - } else { - /* missing message */ - stream->state = XSS_ERROR; - } -} - -/** - * Handle request - * @param stream the xmpp stream - * @param node the node - * @return NULL - */ -static iks *on_iq_set_xmpp_session(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - iks *reply; - - switch(stream->state) { - case XSS_RESOURCE_BOUND: { - if (context->ready_callback && !context->ready_callback(stream)) { - reply = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR); - stream->state = XSS_ERROR; - } else { - reply = iks_new_iq_result(node); - stream->state = XSS_READY; - - /* add to available streams */ - switch_mutex_lock(context->streams_mutex); - switch_core_hash_insert(context->routes, stream->jid, stream); - switch_mutex_unlock(context->streams_mutex); - } - - break; - } - case XSS_AUTHENTICATED: - case XSS_READY: - default: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, %s:%i, iq UNEXPECTED , state = %s\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state)); - reply = iks_new_error(node, STANZA_ERROR_SERVICE_UNAVAILABLE); - break; - } - - return reply; -} - -/** - * Handle request - * @param stream the xmpp stream - * @param node the node - */ -static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node) -{ - iks *reply = NULL; - - switch(stream->state) { - case XSS_AUTHENTICATED: { - struct xmpp_stream_context *context = stream->context; - iks *bind = iks_find(node, "bind"); - iks *x; - /* get optional client resource ID */ - char *resource_id = iks_find_cdata(bind, "resource"); - - /* generate resource ID for client if not already set */ - if (zstr(resource_id)) { - char resource_id_buf[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_uuid_str(resource_id_buf, sizeof(resource_id_buf)); - resource_id = switch_core_strdup(stream->pool, resource_id_buf); - } - - stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id); - if (context->bind_callback && !context->bind_callback(stream)) { - stream->jid = NULL; - reply = iks_new_error(node, STANZA_ERROR_CONFLICT); - } else { - stream->state = XSS_RESOURCE_BOUND; - - reply = iks_new_iq_result(node); - x = iks_insert(reply, "bind"); - iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND); - iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid)); - } - break; - } - default: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, %s:%i, iq UNEXPECTED \n", stream->jid, stream->address, stream->port); - reply = iks_new_error(node, STANZA_ERROR_NOT_ALLOWED); - break; - } - - return reply; -} - -/** - * Handle message callback - * @param stream the stream - * @param iq the packet - */ -static void on_stream_iq(struct xmpp_stream *stream, iks *iq) -{ - struct xmpp_stream_context *context = stream->context; - switch(stream->state) { - case XSS_CONNECT: - case XSS_SECURE: { - iks *error = iks_new_error(iq, STANZA_ERROR_NOT_AUTHORIZED); - xmpp_stream_stanza_send(stream, error); - break; - } - case XSS_AUTHENTICATED: { - iks *cmd = iks_first_tag(iq); - if (cmd && !strcmp("bind", iks_name(cmd)) && !strcmp(IKS_NS_XMPP_BIND, iks_find_attrib_soft(cmd, "xmlns"))) { - iks *reply = on_iq_set_xmpp_bind(stream, iq); - xmpp_stream_stanza_send(stream, reply); - } else { - iks *error = iks_new_error(iq, STANZA_ERROR_SERVICE_UNAVAILABLE); - xmpp_stream_stanza_send(stream, error); - } - break; - } - case XSS_RESOURCE_BOUND: { - iks *cmd = iks_first_tag(iq); - if (cmd && !strcmp("session", iks_name(cmd)) && !strcmp(IKS_NS_XMPP_SESSION, iks_find_attrib_soft(cmd, "xmlns"))) { - iks *reply = on_iq_set_xmpp_session(stream, iq); - xmpp_stream_stanza_send(stream, reply); - } else { - iks *error = iks_new_error(iq, STANZA_ERROR_SERVICE_UNAVAILABLE); - xmpp_stream_stanza_send(stream, error); - } - break; - } - case XSS_READY: { - /* client requests */ - if (context->recv_callback) { - context->recv_callback(stream, iq); - } - break; - } - case XSS_SHUTDOWN: - case XSS_DESTROY: - case XSS_ERROR: { - iks *error = iks_new_error(iq, STANZA_ERROR_UNEXPECTED_REQUEST); - xmpp_stream_stanza_send(stream, error); - break; - } - }; -} - -/** - * Handle - * @param stream the stream - */ -static void on_stream_stop(struct xmpp_stream *stream) -{ - if (stream->state != XSS_SHUTDOWN) { - iks_send_raw(stream->parser, ""); - } - stream->state = XSS_DESTROY; -} - -/** - * Handle from a client - * @param stream the stream - * @param node the stream message - */ -static void on_client_stream_start(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - const char *to = iks_find_attrib_soft(node, "to"); - const char *xmlns = iks_find_attrib_soft(node, "xmlns"); - - /* to is optional, must be server domain if set */ - if (!zstr(to) && strcmp(context->domain, to)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, wrong server domain!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - return; - } - - /* xmlns = client */ - if (zstr(xmlns) || strcmp(xmlns, IKS_NS_CLIENT)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, wrong stream namespace!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - return; - } - - switch (stream->state) { - case XSS_CONNECT: - xmpp_send_client_header_tls(stream); - break; - case XSS_SECURE: - xmpp_send_client_header_auth(stream); - break; - case XSS_AUTHENTICATED: - /* client bind required */ - xmpp_stream_new_id(stream); - xmpp_send_client_header_bind(stream); - break; - case XSS_SHUTDOWN: - /* strange... I expect IKS_NODE_STOP, this is a workaround. */ - stream->state = XSS_DESTROY; - break; - case XSS_RESOURCE_BOUND: - case XSS_READY: - case XSS_ERROR: - case XSS_DESTROY: - /* bad state */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, bad state!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - break; - } -} - -/** - * Handle - */ -static void on_stream_dialback_result_valid(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - - /* TODO check domain pair and allow access if pending request exists */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, valid dialback result\n", stream->jid, stream->address, stream->port); - - if (context->ready_callback && !context->ready_callback(stream)) { - stream->state = XSS_ERROR; - } else { - /* this stream is routable */ - stream->state = XSS_READY; - - /* add to available streams */ - switch_mutex_lock(context->streams_mutex); - switch_core_hash_insert(context->routes, stream->jid, stream); - switch_mutex_unlock(context->streams_mutex); - } -} - -/** - * Handle - */ -static void on_stream_dialback_result_invalid(struct xmpp_stream *stream, iks *node) -{ - /* close stream */ - stream->state = XSS_ERROR; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, invalid dialback result!\n", stream->jid, stream->address, stream->port); -} - -/** - * Handle - */ -static void on_stream_dialback_result_error(struct xmpp_stream *stream, iks *node) -{ - /* close stream */ - stream->state = XSS_ERROR; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, error dialback result!\n", stream->jid, stream->address, stream->port); -} - -/** - * Handle - */ -static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - const char *from = iks_find_attrib_soft(node, "from"); - const char *to = iks_find_attrib_soft(node, "to"); - iks *cdata = iks_child(node); - iks *reply; - const char *dialback_key = NULL; - - if (cdata && iks_type(cdata) == IKS_CDATA) { - dialback_key = iks_cdata(cdata); - } - if (zstr(dialback_key)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing dialback key"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback result missing key!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - stream->state = XSS_ERROR; - return; - } - - if (zstr(from)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing from"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback result missing from!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - stream->state = XSS_ERROR; - return; - } - - if (zstr(to)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing to"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback result missing to!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - stream->state = XSS_ERROR; - return; - } - - if (strcmp(context->domain, to)) { - iks *error = iks_new_error(node, STANZA_ERROR_ITEM_NOT_FOUND); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, invalid domain!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - stream->state = XSS_ERROR; - return; - } - - /* this stream is not routable */ - stream->state = XSS_READY; - stream->jid = switch_core_strdup(stream->pool, from); - - if (context->ready_callback && !context->ready_callback(stream)) { - iks *error = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR); - iks_send(stream->parser, error); - iks_delete(error); - stream->state = XSS_ERROR; - return; - } - - /* TODO validate key */ - reply = iks_new("db:result"); - iks_insert_attrib(reply, "from", to); - iks_insert_attrib(reply, "to", from); - iks_insert_attrib(reply, "type", "valid"); - iks_send(stream->parser, reply); - iks_delete(reply); -} - -/** - * Handle - */ -static void on_stream_dialback_result(struct xmpp_stream *stream, iks *node) -{ - const char *type = iks_find_attrib_soft(node, "type"); - - if (stream->state == XSS_ERROR || stream->state == XSS_DESTROY) { - stream->state = XSS_ERROR; - return; - } - - if (zstr(type)) { - on_stream_dialback_result_key(stream, node); - } else if (!strcmp("valid", type)) { - on_stream_dialback_result_valid(stream, node); - } else if (!strcmp("invalid", type)) { - on_stream_dialback_result_invalid(stream, node); - } else if (!strcmp("error", type)) { - on_stream_dialback_result_error(stream, node); - } -} - -/** - * Handle - */ -static void on_stream_dialback_verify(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - const char *from = iks_find_attrib_soft(node, "from"); - const char *id = iks_find_attrib_soft(node, "id"); - const char *to = iks_find_attrib_soft(node, "to"); - iks *cdata = iks_child(node); - iks *reply; - const char *dialback_key = NULL; - char *expected_key = NULL; - int valid; - - if (stream->state == XSS_ERROR || stream->state == XSS_DESTROY) { - stream->state = XSS_ERROR; - return; - } - - if (cdata && iks_type(cdata) == IKS_CDATA) { - dialback_key = iks_cdata(cdata); - } - if (zstr(dialback_key)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing dialback key"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback verify missing key!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - return; - } - - if (zstr(id)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing id"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback verify missing stream ID!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - return; - } - - if (zstr(from)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing from"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback verify missing from!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - return; - } - - if (zstr(to)) { - iks *error = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "Missing to"); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, dialback verify missing to!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - return; - } - - if (strcmp(context->domain, to)) { - iks *error = iks_new_error(node, STANZA_ERROR_ITEM_NOT_FOUND); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, invalid domain!\n", stream->jid, stream->address, stream->port); - iks_send(stream->parser, error); - iks_delete(error); - return; - } - - expected_key = iks_server_dialback_key(context->dialback_secret, from, to, id); - valid = expected_key && !strcmp(expected_key, dialback_key); - - reply = iks_new("db:verify"); - iks_insert_attrib(reply, "from", to); - iks_insert_attrib(reply, "to", from); - iks_insert_attrib(reply, "id", id); - iks_insert_attrib(reply, "type", valid ? "valid" : "invalid"); - iks_send(stream->parser, reply); - iks_delete(reply); - free(expected_key); - - if (!valid) { - /* close the stream */ - stream->state = XSS_ERROR; - } -} - -/** - * Handle from an outbound peer server - */ -static void on_outbound_server_stream_start(struct xmpp_stream *stream, iks *node) -{ - const char *xmlns = iks_find_attrib_soft(node, "xmlns"); - - /* xmlns = server */ - if (zstr(xmlns) || strcmp(xmlns, IKS_NS_SERVER)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, wrong stream namespace!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - return; - } - - switch (stream->state) { - case XSS_CONNECT: { - /* get stream ID and send dialback */ - const char *id = iks_find_attrib_soft(node, "id"); - if (zstr(id)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, missing stream ID!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - return; - } - xmpp_stream_set_id(stream, id); - - /* send dialback */ - xmpp_send_dialback_key(stream); - break; - } - case XSS_SHUTDOWN: - /* strange... I expect IKS_NODE_STOP, this is a workaround. */ - stream->state = XSS_DESTROY; - break; - case XSS_SECURE: - case XSS_AUTHENTICATED: - case XSS_RESOURCE_BOUND: - case XSS_READY: - case XSS_ERROR: - case XSS_DESTROY: - /* bad state */ - stream->state = XSS_ERROR; - break; - } -} - -/** - * Handle from an inbound peer server - * @param stream the stream - * @param node the stream message - */ -static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node) -{ - struct xmpp_stream_context *context = stream->context; - const char *to = iks_find_attrib_soft(node, "to"); - const char *xmlns = iks_find_attrib_soft(node, "xmlns"); - - /* to is required, must be server domain */ - if (zstr(to) || strcmp(context->domain, to)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, wrong server domain!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - return; - } - - /* xmlns = server */ - if (zstr(xmlns) || strcmp(xmlns, IKS_NS_SERVER)) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, wrong stream namespace!\n", stream->jid, stream->address, stream->port); - stream->state = XSS_ERROR; - return; - } - - switch (stream->state) { - case XSS_CONNECT: - xmpp_send_server_header_auth(stream); - break; - case XSS_SECURE: - break; - case XSS_AUTHENTICATED: { - if (context->ready_callback && !context->ready_callback(stream)) { - stream->state = XSS_ERROR; - break; - } - - /* all set */ - xmpp_send_server_header_features(stream); - stream->state = XSS_READY; - - /* add to available streams */ - switch_mutex_lock(context->streams_mutex); - switch_core_hash_insert(context->routes, stream->jid, stream); - switch_mutex_unlock(context->streams_mutex); - break; - } - case XSS_SHUTDOWN: - /* strange... I expect IKS_NODE_STOP, this is a workaround. */ - stream->state = XSS_DESTROY; - break; - case XSS_RESOURCE_BOUND: - case XSS_READY: - case XSS_ERROR: - case XSS_DESTROY: - /* bad state */ - stream->state = XSS_ERROR; - break; - } -} - -/** - * Handle XML stream callback - * @param user_data the xmpp stream - * @param type stream type (start/normal/stop/etc) - * @param node optional XML node - * @return IKS_OK - */ -static int on_stream(void *user_data, int type, iks *node) -{ - struct xmpp_stream *stream = (struct xmpp_stream *)user_data; - - stream->idle = 0; - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, state = %s, node type = %s\n", stream->jid, stream->address, stream->port, xmpp_stream_state_to_string(stream->state), iks_node_type_to_string(type)); - - switch(type) { - case IKS_NODE_START: - /* */ - if (node) { - if (stream->s2s) { - if (stream->incoming) { - on_inbound_server_stream_start(stream, node); - } else { - on_outbound_server_stream_start(stream, node); - } - } else { - on_client_stream_start(stream, node); - } - } else { - stream->state = XSS_ERROR; - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, missing node!\n", stream->jid, stream->address, stream->port); - } - break; - case IKS_NODE_NORMAL: - /* stanza */ - if (node) { - const char *name = iks_name(node); - if (!strcmp("iq", name) || !strcmp("message", name)) { - on_stream_iq(stream, node); - } else if (!strcmp("presence", name)) { - on_stream_presence(stream, node); - } else if (!strcmp("auth", name)) { - on_stream_auth(stream, node); - } else if (!strcmp("starttls", name)) { - on_stream_starttls(stream, node); - } else if (!strcmp("db:result", name)) { - on_stream_dialback_result(stream, node); - } else if (!strcmp("db:verify", name)) { - on_stream_dialback_verify(stream, node); - } else { - /* unknown first-level element */ - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, unknown first-level element: %s\n", stream->jid, stream->address, stream->port, name); - } - } - break; - case IKS_NODE_ERROR: - /* */ - break; - case IKS_NODE_STOP: - on_stream_stop(stream); - break; - } - - if (node) { - iks_delete(node); - } - - return IKS_OK; -} - -/** - * Cleanup xmpp stream - */ -static void xmpp_stream_destroy(struct xmpp_stream *stream) -{ - struct xmpp_stream_context *context = stream->context; - switch_memory_pool_t *pool = stream->pool; - stream->state = XSS_DESTROY; - - /* remove from available streams */ - switch_mutex_lock(context->streams_mutex); - if (stream->jid) { - switch_core_hash_delete(context->routes, stream->jid); - } - if (stream->id) { - switch_core_hash_delete(context->streams, stream->id); - } - switch_mutex_unlock(context->streams_mutex); - - /* close connection */ - if (stream->parser) { - iks_disconnect(stream->parser); - iks_parser_delete(stream->parser); - } - - if (stream->socket) { - switch_socket_shutdown(stream->socket, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(stream->socket); - } - - /* flush pending messages */ - if (stream->msg_queue) { - char *msg; - while (switch_queue_trypop(stream->msg_queue, (void *)&msg) == SWITCH_STATUS_SUCCESS) { - iks_free(msg); - } - } - - if (context->destroy_callback) { - context->destroy_callback(stream); - } - - switch_core_destroy_memory_pool(&pool); -} - -/** - * @param stream the xmpp stream to check - * @return 0 if stream is dead - */ -static int xmpp_stream_ready(struct xmpp_stream *stream) -{ - return stream->state != XSS_ERROR && stream->state != XSS_DESTROY; -} - -#define KEEP_ALIVE_INTERVAL_NS (60 * 1000 * 1000) - -/** - * Thread that handles xmpp XML stream - * @param thread this thread - * @param obj the xmpp stream - * @return NULL - */ -static void *SWITCH_THREAD_FUNC xmpp_stream_thread(switch_thread_t *thread, void *obj) -{ - struct xmpp_stream *stream = (struct xmpp_stream *)obj; - struct xmpp_stream_context *context = stream->context; - int err_count = 0; - switch_time_t last_activity = 0; - int ping_id = 1; - - if (stream->incoming) { - switch_thread_rwlock_rdlock(context->shutdown_rwlock); - } - - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s:%i, New %s_%s stream\n", stream->address, stream->port, stream->s2s ? "s2s" : "c2s", stream->incoming ? "in" : "out"); - - if (stream->s2s && !stream->incoming) { - xmpp_send_outbound_server_header(stream); - } - - while (xmpp_stream_ready(stream)) { - char *msg; - int result; - switch_time_t now = switch_micro_time_now(); - - /* read any messages from client */ - stream->idle = 1; - result = iks_recv(stream->parser, 0); - switch (result) { - case IKS_OK: - err_count = 0; - break; - case IKS_NET_TLSFAIL: - case IKS_NET_RWERR: - case IKS_NET_NOCONN: - case IKS_NET_NOSOCK: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, iks_recv() error = %s, ending session\n", stream->jid, stream->address, stream->port, iks_net_error_to_string(result)); - stream->state = XSS_ERROR; - goto done; - default: - if (err_count++ == 0) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, iks_recv() error = %s\n", stream->jid, stream->address, stream->port, iks_net_error_to_string(result)); - } - if (err_count >= 50) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, too many iks_recv() error = %s, ending session\n", stream->jid, stream->address, stream->port, iks_net_error_to_string(result)); - stream->state = XSS_ERROR; - goto done; - } - } - - /* send queued stanzas once stream is authorized for outbound stanzas */ - if (!stream->s2s || stream->state == XSS_READY) { - while (switch_queue_trypop(stream->msg_queue, (void *)&msg) == SWITCH_STATUS_SUCCESS) { - if (!stream->s2s || !stream->incoming) { - iks_send_raw(stream->parser, msg); - } else { - /* TODO sent out wrong stream! */ - } - iks_free(msg); - stream->idle = 0; - } - } - - /* check for shutdown */ - if (stream->state != XSS_DESTROY && context->shutdown && stream->state != XSS_SHUTDOWN) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, %s:%i, detected shutdown\n", stream->jid, stream->address, stream->port); - iks_send_raw(stream->parser, ""); - stream->state = XSS_SHUTDOWN; - stream->idle = 0; - } - - if (stream->idle) { - int fdr = 0; - - /* send keep-alive ping if idle for a long time */ - if (stream->s2s && !stream->incoming && stream->state == XSS_READY && now - last_activity > KEEP_ALIVE_INTERVAL_NS) { - char *ping = switch_mprintf("", - stream->jid, stream->context->domain, ping_id++); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, keep alive\n", stream->jid, stream->address, stream->port); - last_activity = now; - iks_send_raw(stream->parser, ping); - free(ping); - } - - switch_poll(stream->pollfd, 1, &fdr, 20000); - } else { - last_activity = now; - switch_os_yield(); - } - } - - done: - - if (stream->incoming) { - xmpp_stream_destroy(stream); - switch_thread_rwlock_unlock(context->shutdown_rwlock); - } - - return NULL; -} - -/** - * Initialize the xmpp stream - * @param context the stream context - * @param stream the stream to initialize - * @param pool for this stream - * @param address remote address - * @param port remote port - * @param s2s true if a server-to-server stream - * @param incoming true if incoming stream - * @return the stream - */ -static struct xmpp_stream *xmpp_stream_init(struct xmpp_stream_context *context, struct xmpp_stream *stream, switch_memory_pool_t *pool, const char *address, int port, int s2s, int incoming) -{ - stream->context = context; - stream->pool = pool; - if (incoming) { - xmpp_stream_new_id(stream); - } - switch_mutex_init(&stream->mutex, SWITCH_MUTEX_NESTED, pool); - if (!zstr(address)) { - stream->address = switch_core_strdup(pool, address); - } - if (port > 0) { - stream->port = port; - } - stream->s2s = s2s; - stream->incoming = incoming; - switch_queue_create(&stream->msg_queue, MAX_QUEUE_LEN, pool); - - /* set up XMPP stream parser */ - stream->parser = iks_stream_new(stream->s2s ? IKS_NS_SERVER : IKS_NS_CLIENT, stream, on_stream); - - /* enable logging of XMPP stream */ - iks_set_log_hook(stream->parser, on_stream_log); - - return stream; -} - -/** - * Create a new xmpp stream - * @param context the stream context - * @param pool the memory pool for this stream - * @param address remote address - * @param port remote port - * @param s2s true if server-to-server stream - * @param incoming true if incoming stream - * @return the new stream or NULL - */ -static struct xmpp_stream *xmpp_stream_create(struct xmpp_stream_context *context, switch_memory_pool_t *pool, const char *address, int port, int s2s, int incoming) -{ - struct xmpp_stream *stream = NULL; - if (!(stream = switch_core_alloc(pool, sizeof(*stream)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n"); - return NULL; - } - return xmpp_stream_init(context, stream, pool, address, port, s2s, incoming); -} - -/** - * Thread that handles XMPP XML stream - * @param thread this thread - * @param obj the XMPP stream - * @return NULL - */ -static void *SWITCH_THREAD_FUNC xmpp_outbound_stream_thread(switch_thread_t *thread, void *obj) -{ - struct xmpp_stream *stream = (struct xmpp_stream *)obj; - struct xmpp_stream_context *context = stream->context; - switch_socket_t *socket; - int warned = 0; - - switch_thread_rwlock_rdlock(context->shutdown_rwlock); - - /* connect to server */ - while (!context->shutdown) { - struct xmpp_stream *new_stream = NULL; - switch_memory_pool_t *pool; - switch_sockaddr_t *sa; - - if (switch_sockaddr_info_get(&sa, stream->address, SWITCH_UNSPEC, stream->port, 0, stream->pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:%i, failed to get sockaddr info!\n", stream->address, stream->port); - goto fail; - } - - if (switch_socket_create(&socket, switch_sockaddr_get_family(sa), SOCK_STREAM, SWITCH_PROTO_TCP, stream->pool) != SWITCH_STATUS_SUCCESS) { - if (!warned) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_ERROR, "%s:%i, failed to create socket!\n", stream->address, stream->port); - } - goto sock_fail; - } - - switch_socket_opt_set(socket, SWITCH_SO_KEEPALIVE, 1); - switch_socket_opt_set(socket, SWITCH_SO_TCP_NODELAY, 1); - - if (switch_socket_connect(socket, sa) != SWITCH_STATUS_SUCCESS) { - if (!warned) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_ERROR, "%s:%i, Socket Error!\n", stream->address, stream->port); - } - goto sock_fail; - } - - if (warned) { - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_ERROR, "%s:%i, connected!\n", stream->address, stream->port); - warned = 0; - } - - /* run the stream thread */ - xmpp_stream_set_socket(stream, socket); - xmpp_stream_thread(thread, stream); - - /* re-establish connection if not shutdown */ - if (!context->shutdown) { - /* create new stream for reconnection */ - switch_core_new_memory_pool(&pool); - new_stream = xmpp_stream_create(stream->context, pool, stream->address, stream->port, 1, 0); - new_stream->jid = switch_core_strdup(pool, stream->jid); - xmpp_stream_destroy(stream); - stream = new_stream; - - switch_yield(1000 * 1000); /* 1000 ms */ - continue; - } - break; - - sock_fail: - if (socket) { - switch_socket_close(socket); - socket = NULL; - } - if (!warned) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error! Could not connect to %s:%i\n", stream->address, stream->port); - warned = 1; - } - switch_yield(1000 * 1000); /* 1000 ms */ - } - - fail: - - xmpp_stream_destroy(stream); - - switch_thread_rwlock_unlock(context->shutdown_rwlock); - return NULL; -} - -/** - * Set the id for this stream - * @param stream - * @param id - */ -static void xmpp_stream_set_id(struct xmpp_stream *stream, const char *id) -{ - struct xmpp_stream_context *context = stream->context; - if (!zstr(stream->id)) { - switch_mutex_lock(context->streams_mutex); - switch_core_hash_delete(context->streams, stream->id); - switch_mutex_unlock(context->streams_mutex); - } - if (!zstr(id)) { - stream->id = switch_core_strdup(stream->pool, id); - switch_mutex_lock(context->streams_mutex); - switch_core_hash_insert(context->streams, stream->id, stream); - switch_mutex_unlock(context->streams_mutex); - } else { - stream->id = NULL; - } -} - -/** - * Destroy the listener - * @param server the server - */ -static void xmpp_listener_destroy(struct xmpp_listener *listener) -{ - switch_memory_pool_t *pool = listener->pool; - - /* shutdown socket */ - if (listener->socket) { - switch_socket_shutdown(listener->socket, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(listener->socket); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "xmpp listener %s:%u closed\n", listener->addr, listener->port); - switch_core_destroy_memory_pool(&pool); -} - -/** - * Open a new XMPP stream with a peer server - * @param peer_domain of server - if not set, address is used - * @param peer_address of server - if not set, domain is used - * @param peer_port of server - if not set default port is used - */ -switch_status_t xmpp_stream_context_connect(struct xmpp_stream_context *context, const char *peer_domain, const char *peer_address, int peer_port) -{ - struct xmpp_stream *stream; - switch_memory_pool_t *pool; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - - if (peer_port <= 0) { - peer_port = IKS_JABBER_SERVER_PORT; - } - - if (zstr(peer_address)) { - peer_address = peer_domain; - } else if (zstr(peer_domain)) { - peer_domain = peer_address; - } - - /* start outbound stream thread */ - switch_core_new_memory_pool(&pool); - stream = xmpp_stream_create(context, pool, peer_address, peer_port, 1, 0); - stream->jid = switch_core_strdup(pool, peer_domain); - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, xmpp_outbound_stream_thread, stream, pool); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Thread that listens for new XMPP connections - * @param thread this thread - * @param obj the listener - * @return NULL - */ -static void *SWITCH_THREAD_FUNC xmpp_listener_thread(switch_thread_t *thread, void *obj) -{ - struct xmpp_listener *listener = (struct xmpp_listener *)obj; - struct xmpp_stream_context *context = listener->context; - switch_memory_pool_t *pool = NULL; - uint32_t errs = 0; - int warned = 0; - - switch_thread_rwlock_rdlock(context->shutdown_rwlock); - - /* bind to XMPP port */ - while (!context->shutdown) { - switch_status_t rv; - switch_sockaddr_t *sa; - rv = switch_sockaddr_info_get(&sa, listener->addr, SWITCH_UNSPEC, listener->port, 0, listener->pool); - if (rv) - goto fail; - rv = switch_socket_create(&listener->socket, switch_sockaddr_get_family(sa), SOCK_STREAM, SWITCH_PROTO_TCP, listener->pool); - if (rv) - goto sock_fail; - rv = switch_socket_opt_set(listener->socket, SWITCH_SO_REUSEADDR, 1); - if (rv) - goto sock_fail; -#ifdef WIN32 - /* Enable dual-stack listening on Windows (if the listening address is IPv6), it's default on Linux */ - if (switch_sockaddr_get_family(sa) == AF_INET6) { - rv = switch_socket_opt_set(listener->socket, SWITCH_SO_IPV6_V6ONLY, 0); - if (rv) goto sock_fail; - } -#endif - rv = switch_socket_bind(listener->socket, sa); - if (rv) - goto sock_fail; - rv = switch_socket_listen(listener->socket, 5); - if (rv) - goto sock_fail; - - rv = switch_socket_create_pollset(&listener->read_pollfd, listener->socket, SWITCH_POLLIN | SWITCH_POLLERR, listener->pool); - if (rv) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Create pollset for %s listener socket %s:%u error!\n", listener->s2s ? "s2s" : "c2s", listener->addr, listener->port); - goto sock_fail; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "xmpp %s listener bound to %s:%u\n", listener->s2s ? "s2s" : "c2s", listener->addr, listener->port); - - break; - sock_fail: - if (listener->socket) { - switch_socket_close(listener->socket); - listener->socket = NULL; - } - if (!warned) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error! xmpp %s listener could not bind to %s:%u\n", listener->s2s ? "s2s" : "c2s", listener->addr, listener->port); - warned = 1; - } - switch_yield(1000 * 100); /* 100 ms */ - } - - /* Listen for XMPP client connections */ - while (!context->shutdown) { - switch_socket_t *socket = NULL; - switch_status_t rv; - int32_t fdr; - - if (pool == NULL && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create memory pool for new client connection!\n"); - goto fail; - } - - /* is there a new connection? */ - rv = switch_poll(listener->read_pollfd, 1, &fdr, 1000 * 1000 /* 1000 ms */); - if (rv != SWITCH_STATUS_SUCCESS) { - continue; - } - - /* accept the connection */ - if (switch_socket_accept(&socket, listener->socket, pool)) { - if (context->shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Shutting down xmpp listener\n"); - goto end; - } else { - /* I wish we could use strerror_r here but its not defined everywhere =/ */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Accept connection error [%s]\n", strerror(errno)); - if (++errs > 100) { - goto end; - } - } - } else { /* got a new connection */ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - struct xmpp_stream *stream; - switch_sockaddr_t *sa = NULL; - char remote_ip[50] = { 0 }; - int remote_port = 0; - - errs = 0; - - /* get remote address and port */ - if (switch_socket_addr_get(&sa, SWITCH_TRUE, socket) == SWITCH_STATUS_SUCCESS && sa) { - switch_get_addr(remote_ip, sizeof(remote_ip), sa); - remote_port = switch_sockaddr_get_port(sa); - } - - if (zstr_buf(remote_ip)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to get IP of incoming connection.\n"); - switch_socket_shutdown(socket, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(socket); - continue; - } - - /* check if connection is allowed */ - if (listener->acl) { - if (!switch_check_network_list_ip(remote_ip, listener->acl)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ACL %s denies access to %s.\n", listener->acl, remote_ip); - switch_socket_shutdown(socket, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(socket); - continue; - } - } - - /* start connection thread */ - if (!(stream = xmpp_stream_create(context, pool, remote_ip, remote_port, listener->s2s, 1))) { - switch_socket_shutdown(socket, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(socket); - break; - } - xmpp_stream_set_socket(stream, socket); - pool = NULL; /* connection now owns the pool */ - switch_threadattr_create(&thd_attr, stream->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, xmpp_stream_thread, stream, stream->pool); - } - } - - end: - - if (pool) { - switch_core_destroy_memory_pool(&pool); - } - - fail: - - xmpp_listener_destroy(listener); - - switch_thread_rwlock_unlock(context->shutdown_rwlock); - return NULL; -} - -/** - * Add a new socket to listen for XMPP client/server connections. - * @param context the XMPP context - * @param addr the IP address - * @param port the port - * @param is_s2s true if s2s - * @param acl name of optional access control list - * @return SWITCH_STATUS_SUCCESS if successful - */ -switch_status_t xmpp_stream_context_listen(struct xmpp_stream_context *context, const char *addr, int port, int is_s2s, const char *acl) -{ - switch_memory_pool_t *pool; - struct xmpp_listener *new_listener = NULL; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - - if (zstr(addr)) { - return SWITCH_STATUS_FALSE; - } - - switch_core_new_memory_pool(&pool); - new_listener = switch_core_alloc(pool, sizeof(*new_listener)); - new_listener->pool = pool; - new_listener->addr = switch_core_strdup(pool, addr); - if (!zstr(acl)) { - new_listener->acl = switch_core_strdup(pool, acl); - } - - new_listener->s2s = is_s2s; - if (port <= 0) { - new_listener->port = is_s2s ? IKS_JABBER_SERVER_PORT : IKS_JABBER_PORT; - } else { - new_listener->port = port; - } - new_listener->context = context; - - /* start the server thread */ - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, xmpp_listener_thread, new_listener, pool); - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Queue a message for delivery - */ -void xmpp_stream_context_send(struct xmpp_stream_context *context, const char *jid, iks *msg) -{ - if (!zstr(jid)) { - if (msg) { - struct xmpp_stream *stream; - switch_mutex_lock(context->streams_mutex); - stream = switch_core_hash_find(context->routes, jid); - if (stream) { - char *raw = iks_string(NULL, msg); - if (switch_queue_trypush(stream->msg_queue, raw) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s, %s:%i, failed to deliver outbound message via %s!\n", stream->jid, stream->address, stream->port, jid); - iks_free(raw); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s stream is gone\n", jid); - /* TODO automatically open connection if valid domain JID? */ - } - switch_mutex_unlock(context->streams_mutex); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missing message\n"); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missing stream JID\n"); - } -} - -/** - * Dump xmpp stream stats - */ -void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream_handle_t *stream) -{ - switch_hash_index_t *hi; - switch_mutex_lock(context->streams_mutex); - stream->write_function(stream, "\nACTIVE STREAMS\n"); - for (hi = switch_core_hash_first(context->streams); hi; hi = switch_core_hash_next(&hi)) { - struct xmpp_stream *s = NULL; - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - s = (struct xmpp_stream *)val; - switch_assert(s); - stream->write_function(stream, " TYPE='%s_%s',ID='%s',JID='%s',REMOTE_ADDRESS='%s',REMOTE_PORT=%i,STATE='%s'\n", s->s2s ? "s2s" : "c2s", s->incoming ? "in" : "out", s->id, s->jid, s->address, s->port, xmpp_stream_state_to_string(s->state)); - } - switch_mutex_unlock(context->streams_mutex); -} - -/** - * Create a new XMPP stream context - * @param domain for new streams - * @param domain_secret domain shared secret for server dialback - * @param bind_cb callback function when a resource is bound to a new stream - * @param ready callback function when new stream is ready - * @param recv callback function when a new stanza is received - * @param destroy callback function when a stream is destroyed - * @return the context - */ -struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy) -{ - switch_memory_pool_t *pool; - struct xmpp_stream_context *context; - - switch_core_new_memory_pool(&pool); - context = switch_core_alloc(pool, sizeof(*context)); - context->pool = pool; - switch_mutex_init(&context->streams_mutex, SWITCH_MUTEX_NESTED, context->pool); - switch_core_hash_init(&context->routes); - switch_core_hash_init(&context->streams); - context->dialback_secret = switch_core_strdup(context->pool, domain_secret); - context->bind_callback = bind_cb; - context->ready_callback = ready; - context->destroy_callback = destroy; - context->recv_callback = recv; - context->shutdown = 0; - context->domain = switch_core_strdup(context->pool, domain); - switch_thread_rwlock_create(&context->shutdown_rwlock, context->pool); - switch_core_hash_init(&context->users); - - return context; -} - -/** - * Add an authorized user - * @param context the context to add user to - * @param user the username - * @param password the password - */ -void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password) -{ - switch_core_hash_insert(context->users, user, switch_core_strdup(context->pool, password)); -} - -/** - * Destroy an XMPP stream context. All open streams are closed. - * @param context to destroy - */ -void xmpp_stream_context_destroy(struct xmpp_stream_context *context) -{ - switch_memory_pool_t *pool; - context->shutdown = 1; - /* wait for threads to finish */ - switch_thread_rwlock_wrlock(context->shutdown_rwlock); - switch_core_hash_destroy(&context->routes); - switch_core_hash_destroy(&context->streams); - switch_core_hash_destroy(&context->users); - pool = context->pool; - switch_core_destroy_memory_pool(&pool); -} - -/** - * @param stream - * @return true if server-to-server stream - */ -int xmpp_stream_is_s2s(struct xmpp_stream *stream) -{ - return stream->s2s; -} - -/** - * @param stream - * @return true if incoming stream - */ -int xmpp_stream_is_incoming(struct xmpp_stream *stream) -{ - return stream->incoming; -} - -/** - * @param stream - * @return the stream JID - */ -const char *xmpp_stream_get_jid(struct xmpp_stream *stream) -{ - return stream->jid; -} - -/** - * Set private data for this stream - */ -void xmpp_stream_set_private(struct xmpp_stream *stream, void *user_private) -{ - stream->user_private = user_private; -} - -/** - * Get private data for this stream - */ -void *xmpp_stream_get_private(struct xmpp_stream *stream) -{ - return stream->user_private; -} - -/** - * Add PEM cert file to stream for new SSL connections - */ -void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file) -{ - context->cert_pem_file = switch_core_strdup(context->pool, cert_pem_file); -} - -/** - * Add PEM key file to stream for new SSL connections - */ -void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file) -{ - context->key_pem_file = switch_core_strdup(context->pool, key_pem_file); -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.h b/src/mod/event_handlers/mod_rayo/xmpp_streams.h deleted file mode 100644 index b7ee04383b..0000000000 --- a/src/mod/event_handlers/mod_rayo/xmpp_streams.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2018, Grasshopper - * - * 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. - * - * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * xmpp_streams.h -- XMPP in/out s2s and in c2s streams - * - */ -#ifndef XMPP_STREAMS_H -#define XMPP_STREAMS_H - -struct xmpp_stream; -struct xmpp_stream_context; - -typedef int (* xmpp_stream_bind_callback)(struct xmpp_stream *stream); -typedef int (* xmpp_stream_ready_callback)(struct xmpp_stream *stream); -typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stanza); -typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream); - -SWITCH_DECLARE(struct xmpp_stream_context *) xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy); -SWITCH_DECLARE(void) xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file); -SWITCH_DECLARE(void) xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file); -SWITCH_DECLARE(void) xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password); -SWITCH_DECLARE(void) xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream_handle_t *stream); -SWITCH_DECLARE(void) xmpp_stream_context_destroy(struct xmpp_stream_context *context); -SWITCH_DECLARE(void) xmpp_stream_context_send(struct xmpp_stream_context *context, const char *jid, iks *stanza); - -SWITCH_DECLARE(switch_status_t) xmpp_stream_context_listen(struct xmpp_stream_context *context, const char *addr, int port, int is_s2s, const char *acl); -SWITCH_DECLARE(switch_status_t) xmpp_stream_context_connect(struct xmpp_stream_context *context, const char *peer_domain, const char *peer_address, int peer_port); - -SWITCH_DECLARE(int) xmpp_stream_is_s2s(struct xmpp_stream *stream); -SWITCH_DECLARE(int) xmpp_stream_is_incoming(struct xmpp_stream *stream); -SWITCH_DECLARE(const char *) xmpp_stream_get_jid(struct xmpp_stream *stream); -SWITCH_DECLARE(void) xmpp_stream_set_private(struct xmpp_stream *stream, void *user_private); -SWITCH_DECLARE(void *) xmpp_stream_get_private(struct xmpp_stream *stream); - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/src/mod/formats/mod_ssml/Makefile.am b/src/mod/formats/mod_ssml/Makefile.am deleted file mode 100644 index 9da6a7cce1..0000000000 --- a/src/mod/formats/mod_ssml/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_ssml - -IKS_DIR=$(switch_srcdir)/libs/iksemel -IKS_BUILDDIR=$(switch_builddir)/libs/iksemel -IKS_LA=$(IKS_BUILDDIR)/src/libiksemel.la - -noinst_LTLIBRARIES = libssmlmod.la -libssmlmod_la_SOURCES = mod_ssml.c -libssmlmod_la_CFLAGS = $(AM_CFLAGS) -I$(IKS_DIR)/include - -mod_LTLIBRARIES = mod_ssml.la -mod_ssml_la_SOURCES = mod_ssml.c -mod_ssml_la_CFLAGS = $(AM_CFLAGS) -I$(IKS_DIR)/include -mod_ssml_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(IKS_LA) -mod_ssml_la_LDFLAGS = -avoid-version -module -no-undefined -shared - -BUILT_SOURCES=$(IKS_LA) - -$(IKS_LA): $(IKS_BUILDDIR) $(IKS_DIR) $(IKS_DIR)/.update - @cd $(IKS_DIR) && $(MAKE) - @$(TOUCH_TARGET) - -deps: $(IKS_LA) diff --git a/src/mod/formats/mod_ssml/conf/autoload_configs/ssml.conf.xml b/src/mod/formats/mod_ssml/conf/autoload_configs/ssml.conf.xml deleted file mode 100644 index a3e732f88d..0000000000 --- a/src/mod/formats/mod_ssml/conf/autoload_configs/ssml.conf.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/formats/mod_ssml/mod_ssml.c b/src/mod/formats/mod_ssml/mod_ssml.c deleted file mode 100644 index 0301162297..0000000000 --- a/src/mod/formats/mod_ssml/mod_ssml.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * mod_ssml for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2014,2016 Grasshopper - * - * 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. - * - * The Original Code is mod_ssml for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is Grasshopper - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Chris Rienzo - * - * mod_ssml.c -- SSML audio rendering format - * - */ -#include -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_ssml_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_ssml_shutdown); -SWITCH_MODULE_DEFINITION(mod_ssml, mod_ssml_load, mod_ssml_shutdown, NULL); - -#define MAX_VOICE_FILES 256 -#define MAX_VOICE_PRIORITY 999 -#define VOICE_NAME_PRIORITY 1000 -#define VOICE_GENDER_PRIORITY 1000 -#define VOICE_LANG_PRIORITY 1000000 - -struct ssml_parser; - -/** function to handle tag attributes */ -typedef int (* tag_attribs_fn)(struct ssml_parser *, char **); -/** function to handle tag CDATA */ -typedef int (* tag_cdata_fn)(struct ssml_parser *, char *, size_t); - -/** - * Tag definition - */ -struct tag_def { - tag_attribs_fn attribs_fn; - tag_cdata_fn cdata_fn; - switch_bool_t is_root; - switch_hash_t *children_tags; -}; - -/** - * Module configuration - */ -static struct { - /** Mapping of mod-name-language-gender to voice */ - switch_hash_t *voice_cache; - /** Mapping of voice names */ - switch_hash_t *say_voice_map; - /** Synchronizes access to say_voice_map */ - switch_mutex_t *say_voice_map_mutex; - /** Mapping of voice names */ - switch_hash_t *tts_voice_map; - /** Synchronizes access to tts_voice_map */ - switch_mutex_t *tts_voice_map_mutex; - /** Mapping of interpret-as value to macro */ - switch_hash_t *interpret_as_map; - /** Mapping of ISO language code to say-module */ - switch_hash_t *language_map; - /** Mapping of tag name to definition */ - switch_hash_t *tag_defs; - /** module memory pool */ - switch_memory_pool_t *pool; -} globals; - -/** - * A say language - */ -struct language { - /** The ISO language code */ - char *iso; - /** The FreeSWITCH language code */ - char *language; - /** The say module name */ - char *say_module; -}; - -/** - * A say macro - */ -struct macro { - /** interpret-as name (cardinal...) */ - char *name; - /** language (en-US, en-UK, ...) */ - char *language; - /** type (number, items, persons, messages...) */ - char *type; - /** method (pronounced, counted, iterated...) */ - char *method; -}; - -/** - * A TTS voice - */ -struct voice { - /** higher priority = more likely to pick */ - int priority; - /** voice gender */ - char *gender; - /** voice name / macro */ - char *name; - /** voice language */ - char *language; - /** internal file prefix */ - char *prefix; -}; - -#define TAG_LEN 32 -#define NAME_LEN 128 -#define LANGUAGE_LEN 6 -#define GENDER_LEN 8 - -/** - * SSML voice state - */ -struct ssml_node { - /** tag name */ - char tag_name[TAG_LEN]; - /** requested name */ - char name[NAME_LEN]; - /** requested language */ - char language[LANGUAGE_LEN]; - /** requested gender */ - char gender[GENDER_LEN]; - /** voice to use */ - struct voice *tts_voice; - /** say macro to use */ - struct macro *say_macro; - /** tag handling data */ - struct tag_def *tag_def; - /** previous node */ - struct ssml_node *parent_node; -}; - -/** - * A file to play - */ -struct ssml_file { - /** prefix to add to file handle */ - char *prefix; - /** the file to play */ - const char *name; -}; - -/** - * SSML parser state - */ -struct ssml_parser { - /** current attribs */ - struct ssml_node *cur_node; - /** files to play */ - struct ssml_file *files; - /** number of files */ - int num_files; - /** max files to play */ - int max_files; - /** memory pool to use */ - switch_memory_pool_t *pool; - /** desired sample rate */ - int sample_rate; -}; - -/** - * SSML playback state - */ -struct ssml_context { - /** handle to current file */ - switch_file_handle_t fh; - /** files to play */ - struct ssml_file *files; - /** number of files */ - int num_files; - /** current file being played */ - int index; -}; - -/** - * Add a definition for a tag - * @param tag the name - * @param attribs_fn the function to handle the tag attributes - * @param cdata_fn the function to handler the tag CDATA - * @param children_tags comma-separated list of valid child tag names - * @return the definition - */ -static struct tag_def *add_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) -{ - struct tag_def *def = switch_core_alloc(globals.pool, sizeof(*def)); - switch_core_hash_init(&def->children_tags); - if (!zstr(children_tags)) { - char *children_tags_dup = switch_core_strdup(globals.pool, children_tags); - char *tags[32] = { 0 }; - int tag_count = switch_separate_string(children_tags_dup, ',', tags, sizeof(tags) / sizeof(tags[0])); - if (tag_count) { - int i; - for (i = 0; i < tag_count; i++) { - switch_core_hash_insert(def->children_tags, tags[i], tags[i]); - } - } - } - def->attribs_fn = attribs_fn; - def->cdata_fn = cdata_fn; - def->is_root = SWITCH_FALSE; - switch_core_hash_insert(globals.tag_defs, tag, def); - return def; -} - -/** - * Add a definition for a root tag - * @param tag the name - * @param attribs_fn the function to handle the tag attributes - * @param cdata_fn the function to handler the tag CDATA - * @param children_tags comma-separated list of valid child tag names - * @return the definition - */ -static struct tag_def *add_root_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) -{ - struct tag_def *def = add_tag_def(tag, attribs_fn, cdata_fn, children_tags); - def->is_root = SWITCH_TRUE; - return def; -} - -/** - * Handle tag attributes - * @param parser the parser - * @param name the tag name - * @param atts the attributes - * @return IKS_OK if OK IKS_BADXML on parse failure - */ -static int process_tag(struct ssml_parser *parser, const char *name, char **atts) -{ - struct tag_def *def = switch_core_hash_find(globals.tag_defs, name); - if (def) { - parser->cur_node->tag_def = def; - if (def->is_root && parser->cur_node->parent_node == NULL) { - /* no parent for ROOT tags */ - return def->attribs_fn(parser, atts); - } else if (!def->is_root && parser->cur_node->parent_node) { - /* check if this child is allowed by parent node */ - struct tag_def *parent_def = parser->cur_node->parent_node->tag_def; - if (switch_core_hash_find(parent_def->children_tags, "ANY") || - switch_core_hash_find(parent_def->children_tags, name)) { - return def->attribs_fn(parser, atts); - } - } - } - return IKS_BADXML; -} - -/** - * Handle CDATA that is ignored - * @param parser the parser - * @param data the CDATA - * @param len the CDATA length - * @return IKS_OK - */ -static int process_cdata_ignore(struct ssml_parser *parser, char *data, size_t len) -{ - return IKS_OK; -} - -/** - * Handle CDATA that is not allowed - * @param parser the parser - * @param data the CDATA - * @param len the CDATA length - * @return IKS_BADXML - */ -static int process_cdata_bad(struct ssml_parser *parser, char *data, size_t len) -{ - int i; - for (i = 0; i < len; i++) { - if (isgraph(data[i])) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Unexpected CDATA for <%s>\n", parser->cur_node->tag_name); - return IKS_BADXML; - } - } - return IKS_OK; -} - -/** - * Score the voice on how close it is to desired language, name, and gender - * @param voice the voice to score - * @param cur_node the desired voice attributes - * @param lang_required if true, language must match - * @return the score - */ -static int score_voice(struct voice *voice, struct ssml_node *cur_node, int lang_required) -{ - /* language > gender,name > priority */ - int score = voice->priority; - if (!zstr_buf(cur_node->gender) && !strcmp(cur_node->gender, voice->gender)) { - score += VOICE_GENDER_PRIORITY; - } - if (!zstr_buf(cur_node->name) && !strcmp(cur_node->name, voice->name)) { - score += VOICE_NAME_PRIORITY; - } - if (!zstr_buf(cur_node->language) && !strcmp(cur_node->language, voice->language)) { - score += VOICE_LANG_PRIORITY; - } else if (lang_required) { - score = 0; - } - return score; -} - -/** - * Search for best voice based on attributes - * @param cur_node the desired voice attributes - * @param map the map to search - * @param type "say" or "tts" - * @param lang_required if true, language must match - * @return the voice or NULL - */ -static struct voice *find_voice(struct ssml_node *cur_node, switch_hash_t *map, char *type, int lang_required) -{ - switch_hash_index_t *hi = NULL; - struct voice *voice = NULL; - char *lang_name_gender = NULL; - int best_score = 0; - - /* check cache */ - lang_name_gender = switch_mprintf("%s-%s-%s-%s", type, cur_node->language, cur_node->name, cur_node->gender); - voice = (struct voice *)switch_core_hash_find(globals.voice_cache, lang_name_gender); - if (voice) { - /* that was easy! */ - goto done; - } - - /* find best language, name, gender match */ - for (hi = switch_core_hash_first(map); hi; hi = switch_core_hash_next(&hi)) { - const void *key; - void *val; - struct voice *candidate; - int candidate_score = 0; - switch_core_hash_this(hi, &key, NULL, &val); - candidate = (struct voice *)val; - candidate_score = score_voice(candidate, cur_node, lang_required); - if (candidate_score > 0 && candidate_score > best_score) { - voice = candidate; - best_score = candidate_score; - } - } - - /* remember for next time */ - if (voice) { - switch_core_hash_insert(globals.voice_cache, lang_name_gender, voice); - } - -done: - switch_safe_free(lang_name_gender); - - return voice; -} - -/** - * Search for best voice based on attributes - * @param cur_node the desired voice attributes - * @return the voice or NULL - */ -static struct voice *find_tts_voice(struct ssml_node *cur_node) -{ - struct voice *v; - switch_mutex_lock(globals.tts_voice_map_mutex); - v = find_voice(cur_node, globals.tts_voice_map, "tts", 0); - switch_mutex_unlock(globals.tts_voice_map_mutex); - return v; -} - -/** - * Search for best voice based on attributes - * @param cur_node the desired voice attributes - * @return the voice or NULL - */ -static struct voice *find_say_voice(struct ssml_node *cur_node) -{ - struct voice *v; - switch_mutex_lock(globals.say_voice_map_mutex); - v = find_voice(cur_node, globals.say_voice_map, "say", 1); - switch_mutex_unlock(globals.say_voice_map_mutex); - return v; -} - -/** - * Handle tag attributes that are ignored - * @param parser the parser - * @param atts the attributes - * @return IKS_OK - */ -static int process_attribs_ignore(struct ssml_parser *parsed_data, char **atts) -{ - struct ssml_node *cur_node = parsed_data->cur_node; - cur_node->tts_voice = find_tts_voice(cur_node); - return IKS_OK; -} - -/** - * open next file for reading - * @param handle the file handle - */ -static switch_status_t next_file(switch_file_handle_t *handle) -{ - struct ssml_context *context = handle->private_info; - const char *file; - - top: - - context->index++; - - if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { - switch_core_file_close(&context->fh); - } - - if (context->index >= context->num_files) { - return SWITCH_STATUS_FALSE; - } - - - file = context->files[context->index].name; - context->fh.prefix = context->files[context->index].prefix; - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - /* unsupported */ - return SWITCH_STATUS_FALSE; - } - - if (switch_core_file_open(&context->fh, file, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { - goto top; - } - - handle->samples = context->fh.samples; - handle->format = context->fh.format; - handle->sections = context->fh.sections; - handle->seekable = context->fh.seekable; - handle->speed = context->fh.speed; - handle->interval = context->fh.interval; - - if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { - switch_set_flag_locked(handle, SWITCH_FILE_NATIVE); - } else { - switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE); - } - - return SWITCH_STATUS_SUCCESS; -} - -/** - * Process xml:lang attribute - */ -static int process_xml_lang(struct ssml_parser *parsed_data, char **atts) -{ - struct ssml_node *cur_node = parsed_data->cur_node; - - /* only allow language change in ,

, and */ - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("xml:lang", atts[i])) { - if (!zstr(atts[i + 1])) { - snprintf(cur_node->language, LANGUAGE_LEN, "%s", atts[i + 1]); - } - } - i += 2; - } - } - cur_node->tts_voice = find_tts_voice(cur_node); - return IKS_OK; -} - -/** - * Process - */ -static int process_voice(struct ssml_parser *parsed_data, char **atts) -{ - struct ssml_node *cur_node = parsed_data->cur_node; - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("xml:lang", atts[i])) { - if (!zstr(atts[i + 1])) { - snprintf(cur_node->language, LANGUAGE_LEN, "%s", atts[i + 1]); - } - } else if (!strcmp("name", atts[i])) { - if (!zstr(atts[i + 1])) { - snprintf(cur_node->name, NAME_LEN, "%s", atts[i + 1]); - } - } else if (!strcmp("gender", atts[i])) { - if (!zstr(atts[i + 1])) { - snprintf(cur_node->gender, GENDER_LEN, "%s", atts[i + 1]); - } - } - i += 2; - } - } - cur_node->tts_voice = find_tts_voice(cur_node); - return IKS_OK; -} - -/** - * Process - */ -static int process_say_as(struct ssml_parser *parsed_data, char **atts) -{ - struct ssml_node *cur_node = parsed_data->cur_node; - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("interpret-as", atts[i])) { - char *interpret_as = atts[i + 1]; - if (!zstr(interpret_as)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "interpret-as: %s\n", atts[i + 1]); - cur_node->say_macro = (struct macro *)switch_core_hash_find(globals.interpret_as_map, interpret_as); - } - break; - } - i += 2; - } - } - cur_node->tts_voice = find_tts_voice(cur_node); - return IKS_OK; -} - -/** - * Process - this is a period of silence - */ -static int process_break(struct ssml_parser *parsed_data, char **atts) -{ - if (atts) { - int i = 0; - while (atts[i]) { - if (!strcmp("time", atts[i])) { - char *t = atts[i + 1]; - if (!zstr(t) && parsed_data->num_files < parsed_data->max_files) { - int timeout_ms = 0; - char *unit; - if ((unit = strstr(t, "ms"))) { - *unit = '\0'; - if (switch_is_number(t)) { - timeout_ms = atoi(t); - } - } else if ((unit = strstr(t, "s"))) { - *unit = '\0'; - if (switch_is_number(t)) { - timeout_ms = atoi(t) * 1000; - } - } - if (timeout_ms > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding : \"%s\"\n", t); - parsed_data->files[parsed_data->num_files].name = switch_core_sprintf(parsed_data->pool, "silence_stream://%i", timeout_ms); - parsed_data->files[parsed_data->num_files++].prefix = NULL; - } - } - return IKS_OK; - } - i += 2; - } - } - return IKS_OK; -} - -/** - * Process

- 35716ecf:2 - 98e6c103:0 -

- - - - - 1 - 3 - 65535 - 1266110339 - - - 1 - - - 1 - - - 1000000166 - 1303166852 - 1303209779 - - - 1267114269 - - 2 - - 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 - - - 1267114267 - 11 - 4263C0064DD5ACF9A03594DAB928D2B81510 - - - - <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 - - - - - skypopen - - - 0 - 2 - 2 - 2 - - diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat deleted file mode 100644 index fc7f2b1150..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat +++ /dev/null @@ -1 +0,0 @@ -B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat deleted file mode 100644 index b8b96d84318e540df1ace348fe21db2b6bc5db1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmXwuNdbT`5X8FNmjYy9pe~S#BNQM2CZ)5VNwV*L#B-llsu$ko2Zk2aTXAXCJ2}n& hUQDwOVw!yv)9jO&W}n40`y!^<5k^1s4DS diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/main.lock deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml deleted file mode 100644 index f7af8873ad..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - 300 - 1800 - 63 - - - 41010300676D6172757A7A3400 - 1268962216 - - - 0 - 0 - 1303202372 - 0 - -

- 35716ecf:2 - 98e6c103:0 -

- -
-
- - 1 - 3 - 65535 - 1266110339 - - - 1 - - - 1 - - - 1000000166 - 1303166852 - 1303209779 - - - 1267114269 - - 2 - - 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 - - - 1267114267 - 11 - 4263C0064DD5ACF9A03594DAB928D2B81510 - - - - <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 - -
- - - skypopen - - - 0 - 2 - 2 - 2 - -
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat deleted file mode 100644 index fc7f2b1150..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat +++ /dev/null @@ -1 +0,0 @@ -B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat deleted file mode 100644 index b8b96d84318e540df1ace348fe21db2b6bc5db1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmXwuNdbT`5X8FNmjYy9pe~S#BNQM2CZ)5VNwV*L#B-llsu$ko2Zk2aTXAXCJ2}n& hUQDwOVw!yv)9jO&W}n40`y!^<5k^1s4DS diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/main.lock deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml deleted file mode 100644 index 4b72e67eb5..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - <_2>00001000A563932E7DE5A581942041A820F8437512A079C7ACB1B73281F191D109521E265BCD38C4133596B834AD9AA1D6BB5E1AC3D59E8675785321F722D39FBFAFB9A24E6482FA3030FFA3692D2C4A53BBCE9DC63F25D10207A20FA969982FEDC1DCC2A7C599071F4735E52AB2E06E34CA232C08B3AA2FB88A0C4A5763E0CD23C3AA37D1D2A7D6EED691EE99BA08BE294F68C24F9AE777DAF294F0AEB8346325A978DC6CF7C210AD11EF3F38111F6D98F388CF41CCBA40ABE9F0D6CBBD3118BA0588344953DF3C5E88B2CCAEDE2E692F320D20EBF16D7DB36156E617C0CC9FB2855D7FDB4C7F8638CC9830E7448D5EAE301A2810277062989841EE679E00E4E277615FEC038DE3A0A20DD7C6A2A00DFBC6A2A00DA6E2B6F404FDC6A2A00DFEC6A2A00DF7FBBB990CF2C6A2A00D8EB4FE8A0C8FB4FE8A0C95C7A6E00CF5FBBB990CD6C7A6E00CD0F896950CCCE2B6F40485CCA2A00DA1D8EEA50DFDFBBB990CA7C7A6E00CA8C7A6E00CA9C7A6E00C97C7A6E00C90B4FE8A0CFE90D59308C290D59308D1E2B6F404C5E2B6F404C6AAF18705C7AAF18705C8AAF18705BBD8EEA50DBCD8EEA50DBDD8EEA50D93CCA2A00D94CCA2A00DEFE2B6F40491B4FE8A0CE2FBBB990CE3FBBB990CBED8EEA50DA0CCA2A00DA1CCA2A00DA6B4FE8A0CA7B4FE8A0CCED8EEA50DA3CCA2A00DA4CCA2A00D84E698AD0DB8C7A6E00CD9E2B6F404E0E2B6F40486E698AD0DFDF896950C0013A60400173D0018DE0200190300AB01F40300449875044518C15F9A278109D4BBAC4E8109D408A6238109D5A63304810904460CC15F9A26303ED408A624303E0047B054004801004980A305004A80E90F004BE0A801004C80A305004D01005CAC02045E5A50FC55465BA050FC55475BA050FC55485BA0C32EFDEE5BA0C32EFDEF5BA0C2A5BC4A5BA0C2A5BC4B5BA0D4BBAC055BA0D4BBAC145BA0D4BBAC215BA0D408A3575BA0D408A37D5BA0D408A37E5BA08275487E5BA0827548425BA00060B817046506CC09A3D6303E04AE018C0125F8D500021A25F9D500011A162102200301220125FFD50025FAD5000C03E4000D2580D6000F060125F8D5000302172105050103080D06010501011C210302060125FCD50025F9D5000A25FDD50025FED5000A0D06020502050119211305020380808080100C05010D0380808080100B25FDD5000C01080005000380808080100D060307010503220101220104AC01BF012597CE002597CE002590CE0019152590CE002597CE000B033C1815210220030122012593CE0014212E2594CE002103030B220125A5CE00030F172103030B22012596CE00142103030B22012597CE00142103030B22012599CE00142103030A220125A5CE00030A1A2590CE002592CE000B031E1B15142103030A220125A4CE000380201D14210303092201259BCE0014210A2594CE002103030B2201259DCE00142103030822012593CE002103012201259ECE001421030306220103022201006800006901006A01006C987504740CC2A5BC4C303ED408A34C303E007828047912CC09A3D3303E82754864303E4E8DB16F303E047DBF010203020800050003020D0B0601030308000500020501030508000500021A03060800050003041A16030508000500021D160C0A0C060203D00F251205020A03020D0A050103D00F0C0A0603010800050003FFFFFFFF0F18030208000500021D141506042512020800050003030D05040C10030205040B0C06050306050505020A0C060603040800050003050800050003E400180C0607050703E400250A0B250A011C0C0A0314100608050303C03E0F03B8171005060388270F03DC0B100508047E5E0380010304080005000B03040D250403E4000F03140D0A2503250203030D0A0B0110060101080005000380020D0302080005000380020D172103010601250A03E4001B210D0501030A03E400250A210303DF002002250A0B0D0F0601050100800180EA49008101E003036F3139352E34362E3235332E3235333A313233353000038201706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B7970653B706F6F6C333D6578747261732E646F776E6C6F6164732E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B7970653B706F6F6C353D2A2E7072656D69756D2E736B7970653B706F6F6C363D2A2E6D756C74696D656469612E736B7970653B706F6F6C373D2A2E6D756C74696D656469612E6D657461636166653B706F6F6C383D2A2E6D756C74696D656469612E6461696C796D6F74696F6E3B706F6F6C393D2A2E6D756C74696D656469612E6D6574616F6D6E69747572653B706F6F6C31303D77686174736E65772E736B7970653B706F6F6C31313D7061792E736B7970653B706F6F6C31323D7365637572652E7061792E736B7970653B706F6F6C31333D2A2E70696373746F72653B706F6F6C31343D2A2E6D796163636F756E742E736B7970653B706F6F6C31353D2A2E62696269743B706F6F6C31363D2A2E70726F6363796265723B706F6F6C31373D747261636B696E672E6F6D6E69747572653B706F6F6C31383D676F2E736B7970653B706F6F6C31393D747261636B2E736B7970657C706F6F6C313D3139342E3139322E3139392E3235313A31323335303B706F6F6C323D3139342E3139322E3139392E3235323A31323335303B706F6F6C333D3139342E3139322E3139392E3235323A31323335303B706F6F6C343D3139342E3136352E3138382E3130313A31323335303B706F6F6C353D3139332E39352E3135342E31353A31323335313B706F6F6C363D3139342E3136352E3138382E3130303A31323335303B706F6F6C373D3139342E3136352E3138382E3130303A31323335303B706F6F6C383D3139342E3136352E3138382E3130303A31323335303B706F6F6C393D3139342E3136352E3138382E3130303A31323335303B706F6F6C31303D3230342E392E3136332E3134313A31323335303B706F6F6C31313D3139352E34362E3235332E3234353A31323335303B706F6F6C31323D3139352E34362E3235332E3234353A31323335303B706F6F6C31333D3139332E39352E3135342E31343A31323335313B706F6F6C31343D3139332E39352E3135342E31343A31323335313B706F6F6C31353D3139332E39352E3135342E31343A31323335313B706F6F6C31363D3139332E39352E3135342E31343A31323335313B706F6F6C31373D3139342E3136352E3138382E3130303A31323335303B706F6F6C31383D3139342E3136352E3138382E3130303A31323335303B706F6F6C31393D3139332E39352E3135342E31343A31323335310003B101706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B797065206578747261732E646F776E6C6F6164732E736B7970653B706F6F6C333D2A2E687773746F72652E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B797065202A2E6469726563746F72792E736B7970653B706F6F6C353D2A2E70696373746F7265202A2E6D796163636F756E742E736B797065202A2E6269626974202A2E70726F63637962657220747261636B2E736B79706520617070732E736B7970656173736574733B706F6F6C363D2A2E6D756C74696D656469612E736B797065202A2E6D756C74696D656469612E6D65746163616665202A2E6D756C74696D656469612E6461696C796D6F74696F6E202A2E6D756C74696D656469612E6D6574616F6D6E6974757265207777772E736B7970652077686174736E65772E736B7970653B706F6F6C373D7061792E736B797065207365637572652E7061792E736B7970653B706F6F6C383D6170692E736B7970653B706F6F6C393D63616C6C70686F6E65732E736B7970652063616C6C72617465732E736B7970653B706F6F6C31303D2A2E7072656D69756D2E736B7970653B706F6F6C31323D6C6F67732E736B7970653B706F6F6C31333D617661746172736572766963652E736B79706520636F6E74616374696D706F72742E736B7970653B706F6F6C31343D676F2E736B7970653B706F6F6C31353D747261636B696E672E6F6D6E69747572657C706F6F6C313D3139342E3139322E3139392E3235312C31323335302C312C4E4C2C77652C35302C313B706F6F6C323D3139342E3139322E3139392E3235322C31323335302C312C444B2C77652C35302C313B706F6F6C333D3139332E39352E3135342E31372C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36322C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232372C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33332C31323335312C312C4C552C77652C35302C313B706F6F6C343D3139342E3136352E3138382E3130312C31323335302C312C49452C77652C35302C313B706F6F6C353D3139332E39352E3135342E31342C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3230352C31323335312C312C4C552C77652C35302C31203231322E3138372E3137322E35392C31323335312C312C49452C77652C35302C31203231322E382E3136362E31392C31323335312C312C4C552C77652C35302C313B706F6F6C363D3139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134302C31323335302C312C43412C6E612C35302C313B706F6F6C373D3139352E34362E3235332E3234352C31323335302C312C4C552C77652C35302C31203139332E39352E3135342E31362C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36312C31323335312C312C49452C77652C35302C31203231322E382E3136362E32302C31323335302C312C4C552C77652C35302C313B706F6F6C383D3230342E392E3136332E3138342C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38392C31323335302C312C4C552C77652C35302C313B706F6F6C393D3139342E3136352E3138382E3131352C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134312C31323335302C312C43412C6E612C35302C313B706F6F6C31303D3139332E39352E3135342E31352C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36302C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232362C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33322C31323335312C312C4C552C77652C35302C313B706F6F6C31323D37382E3134312E3137372E37362C31323335302C312C4C552C77652C35302C313B706F6F6C31333D3230342E392E3136332E3136372C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38312C31323335302C312C4C552C77652C35302C313B706F6F6C31343D3230342E392E3136332E3136382C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C313B706F6F6C31353D3230342E392E3136332E3136392C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C3100039701736B79706566696E642E736B7970653D31372C362C382C2D33392C3139206469726563746F72792E736B7970653D31372C362C382C2D33392C31390003A60138302E3235322E38352E37302C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37312C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37322C32333435362C312C6E6C2C77652C35302C31203139352E34362E3235332E3233382C32333435362C322C6C752C77652C35302C31203139352E34362E3235332E3233392C32333435362C322C6C752C77652C35302C31203139342E3136352E3138382E37342C32333435362C332C69652C77652C35302C31203139342E3136352E3138382E37352C32333435362C332C69652C77652C35302C31203231322E3138372E3137322E352C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E32302C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E33332C32333435362C342C69652C77652C35302C31203231322E382E3136332E38372C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132352C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132362C32333435362C362C6C752C77652C35302C31203133302E3131372E37322E3132362C32333435362C372C6E6C2C77652C35302C31203133302E3131372E37322E36362C32333435362C372C6E6C2C77652C35302C310004B2010B03A09C0125B3EA010B220104A5012A24A39C012102220025A19C010401F3C2011A142103030A220125B0EA0103051A2103030B2201030522010384012B39393030303131313A37382E3134312E3137372E39363A3233343536000086010C008701880E039101000493010CC2A5BC5C2774C32EFDD927740496010CD592BC1034504E8DB5F2345006C20105F801F901FA01FB01FC010395016272617465303D31206272617465313D31206272617465323D31206272617465333D31206272617465343D31206272617465353D31206272617465363D31206272617465373D31206272617465383D31207372617465303D31207372617465313D31207372617465323D31207372617465333D31207372617465343D31207372617465353D31207372617465363D31207372617465373D31207372617465383D310003B4013139342E3136352E3138382E37373A3132333530203231322E382E3136332E3130333A31323335300000C0010100C1010103CB012E6163636573732E736B7970652E6E65740000E1010F00F0010100F101A982CA950303D50137382E3134312E3137372E33383A3132333530203230342E392E3136332E3135313A31323335300003CF0137382E3134312E3137372E36393A3132333530203230342E392E3136332E3134393A31323335300000D6010103E4013139342E3136352E3138382E38303A3132333530203231322E382E3136362E353A31323335300003E5010000F8016403F7015B574845453A204F4646203130302C20563120302C20563220305D205B496E70757445513A204F46462035302C2056312035305D205B4945513A204F46462031362C2056312031322C2056322031322C2056332031322C2056342031322C2056352031322C2056362031322C2056372031325D205B53453A204453203130302C2057494F20305D205B5345323A2044532039302C2057494F2031305D205B414D504D3A204F4C442035302C20444147432035305D205B4B54523A204F46462035302C204F4E2035305D205B49414D323A204F46462039392C204D3120312C204D3220305D0003FA0152434F4E3D350003F901302F342E322E2A2E2A2C33322C3320302F352E302E2A2E2A2C31342C3320302F352E312E2A2E3130342C342C330003A80168747470733A2F2F7777775C2E70617970616C5C2E2E3F2E3F2E3F247C68747470733A2F2F696D616765735C2E70617970616C5C2E636F6D247C68747470733A2F2F7777775C2E70617970616C6F626A656374735C2E636F6D247C68747470733F3A2F2F2E2B5C2E666263646E5C2E6E6574247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D247C68747470733F3A2F2F6368616E6E656C5C2E736B7970655C2E636F6D247C68747470733A2F2F617070735C2E736B7970655C2E636F6D247C68747470733F3A2F2F7161617070735C2E736B7970655C2E6E6574247C68747470733F3A2F2F636F6E6E6563745C2E66616365626F6F6B5C2E6E6574247C68747470733A2F2F2E2A5C2E736B7970656173736574735C2E636F6D247C68747470733A2F2F61645C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D656D65615C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D617061635C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F737461746963323F5C2E736B7970655C2E636F6D247C68747470733A2F2F7161737461746963323F5C2E736B7970655C2E6E6574247C68747470733A2F2F7072657374617469635C2E736B7970655C2E6E6574240003FF013078313030303230343030393136333231372D642D723230342E392E3136332E3231373A38313932203078313030303230343030393136333231392D642D723230342E392E3136332E3231393A38313932203078313030303230343030393136333232312D642D723230342E392E3136332E3232313A38313932203078313030303230343030393136333232332D642D723230342E392E3136332E3232333A38313932203078313030303230343030393136333232352D642D723230342E392E3136332E3232353A38313932203078313030303230343030393136333232372D642D723230342E392E3136332E3232373A38313932203078313030303230383038383138363030352D642D723230382E38382E3138362E353A38313932203078313030303230383038383138363030372D642D723230382E38382E3138362E373A38313932203078313030303230383038383138363030392D642D723230382E38382E3138362E393A38313932203078313030303230383038383138363031312D642D723230382E38382E3138362E31313A38313932203078313030303230383038383138363031332D642D723230382E38382E3138362E31333A38313932203078313030303230383038383138363031352D642D723230382E38382E3138362E31353A38313932203078313030303230383038383138363031372D642D723230382E38382E3138362E31373A38313932203078313030303230383038383138363031392D642D723230382E38382E3138362E31393A38313932203078313030303230383038383138363032312D642D723230382E38382E3138362E32313A38313932203078313030303230383038383138363032332D642D723230382E38382E3138362E32333A38313932203078313030303230383038383138363032352D642D723230382E38382E3138362E32353A38313932203078313030303230383038383138363032372D642D723230382E38382E3138362E32373A38313932203078313030303230383038383138363032392D642D723230382E38382E3138362E32393A38313932203078313030303230383038383138363033312D642D723230382E38382E3138362E33313A38313932203078313030303230383038383138363033332D642D723230382E38382E3138362E33333A38313932203078313030303230383038383138363033352D642D723230382E38382E3138362E33353A38313932203078313030303230383038383138363033372D642D723230382E38382E3138362E33373A38313932203078313030303230383038383138363033392D642D723230382E38382E3138362E33393A38313932203078313030303230383038383138363034372D642D723230382E38382E3138362E34373A38313932203078313030303230383038383138363034392D642D723230382E38382E3138362E34393A38313932203078313030303230383038383138363035312D642D723230382E38382E3138362E35313A38313932203078313030303230383038383138363035332D642D723230382E38382E3138362E35333A38313932203078313030303230383038383138363035352D642D723230382E38382E3138362E35353A38313932203078313030303230383038383138363035372D642D723230382E38382E3138362E35373A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E35393A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36313A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36333A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E36353A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36373A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36393A38313932203078313030303230383038383138363037312D642D723230382E38382E3138362E37313A38313932203078313030303230383038383138363037332D642D723230382E38382E3138362E37333A38313932203078313030303230383038383138363037352D642D723230382E38382E3138362E37353A38313932203078313030303230383038383138363037372D642D723230382E38382E3138362E37373A38313932203078313030303230383038383138363037392D642D723230382E38382E3138362E37393A38313932203078313030303230383038383138363038312D642D723230382E38382E3138362E38313A38313932203078313030303230383038383138363038332D642D723230382E38382E3138362E38333A38313932203078313030303230383038383138363038352D642D723230382E38382E3138362E38353A38313932203078313030303230383038383138363038372D642D723230382E38382E3138362E38373A38313932203078313030303230383038383138363038392D642D723230382E38382E3138362E38393A38313932203078313030303230383038383138363039312D642D723230382E38382E3138362E39313A38313932203078313030303230383038383138363039332D642D723230382E38382E3138362E39333A38313932203078313030303230383038383138363039352D642D723230382E38382E3138362E39353A38313932203078313030303230383038383138363039372D642D723230382E38382E3138362E39373A38313932203078313030303230383038383138363039392D642D723230382E38382E3138362E39393A38313932203078313030303230383038383138363130312D642D723230382E38382E3138362E3130313A38313932203078313030303230383038383138363130332D642D723230382E38382E3138362E3130333A38313932203078313030303230383038383138363130352D642D723230382E38382E3138362E3130353A38313932203078313030303230383038383138363130372D642D723230382E38382E3138362E3130373A38313932203078313030303230383038383138363130392D642D723230382E38382E3138362E3130393A38313932203078313030303230383038383138363131312D642D723230382E38382E3138362E3131313A38313932203078313030303230383038383138363131332D642D723230382E38382E3138362E3131333A38313932203078313030303230383038383138363131352D642D723230382E38382E3138362E3131353A38313932203078313030303230383038383138363131372D642D723230382E38382E3138362E3131373A38313932203078323030303134393030353034353031312D642D723134392E352E34352E31313A38313932203078323030303134393030353034353031332D642D723134392E352E34352E31333A38313932203078323030303134393030353034353031352D642D723134392E352E34352E31353A38313932203078323030303134393030353034353031372D642D723134392E352E34352E31373A38313932203078323030303134393030353034353031392D642D723134392E352E34352E31393A38313932203078323030303134393030353034353032312D642D723134392E352E34352E32313A38313932203078323030303134393030353034353032332D642D723134392E352E34352E32333A38313932203078323030303134393030353034353032352D642D723134392E352E34352E32353A38313932203078323030303134393030353034353032372D642D723134392E352E34352E32373A38313932203078323030303134393030353034353032392D642D723134392E352E34352E32393A38313932203078323030303134393030353034353033312D642D723134392E352E34352E33313A38313932203078323030303134393030353034353033332D642D723134392E352E34352E33333A38313932203078323030303134393030353034353033352D642D723134392E352E34352E33353A38313932203078323030303134393030353034353033372D642D723134392E352E34352E33373A38313932203078323030303134393030353034353033392D642D723134392E352E34352E33393A38313932203078323030303134393030353034353034312D642D723134392E352E34352E34313A38313932203078323030303134393030353034353034332D642D723134392E352E34352E34333A38313932203078323030303134393030353034353034352D642D723134392E352E34352E34353A38313932203078323030303134393030353034353034372D642D723134392E352E34352E34373A38313932203078323030303134393030353034353034392D642D723134392E352E34352E34393A38313932203078323030303134393030353034353035312D642D723134392E352E34352E35313A38313932203078323030303134393030353034353035332D642D723134392E352E34352E35333A38313932203078323030303134393030353034353035352D642D723134392E352E34352E35353A38313932203078323030303134393030353034353035372D642D723134392E352E34352E35373A38313932203078323030303134393030353034353035392D642D723134392E352E34352E35393A38313932203078323030303134393030353034353036312D642D723134392E352E34352E36313A38313932203078323030303134393030353034353036332D642D723134392E352E34352E36333A38313932203078323030303134393030353034353036352D642D723134392E352E34352E36353A38313932203078323030303134393030353034353036372D642D723134392E352E34352E36373A38313932203078323030303134393030353034353036392D642D723134392E352E34352E36393A38313932203078323030303134393030353034353037312D642D723134392E352E34352E37313A38313932203078323030303134393030353034353037332D642D723134392E352E34352E37333A38313932203078323030303134393030353034353037352D642D723134392E352E34352E37353A38313932203078323030303134393030353034353037372D642D723134392E352E34352E37373A38313932203078323030303134393030353034353037392D642D723134392E352E34352E37393A38313932203078323030303134393030353034353038312D642D723134392E352E34352E38313A38313932203078323030303134393030353034353038332D642D723134392E352E34352E38333A38313932203078323030303134393030353034353038352D642D723134392E352E34352E38353A38313932203078323030303134393030353034353038372D642D723134392E352E34352E38373A38313932203078323030303134393030353034353038392D642D723134392E352E34352E38393A38313932203078323030303134393030353034353039312D642D723134392E352E34352E39313A38313932203078323030303134393030353034353039332D642D723134392E352E34352E39333A38313932203078323030303134393030353034353039352D642D723134392E352E34352E39353A38313932203078323030303134393030353034353039372D642D723134392E352E34352E39373A38313932203078323030303134393030353034353039392D642D723134392E352E34352E39393A38313932203078323030303134393030353034353130312D642D723134392E352E34352E3130313A38313932203078323030303134393030353034353130332D642D723134392E352E34352E3130333A38313932203078323030303134393030353034353130352D642D723134392E352E34352E3130353A38313932203078323030303134393030353034353130372D642D723134392E352E34352E3130373A38313932203078323030303134393030353034353130392D642D723134392E352E34352E3130393A38313932203078323030303134393030353034353131312D642D723134392E352E34352E3131313A38313932203078323030303134393030353034353131332D642D723134392E352E34352E3131333A38313932203078323030303134393030353034353131352D642D723134392E352E34352E3131353A38313932203078323030303134393030353034353131372D642D723134392E352E34352E3131373A38313932203078323030303134393030353034353131392D642D723134392E352E34352E3131393A38313932203078323030303134393030353034353132312D642D723134392E352E34352E3132313A38313932203078323030303134393030353034353132332D642D723134392E352E34352E3132333A38313932203078323030303134393030353034353132352D642D723134392E352E34352E3132353A38313932203078323030303134393030353034353132372D642D723134392E352E34352E3132373A38313932203078323030303134393030353034353132392D642D723134392E352E34352E3132393A38313932000089020A062E19AEBFD5A40B80D4B6B30280D2AFF205808CFD910B80DEB9F1048FA486F4049CA486F404D5A486F404ACC686F404C2C686F404878F87F404CEB887F404ADC487F404BCC687F404D4D087F404F9EA87F4049CF587F404C8F487F404C9F487F404CAF487F404EACCBB9C05F7CCBB9C05E694D7BB058E96D7BB05A896D7BB050094023C0095021400930201039902536B79706520546563686E6F6C6F6769657320534100008E0200008F0280BAB70300910280A30503F2013231332E3134362E3138392E3230313A3132333530203231332E3134362E3138392E3230323A3132333530203231332E3134362E3138392E3230333A3132333530203231332E3134362E3138392E3230343A3132333530203231332E3134362E3138392E3230353A3132333530203231332E3134362E3138392E3230363A3132333530203231322E3136312E382E31303A3132333530203231322E3136312E382E323A3132333530203231322E3136312E382E333A3132333530203231322E3136312E382E343A3132333530203231322E3136312E382E353A3132333530203231322E3136312E382E363A31323335300000FC010106FD0106011E64AC02A403E807009002C20103C301687474703A2F2F37392E3132352E36332E3732247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D240000DE0148 - <_256>000010011AC0AA3BA66DF7FB48228AE35F9BB4A032FE4A6A898DA7A1A5AE37DC59FB3D09607F1CACD46A5DBC008DABF8F09C797DF5A8903307D04C318825CEA7C481303C655A9EEE099E9A0AF1158373B458BB8FDACB336A6EC63C043E6782688E2350B417DDDDFF96B474DAEA7D1DF3742303B79111FC752BFB5D6887A5B822F945CC761FAF6E80DE5EC60868768CB8A9F9C876137806DCEA0DD1300181558ABFDBA26592078F5F84195C526D8C7F339EF82700FD93F8FB71ADA5ED3E977D27FA52D1F489EF5DA0A9E00B146BADCBDEBFB0DFEBCD61E5B8352A49893357E0DC3A736743929DA975782EA4D8184605FD064641986C47706D264281C876F926BF58003E9E - <_3>0000100498ECF8A7A4585F76C930739A1EAE590DE96D9EF3AA9B231E67965F3F08ECFC493E1DA23ECDE17A85C94CBE034E88F9414E9BBC82F32AAFCFFB2C09F6F57A478238BAEC9EEF2BB9C67F71257722E6786D88D6400F6B7D81450FB3B6CCCC3986E3782D2387E354EBA9099331AEF510D479C6601D2383D866E2B5B525DF0BA975D58C120EFAE88C89EE365FC696CC891B77F67CFA18FDE8E95DDAC25A7C7D70FA7A1414BAE593856A658888C622836006C1C131B4B2E805554DCFA52F3EFD34C1B759BF8A302E491835DCE701E84D37ED150C8ADD699AD3DCA9F515123C5B5AD94E253E173BA3465E64A0079D5EF4E6075E66D0F5FBC3D9BC25C4E80C4CB2FE9B87040003000004D00F0005D00F050041040400B80125C20003141B14230025D50003031B14230024E100142300250003191714230025EA0003141714230025EA00011724EA00140A14230025E400030F1C14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E10025E10003A006100A0309031725000325180C0A25C20003140B0C03040D0A03882725C3000C0A03E43225C4000C0A0602050228038407DC08FA1E0601050102050203FA1E1C0603250028061D1E1F202122060105010205010503050141060300636F756E74206279207175616C697479000001CC080002040003000004010005010501410603006261647175616C69747920636F756E742062792076657273696F6E000001D6080002070003000004010005010501410603006261647175616C6974792073756D2062792076657273696F6E000001E0080002070003000004010005010500410304005424E400142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E40025E40028043CB401D804901C060105010205014106030073756D206F66206C61737463616C6C206475726174696F6E73000001B009000201000300000480A3050005B054050141060300636F756E74206279206C61737463616C6C206475726174696F6E000001BA090002050003000004010005010500410204005025EB00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EB0028031E32D0000601050102050141060300636F756E742062792073797374656D20637075207573616765000001940A0002040003000004010005010500410204004F25EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050141060300636F756E742062792070726F63657373206370752075736167650000019E0A0002040003000004010005010500410304006824C20014230024E60014230025E600011A14230025EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050125C2000501410603006A6974746572636F756E742062792070726F6365737320637075207573616765000001F80A0002040003000004010005010501410603006A69747465722062792070726F6365737320637075207573616765000001820B0002040003000004D00F0005D00F0500410304004424E700142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A1423000225E700050141060300706F74656E7469616C207463702066616C6C6261636B73000001DC0B00020100030000040100050105014106030061637475616C207463702066616C6C6261636B73000001E60B00020100030000040100050105004103040056240C142300250C030A1814230025EA0003141714230025EA00011724EA00140A14230024E70014230025E700011A14230024E50014230025E500011C0602250C29050306070809280401020405060105010205010502050141060300636F756E74206279206E617474797065000001C00C0002050003000004010005010501410603007564706661696C75726573206279206E617474797065000001CA0C0002050003000004010005010500410204001B25D90014230025D90025DA000B0602050228030102040601050102050141060300636F756E74206279206E726F666D756C74696368617473000001A40D0002040003000004010005010500410304001425F700011C14230025000319171423000225F90005014106030075736572732077686F206861766520636F6D706C65746564204943000001880E0002010003000004010005010501410603006C617374204943207969656C6420676C6F62616C73756D000001920E0002010003000004E8070005500500410304001224F60014230025000319171423000225F60005014106030075736572732077686F206861766520494320737570706F7274000001EC0E0002010003000004010005010501410603004943207374617274757020636F756E7420676C6F62616C73756D000001F60E00020100030000046400051405004102040025240C142300250C030A18142300250C011C142300250C280802030405060708090601050102050141060300636F756E74206279206E617474797065000001D00F0002090003000004010005010500410404001A250003191714230025E20025E30025FC00280201020601050102050141060300766964656F2073656E642063617061626C650000019811000201000300000401000501050141060300766964656F20706172616C6C656C2063616C6C730000019911000201000300000414000502050141060300636F756E7420627920766964656F2063616C6C73206D616465000001A2110002030003000004010005010500410204003A250003191714230025EA0003141714230025EA00011724EA00140A14230024E50014230025E50003031914230025E50028030102030601050102050141060300636F756E742062792073747265616D7472616E73706F7274000001FC11000204000300000401000501050041090400E00125C20003141B25E400030F1C1514230024E100142300250003191714230025EA0003141725EA0001171514230025FF002580010A011A14230025E60003031A25E50003031A1514230024F5001423002412142300249F0114230025C30025E10025E10003A006100A03A0060B0309031725000325180C0A25C20003140B0C03040D0A2512030A0C251025F5001703CC080C0A1C160602020502250003231B241D150603050305020503150503251D03808080808080808080011D14150603050305020503150503251D038080808080808080C0011D1415060305030502050315050141060300706F74656E7469616C2052555F756E65787065637465645F62616471000001E01200020100030000040100050105014106030061637475616C2052555F756E65787065637465645F62616471000001EA1200020100030000040100050105014106030042435020706F74656E7469616C2052555F756E65787065637465645F62616471000001F4120002010003000004010005010501410603004243502061637475616C2052555F756E65787065637465645F62616471000001FE12000201000300000401000501050141060300424350203220706F74656E7469616C2052555F756E65787065637465645F62616471000001881300020100030000040100050105014106030042435020322061637475616C2052555F756E65787065637465645F626164710000019213000201000300000401000501050141060300424350203420706F74656E7469616C2052555F756E65787065637465645F626164710000019C130002010003000004010005010501410603004243502031362061637475616C2052555F756E65787065637465645F62616471000001A6130002010003000004010005010500410304000825B801011C25B701050141060300757365727320696E207075626C6963206368617473000001C4130002010003000004010005010501410603007075626C69632063686174206D6573736167657320696E206C617374206D696E757465000001CE1300020100030000046400050A0500410404005F248E0114230024D5001423002500032B1B1423002500032B1C250D03021C16250E03FFFFFFFF0F1D03B4E2C8F10217250E0380808080100D03B4E2C8F10217151614230025D500280219C80106010501020501258E010501258E0103880E1C050141060300636F756E742062792062756464696573000001A814000203000300000401000501050141060300617661696C6162696C697479206167652062792062756464696573000001B2140002030003000004C0FC150005A099020501410603006C6F6E6720617661696C6162696C697479206167652062792062756464696573000001BC140002030003000004010005010500410204003324C000142300250003191714230025F301290300E5C68583B7AEDE36F2CAB9A3A7AE983806020502280202030601050125C00005014106030073696D756C74616E656F75732063616C6C7320706572206E616D6573706163650000018C15000203000300000419000519050041020400C50125C00006020502142300250006030503031917142300050303231B06040504210302200225A1010605050421030502200225A2010606030606070505021A050503021A160506021A15210305072002010607050203021B050603021B152103050720020206070502021A050603021B15210305072002030206070502021A050503041A15210305072002030306070502021A050503031A15210305072002030406070502021A050503051A152103050720020305060705072806010203040506060105010205014106030063616C6C6572733A207332735F313120636F6E665F686F737420636F6E665F636C69656E7420736B7970656F757420736B797065696E20766F6963656D61696C20756E6B6E6F776E000001F015000207000300000401000501 - <_4>000010052A0B6759B71FBC1EF05BE97DFEA4EE6C1E15AF19ED70DEC1130B14C13CE41246D302B9662592907E3CA508A57702B5C00C2A05170857FA22012E0F235B425B4D919B23A541D3AD6E948FC634DE71A29493634884DFD5E9D89C5D951CBCD71B9B3ABFD3C4E2779BB1817D76E7C223CA36BD75A6A05B730AF138057E4048B2FFDD522BB588EC0B9D3E014BF9E354EB608150BC613C739D9E8C7465F05F047FAF7AFA3EE89B9B58BF0FC35F07B55CF3E4B59A7C4ED48B1C0C7F0305E6AC2E80AAEAD6064EB6ACDC1806FCE0B5CB66F0840DA7F0FE7B228E3898E3E42A9AFEFE13DDF019EF8D8F02A631AF2615BBC6E1EDB65C89A775F642C88109E6247EC4B463DC302E2A2E323000050541020006020307322E302E2A2E3100050541030006020307322E302E2A2E3200000AE4ED8009050541030006020307322E302E2A2E33000009B3E6CC990B050541040006020307322E302E2A2E3400000AE4ED8009000BA00B050541030006020308322E302E2A2E35000307322E302E2A2E3900050541040006020308322E302E2A2E39000307322E302E2A2E313100000AE4ED8009050541040006020308322E302E2A2E3131000307322E302E2A2E3135000009E6CC99B306050541050006020308322E302E2A2E3135000307322E302E2A2E323000000AE4ED8009000BA00B050041050303557067726164655465737433000301332E302E302E3130300003044E6963654272616E6400050541040006020307332E302E302E2A0003074E6963654272616E6400000AE4ED8009050541040006020307322E302E302E2A0003074E6963654272616E6400000AE4ED80090500410E0303557067726164655465737433000301332E302E302E31303000050541040006020307332E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307322E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307332E302E302E39380003074F746865724272616E64000009B3E6CC990B050541040006020307322E302E302E39380003074F746865724272616E64000009B3E6CC990B050541050006020307332E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541050006020307322E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541030006020307332E302E302E393900000AE4ED8009050541030006020307322E302E302E393900000AE4ED8009050541030006020307332E302E302E3938000009B3E6CC990B050541030006020307322E302E302E3938000009B3E6CC990B050541040006020307332E302E302E393700000AE4ED8009000BA00B050541040006020307322E302E302E393700000AE4ED8009000BA00B0500410303033130303031000301302E302E302E313000050541020006020307302E302E302E3900 - <_5>00001006739CA527EF827847E16F23CD52458C3EBA3460A42935EC6948BEFA626B49E3BDF279FC62486E2DDBCA19609ED23D31F4E5175920F282AD74A74A997C3909E67B622480C68A058E886C7D5F3C40954880D7798CD61CEA0FBAFB389BE5B2B8A887348F7AADB4DF642B194B814047CDA0E698EDDE61DFA731DCA5883A76F913D8C94066718054E85ADA7AE009F2B2A9AF762FDCB9B6CAF64C156911E3AB172CFD795F66FB6E8E15048A54E4AB17979D6C447DEBADE75CC6F606050D980061112AFF9AE7C7BF8065D711949E41FA4C8B6CBF0916BB395B3E186A7D617D353C6BFFC687FE79475DFA095D113D70B828FB597BC3665B7C9C3669CA9CBE5D308D3FC23803044E45544745415200050541020006040307302E392E302E2A000500410503033130303033000301312E302E302E3137000304534D4300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E312E302E313000030442454C4B494E00050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E3137000304454447452D434F524500050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E31330003044C4F474954454300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303035000301312E342E38382E31333636000304544F50434F4D00050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410503033130303035000301312E342E38382E313336360003045043484F4D4500050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410403033130303036000301302E302E302E313000050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303037000301312E302E312E330003045445434F00050541020006040307312E302E302E3800050541020006020307312E302E312E31000500410503033130303038000301302E392E332E3339370003044C494E4B53595300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003044E45544745415200050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003045048494C49505300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410403033130303130000301302E392E302E31310003044C494E4B53595300050541020006040307302E392E302E3130000500410403033130303130000301302E392E302E313100030442554646414C4F00050541020006040307302E392E302E3130000500410503033130303132000301312E302E302E310003044353544E00050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303133000301302E302E332E3234000304414B00050541020006040307302E302E312E323400050541020006020307302E302E322E3234000500410303033130303134000301312E372E34332E33382E3200050541020006040307312E372E32332E32372E34000500410503033130303135000301312E322E31372E30000304415A5445434800050541020006040307312E322E31312E3000050541020006020307312E322E31352E30000500410303033130303230000301312E302E302E343700050541030006020308312E302E302E3233000307312E302E302E3233000500410403033130303234000301332E322E302E323800050541030006040308332E302E302E35000307332E302E302E3500050541030006020308332E312E302E31000307332E322E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E494300050541020006040307302E302E302E3100050541020006020307302E302E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E4943434F4E53554D455200050541020006040307302E302E302E3100050541020006020307302E302E302E3800 - - 1 - - 400 - - - - 8118 - 39,64,8184 - 37,50,13164 - - 1 - - 1 - - - -1431699456 - -1431699456 - 1610612735 - - 41C801050041050200D9AF0D45D9E900010400028788BCED0400038788BCED04000400050041050200BB0AB3FDD1A40001040002B7DCBCED040003B7DCBCED040004000500410502005C3766C2DA6B00010400029FB2BCED0400039FB2BCED04000400050041050200D9F8DC20CA33000104000296DAAAED04000396DAAAED0400040005004105020063847B3765900001040002D794BDED040003D794BDED040004000500410502004E80142FD3C70001040002CF86BDED040003CF86BDED04000400050041050200C3B213EA24A50001040002BF89BBED040003BF89BBED040004000500410502006FFEF1BA804C0001040002CF86BDED040003CF86BDED0400040005004105020052ED923CB3A700010400028788BCED0400038788BCED040004000500410502005243330D305B000104000283FFB2ED04000383FFB2ED040004000500410502006FF9438E9E5D0001040002CF86BDED040003CF86BDED04000400050041050200585515F19D77000104000283FFB2ED04000383FFB2ED04000400050041050200729EE3A8DD460001040002CF86BDED040003CF86BDED040004000500410502004572795D3BB300010400029FB2BCED0400039FB2BCED040004000500410502009F94D72CABA40001040002CF86BDED040003CF86BDED0400040005004105020095052D9C81090001040002B7DCBCED040003B7DCBCED040004000500410502005859A15FD7FC0001040002DC8FB5ED040003DC8FB5ED0400040005004105020059D7AB3EBBFB0001020002F8FABCED040003CF86BDED04000400050041050200BB2481B9390E0001040002CF86BDED040003CF86BDED0400040005004105020059D7F395A7BA0001040002B7DCBCED040003B7DCBCED040004000500410502006DC4BEF5D52E0001040002B0DFBAED040003B0DFBAED040004000500410502004B6E709CF4290001040002B7DCBCED040003B7DCBCED040004000500410502007A7D5CEC2B8D0001040002CF86BDED040003CF86BDED040004000500410502006FFFA8AFB19D0001040002B7DCBCED040003B7DCBCED040004000500410502003E4475A07A6F0001040002B7DCBCED040003B7DCBCED040004000500410502003EDD8384A4F90001040002BF89BBED040003BF89BBED04000400050041050200560FBFA4E4900001040002B7DCBCED040003B7DCBCED04000400050041050200C24FAEEE43F10001040002B3CEB5ED040003B3CEB5ED040004000500410502004F378778C6F30001040002CF86BDED040003CF86BDED04000400050041050200C94418BB0EDF0001040002B7DCBCED040003B7DCBCED040004000500410502003B75A58BECB30001040002CF86BDED040003CF86BDED04000400050041050200772A7A0908890001040002CF86BDED040003CF86BDED0400040005004105020048BB63586DE100010400029088BCED0400039088BCED040004000500410502005544F881BEDA000104000283FFB2ED04000383FFB2ED040004000500410502005B4C1468EDF80001040002B7DCBCED040003B7DCBCED04000400050041050200538BAF3F934F0001040002B3CEB5ED040003B3CEB5ED0400040005004105020055D6F93A4FD70001040002D7B3BBED040003D7B3BBED04000400050041050200D5D64561E55F00010400028788BCED0400038788BCED0400040005004105020046ADF229B8570001040002CF86BDED040003CF86BDED04000400050041050200D5151C19FFD600010200029FB2BCED040003B7DCBCED04000400050041050200973CA35DB82400010400029FB2BCED0400039FB2BCED04000400050041050200C249E5B953700001040002CF86BDED040003CF86BDED04000400050041050200722C69D8C4F500010400029FB2BCED0400039FB2BCED0400040005004105020058CBB311F2400001040002DC8FB5ED040003DC8FB5ED040004000500410502004BB7A090766E0001040002CF86BDED040003CF86BDED040004000500410502007DEF80FBEBD90001040002EFDDBBED040003EFDDBBED0400040005004105020076A03698F87A0001040002CF86BDED040003CF86BDED0400040005004105020050E5DFDD0C700001040002CF86BDED040003CF86BDED040004000500410502004D4C85E0CEC80001040002CF86BDED040003CF86BDED040004000500410502006FEA6BCD92A10001020002F8FABCED040003CF86BDED0400040005004105020043BAA930F28600010400029FB2BCED0400039FB2BCED04000400050041050200722DB82DDB780001040002CF86BDED040003CF86BDED0400040005004105020052E995118B9F0001040002CF86BDED040003CF86BDED040004000500410502005403013B36D20001040002EFDDBBED040003EFDDBBED04000400050041050200B27C0C920B260001040002B7DCBCED040003B7DCBCED04000400050041050200D9AF0997A7450001040002BCD9AAED040003BCD9AAED04000400050041050200BC00130BB5F60001040002CF86BDED040003CF86BDED04000400050041050200591FF23B53830001040002CF86BDED040003CF86BDED04000400050041050200557EB01367590001040002CF86BDED040003CF86BDED04000400050041050200505F157093A2000102000297A4BCED04000397A4BCED040004000500410502003A036C495C670001040002CF86BDED040003CF86BDED0400040005004105020050D8CF0B7D480001040002B7DCBCED040003B7DCBCED040004000500410502004E34E4D0FF250001040002B7DCBCED040003B7DCBCED040004000500410502007A1E50A46E770001040002CF86BDED040003CF86BDED040004000500410502005F18C666CBB80001040002EFDDBBED040003EFDDBBED04000400050041050200C19335603A9E0001040002DC8FB5ED040003DC8FB5ED0400040005004105020097142BD7DF890001040002AFDFBAED040003AFDFBAED0400040005004105020052F3355FFED400010400029FB2BCED0400039FB2BCED04000400050041050200BCBA857EECDF0001040002D7B3BBED040003D7B3BBED04000400050041050200729259D605EF0001040002CF86BDED040003CF86BDED04000400050041050200BEC2F57655B300010400029FB2BCED0400039FB2BCED040004000500410502005BD905C8304B0001020002A8EEBBED0400038788BCED0400040005004105020055F2C0360F360001040002EFDDBBED040003EFDDBBED0400040005004105020082C01DB9605D00010400028788BCED0400038788BCED04000400050041050200BC73B8FB30360001040002CF86BDED040003CF86BDED0400040005004105020050390E32DF8B0001040002B0DFBAED040003B0DFBAED040004000500410502005BCE8A2D7B8000010400028788BCED0400038788BCED0400040005004105020042292BB45D2D0001040002CF86BDED040003CF86BDED040004000500410502004F1A354DCA9A00010400029FB2BCED0400039FB2BCED04000400050041050200591C1D7F0EC900010400028788BCED0400038788BCED04000400050041050200722E9D2CCB030001040002CF86BDED040003CF86BDED04000400050041050200443AB71D3F8A0001040002CF86BDED040003CF86BDED0400040005004105020018DEF34EB70600010400028788BCED0400038788BCED0400040005004105020097215860080F00010400029FB2BCED0400039FB2BCED040004000500410502007229C156A49E0001040002B7DCBCED040003B7DCBCED040004000500410502003A72EDECB0250001040002B3F7B4ED040003B3F7B4ED04000400050041050200D52F8CD18F640001040002E285B0ED040003E285B0ED040004000500410502006B0325208B4C0001040002EFDDBBED040003EFDDBBED040004000500410502005164424285660001040002938AB5ED040003938AB5ED04000400050041050200D4E9D6AB12F80001040002AFDFBAED040003AFDFBAED0400040005004105020059B3090F459C0001040002FCDDAAED040003FCDDAAED04000400050041050200BC10C41E7AAB0001040002CF86BDED040003CF86BDED040004000500410502009F9532B560C100010400028788BCED0400038788BCED0400040005004105020050EA7B4A63750001040002CF86BDED040003CF86BDED0400040005004105020045A658245E790001040002CF86BDED040003CF86BDED0400040005004105020047E3059299620001040002CF86BDED040003CF86BDED0400040005004105020081164AFC3B450001040002CF86BDED040003CF86BDED040004000500410502005703C3FC60FF00010400028788BCED0400038788BCED0400040005004105020063FAEB02F39300010400028788BCED0400038788BCED040004000500410502005714F2D9F6650001020002AFDFBAED040003ECE7BAED04000400050041050200505F1B22B00D0001040002CF86BDED040003CF86BDED0400040005004105020062C2F2A80C7900010400029FB2BCED0400039FB2BCED04000400050041050200425CA6CCD1FF0001040002CF86BDED040003CF86BDED0400040005004105020084C778D4AB110001040002CF86BDED040003CF86BDED040004000500410502005106437CD3B60001040002CF86BDED040003CF86BDED0400040005004105020058506B2B47D40001040002D7B3BBED040003D7B3BBED04000400050041050200DD70204563390001040002B7DCBCED040003B7DCBCED040004000500410502005CFFA5BE4A0000010200028888BCED040003F8FABCED0400040005004105020089BD8692E0400001040002B7DCBCED040003B7DCBCED040004000500410502004AC12BB2AB8D0001040002B7DCBCED040003B7DCBCED04000400050041050200DB555CBAEE6B0001040002CF86BDED040003CF86BDED0400040005004105020095052D8F81090001020002A7FDBCED040003CF86BDED04000400050041050200473AA0E1C9110001020002A7FDBCED040003CF86BDED040004000500410502004EFA971D2E4C0001040002B7DCBCED040003B7DCBCED04000400050041050200BCE6C5A829D900010400029E90B5ED0400039E90B5ED0400040005004105020051699F18DC540001040002D7B3BBED040003D7B3BBED040004000500410502005CFB85D7E6460001040002B3CEB5ED040003B3CEB5ED0400040005004105020052D17CE5A9840001040002BF89BBED040003BF89BBED0400040005004105020054DD54C818F20001040002CF86BDED040003CF86BDED040004000500410502005C3555EBDC670001040002B7DCBCED040003B7DCBCED0400040005004105020051D92EE554370001040002BF89BBED040003BF89BBED0400040005004105020095549556182D0001040002CF86BDED040003CF86BDED040004000500410502005419C1F7F52A0001040002B3CEB5ED040003B3CEB5ED040004000500410502008C7259638E1D0001040002B7DCBCED040003B7DCBCED04000400050041050200516745231C2200010400029FB2BCED0400039FB2BCED0400040005004105020055FB3DEAE2380001040002B7DCBCED040003B7DCBCED040004000500410502005D5470BCB83A00010400028788BCED0400038788BCED0400040005004105020054C6D511E6810001040002CF86BDED040003CF86BDED0400040005004105020062A7FAC0119000010200028788BCED0400038888BCED040004000500410502007225A1DCFB1A00010200028788BCED0400038888BCED04000400050041050200708B358CF15C00010400028788BCED0400038788BCED04000400050041050200D9A293C3FE550001040002AFDFBAED040003AFDFBAED04000400050041050200722119BAFCB600010400029FB2BCED0400039FB2BCED0400040005004105020054369C95EAC60001040002CF86BDED040003CF86BDED04000400050041050200AE74419813810001040002B7DCBCED040003B7DCBCED0400040005004105020048C613BC68510001040002EFDDBBED040003EFDDBBED04000400050041050200516E168D638B0001040002EFDDBBED040003EFDDBBED040004000500410502001819CFB484D20001040002CF86BDED040003CF86BDED04000400050041050200ADE013B3E9F10001040002CF86BDED040003CF86BDED040004000500410502005C708ABFAC890001040002B3CEB5ED040003B3CEB5ED04000400050041050200BC81882E891C0001040002B7DCBCED040003B7DCBCED0400040005004105020057785543EB480001040002CF86BDED040003CF86BDED040004000500410502006FF0CE6CB4500001040002CF86BDED040003CF86BDED040004000500410502005CE13B7199D4000102000283ADE7E304000383ADE7E30400040005004105020063F610137D170001040002B7DCBCED040003B7DCBCED04000400050041050200DC887BC89E210001040002CF86BDED040003CF86BDED040004000500410502005D9324151E7F0001020002A7FDBCED040003CF86BDED04000400050041050200BC02D363924D00010400029FB2BCED0400039FB2BCED040004000500410502004F28848E1AC50001040002CF86BDED040003CF86BDED0400040005004105020054C606DD0D260001040002D984B5ED040003D984B5ED04000400050041050200D5F586558C850001040002BF89BBED040003BF89BBED0400040005004105020082582B0468CF00010400028788BCED0400038788BCED040004000500410502005CE21BB9BD7C00010400029FB2BCED0400039FB2BCED0400040005004105020059A9ACE3BC02000104000296DAAAED04000396DAAAED040004000500410502005557DB28EDA300010400028788BCED0400038788BCED0400040005004105020076ABA00FF52C0001040002CF86BDED040003CF86BDED0400040005004105020052185C5CB8440001040002B7DCBCED040003B7DCBCED04000400050041050200441402A770A800010200028788BCED0400038888BCED04000400050041050200516623CC99760001040002CF86BDED040003CF86BDED040004000500410502005A3D6D867C2A0001040002BF89BBED040003BF89BBED04000400050041050200BC70864FCE530001040002B3F7B4ED040003B3F7B4ED040004000500410502005E9C9B4E7A740001040002CF86BDED040003CF86BDED0400040005004105020058ABF63F0EA70001040002FCDDAAED040003FCDDAAED040004000500410502005556BDBE86AC000104000286FFB2ED04000386FFB2ED0400040005004105020059D0D49C9B8000010400028788BCED0400038788BCED0400040005004105020059A934952E920001040002B3F7B4ED040003B3F7B4ED040004000500410502007220ABEC82C80001040002B7DCBCED040003B7DCBCED04000400050041050200807AB45544310001040002BF89BBED040003BF89BBED04000400050041050200187A8DFCCDCF0001040002BF89BBED040003BF89BBED04000400050041050200616B5C35801000010400028788BCED0400038788BCED040004000500410502005ABCE5EAE3790001040002938AB5ED040003938AB5ED0400040005004105020048DF5F3311D10001020002F8FABCED040003CF86BDED04000400050041050200D3146B24D6340001040002CF86BDED040003CF86BDED0400040005004105020059037023AC7D00010400029FB2BCED0400039FB2BCED040004000500410502003EDD92C929340001040002BF89BBED040003BF89BBED040004000500410502004C4EB0C1270D0001040002CF86BDED040003CF86BDED04000400050041050200BCA300CD17370001040002CF86BDED040003CF86BDED040004000500410502005BC42D9E789A0001040002D7B3BBED040003D7B3BBED04000400050041050200589755D3E75F0001020002D884B5ED040003B3CEB5ED040004000500410502007A7CC86B21530001040002CF86BDED040003CF86BDED040004000500410502005352A2DA24D300010400028788BCED0400038788BCED0400040005004105020058C9F9B6A86F0001040002B7DCBCED040003B7DCBCED040004000500410502005706A79DEAE60001020002AFDFBAED040003ECE7BAED0400040005004105020082D1B28F7A3A0001040002CF86BDED040003CF86BDED0400040005004105020052217343E79C0001040002CF86BDED040003CF86BDED0400040005004105020082CEA3A289FE000104000296DAAAED04000396DAAAED04000400050041050200D9E0FF79D1180001040002B7DCBCED040003B7DCBCED0400040005004105020052FD31513EE90001040002938AB5ED040003938AB5ED0400040005004105020052128CCDBA7C00010400029FB2BCED0400039FB2BCED040004000500410502006FB83DA167580001040002CF86BDED040003CF86BDED040004000500410502002E14B9387F540001020002B7DCBCED040003CF86BDED040004000500410502004F7E6F098A990001040002CF86BDED040003CF86BDED040004000500410502005D98B7099E1F0001040002B7DCBCED040003B7DCBCED04000400050041050200722A7476317600010400029FB2BCED0400039FB2BCED04000400050041050200BC18CE5EBDA10001020002AFDFBAED040003ECE7BAED040004000500410502005CF890CF3E270001040002B7DCBCED040003B7DCBCED040004000500410502008D72AE6DBEE30001040002CF86BDED040003CF86BDED0400040005004105020076A6D8E9EAAB0001040002CF86BDED040003CF86BDED04000400050041050200721B63925A140001040002CF86BDED040003CF86BDED040004000500410502007608B348A53A0001040002CF86BDED040003CF86BDED04000400 - - 0 - - -645574544 - 0 - 47500 - - 1 - - - 217.133.80.112:1076 217.133.80.112:47500 217.133.80.112:1083 217.133.80.112:1083 217.133.80.112:49734 - 7 - - <_1303289856>6C81442204F3D9855070B98CAE5879A505F3D9855070B98C4D4320134B66D9855070B98C5F4E60ED0D34D98550700434 - <_1303293952>4287274ED659D9855070B98C4287274ED74BD9855070B98C4287274EC15CD9855070B98C4287274ECE92D9855070B98C4287274EA75BD9855070B98C4287274E4B98D9855070B98C4287274EAA2DD9855070B98C4287274EA175D9855070B98C4287274ED735D9855070B98C4287274EAE25D9855070B98C4287274E1A2BD9855070B98C3D7D44372576D9855070B98CCF86DF304366D9855070B98C3D2E02A2259CD9855070B98C4287274EB98CD9855070B98C - <_1303298048>2E3363049108D9855070B98C2E3795FA3202D9855070B98C2E2F6F42E86DD9855070B98CB4B0620AA528D9855070B98C - <_1303306240>5F1894D8122BD9855070B98C2E40484969A3D9855070B98CD592A70A5566D9855070B98C2E26119F8DBED9855070B98C2E3754264E48D9855070B98C - <_1303314432>4D2BFFCAEC6CD9855070043B54BAD08D05E0D9855070B98C9D9D4DA11995D9855070B98C59584CCBB5CED9855070B98C972AC71733DDD9855070B98C - <_1303322624>5F3B0DCEB535D9855070043BD5150C1746D3D9855070B98C4D4B8646EF29D9855070B98CD5152F4D12BBD9855070B98C - <_1303326720>59D0D11D89DCD9855070C2462E755D8E1E97D9855070B98C2E492F875789D9855070B98C2E378784E9C6D9855070B98C2E2F6F6B48FCD9855070B98C - - - <_1303289856>9A4A56D31C619325C6601C71B23E13FDFAF5CA49F15C34A4E33F239B524D6BBC226021F010D2270A3B48DFA2E8CDB6FD37531B1118DB2D471CB980D0 - <_1303293952>D5A2186D0B45088ADDFA7B626C0904CED47E3DF13172672AED483E1EAD69DB781ABEC0D8812B1B5EFF91BC28C67FB5A3404D875A - <_1303298048>DB0EC5161D10171C7C6A4C7109DD - <_1303302144>5379BD98 - <_1303306240>88B19442A48D863ED54D712EEC36D53127BCE36653FE - <_1303310336>1908404B0F7BA3BE952CB1C533456D3CDA410BCB774AF93880FB8BD8C110 - <_1303314432>4B015AD444DD027FD3F61B2A51A53BA0 - <_1303322624>878BAF81A9F053B39E35081485E24B4EDA5F79D37E176C409B6E237A336451F42CFA7CEC013C98A18B51 - <_1303326720>CFB137906F6CCE77246BD5B6B434875570B1F9B9140C85D5114EE6953110B04F3557C0D1686D46A9F69106521979AE49E19F8622F93A - <_1303330816>BA4B81F735FDCDA4E4EF57ACF8A37051C66401E41CA4E562A5A49ACC2E246CCE - - - - 1 - - - 1 - - - 0 - - - 1 - - - - 9BF92EA4B417A7F6 - - - 4102030E322F322E302E302E37322F31373400000FF6EB9ADC04 - - - 0 - - - - 2 - en - - 357 - 258 - 0 - 0 - - 0 - - diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml deleted file mode 100644 index f7af8873ad..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - 300 - 1800 - 63 - - - 41010300676D6172757A7A3400 - 1268962216 - - - 0 - 0 - 1303202372 - 0 - -

- 35716ecf:2 - 98e6c103:0 -

- -
-
- - 1 - 3 - 65535 - 1266110339 - - - 1 - - - 1 - - - 1000000166 - 1303166852 - 1303209779 - - - 1267114269 - - 2 - - 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 - - - 1267114267 - 11 - 4263C0064DD5ACF9A03594DAB928D2B81510 - - - - <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 - -
- - - skypopen - - - 0 - 2 - 2 - 2 - -
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat deleted file mode 100644 index fc7f2b1150..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat +++ /dev/null @@ -1 +0,0 @@ -B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat deleted file mode 100644 index b8b96d84318e540df1ace348fe21db2b6bc5db1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmXwuNdbT`5X8FNmjYy9pe~S#BNQM2CZ)5VNwV*L#B-llsu$ko2Zk2aTXAXCJ2}n& hUQDwOVw!yv)9jO&W}n40`y!^<5k^1s4DS diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/main.lock deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml deleted file mode 100644 index f7af8873ad..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - 300 - 1800 - 63 - - - 41010300676D6172757A7A3400 - 1268962216 - - - 0 - 0 - 1303202372 - 0 - -

- 35716ecf:2 - 98e6c103:0 -

- -
-
- - 1 - 3 - 65535 - 1266110339 - - - 1 - - - 1 - - - 1000000166 - 1303166852 - 1303209779 - - - 1267114269 - - 2 - - 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 - - - 1267114267 - 11 - 4263C0064DD5ACF9A03594DAB928D2B81510 - - - - <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 - -
- - - skypopen - - - 0 - 2 - 2 - 2 - -
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat deleted file mode 100644 index fc7f2b1150..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat +++ /dev/null @@ -1 +0,0 @@ -B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat deleted file mode 100644 index b8b96d84318e540df1ace348fe21db2b6bc5db1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmXwuNdbT`5X8FNmjYy9pe~S#BNQM2CZ)5VNwV*L#B-llsu$ko2Zk2aTXAXCJ2}n& hUQDwOVw!yv)9jO&W}n40`y!^<5k^1s4DS diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/main.lock deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml deleted file mode 100644 index f7af8873ad..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - 300 - 1800 - 63 - - - 41010300676D6172757A7A3400 - 1268962216 - - - 0 - 0 - 1303202372 - 0 - -

- 35716ecf:2 - 98e6c103:0 -

- -
-
- - 1 - 3 - 65535 - 1266110339 - - - 1 - - - 1 - - - 1000000166 - 1303166852 - 1303209779 - - - 1267114269 - - 2 - - 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 - - - 1267114267 - 11 - 4263C0064DD5ACF9A03594DAB928D2B81510 - - - - <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 - -
- - - skypopen - - - 0 - 2 - 2 - 2 - -
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat deleted file mode 100644 index fc7f2b1150..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat +++ /dev/null @@ -1 +0,0 @@ -B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat deleted file mode 100644 index b8b96d84318e540df1ace348fe21db2b6bc5db1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmXwuNdbT`5X8FNmjYy9pe~S#BNQM2CZ)5VNwV*L#B-llsu$ko2Zk2aTXAXCJ2}n& hUQDwOVw!yv)9jO&W}n40`y!^<5k^1s4DS diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/main.lock deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml b/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml deleted file mode 100644 index c03fd718e0..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_skypopen/configs/startskype.bat b/src/mod/endpoints/mod_skypopen/configs/startskype.bat deleted file mode 100644 index 5624b02af4..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/startskype.bat +++ /dev/null @@ -1,52 +0,0 @@ -echo off -REM -REM you MUST use the new Skype (4.x) for Windows, older versions (3.x) cannot be started this way -REM -REM you have to adjust PATH to where the Skype executable is -set PATH=%PATH%;C:\Program Files\Skype\Phone\ - -echo %PATH% - -REM start a Skype client instance that will login to the Skype network using the "username password" you give to it. Here xxx would be the password and user1 the username -start Skype.exe /secondary /username:user1 /password:xxx -call wait 7 -start Skype.exe /secondary /username:user2 /password:xxx -call wait 7 -REM -REM Following Skype client instances are commented out -REM -REM start Skype.exe /secondary /username:user3 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user4 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user5 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user6 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user7 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user8 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user9 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user10 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user11 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user12 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user13 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user14 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user15 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user16 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user17 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user18 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user19 /password:xxx -REM call wait 7 -REM start Skype.exe /secondary /username:user20 /password:xxx diff --git a/src/mod/endpoints/mod_skypopen/configs/wait.bat b/src/mod/endpoints/mod_skypopen/configs/wait.bat deleted file mode 100644 index 8381230f47..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/wait.bat +++ /dev/null @@ -1,4 +0,0 @@ -REM would you believe there is no sleep() in standard windows batchfiles? -@ping 127.0.0.1 -n 2 -w 1000 > nul -@ping 127.0.0.1 -n %1% -w 1000> nul - diff --git a/src/mod/endpoints/mod_skypopen/configs/windows-service/startskype.cmd b/src/mod/endpoints/mod_skypopen/configs/windows-service/startskype.cmd deleted file mode 100644 index 505a36c4b5..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/windows-service/startskype.cmd +++ /dev/null @@ -1,61 +0,0 @@ -echo off - -REM -REM you MUST use the new Skype (4.x) for Windows, older versions (3.x) cannot be started this way -REM -REM you have to adjust PATH to where the Skype executable is -set PATH=%PATH%;C:\Program Files\Skype\Phone\ - -REM echo %PATH% - -REM start a Skype client instance that will login to the Skype network using the "username password" you give to it. -REM Here xxxx would be the password and user20 the username - -start Skype.exe /secondary /username:user20 /password:xxxx -call C:\wait.cmd 20 - -start Skype.exe /secondary /username:user19 /password:xxxx -call C:\wait.cmd 5 - -REM -REM Following Skype client instances are commented out -REM - -REM start Skype.exe /secondary /username:user18 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user17 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user16 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user15 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user14 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user13 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user12 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user11 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user10 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user9 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user8 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user7 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user6 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user5 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user4 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user3 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user2 /password:xxxx -REM call C:\wait.cmd 5 -REM start Skype.exe /secondary /username:user1 /password:xxxx -call C:\wait.cmd 120 -NET start AICCU2 -pause diff --git a/src/mod/endpoints/mod_skypopen/configs/windows-service/wait.cmd b/src/mod/endpoints/mod_skypopen/configs/windows-service/wait.cmd deleted file mode 100644 index 8381230f47..0000000000 --- a/src/mod/endpoints/mod_skypopen/configs/windows-service/wait.cmd +++ /dev/null @@ -1,4 +0,0 @@ -REM would you believe there is no sleep() in standard windows batchfiles? -@ping 127.0.0.1 -n 2 -w 1000 > nul -@ping 127.0.0.1 -n %1% -w 1000> nul - diff --git a/src/mod/endpoints/mod_skypopen/install/install.pl b/src/mod/endpoints/mod_skypopen/install/install.pl deleted file mode 100755 index e449f0ad2e..0000000000 --- a/src/mod/endpoints/mod_skypopen/install/install.pl +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/perl - -my $myname ; -my $skype_download_url = "http://download.skype.com/linux/skype-4.3.0.37.tar.bz2"; -my $skype_download_pkg = "skype-4.3.0.37.tar.bz2"; -my $skype_binary_dir = "/usr/local/freeswitch/skypopen/skype-clients-symlinks-dir"; -my $skype_download_dir = "/tmp/skype_download"; -my $skype_unpacked_dir = "skype-4.3.0.37"; -my $skype_share_dir = "/usr/share/skype"; -my $freeswitch_modules_config_dir = "/usr/local/freeswitch/conf/autoload_configs"; -my $skypopen_sound_driver_dir = "/usr/local/freeswitch/skypopen/skypopen-sound-driver-dir"; -my $skype_config_dir = "/usr/local/freeswitch/skypopen/skype-clients-configuration-dir"; -my $skype_startup_dir = "/usr/local/freeswitch/skypopen/skype-clients-startup-dir"; -my $skype_symlinks_dir = "/usr/local/freeswitch/skypopen/skype-clients-symlinks-dir"; -my $skype_clients_to_be_launched = "5"; -my $skype_clients_starting_number = "100"; -my $multi_skypeusername = "one"; -my $skype_username = "your_own_skype_username"; -my $skype_password = "your_own_skype_password"; -my @skype_username_array; -my @skype_password_array; -my $sure = "nope"; - -### PRESENTATION ### -system("clear"); -printf("\n"); -printf("This is the interactive installation helper for Skypopen\n"); -printf("(http://wiki.freeswitch.org/wiki/Mod_skypopen_Skype_Endpoint_and_Trunk)\n"); -printf("\n"); -printf("Especially designed for FreeSWITCH\n"); -printf("by Giovanni Maruzzelli\n"); -printf("\n"); -printf("Please direct all questions or issues to the FreeSWITCH mailing list or Jira\n"); -printf("(http://lists.freeswitch.org/mailman/listinfo or https://freeswitch.org/jira)\n"); -printf("\n"); -printf("\n"); -printf("I'll ask you questions, giving default answers in square brackets [] if any\n"); -printf("To accept the default, just press Enter\n"); -printf("You'll be prompted to confirm your answer at each step\n"); -printf("At the end of questions, before I do anything, I'll let you review it all\n"); -printf("To abort, press Ctrl-C\n"); -printf("\n"); -printf("\n"); -printf("Let's start asking your name, so you see how the question/answer works\n"); -printf("To accept the default, just press Enter\n"); -$myname = &promptUser("Enter your name ", "Giovanni"); -system("clear"); -printf("\n"); -printf("OK %s, GREAT! Let's start real questions! (At any time, Ctrl-C to abort)\n", $myname); -printf("\n"); -printf("At the end of questions, before I do anything, I'll let you review all your answers, don't worry! :)\n"); -printf("\n"); -printf("\n"); - -### ASKING QUESTIONS ### - -printf("I'm about to download the Skype client for Linux version 2.0.0.72 for OSS\n"); -printf("nicely repackaged by Arch Linux with official Skype permission.\n"); -printf("I need to create a directory to download and unpack the Skype client\n"); -printf("To accept the default, just press Enter\n"); -$skype_download_dir = &promptUser("Enter the full path of the Skype download directory ", "$skype_download_dir"); -system("clear"); -printf("\n"); -printf("I'm about to install the Skype client\n"); -printf("I would put the binary in $skype_binary_dir and the associated files in $skype_share_dir\n"); -printf("Location of associated files is mandatory ($skype_share_dir)\n"); -printf("Location of binary is recommended ($skype_binary_dir)\n"); -printf("To accept the default, just press Enter\n"); -$skype_binary_dir = &promptUser("Enter the directory full path for Skype client binary ", "$skype_binary_dir"); -system("clear"); -printf("\n"); -printf("I'm about to create the FreeSWITCH configuration file for mod_skypopen (skypopen.conf.xml)\n"); -printf("I need to know where to put it, eg: where is the FreeSWITCH modules' config dir\n"); -printf("To accept the default, just press Enter\n"); -$freeswitch_modules_config_dir = &promptUser("Enter the directory full path for FreeSWITCH modules' config files ", "$freeswitch_modules_config_dir"); -system("clear"); -printf("\n"); -printf("I'm about to create the directory where to put our fake sound driver\n"); -printf("Location of fake sound driver directory is where you like it more :)\n"); -printf("To accept the default, just press Enter\n"); -$skypopen_sound_driver_dir = &promptUser("Enter the directory full path for fake sound driver ", "$skypopen_sound_driver_dir"); -system("clear"); -printf("\n"); -printf("I'm about to create the configuration directory needed by the Skype clients\n"); -printf("Location of Skype clients configuration directory is where you like it more :)\n"); -printf("To accept the default, just press Enter\n"); -$skype_config_dir = &promptUser("Enter the directory full path for Skype clients config ", "$skype_config_dir"); -system("clear"); -printf("\n"); -printf("I'm about to create a directory where I'll put the Skype clients startup script\n"); -printf("Location of Skype clients startup script directory is where you like it more :)\n"); -printf("To accept the default, just press Enter\n"); -$skype_startup_dir = &promptUser("Enter the directory full path for Skype clients startup script ", "$skype_startup_dir"); -system("clear"); -printf("\n"); -printf("I'm about to create the directory for symlinks needed by the Skype clients startup script\n"); -printf("Location of symlinks directory is where you like it more :)\n"); -printf("To accept the default, just press Enter\n"); -$skype_symlinks_dir = &promptUser("Enter the directory full path for Skype clients symlinks ", "$skype_symlinks_dir"); -system("clear"); -printf("\n"); -printf("How many Skype clients (channels) do you want to launch?\n"); -printf("Each Skype client will be one channel to FreeSWITCH and use approx 70MB of ram\n"); -printf("A quad core CPU can very easily support 20 or more Skype clients\n"); -printf("Each Skype client allows one concurrent call\n"); -printf("Eg: if you plan to have a max of 10 concurrent (outbound and/or inbound) Skype calls then enter 10\n"); -printf("To accept the default, just press Enter\n"); -$skype_clients_to_be_launched = &promptUser("Enter how many Skype clients will be launched ", "$skype_clients_to_be_launched"); -system("clear"); -printf("\n"); - - -while(1){ - printf("You want all of the Skype clients to use the same Skype login (skypeusername)?\n"); - printf("eg: you want all of your skypopen channels to be Bob on the Skype network, or you want channel skype01 to be Bob, channel skype02 to be Alice, etc?\n"); - printf("Please answer 'one' for all channels using the same Skype login (you'll be asked just one time for Skype login and password) or 'multi' for being asked for each channel\n"); - printf("\n"); - $multi_skypeusername = &promptUser("Enter 'one' or 'multi' ", "$multi_skypeusername"); - system("clear"); - printf("\n"); - if($multi_skypeusername eq "one" or $multi_skypeusername eq "multi"){ - last; - } -} - - -if($multi_skypeusername eq "one"){ - printf("I need the Skype username which will be used by ALL the Skype clients to be launched\n"); - printf("(That's the one-word you registered as login to the Skype network)\n"); - printf("This installer will create the needed files to launch concurrently many (or one) instances of it\n"); - printf("\n"); - printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); - $skype_username = &promptUser("Enter the Skype clients username ", "$skype_username"); - for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ - $skype_username_array[$count] = $skype_username; - } - system("clear"); - printf("\n"); - printf("I need the Skype password which will be used by ALL the Skype clients to be launched\n"); - printf("(That's the one-word you registered as password to the Skype network)\n"); - printf("\n"); - printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); - $skype_password = &promptUser("Enter the Skype clients password ", "$skype_password"); - for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ - $skype_password_array[$count] = $skype_password; - } - system("clear"); -} else { - for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ - $skype_client_extension = $skype_clients_starting_number + $count ; - printf("I need the Skype username which will be used by the Skype client for channel 'skype$skype_client_extension'\n"); - printf("(That's the one-word you registered as login to the Skype network)\n"); - printf("\n"); - printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); - $skype_username = &promptUser("Enter the Skype username for channel 'skype$skype_client_extension'", "$skype_username"); - $skype_username_array[$count] = $skype_username; - system("clear"); - printf("\n"); - printf("I need the Skype password which will be used by the Skype client 'skype$skype_client_extension'\n"); - printf("(That's the one-word you registered as password to the Skype network)\n"); - printf("\n"); - printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); - $skype_password = &promptUser("Enter the Skype password for '$skype_username'", "$skype_password"); - $skype_password_array[$count] = $skype_password; - system("clear"); - } - -} - -### GETTING FINAL APPROVAL ### -printf("\n"); -printf("Please check the following values:\n"); -printf("\n"); -printf("directory for downloading and unpacking Skype client:\n'$skype_download_dir'\n"); -printf("directory for Skype client binary:\n'$skype_binary_dir'\n"); -printf("directory for FreeSWITCH modules' configs:\n'$freeswitch_modules_config_dir'\n"); -printf("directory for fake sound driver:\n'$skypopen_sound_driver_dir'\n"); -printf("directory for Skype clients configs:\n'$skype_config_dir'\n"); -printf("directory for Skype clients startup script:\n'$skype_startup_dir'\n"); -printf("directory for Skype clients symlinks:\n'$skype_symlinks_dir'\n"); -printf("how many Skype clients to launch: '$skype_clients_to_be_launched'\n"); -if($multi_skypeusername eq "one"){ - printf("Skype login: '$skype_username'\n"); - printf("Skype password: '$skype_password'\n"); -}else { - for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ - $skype_client_extension = $skype_clients_starting_number + $count ; - printf("channel='skype$skype_client_extension' Skype login='$skype_username_array[$count]' Skype password='$skype_password_array[$count]'\n"); - } -} - -$sure = &promptUser("Are you sure you like the values? Write 'sure' for yes ", "$sure"); -if($sure ne "sure"){ - printf("No problem, please relaunch the installer and begin again\n"); - exit 0; -} -system("clear"); - -printf("\n"); -printf("GREAT! Please stand back, I'm working...\n"); -printf("\n"); - -#### EXECUTION ### - -system("mkdir -p $skype_download_dir"); -system("cd $skype_download_dir ; wget -c $skype_download_url"); -system("cd $skype_download_dir ; tar -xjf $skype_download_pkg"); - -system("mkdir -p $skype_binary_dir"); -system("cd $skype_download_dir/$skype_unpacked_dir ; cp skype $skype_binary_dir/"); - -system("mkdir -p $skype_share_dir"); -system("cd $skype_download_dir/$skype_unpacked_dir ; cp -a avatars $skype_share_dir/"); -system("cd $skype_download_dir/$skype_unpacked_dir ; cp -a sounds $skype_share_dir/"); -system("cd $skype_download_dir/$skype_unpacked_dir ; cp -a lang $skype_share_dir/"); -system("cd $skype_download_dir/$skype_unpacked_dir ; cp -a icons $skype_share_dir/"); - - -system("mkdir -p $skype_config_dir"); -system("mkdir -p $skype_startup_dir"); -system("mkdir -p $skype_symlinks_dir"); - -system("echo \"\" > $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); - - -system("echo \"#!/bin/sh\" > $skype_startup_dir/start_skype_clients.sh"); -system("echo >> $skype_startup_dir/start_skype_clients.sh"); -system("echo >> $skype_startup_dir/start_skype_clients.sh"); - - -for ($count = 1; $count <= $skype_clients_to_be_launched; $count++) { - $skype_client_extension = $skype_clients_starting_number + $count ; - $skype_login=$skype_username_array[$count]; - $skype_passwd=$skype_password_array[$count]; - system("ln -s $skype_binary_dir/skype $skype_symlinks_dir/skype$skype_client_extension"); - system("mkdir -p $skype_config_dir/skype$skype_client_extension"); - system("cp -a ../configs/skype-client-configuration-dir-template/skypeclient01/shared.* $skype_config_dir/skype$skype_client_extension"); - system("cp -a ../configs/skype-client-configuration-dir-template/skypeclient01/skypenameA $skype_config_dir/skype$skype_client_extension/$skype_login"); - - system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); - if($multi_skypeusername ne "one"){ - system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); - } - system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); - system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); - - system("echo \"#start the fake X server on the given port\" >> $skype_startup_dir/start_skype_clients.sh"); - system("echo \"/usr/bin/Xvfb :$skype_client_extension -ac -nolisten tcp -screen 0 640x480x8 &\" >> $skype_startup_dir/start_skype_clients.sh"); - system("echo \"sleep 3\" >> $skype_startup_dir/start_skype_clients.sh"); - system("echo \"# start a Skype client instance that will connect to the X server above, and will login to the Skype network using the 'username password' you send to it on stdin.\" >> $skype_startup_dir/start_skype_clients.sh"); - system("echo \"su root -c \\\"/bin/echo '$skype_login $skype_passwd'| DISPLAY=:$skype_client_extension $skype_symlinks_dir/skype$skype_client_extension --dbpath=$skype_config_dir/skype$skype_client_extension --pipelogin &\\\"\" >> $skype_startup_dir/start_skype_clients.sh"); - system("echo \"sleep 7\" >> $skype_startup_dir/start_skype_clients.sh"); - system("echo >> $skype_startup_dir/start_skype_clients.sh"); -} - -system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); -system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); - -system("echo \"exit 0\" >> $skype_startup_dir/start_skype_clients.sh"); - - -printf("\n"); -printf("SUCCESS!!!\n"); -printf("\n"); - - -#=========================================================================# - - -#-------------------------------------------------------------------------# -# promptUser, a Perl subroutine to prompt a user for input. -# Copyright 2010 Alvin Alexander, devdaily.com. -# This code is shared here under the -# Creative Commons Attribution-ShareAlike Unported 3.0 license. -# See http://creativecommons.org/licenses/by-sa/3.0/ for more information. -#-------------------------------------------------------------------------# - -# Original at: http://www.devdaily.com/perl/edu/articles/pl010005 -# Modified to get confirmations by Giovanni Maruzzelli - -#----------------------------( promptUser )-----------------------------# -# # -# FUNCTION: promptUser # -# # -# PURPOSE: Prompt the user for some type of input, and return the # -# input back to the calling program. # -# # -# ARGS: $promptString - what you want to prompt the user with # -# $defaultValue - (optional) a default value for the prompt # -# # -#-------------------------------------------------------------------------# - -sub promptUser { - -#-------------------------------------------------------------------# -# two possible input arguments - $promptString, and $defaultValue # -# make the input arguments local variables. # -#-------------------------------------------------------------------# - - local($promptString,$defaultValue) = @_; - local $input; - local $confirm; - local $gave; - -#-------------------------------------------------------------------# -# if there is a default value, use the first print statement; if # -# no default is provided, print the second string. # -#-------------------------------------------------------------------# - - while(1){ - printf("\n"); - if ($defaultValue) { - print $promptString, "\n[", $defaultValue, "]: "; - } else { - print $promptString, ": "; - } - - $| = 1; # force a flush after our print - $input = ; # get the input from STDIN (presumably the keyboard) - - -#------------------------------------------------------------------# -# remove the newline character from the end of the input the user # -# gave us. # -#------------------------------------------------------------------# - - chomp($input); - - $gave = $input ? $input : $defaultValue; - print("You gave: '$gave'\nIt's OK? Please answer 'Y' for yes or 'N' for not [N]: "); - $| = 1; # force a flush after our print - $confirm = ; - chomp($confirm); - if($confirm eq "Y" or $confirm eq "y"){ - last; - } - } -#-----------------------------------------------------------------# -# if we had a $default value, and the user gave us input, then # -# return the input; if we had a default, and they gave us no # -# no input, return the $defaultValue. # -# # -# if we did not have a default value, then just return whatever # -# the user gave us. if they just hit the key, # -# the calling routine will have to deal with that. # -#-----------------------------------------------------------------# - - if ("$defaultValue") { - return $input ? $input : $defaultValue; # return $_ if it has a value - } else { - return $input; - } -} - diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.2015.vcxproj b/src/mod/endpoints/mod_skypopen/mod_skypopen.2015.vcxproj deleted file mode 100644 index bb8fd5eda9..0000000000 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.2015.vcxproj +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_skypopen - {C6E78A4C-DB1E-47F4-9B63-4DC27D86343F} - mod_skypopen - Win32Proj - - - - DynamicLibrary - MultiByte - v140 - - - DynamicLibrary - MultiByte - v140 - - - DynamicLibrary - MultiByte - v140 - - - DynamicLibrary - MultiByte - v140 - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - %(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - - - Level4 - false - 28252;28253;4456;6031;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - rpcrt4.lib "..\..\..\..\libs\spandsp\src\Win32\Debug\libtiff.lib" "..\..\..\..\Win32\Debug\libspandsp.lib" %(AdditionalOptions) - false - - - - - - - %(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - - - Level4 - false - 28183;28252;28253;4456;6031;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - rpcrt4.lib "..\..\..\..\libs\spandsp\src\x64\Debug\libtiff.lib" "..\..\..\..\x64\Debug\libspandsp.lib" %(AdditionalOptions) - false - - - - - - - %(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - - - 28252;28253;4456;6031;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - rpcrt4.lib "..\..\..\..\libs\spandsp\src\Win32\Release\libtiff.lib" "..\..\..\..\Win32\Release\libspandsp.lib" %(AdditionalOptions) - false - - - - - - - %(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - - - 28252;28253;4456;6031;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - rpcrt4.lib "..\..\..\..\libs\spandsp\src\x64\Release\libtiff.lib" "..\..\..\..\x64\Release\libspandsp.lib" %(AdditionalOptions) - false - - - - - - - - - - - - - - - - - 4305;4306;28193;4244;4267;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - 4305;4306;28193;4244;4267;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - 4305;4306;28193;4244;4267;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - 4305;4306;28193;4244;4267;4324;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - - - - - - - - - - - - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - - - - \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c deleted file mode 100644 index ccfcc0d567..0000000000 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ /dev/null @@ -1,3403 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli - * - * Maintainer: Giovanni Maruzzelli - * - * mod_skypopen.c -- Skype compatible Endpoint Module - * - */ - - -#include "skypopen.h" -#define SKYPE_CHAT_PROTO "skype" - -#ifdef WIN32 -/***************/ -// from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/ - -#include - -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else /* */ -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif /* */ -struct sk_timezone { - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; -int gettimeofday(struct timeval *tv, struct sk_timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - if (NULL != tv) { - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch */ - tmpres /= 10; /*convert into microseconds */ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long) (tmpres / 1000000UL); - tv->tv_usec = (long) (tmpres % 1000000UL); - } - if (NULL != tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - return 0; -} - -/***************/ -#endif /* WIN32 */ -SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypopen_shutdown); -SWITCH_MODULE_DEFINITION(mod_skypopen, mod_skypopen_load, mod_skypopen_shutdown, NULL); -SWITCH_STANDARD_API(sk_function); -/* BEGIN: Changes here */ -#define SK_SYNTAX "list [full] || console || skype_API_msg || remove < skypeusername | #interface_name | #interface_id > || reload" -/* END: Changes heres */ -SWITCH_STANDARD_API(skypopen_function); -#define SKYPOPEN_SYNTAX "interface_name skype_API_msg" - -SWITCH_STANDARD_API(skypopen_chat_function); -#define SKYPOPEN_CHAT_SYNTAX "interface_name remote_skypename TEXT" -#define FULL_RELOAD 0 -#define SOFT_RELOAD 1 - -char *interface_status[] = { /* should match SKYPOPEN_STATE_xxx in skypopen.h */ - "IDLE", - "DOWN", - "RING", - "DIALING", - "BUSY", - "UP", - "RINGING", - "PRERING", - "DOUBLE", - "SELECTD", - "HANG_RQ", - "PREANSW", - "DEAD" -}; - -char *skype_callflow[] = { /* should match CALLFLOW_XXX in skypopen.h */ - "IDLE", - "DOWN", - "INC_RNG", - "CALL_DIALING", - "CALL_LINEBUSY", - "CALL_ACTIVE", - "INC_HNG", - "CALL_RLEASD", - "CALL_NOCARR", - "CALL_INFLUX", - "CALL_INCOMING", - "CALL_FAILED", - "CALL_NOSRVC", - "CALL_OUTRESTR", - "CALL_SECFAIL", - "CALL_NOANSWER", - "FNSHED", - "CANCLED", - "FAILED", - "REFUSED", - "RINGING", - "INPROGRS", - "UNPLACD", - "ROUTING", - "EARLYMD", - "INC_CLID", - "RMTEHOLD" -}; - - -static struct { - int debug; - char *context; - char *dialplan; - char *destination; - char *skype_user; - char *report_incoming_chatmessages; - char *silent_mode; - char *write_silence_when_idle; - char *setsockopt; - int calls; - int real_interfaces; - int next_interface; - private_t SKYPOPEN_INTERFACES[SKYPOPEN_MAX_INTERFACES]; - switch_mutex_t *mutex; - private_t *sk_console; - int start_port; - - // CLOUDTREE (THomas Hazel) - switch_mutex_t *list_mutex; - -} globals; - -switch_endpoint_interface_t *skypopen_endpoint_interface; -switch_memory_pool_t *skypopen_module_pool = NULL; -int running = 0; - -// CLOUDTREE (THomas Hazel) -#ifndef WIN32 -struct SkypopenList global_handles_list; -extern int xio_error_handler(Display * dpy); -extern int X11_errors_handler(Display * dpy, XErrorEvent * err); -extern int xio_error_handler2(Display * dpy, XErrorEvent * err); -#endif - -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_destination, globals.destination); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_skype_user, globals.skype_user); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_report_incoming_chatmessages, globals.report_incoming_chatmessages); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_silent_mode, globals.silent_mode); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_write_silence_when_idle, globals.write_silence_when_idle); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_setsockopt, globals.setsockopt); - -static switch_status_t interface_exists(char *the_interface); -/* CLOUDTREE (Thomas Hazel) static*/ switch_status_t remove_interface(char *the_interface, /* CLOUDTREE (Thomas Hazel */ switch_bool_t force); - -static switch_status_t channel_on_init(switch_core_session_t *session); -static switch_status_t channel_on_hangup(switch_core_session_t *session); -//static switch_status_t channel_on_reset(switch_core_session_t *session); -static switch_status_t channel_on_destroy(switch_core_session_t *session); -static switch_status_t channel_on_routing(switch_core_session_t *session); -static switch_status_t channel_on_exchange_media(switch_core_session_t *session); -static switch_status_t channel_on_consume_media(switch_core_session_t *session); -static switch_status_t channel_on_soft_execute(switch_core_session_t *session); -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause); -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); -static switch_status_t skypopen_tech_init(private_t *tech_pvt, switch_core_session_t *session); - -static switch_status_t skypopen_codec(private_t *tech_pvt, int sample_rate, int codec_ms) -{ - switch_core_session_t *session = NULL; - - if (switch_core_codec_init - (&tech_pvt->read_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - ERRORA("skypopen_codec: Can't load codec?\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - if (switch_core_codec_init - (&tech_pvt->write_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - ERRORA("skypopen_codec: Can't load codec?\n", SKYPOPEN_P_LOG); - switch_core_codec_destroy(&tech_pvt->read_codec); - return SWITCH_STATUS_FALSE; - } - - tech_pvt->read_frame.rate = sample_rate; - tech_pvt->read_frame.codec = &tech_pvt->read_codec; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - - if (session) { - switch_core_session_set_read_codec(session, &tech_pvt->read_codec); - switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - switch_core_session_rwunlock(session); - } else { - ERRORA("skypopen_codec: no session\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - DEBUGA_SKYPE("codecs UP\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t skypopen_tech_init(private_t *tech_pvt, switch_core_session_t *session) -{ - - switch_assert(tech_pvt != NULL); - switch_assert(session != NULL); - tech_pvt->read_frame.data = tech_pvt->databuf; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); - switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_core_session_set_private(session, tech_pvt); - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str)); - if (!strlen(tech_pvt->session_uuid_str)) { - ERRORA("skypopen_tech_init: no tech_pvt->session_uuid_str\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - if (skypopen_codec(tech_pvt, SAMPLERATE_SKYPOPEN, MS_SKYPOPEN) != SWITCH_STATUS_SUCCESS) { - ERRORA("skypopen_tech_init: skypopen_codec FAILED\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - dtmf_rx_init(&tech_pvt->dtmf_state, NULL, NULL); - dtmf_rx_parms(&tech_pvt->dtmf_state, 0, 10, 10, -99); - - - DEBUGA_SKYPE("skypopen_tech_init SUCCESS\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t interface_exists(char *the_interface) -{ - int i; - int interface_id; - - if (*the_interface == '#') { /* look by interface id or interface name */ - the_interface++; - switch_assert(the_interface); - interface_id = atoi(the_interface); - - /* take a number as interface id */ - if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) { - if (strlen(globals.SKYPOPEN_INTERFACES[interface_id].name)) { - return SWITCH_STATUS_SUCCESS; - } - } else { - /* interface name */ - for (interface_id = 0; interface_id < SKYPOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.SKYPOPEN_INTERFACES[interface_id].name, the_interface) == 0) { - return SWITCH_STATUS_SUCCESS; - break; - } - } - } - } else { /* look by skype_user */ - - - for (i = 0; i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].skype_user)) { - if (strcmp(globals.SKYPOPEN_INTERFACES[i].skype_user, the_interface) == 0) { - return SWITCH_STATUS_SUCCESS; - } - } - } - } - return SWITCH_STATUS_FALSE; -} - -/* CLOUDTREE (Thomas Hazel) static */ switch_status_t remove_interface(char *the_interface, /* CLOUDTREE (Thomas Hazel) */ switch_bool_t force) -{ - int x = 10; - switch_size_t howmany = 8; - int interface_id = -1; - private_t *tech_pvt = NULL; - switch_status_t status; - - - if (*the_interface == '#') { /* remove by interface id or interface name */ - the_interface++; - switch_assert(the_interface); - interface_id = atoi(the_interface); - - if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) { - /* take a number as interface id */ - tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id]; - } else { - - for (interface_id = 0; interface_id < SKYPOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.SKYPOPEN_INTERFACES[interface_id].name, the_interface) == 0) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id]; - break; - } - } - } - } else { /* remove by skype_user */ - for (interface_id = 0; interface_id < SKYPOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.SKYPOPEN_INTERFACES[interface_id].skype_user, the_interface) == 0) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id]; - break; - } - } - } - - if (!tech_pvt) { - DEBUGA_SKYPE("interface '%s' does not exist\n", SKYPOPEN_P_LOG, the_interface); - goto end; - } - - if ( /* CLOUDTREE (Thomas Hazel) */ (force == FALSE) && strlen(globals.SKYPOPEN_INTERFACES[interface_id].session_uuid_str)) { - DEBUGA_SKYPE("interface '%s' is busy\n", SKYPOPEN_P_LOG, the_interface); - goto end; - } - - globals.SKYPOPEN_INTERFACES[interface_id].running = 0; - - tech_pvt->interface_state = SKYPOPEN_STATE_DEAD; - - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread) { -#ifdef WIN32 - skypopen_signaling_write(tech_pvt, "DIE"); - switch_sleep(20000); - switch_file_write(tech_pvt->SkypopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die -#else /* WIN32 */ - howmany = write(tech_pvt->SkypopenHandles.fdesc[1], "sciutati", howmany); -#endif /* WIN32 */ - } - - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread) { -#ifdef WIN32 - if (SendMessage(tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) { // let's the skypopen_api_thread_func die - DEBUGA_SKYPE("got FALSE here, thread probably was already dead. GetLastError returned: %d\n", SKYPOPEN_P_LOG, GetLastError()); - globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread = NULL; - } -#else - if (tech_pvt->running && tech_pvt->SkypopenHandles.disp) { - XEvent e; - Atom atom1 = XInternAtom(tech_pvt->SkypopenHandles.disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False); - switch_sleep(20000); - XFlush(tech_pvt->SkypopenHandles.disp); - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.message_type = atom1; /* leading message */ - e.xclient.display = tech_pvt->SkypopenHandles.disp; - e.xclient.window = tech_pvt->SkypopenHandles.skype_win; - e.xclient.format = 8; - - XSendEvent(tech_pvt->SkypopenHandles.disp, tech_pvt->SkypopenHandles.win, False, 0, &e); - XFlush(tech_pvt->SkypopenHandles.disp); - } -#endif - } - - while (x) { - x--; - switch_yield(50000); - } - -#ifndef WIN32 - if (tech_pvt->SkypopenHandles.disp) { - } -#endif - - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread) { - switch_thread_join(&status, globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread); - } - - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread) { - switch_thread_join(&status, globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread); - } - - switch_mutex_lock(globals.mutex); - if (globals.sk_console == &globals.SKYPOPEN_INTERFACES[interface_id]) { - DEBUGA_SKYPE("interface '%s' no more console\n", SKYPOPEN_P_LOG, the_interface); - globals.sk_console = NULL; - } else { - DEBUGA_SKYPE("interface '%s' STILL console\n", SKYPOPEN_P_LOG, the_interface); - } - if (strlen(tech_pvt->session_uuid_str)) { - - } else { - memset(&globals.SKYPOPEN_INTERFACES[interface_id], '\0', sizeof(private_t)); - } - globals.real_interfaces--; - switch_mutex_unlock(globals.mutex); - - DEBUGA_SKYPE("interface '%s' deleted successfully\n", SKYPOPEN_P_LOG, the_interface); - globals.SKYPOPEN_INTERFACES[interface_id].running = 1; - end: - return SWITCH_STATUS_SUCCESS; -} - - -/* - State methods they get called when the state changes to the specific state - returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next - so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. -*/ -static switch_status_t channel_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt = NULL; - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - memset(tech_pvt->skype_voicemail_id, '\0', sizeof(tech_pvt->skype_voicemail_id)); - memset(tech_pvt->skype_voicemail_id_greeting, '\0', sizeof(tech_pvt->skype_voicemail_id_greeting)); - switch_channel_set_variable(channel, "skype_user", tech_pvt->skype_user); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_IO); - switch_mutex_unlock(tech_pvt->flag_mutex); - - DEBUGA_SKYPE("%s CHANNEL INIT %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_destroy(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - switch_status_t status; - int conta; - - tech_pvt = switch_core_session_get_private(session); - - - if (tech_pvt) { - DEBUGA_SKYPE("%s CHANNEL DESTROY %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - if (tech_pvt->interface_state != SKYPOPEN_STATE_DEAD) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - } - switch_mutex_unlock(tech_pvt->flag_mutex); - - DEBUGA_SKYPE("audio tcp threads to DIE\n", SKYPOPEN_P_LOG); - conta = 0; - while (tech_pvt->tcp_srv_thread) { - switch_sleep(50000); - conta++; - if (conta == 20) { - ERRORA("tcp_srv_thread is NOT dead, this can LEAK MEMORY\n", SKYPOPEN_P_LOG); - break; - } - } - DEBUGA_SKYPE("audio tcp srv thread DEAD %d\n", SKYPOPEN_P_LOG, conta); - conta = 0; - while (tech_pvt->tcp_cli_thread) { - switch_sleep(50000); - conta++; - if (conta == 20) { - ERRORA("tcp_cli_thread is NOT dead, this can LEAK MEMORY\n", SKYPOPEN_P_LOG); - break; - } - } - DEBUGA_SKYPE("audio tcp cli thread DEAD %d\n", SKYPOPEN_P_LOG, conta); - - - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - DEBUGA_SKYPE("codecs DOWN\n", SKYPOPEN_P_LOG); - if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { - switch_core_timer_destroy(&tech_pvt->timer_read); - } - - if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { - switch_core_timer_destroy(&tech_pvt->timer_read_srv); - } - - if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { - switch_core_timer_destroy(&tech_pvt->timer_write); - } - - if (tech_pvt->read_buffer) { - switch_buffer_destroy(&tech_pvt->read_buffer); - } - if (tech_pvt->write_buffer) { - switch_buffer_destroy(&tech_pvt->write_buffer); - } - //DEBUGA_SKYPE("debugging_hangup 13\n", SKYPOPEN_P_LOG); - switch_mutex_lock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli lock\n", SKYPOPEN_P_LOG); - if (tech_pvt->tcp_cli_thread) { - //DEBUGA_SKYPE("debugging_hangup 14\n", SKYPOPEN_P_LOG); - switch_thread_join(&status, tech_pvt->tcp_cli_thread); - tech_pvt->tcp_cli_thread = NULL; - //DEBUGA_SKYPE("debugging_hangup 15\n", SKYPOPEN_P_LOG); - } - switch_mutex_unlock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli unlock\n", SKYPOPEN_P_LOG); - switch_mutex_lock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv lock\n", SKYPOPEN_P_LOG); - if (tech_pvt->tcp_srv_thread) { - //DEBUGA_SKYPE("debugging_hangup 16\n", SKYPOPEN_P_LOG); - switch_thread_join(&status, tech_pvt->tcp_srv_thread); - tech_pvt->tcp_srv_thread = NULL; - //DEBUGA_SKYPE("debugging_hangup 17\n", SKYPOPEN_P_LOG); - } - switch_mutex_unlock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv unlock\n", SKYPOPEN_P_LOG); - //DEBUGA_SKYPE("debugging_hangup 18\n", SKYPOPEN_P_LOG); - - *tech_pvt->session_uuid_str = '\0'; - - if (tech_pvt->interface_state != SKYPOPEN_STATE_DEAD) { - tech_pvt->interface_state = SKYPOPEN_STATE_IDLE; - tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE; - } else { - memset(tech_pvt, '\0', sizeof(private_t)); - } - switch_core_session_set_private(session, NULL); - } else { - DEBUGA_SKYPE("!!!!!!NO tech_pvt!!!! CHANNEL DESTROY %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(session)); - } - - DEBUGA_SKYPE("CHANNEL DESTROYED %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(session)); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - char msg_to_skype[256]; - //switch_status_t status; - - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - - //DEBUGA_SKYPE("debugging_hangup 1\n", SKYPOPEN_P_LOG); - - if (tech_pvt) { - if (tech_pvt->interface_state == SKYPOPEN_STATE_DEAD) { - return SWITCH_STATUS_SUCCESS; - } - if (!switch_channel_test_flag(channel, CF_ANSWERED)) { - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - tech_pvt->ob_failed_calls++; - } else { - tech_pvt->ib_failed_calls++; - } - } - - tech_pvt->interface_state = SKYPOPEN_STATE_HANGUP_REQUESTED; - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - } - switch_mutex_unlock(tech_pvt->flag_mutex); - - - //DEBUGA_SKYPE("debugging_hangup 2\n", SKYPOPEN_P_LOG); - - if (strlen(tech_pvt->skype_call_id)) { - DEBUGA_SKYPE("hanging up skype call: %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id); - if(strlen(tech_pvt->skype_voicemail_id_greeting)){ - sprintf(msg_to_skype, "ALTER VOICEMAIL %s STOPPLAYBACK", tech_pvt->skype_voicemail_id_greeting); - skypopen_signaling_write(tech_pvt, msg_to_skype); - switch_sleep(MS_SKYPOPEN * 1000 * 100);//XXX FIXME 2000 millisecs, 2 seconds, so it will record at least 1 second - } - - if(strlen(tech_pvt->skype_voicemail_id_greeting)){ - sprintf(msg_to_skype, "ALTER VOICEMAIL %s DELETE", tech_pvt->skype_voicemail_id_greeting); - skypopen_signaling_write(tech_pvt, msg_to_skype); - switch_sleep(MS_SKYPOPEN * 1000 * 10);//XXX FIXME 200 millisecs - } - if(strlen(tech_pvt->skype_voicemail_id)){ - sprintf(msg_to_skype, "ALTER VOICEMAIL %s STOPRECORDING", tech_pvt->skype_voicemail_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - switch_sleep(MS_SKYPOPEN * 1000 * 10);//XXX FIXME 200 millisecs - } - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", tech_pvt->skype_call_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", tech_pvt->skype_call_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - DEBUGA_SKYPE("%s CHANNEL HANGUP\n", SKYPOPEN_P_LOG, tech_pvt->name); - switch_mutex_lock(globals.mutex); - globals.calls--; - if (globals.calls < 0) { - globals.calls = 0; - } - //DEBUGA_SKYPE("debugging_hangup 9\n", SKYPOPEN_P_LOG); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - if (tech_pvt->skype_callflow == CALLFLOW_STATUS_FINISHED) { - tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE; - } - //DEBUGA_SKYPE("debugging_hangup 10\n", SKYPOPEN_P_LOG); - switch_mutex_unlock(globals.mutex); - } else { - WARNINGA("FYI %s CHANNEL has no tech_pvt in his private\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - //DEBUGA_SKYPE("debugging_hangup 11\n", SKYPOPEN_P_LOG); - } - //DEBUGA_SKYPE("debugging_hangup 12\n", SKYPOPEN_P_LOG); - - //switch_channel_set_state(channel, CS_DESTROY); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_routing(switch_core_session_t *session) -{ - //switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - //channel = switch_core_session_get_channel(session); - //switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_SKYPE("%s CHANNEL ROUTING\n", SKYPOPEN_P_LOG, tech_pvt->name); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_execute(switch_core_session_t *session) -{ - - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_SKYPE("%s CHANNEL EXECUTE\n", SKYPOPEN_P_LOG, tech_pvt->name); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - - //DEBUGA_SKYPE("%s CHANNEL KILL_CHANNEL\n", SKYPOPEN_P_LOG, tech_pvt->name); - if (tech_pvt) { - switch (sig) { - case SWITCH_SIG_KILL: - DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_KILL\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - if (tech_pvt->interface_state == SKYPOPEN_STATE_DEAD) { - switch_channel_set_state(channel, CS_HANGUP); - return SWITCH_STATUS_SUCCESS; - } - tech_pvt->interface_state = SKYPOPEN_STATE_HANGUP_REQUESTED; - if (tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD) { - DEBUGA_SKYPE("FYI %s CHANNEL in CALLFLOW_STATUS_REMOTEHOLD got SWITCH_SIG_KILL\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - } - if (switch_channel_get_state(channel) == CS_NEW) { - WARNINGA("FYI %s CHANNEL in CS_NEW state got SWITCH_SIG_KILL\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - } - if (switch_channel_get_state(channel) != CS_NEW && switch_channel_get_state(channel) < CS_EXECUTE) { - WARNINGA("FYI %s CHANNEL in %d state got SWITCH_SIG_KILL\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel), - switch_channel_get_state(channel)); - } - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_HANGUP); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - } - switch_mutex_unlock(tech_pvt->flag_mutex); - break; - case SWITCH_SIG_BREAK: - DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_BREAK\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_BREAK); - switch_mutex_unlock(tech_pvt->flag_mutex); - break; - default: - break; - } - } else { - WARNINGA("FYI %s CHANNEL has no tech_pvt in his private\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_consume_media(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - - tech_pvt = switch_core_session_get_private(session); - - DEBUGA_SKYPE("%s CHANNEL CONSUME_MEDIA\n", SKYPOPEN_P_LOG, tech_pvt->name); - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t channel_on_exchange_media(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - tech_pvt = switch_core_session_get_private(session); - DEBUGA_SKYPE("%s CHANNEL EXCHANGE_MEDIA\n", SKYPOPEN_P_LOG, tech_pvt->name); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_soft_execute(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - tech_pvt = switch_core_session_get_private(session); - DEBUGA_SKYPE("%s CHANNEL SOFT_EXECUTE\n", SKYPOPEN_P_LOG, tech_pvt->name); - return SWITCH_STATUS_SUCCESS; -} - -#if 0 -static switch_status_t channel_on_reset(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - tech_pvt = switch_core_session_get_private(session); - DEBUGA_SKYPE("%s CHANNEL RESET\n", SKYPOPEN_P_LOG, tech_pvt->name); - - - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No session???\n", SKYPOPEN_P_LOG); - } - if (channel) { - switch_channel_set_state(channel, CS_HANGUP); - } else { - ERRORA("No channel???\n", SKYPOPEN_P_LOG); - } - - - return SWITCH_STATUS_SUCCESS; -} -#endif //0 - - -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - private_t *tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_SKYPE("%s CHANNEL SEND_DTMF\n", SKYPOPEN_P_LOG, tech_pvt->name); - DEBUGA_SKYPE("DTMF: %c\n", SKYPOPEN_P_LOG, dtmf->digit); - - skypopen_senddigit(tech_pvt, dtmf->digit); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - switch_byte_t *data; - char digit_str[256]; - short *frame_16_khz; - short frame_8_khz[160]; - unsigned int i; - unsigned int a; - size_t bytes_read = 0; - int try = 0; - - - *frame = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - tech_pvt->read_frame.flags = SFF_NONE; - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - switch_sleep(MS_SKYPOPEN * 1000); - return SWITCH_STATUS_FALSE; - } - if (!switch_channel_ready(channel)) { - ERRORA("channel not ready \n", SKYPOPEN_P_LOG); - switch_sleep(MS_SKYPOPEN * 1000); - return SWITCH_STATUS_FALSE; - } - - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - //DEBUGA_SKYPE("CHANNEL READ FRAME in TFLAG_PROGRESS goto CNG\n", SKYPOPEN_P_LOG); - //switch_sleep(MS_SKYPOPEN * 1000); - goto cng; - } - - if (!tech_pvt->read_buffer) { - int32_t max_len = BYTES_PER_FRAME * 10; - - switch_buffer_create(skypopen_module_pool, &tech_pvt->read_buffer, max_len); - switch_assert(tech_pvt->read_buffer); - switch_buffer_zero(tech_pvt->read_buffer); - tech_pvt->begin_to_read = 1; - } - - - - if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { - switch_core_timer_next(&tech_pvt->timer_read); - } - - try = 0; - read: - - - if (tech_pvt && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN - && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA - || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { - switch_mutex_lock(tech_pvt->mutex_audio_srv); - if (tech_pvt->read_buffer && switch_buffer_inuse(tech_pvt->read_buffer)) { - bytes_read = switch_buffer_read(tech_pvt->read_buffer, tech_pvt->read_frame.data, BYTES_PER_FRAME); - tech_pvt->read_frame.datalen = (uint32_t)bytes_read; - } - switch_mutex_unlock(tech_pvt->mutex_audio_srv); - - if (!bytes_read) { - switch_sleep(1000); //XXX don't like this - try++; - if (try < 5) { - //DEBUGA_SKYPE("skypopen_audio_read going back to read\n", SKYPOPEN_P_LOG); - goto read; - } - - if (!strlen(tech_pvt->skype_voicemail_id)) { - DEBUGA_SKYPE("READ BUFFER EMPTY, skypopen_audio_read Silence\n", SKYPOPEN_P_LOG); - } - memset(tech_pvt->read_frame.data, 255, BYTES_PER_FRAME); - tech_pvt->read_frame.datalen = BYTES_PER_FRAME; - - } - } else { - memset(tech_pvt->read_frame.data, 255, BYTES_PER_FRAME); - tech_pvt->read_frame.datalen = BYTES_PER_FRAME; - } - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_VOICE); - switch_mutex_unlock(tech_pvt->flag_mutex); - - while (switch_test_flag(tech_pvt, TFLAG_IO)) { - if (switch_test_flag(tech_pvt, TFLAG_BREAK)) { - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_BREAK); - switch_mutex_unlock(tech_pvt->flag_mutex); - DEBUGA_SKYPE("CHANNEL READ FRAME goto CNG\n", SKYPOPEN_P_LOG); - goto cng; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - DEBUGA_SKYPE("CHANNEL READ FRAME not IO\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_mutex_unlock(tech_pvt->flag_mutex); - if (!tech_pvt->read_frame.datalen) { - DEBUGA_SKYPE("CHANNEL READ CONTINUE\n", SKYPOPEN_P_LOG); - continue; - } - *frame = &tech_pvt->read_frame; - - - if (switch_true(switch_channel_get_variable(channel, "skype_get_inband_dtmf"))) { - - frame_16_khz = tech_pvt->read_frame.data; - - a = 0; - for (i = 0; i < tech_pvt->read_frame.datalen / sizeof(short); i++) { - frame_8_khz[a] = frame_16_khz[i]; - i++; - a++; - } - - memset(digit_str, 0, sizeof(digit_str)); - dtmf_rx(&tech_pvt->dtmf_state, (int16_t *) frame_8_khz, 160); - dtmf_rx_get(&tech_pvt->dtmf_state, digit_str, sizeof(digit_str)); - - - if (digit_str[0]) { - switch_time_t new_dtmf_timestamp = switch_time_now(); - if ((new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp) > 350000) { - char *p = digit_str; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (channel) { - - while (p && *p) { - switch_dtmf_t dtmf = { 0 }; - dtmf.digit = *p; - dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION; - switch_channel_queue_dtmf(channel, &dtmf); - p++; - } - NOTICA("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", SKYPOPEN_P_LOG, digit_str, - (unsigned int) new_dtmf_timestamp, (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp)); - tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp; - } else { - WARNINGA("NO CHANNEL ?\n", SKYPOPEN_P_LOG); - } - } - } - } -#if SWITCH_BYTE_ORDER == __BIG_ENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { - switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2); - } -#endif - return SWITCH_STATUS_SUCCESS; - } - DEBUGA_SKYPE("CHANNEL READ no TFLAG_IO\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - DEBUGA_SKYPE("CHANNEL READ FALSE\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - - cng: - data = (switch_byte_t *) tech_pvt->read_frame.data; - data[0] = 65; - data[1] = 0; - tech_pvt->read_frame.datalen = 2; - tech_pvt->read_frame.flags = SFF_CNG; - *frame = &tech_pvt->read_frame; - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - int no_space = 0; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - //DEBUGA_SKYPE("CHANNEL in TFLAG_PROGRESS\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_channel_ready(channel)) { - ERRORA("channel not ready \n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - DEBUGA_SKYPE("channel not in TFLAG_IO \n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } -#if SWITCH_BYTE_ORDER == __BIG_ENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { - switch_swap_linear(frame->data, (int) frame->datalen / 2); - } -#endif - if (!tech_pvt->write_buffer) { - int32_t max_len = BYTES_PER_FRAME * 4; - - switch_buffer_create(skypopen_module_pool, &tech_pvt->write_buffer, max_len); - switch_assert(tech_pvt->write_buffer); - } - - switch_mutex_lock(tech_pvt->mutex_audio_cli); - if (switch_buffer_freespace(tech_pvt->write_buffer) < frame->datalen) { - switch_buffer_zero(tech_pvt->write_buffer); - no_space = 1; - } - switch_buffer_write(tech_pvt->write_buffer, frame->data, frame->datalen); - switch_mutex_unlock(tech_pvt->mutex_audio_cli); - if (no_space && !strlen(tech_pvt->skype_voicemail_id)) { - //switch_sleep(MS_SKYPOPEN * 1000); - DEBUGA_SKYPE("NO SPACE in WRITE BUFFER: there was no space for %d\n", SKYPOPEN_P_LOG, frame->datalen); - } - tech_pvt->begin_to_write = 1; - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_answer_channel(switch_core_session_t *session) -{ - private_t *tech_pvt; - switch_channel_t *channel = NULL; - int conta = 0; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_mutex_unlock(tech_pvt->flag_mutex); - skypopen_answer(tech_pvt); - - while (!switch_test_flag(tech_pvt, TFLAG_IO)) { - if (switch_channel_get_state(channel) == CS_RESET) { - return SWITCH_STATUS_FALSE; - } - switch_sleep(50000); - conta++; - if (conta == 10) { //0.5 seconds - return SWITCH_STATUS_FALSE; - } - } - switch_mutex_lock(globals.mutex); - globals.calls++; - - switch_mutex_unlock(globals.mutex); - DEBUGA_SKYPE("%s CHANNEL ANSWER %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - - - - DEBUGA_SKYPE("ANSWERED! \n", SKYPOPEN_P_LOG); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - char msg_to_skype[256]; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_PROGRESS: - { - DEBUGA_SKYPE("%s CHANNEL got SWITCH_MESSAGE_INDICATE_PROGRESS\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_PROGRESS); - switch_mutex_unlock(tech_pvt->flag_mutex); - } - break; - case SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS: - { - DEBUGA_SKYPE("%s CHANNEL got SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", tech_pvt->ring_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", tech_pvt->ring_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", tech_pvt->skype_call_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", tech_pvt->skype_call_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - switch_mutex_unlock(tech_pvt->flag_mutex); - } - } - break; - - case SWITCH_MESSAGE_INDICATE_ANSWER: - { - DEBUGA_SKYPE("%s CHANNEL got SWITCH_MESSAGE_INDICATE_ANSWER\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - - channel_answer_channel(session); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - switch_mutex_unlock(tech_pvt->flag_mutex); - - if (tech_pvt->read_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_srv); - switch_buffer_zero(tech_pvt->read_buffer); - if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read); - } - if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read_srv); - } - switch_mutex_unlock(tech_pvt->mutex_audio_srv); - } - - if (tech_pvt->write_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_cli); - switch_buffer_zero(tech_pvt->write_buffer); - if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_write); - } - switch_mutex_unlock(tech_pvt->mutex_audio_cli); - } - DEBUGA_SKYPE("Synching audio\n", SKYPOPEN_P_LOG); - - } - break; - case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: - - DEBUGA_SKYPE("%s CHANNEL got SWITCH_MESSAGE_INDICATE_AUDIO_SYNC\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - - if (tech_pvt->read_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_srv); - switch_buffer_zero(tech_pvt->read_buffer); - if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read); - } - if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read_srv); - } - switch_mutex_unlock(tech_pvt->mutex_audio_srv); - } - - if (tech_pvt->write_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_cli); - switch_buffer_zero(tech_pvt->write_buffer); - if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_write); - } - switch_mutex_unlock(tech_pvt->mutex_audio_cli); - } - DEBUGA_SKYPE("Synching audio\n", SKYPOPEN_P_LOG); - break; - case SWITCH_MESSAGE_INDICATE_BRIDGE: - DEBUGA_SKYPE("%s CHANNEL got SWITCH_MESSAGE_INDICATE_BRIDGE\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel)); - - if (tech_pvt->read_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_srv); - switch_buffer_zero(tech_pvt->read_buffer); - if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read); - } - if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read_srv); - } - switch_mutex_unlock(tech_pvt->mutex_audio_srv); - } - - if (tech_pvt->write_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_cli); - switch_buffer_zero(tech_pvt->write_buffer); - if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_write); - } - switch_mutex_unlock(tech_pvt->mutex_audio_cli); - } - DEBUGA_SKYPE("Synching audio\n", SKYPOPEN_P_LOG); - break; - - default: - { - - DEBUGA_SKYPE("MSG_ID=%d\n", SKYPOPEN_P_LOG, msg->message_id); - } - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event) -{ - struct private_object *tech_pvt = switch_core_session_get_private(session); - char *body = switch_event_get_body(event); - switch_assert(tech_pvt != NULL); - - if (!body) { - body = ""; - } - - WARNINGA("event: |||%s|||\n", SKYPOPEN_P_LOG, body); - - return SWITCH_STATUS_SUCCESS; -} - -switch_state_handler_table_t skypopen_state_handlers = { - /*.on_init */ channel_on_init, - /*.on_routing */ channel_on_routing, - /*.on_execute */ channel_on_execute, - /*.on_hangup */ channel_on_hangup, - /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute, - /*.on_consume_media */ channel_on_consume_media, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ channel_on_destroy -}; - -switch_io_routines_t skypopen_io_routines = { - /*.outgoing_channel */ channel_outgoing_channel, - /*.read_frame */ channel_read_frame, - /*.write_frame */ channel_write_frame, - /*.kill_channel */ channel_kill_channel, - /*.send_dtmf */ channel_send_dtmf, - /*.receive_message */ channel_receive_message, - /*.receive_event */ channel_receive_event -}; - -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause) -{ - private_t *tech_pvt = NULL; - if ((*new_session = switch_core_session_request_uuid(skypopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid"))) != 0) { - switch_channel_t *channel = NULL; - switch_caller_profile_t *caller_profile; - char *rdest; - int found = 0; - char interface_name[256]; - - DEBUGA_SKYPE("1 SESSION_REQUEST %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_add_stream(*new_session, NULL); - - - if (!zstr(outbound_profile->destination_number)) { - int i; - char *slash; - - switch_copy_string(interface_name, outbound_profile->destination_number, 255); - slash = strrchr(interface_name, '/'); - if(slash != NULL){ - *slash = '\0'; - } - - switch_mutex_lock(globals.mutex); - if (strncmp("ANY", interface_name, strlen(interface_name)) == 0 || strncmp("RR", interface_name, strlen(interface_name)) == 0) { - /* Find the first idle interface using Round Robin */ - DEBUGA_SKYPE("Finding one available skype interface RR\n", SKYPOPEN_P_LOG); - tech_pvt = find_available_skypopen_interface_rr(NULL); - if (tech_pvt) - found = 1; - } - - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.SKYPOPEN_INTERFACES[i].name) - && (strncmp(globals.SKYPOPEN_INTERFACES[i].name, interface_name, strlen(interface_name)) == 0)) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].session_uuid_str)) { - DEBUGA_SKYPE - ("globals.SKYPOPEN_INTERFACES[%d].name=|||%s||| session_uuid_str=|||%s||| is BUSY\n", - SKYPOPEN_P_LOG, i, globals.SKYPOPEN_INTERFACES[i].name, globals.SKYPOPEN_INTERFACES[i].session_uuid_str); - DEBUGA_SKYPE("1 SESSION_DESTROY %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - DEBUGA_SKYPE("globals.SKYPOPEN_INTERFACES[%d].name=|||%s|||?\n", SKYPOPEN_P_LOG, i, globals.SKYPOPEN_INTERFACES[i].name); - tech_pvt = &globals.SKYPOPEN_INTERFACES[i]; - found = 1; - break; - } - - } - - } else { - ERRORA("Doh! no destination number?\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(new_session); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (!found) { - DEBUGA_SKYPE("Doh! no available interface for |||%s|||?\n", SKYPOPEN_P_LOG, interface_name); - DEBUGA_SKYPE("2 SESSION_DESTROY %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - channel = switch_core_session_get_channel(*new_session); - if (!channel) { - ERRORA("Doh! no channel?\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - switch_channel_set_variable(channel, "waste", "false"); - if (skypopen_tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Doh! no tech_init?\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - - if (outbound_profile) { - char name[128]; - - if (strncmp("ANY", outbound_profile->destination_number, 3) == 0) { - snprintf(name, sizeof(name), "skypopen/%s%s", tech_pvt->name, outbound_profile->destination_number + 3); - } else if (strncmp("RR", outbound_profile->destination_number, 2) == 0) { - snprintf(name, sizeof(name), "skypopen/%s%s", tech_pvt->name, outbound_profile->destination_number + 2); - } else { - snprintf(name, sizeof(name), "skypopen/%s", outbound_profile->destination_number); - } - - switch_channel_set_name(channel, name); - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - } else { - ERRORA("Doh! no caller profile\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - - rdest = strchr(caller_profile->destination_number, '/'); - *rdest++ = '\0'; - - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt->session_uuid_str)); - caller_profile = tech_pvt->caller_profile; - caller_profile->destination_number = rdest; - - switch_mutex_lock(tech_pvt->flag_mutex); - tech_pvt->ob_calls++; - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); - switch_mutex_unlock(tech_pvt->flag_mutex); - switch_channel_set_state(channel, CS_INIT); - skypopen_call(tech_pvt, rdest, 30); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_SUCCESS; - } - - ERRORA("Doh! no new_session\n", SKYPOPEN_P_LOG); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; -} - -/*! - * \brief This thread runs during a call, and monitor the interface for signaling, like hangup, caller id, etc most of signaling is handled inside the skypopen_signaling_read function - * - */ -static void *SWITCH_THREAD_FUNC skypopen_signaling_thread_func(switch_thread_t *thread, void *obj) -{ - private_t *tech_pvt = obj; - int res; - int forever = 1; - switch_event_t *event; - - if (!tech_pvt) - return NULL; - - DEBUGA_SKYPE("In skypopen_signaling_thread_func: started, p=%p\n", SKYPOPEN_P_LOG, (void *) tech_pvt); - - while (forever) { - if (!(running && tech_pvt->running)) - break; - res = skypopen_signaling_read(tech_pvt); - - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INCOMING_RAW) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "X-Skype-Response-Code", "%d", res); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "X-Skype-Interface", "%s", tech_pvt->interface_id); - switch_event_add_body(event, "%s", tech_pvt->message); - switch_event_fire(&event); - } - - if (res == CALLFLOW_INCOMING_HANGUP || tech_pvt->skype_callflow == CALLFLOW_INCOMING_HANGUP) { - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - int conta; - - DEBUGA_SKYPE("skype call ended\n", SKYPOPEN_P_LOG); - - if (tech_pvt) { - if (tech_pvt->interface_state == SKYPOPEN_STATE_DEAD) { - break; - } - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - if (channel) { - switch_channel_state_t state = switch_channel_get_state(channel); - if (state < CS_EXECUTE) { - switch_sleep(20000); //20 msec, let the state evolve from CS_NEW - } - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - } else { - ERRORA("no channel?\n", SKYPOPEN_P_LOG); - } - switch_core_session_rwunlock(session); - } else { - DEBUGA_SKYPE("no session\n", SKYPOPEN_P_LOG); - - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - DEBUGA_SKYPE("audio tcp threads to DIE\n", SKYPOPEN_P_LOG); - conta = 0; - while (tech_pvt->tcp_srv_thread) { - switch_sleep(50000); - conta++; - if (conta == 20) { - ERRORA("tcp_srv_thread is NOT dead, this can LEAK MEMORY\n", SKYPOPEN_P_LOG); - break; - } - } - DEBUGA_SKYPE("audio tcp srv thread DEAD %d\n", SKYPOPEN_P_LOG, conta); - conta = 0; - while (tech_pvt->tcp_cli_thread) { - switch_sleep(50000); - conta++; - if (conta == 20) { - ERRORA("tcp_cli_thread is NOT dead, this can LEAK MEMORY\n", SKYPOPEN_P_LOG); - break; - } - } - DEBUGA_SKYPE("audio tcp cli thread DEAD %d\n", SKYPOPEN_P_LOG, conta); - } - switch_mutex_lock(globals.mutex); - tech_pvt->ringing_state = SKYPOPEN_RINGING_INIT; - *tech_pvt->session_uuid_str = '\0'; - *tech_pvt->initial_skype_user = '\0'; - *tech_pvt->answer_id = '\0'; - *tech_pvt->answer_value = '\0'; - *tech_pvt->ring_id = '\0'; - *tech_pvt->ring_value = '\0'; - *tech_pvt->callid_number = '\0'; - *tech_pvt->callid_name = '\0'; - - tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE; - tech_pvt->interface_state = SKYPOPEN_STATE_IDLE; - switch_mutex_unlock(globals.mutex); - } else { - ERRORA("no tech_pvt?\n", SKYPOPEN_P_LOG); - } - } - } - tech_pvt->skypopen_signaling_thread = NULL; - DEBUGA_SKYPE("EXITING\n", SKYPOPEN_P_LOG); - return NULL; -} - -static switch_status_t load_config(int reload_type) -{ - char *cf = "skypopen.conf"; - switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface; - private_t *tech_pvt = NULL; - - // CLOUDTREE (Thomas Hazel) - always try to load configuration - running = 1; - - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, skypopen_module_pool); - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - ERRORA("open of %s failed\n", SKYPOPEN_P_LOG, cf); - running = 0; - switch_xml_free(xml); - return SWITCH_STATUS_TERM; - } - - switch_mutex_lock(globals.mutex); - if ((global_settings = switch_xml_child(cfg, "global_settings"))) { - for (param = switch_xml_child(global_settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "debug")) { - globals.debug = atoi(val); - DEBUGA_SKYPE("globals.debug=%d\n", SKYPOPEN_P_LOG, globals.debug); - - } else if (!strcmp(var, "context")) { - set_global_context(val); - DEBUGA_SKYPE("globals.context=%s\n", SKYPOPEN_P_LOG, globals.context); - } else if (!strcmp(var, "dialplan")) { - set_global_dialplan(val); - DEBUGA_SKYPE("globals.dialplan=%s\n", SKYPOPEN_P_LOG, globals.dialplan); - } else if (!strcmp(var, "destination")) { - set_global_destination(val); - DEBUGA_SKYPE("globals.destination=%s\n", SKYPOPEN_P_LOG, globals.destination); - } else if (!strcmp(var, "skype_user")) { - set_global_skype_user(val); - DEBUGA_SKYPE("globals.skype_user=%s\n", SKYPOPEN_P_LOG, globals.skype_user); - } else if (!strcmp(var, "report_incoming_chatmessages")) { - set_global_report_incoming_chatmessages(val); - DEBUGA_SKYPE("globals.report_incoming_chatmessages=%s\n", SKYPOPEN_P_LOG, globals.report_incoming_chatmessages); - } else if (!strcmp(var, "silent_mode")) { - set_global_silent_mode(val); - DEBUGA_SKYPE("globals.silent_mode=%s\n", SKYPOPEN_P_LOG, globals.silent_mode); - } else if (!strcmp(var, "write_silence_when_idle")) { - set_global_write_silence_when_idle(val); - DEBUGA_SKYPE("globals.write_silence_when_idle=%s\n", SKYPOPEN_P_LOG, globals.write_silence_when_idle); - } else if (!strcmp(var, "setsockopt")) { - set_global_setsockopt(val); - DEBUGA_SKYPE("globals.setsockopt=%s\n", SKYPOPEN_P_LOG, globals.setsockopt); - } - - } - } - - globals.start_port = 32769; - if ((interfaces = switch_xml_child(cfg, "per_interface_settings"))) { - int i = 0; - - for (myinterface = switch_xml_child(interfaces, "interface"); myinterface; myinterface = myinterface->next) { - char *id = (char *) switch_xml_attr(myinterface, "id"); - char *name = (char *) switch_xml_attr(myinterface, "name"); - char *context = "default"; - char *dialplan = "XML"; - char *destination = "5000"; - char *X11_display = NULL; - char *skype_user = NULL; - char *report_incoming_chatmessages = "true"; - char *silent_mode = "false"; - char *write_silence_when_idle = "true"; - char *setsockopt = "false"; - uint32_t interface_id = 0; - - if (globals.context) - context = globals.context; - if (globals.dialplan) - dialplan = globals.dialplan; - if (globals.destination) - destination = globals.destination; - if (globals.skype_user) - skype_user = globals.skype_user; - if (globals.report_incoming_chatmessages) - report_incoming_chatmessages = globals.report_incoming_chatmessages; - if (globals.silent_mode) - silent_mode = globals.silent_mode; - if (globals.write_silence_when_idle) - write_silence_when_idle = globals.write_silence_when_idle; - if (globals.setsockopt) - setsockopt = globals.setsockopt; - - tech_pvt = NULL; - - for (param = switch_xml_child(myinterface, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "destination")) { - destination = val; - } else if (!strcasecmp(var, "skype_user")) { - skype_user = val; - } else if (!strcasecmp(var, "report_incoming_chatmessages")) { - report_incoming_chatmessages = val; - } else if (!strcasecmp(var, "silent_mode")) { - silent_mode = val; - } else if (!strcasecmp(var, "write_silence_when_idle")) { - write_silence_when_idle = val; - } else if (!strcasecmp(var, "setsockopt")) { - setsockopt = val; - } else if (!strcasecmp(var, "X11-display") || !strcasecmp(var, "X11_display")) { - X11_display = val; - } - - } - if (!skype_user) { - ERRORA("interface missing REQUIRED param 'skype_user'\n", SKYPOPEN_P_LOG); - continue; - } - - if (reload_type == SOFT_RELOAD) { - char the_interface[256]; - sprintf(the_interface, "#%s", name); - - if (interface_exists(the_interface) == SWITCH_STATUS_SUCCESS) { - continue; - } - } -#ifndef WIN32 - if (!X11_display) { - ERRORA("interface missing REQUIRED param 'X11_display'\n", SKYPOPEN_P_LOG); - continue; - } -#endif - if (!id) { - ERRORA("interface missing REQUIRED param 'id'\n", SKYPOPEN_P_LOG); - continue; - } - if (switch_is_number(id)) { - interface_id = atoi(id); - DEBUGA_SKYPE("interface_id=%d\n", SKYPOPEN_P_LOG, interface_id); - } else { - ERRORA("interface param 'id' MUST be a number, now id='%s'\n", SKYPOPEN_P_LOG, id); - continue; - } - - if (!name) { - WARNINGA("interface missing param 'name', not nice, but works\n", SKYPOPEN_P_LOG); - } - - if (name) { - DEBUGA_SKYPE("name=%s\n", SKYPOPEN_P_LOG, name); - } -#ifndef WIN32 - if (!XInitThreads()) { - ERRORA("Not initialized XInitThreads!\n", SKYPOPEN_P_LOG); - } else { - DEBUGA_SKYPE("Initialized XInitThreads!\n", SKYPOPEN_P_LOG); - } - switch_sleep(20000); -#endif /* WIN32 */ - - if (interface_id && interface_id < SKYPOPEN_MAX_INTERFACES) { - private_t newconf; - switch_threadattr_t *skypopen_api_thread_attr = NULL; - switch_threadattr_t *skypopen_signaling_thread_attr = NULL; - - memset(&newconf, '\0', sizeof(newconf)); - globals.SKYPOPEN_INTERFACES[interface_id] = newconf; - globals.SKYPOPEN_INTERFACES[interface_id].running = 1; - - - tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id]; - - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].interface_id, id); - if (name) { - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].name, name); - } else { - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].name, "N/A"); - } - DEBUGA_SKYPE("CONFIGURING interface_id=%d\n", SKYPOPEN_P_LOG, interface_id); - - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].context, context); - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].dialplan, dialplan); - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].destination, destination); - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].X11_display, X11_display); - switch_set_string(globals.SKYPOPEN_INTERFACES[interface_id].skype_user, skype_user); - - if (!strcmp(report_incoming_chatmessages, "true") || !strcmp(report_incoming_chatmessages, "1")) { - globals.SKYPOPEN_INTERFACES[interface_id].report_incoming_chatmessages = 1; - } else { - globals.SKYPOPEN_INTERFACES[interface_id].report_incoming_chatmessages = 0; //redundant, just in case - - } - - if (!strcmp(silent_mode, "true") || !strcmp(silent_mode, "1")) { - globals.SKYPOPEN_INTERFACES[interface_id].silent_mode = 1; - } else { - globals.SKYPOPEN_INTERFACES[interface_id].silent_mode = 0; //redundant, just in case - - } - - if (!strcmp(write_silence_when_idle, "true") || !strcmp(write_silence_when_idle, "1")) { - globals.SKYPOPEN_INTERFACES[interface_id].write_silence_when_idle = 1; - } else { - globals.SKYPOPEN_INTERFACES[interface_id].write_silence_when_idle = 0; //redundant, just in case - - } - - if (!strcmp(setsockopt, "true") || !strcmp(setsockopt, "1")) { - globals.SKYPOPEN_INTERFACES[interface_id].setsockopt = 1; - } else { - globals.SKYPOPEN_INTERFACES[interface_id].setsockopt = 0; //redundant, just in case - - } - - DEBUGA_SKYPE("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].name=%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].name); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].context=%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].context); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].dialplan=%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].dialplan); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].destination=%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].destination); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].X11_display=%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].X11_display); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].skype_user=%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].skype_user); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].report_incoming_chatmessages=%d\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].report_incoming_chatmessages); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].silent_mode=%d\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].silent_mode); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].write_silence_when_idle=%d\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].write_silence_when_idle); - DEBUGA_SKYPE - ("interface_id=%d globals.SKYPOPEN_INTERFACES[interface_id].setsockopt=%d\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].setsockopt); - - WARNINGA("STARTING interface_id=%d\n", SKYPOPEN_P_LOG, interface_id); - - switch_threadattr_create(&skypopen_api_thread_attr, skypopen_module_pool); - switch_threadattr_detach_set(skypopen_api_thread_attr, 0); - switch_threadattr_stacksize_set(skypopen_api_thread_attr, SWITCH_THREAD_STACKSIZE); - - switch_thread_create(&globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread, - skypopen_api_thread_attr, skypopen_do_skypeapi_thread, &globals.SKYPOPEN_INTERFACES[interface_id], - skypopen_module_pool); - - switch_sleep(100000); - - switch_threadattr_create(&skypopen_signaling_thread_attr, skypopen_module_pool); - switch_threadattr_detach_set(skypopen_signaling_thread_attr, 0); - switch_threadattr_stacksize_set(skypopen_signaling_thread_attr, SWITCH_THREAD_STACKSIZE); - - switch_thread_create(&globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread, skypopen_signaling_thread_attr, - skypopen_signaling_thread_func, &globals.SKYPOPEN_INTERFACES[interface_id], skypopen_module_pool); - - switch_sleep(100000); - - skypopen_audio_init(&globals.SKYPOPEN_INTERFACES[interface_id]); - switch_mutex_init(&globals.SKYPOPEN_INTERFACES[interface_id].mutex_audio_srv, SWITCH_MUTEX_NESTED, skypopen_module_pool); - switch_mutex_init(&globals.SKYPOPEN_INTERFACES[interface_id].mutex_audio_cli, SWITCH_MUTEX_NESTED, skypopen_module_pool); - switch_mutex_init(&globals.SKYPOPEN_INTERFACES[interface_id].mutex_thread_audio_srv, SWITCH_MUTEX_NESTED, skypopen_module_pool); - switch_mutex_init(&globals.SKYPOPEN_INTERFACES[interface_id].mutex_thread_audio_cli, SWITCH_MUTEX_NESTED, skypopen_module_pool); - - NOTICA - ("WAITING roughly 10 seconds to find a running Skype client and connect to its SKYPE API for interface_id=%d\n", - SKYPOPEN_P_LOG, interface_id); - i = 0; - while (globals.SKYPOPEN_INTERFACES[interface_id].SkypopenHandles.api_connected == 0 && running && i < 200) { // 10 seconds! thanks Jeff Lenk - switch_sleep(50000); - i++; - } - if (globals.SKYPOPEN_INTERFACES[interface_id].SkypopenHandles.api_connected) { - NOTICA - ("Found a running Skype client, connected to its SKYPE API for interface_id=%d, waiting 60 seconds for CURRENTUSERHANDLE==%s\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].skype_user); - } else { - ERRORA - ("Failed to connect to a SKYPE API for interface_id=%d, no SKYPE client running, please (re)start Skype client. Skypopen exiting\n", - SKYPOPEN_P_LOG, interface_id); - running = 0; - switch_mutex_unlock(globals.mutex); - switch_xml_free(xml); - return SWITCH_STATUS_FALSE; - } - - i = 0; - while (globals.SKYPOPEN_INTERFACES[interface_id].SkypopenHandles.currentuserhandle == 0 && running && i < 1200) { // 60 seconds! thanks Jeff Lenk - switch_sleep(50000); - i++; - } - if (globals.SKYPOPEN_INTERFACES[interface_id].SkypopenHandles.currentuserhandle) { - WARNINGA - ("Interface_id=%d is now STARTED, the Skype client to which we are connected gave us the correct CURRENTUSERHANDLE (%s)\n", - SKYPOPEN_P_LOG, interface_id, globals.SKYPOPEN_INTERFACES[interface_id].skype_user); - - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "PROTOCOL 999"); - switch_sleep(20000); - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "SET AUTOAWAY OFF"); - switch_sleep(20000); - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "SET WINDOWSTATE HIDDEN"); - switch_sleep(20000); - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "SET USERSTATUS ONLINE"); - switch_sleep(20000); - if (globals.SKYPOPEN_INTERFACES[interface_id].silent_mode) { - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "SET SILENT_MODE ON"); - switch_sleep(20000); - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "SET SILENT_MODE OFF"); - switch_sleep(20000); - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[interface_id], "SET SILENT_MODE ON"); - switch_sleep(20000); - } - } else { - ERRORA - ("The Skype client to which we are connected FAILED to gave us CURRENTUSERHANDLE=%s, interface_id=%d FAILED to start. No Skype client logged in as '%s' has been found. Please (re)launch a Skype client logged in as '%s'. Skypopen exiting now\n", - SKYPOPEN_P_LOG, globals.SKYPOPEN_INTERFACES[interface_id].skype_user, - interface_id, globals.SKYPOPEN_INTERFACES[interface_id].skype_user, globals.SKYPOPEN_INTERFACES[interface_id].skype_user); - running = 0; - switch_mutex_unlock(globals.mutex); - switch_xml_free(xml); - return SWITCH_STATUS_FALSE; - } - - } else { - ERRORA("interface id %d is higher than SKYPOPEN_MAX_INTERFACES (%d)\n", SKYPOPEN_P_LOG, interface_id, SKYPOPEN_MAX_INTERFACES); - continue; - } - - } - - for (i = 0; i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - /* How many real intterfaces */ - globals.real_interfaces = i + 1; - - tech_pvt = &globals.SKYPOPEN_INTERFACES[i]; - - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].interface_id=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].interface_id); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].name=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].name); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].context=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].context); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].dialplan=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].dialplan); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].destination=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].destination); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].X11_display=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].X11_display); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].skype_user=%s\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].skype_user); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].report_incoming_chatmessages=%d\n", SKYPOPEN_P_LOG, i, i, - globals.SKYPOPEN_INTERFACES[i].report_incoming_chatmessages); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].silent_mode=%d\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].silent_mode); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].write_silence_when_idle=%d\n", SKYPOPEN_P_LOG, i, i, - globals.SKYPOPEN_INTERFACES[i].write_silence_when_idle); - DEBUGA_SKYPE("i=%d globals.SKYPOPEN_INTERFACES[%d].setsockopt=%d\n", SKYPOPEN_P_LOG, i, i, globals.SKYPOPEN_INTERFACES[i].setsockopt); - } - } - } - - switch_mutex_unlock(globals.mutex); - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t chat_send(switch_event_t *message_event) -{ - char *user = NULL, *host, *f_user = NULL, *f_host = NULL, *f_resource = NULL; - private_t *tech_pvt = NULL; - int i = 0, found = 0, tried = 0; - char skype_msg[1024]; - - const char *proto; - const char *from; - const char *to; - const char *subject; - const char *body; - //const char *type; - const char *hint; - - proto = switch_event_get_header(message_event, "proto"); - from = switch_event_get_header(message_event, "from"); - to = switch_event_get_header(message_event, "to"); - subject = switch_event_get_header(message_event, "subject"); - body = switch_event_get_body(message_event); - //type = switch_event_get_header(message_event, "type"); - hint = switch_event_get_header(message_event, "hint"); - - switch_assert(proto != NULL); - - //DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, type, - // hint ? hint : "NULL"); - DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, - hint ? hint : "NULL"); - - if (!to || !strlen(to)) { - ERRORA("Missing To: header.\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if ((!from && !hint) || (!strlen(from) && !strlen(hint))) { - ERRORA("Missing From: AND Hint: headers.\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if (from && (f_user = strdup(from))) { - if ((f_host = strchr(f_user, '@'))) { - *f_host++ = '\0'; - if ((f_resource = strchr(f_host, '/'))) { - *f_resource++ = '\0'; - } - } - } - - if (to && (user = strdup(to))) { - if ((host = strchr(user, '@'))) { - *host++ = '\0'; - } - //DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, type, - // hint ? hint : "NULL"); - DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, - hint ? hint : "NULL"); - if (hint && strlen(hint)) { - //in hint we receive the interface name to use - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name) - && (strncmp(globals.SKYPOPEN_INTERFACES[i].name, hint, strlen(hint)) == 0)) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[i]; - DEBUGA_SKYPE("Using interface: globals.SKYPOPEN_INTERFACES[%d].name=|||%s|||\n", SKYPOPEN_P_LOG, i, - globals.SKYPOPEN_INTERFACES[i].name); - found = 1; - break; - } - } - } else { - //we have no a predefined interface name to use (hint is NULL), so let's choose an interface from the username (from) - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name) - && (strncmp(globals.SKYPOPEN_INTERFACES[i].skype_user, from, strlen(from)) == 0)) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[i]; - DEBUGA_SKYPE("Using interface: globals.SKYPOPEN_INTERFACES[%d].name=|||%s|||\n", SKYPOPEN_P_LOG, i, - globals.SKYPOPEN_INTERFACES[i].name); - found = 1; - break; - } - } - } - if (!found) { - ERRORA("ERROR: A Skypopen interface with name='%s' or one with skypeuser='%s' was not found\n", SKYPOPEN_P_LOG, hint ? hint : "NULL", - from ? from : "NULL"); - goto end; - } else { - - snprintf(skype_msg, sizeof(skype_msg), "CHAT CREATE %s", to); - skypopen_signaling_write(tech_pvt, skype_msg); - switch_sleep(20000); - } - - found = 0; - - while (!found) { - for (i = 0; i < MAX_CHATS; i++) { - //DEBUGA_SKYPE("tech_pvt->chats[i].dialog_partner='%s' to='%s'\n", SKYPOPEN_P_LOG, tech_pvt->chats[i].dialog_partner, to); - if (!strcmp(tech_pvt->chats[i].dialog_partner, to)) { - snprintf(skype_msg, sizeof(skype_msg), "CHATMESSAGE %s %s", tech_pvt->chats[i].chatname, body); - skypopen_signaling_write(tech_pvt, skype_msg); - found = 1; - break; - } - } - if (found) { - break; - } - tried++; - if (tried > 20) { - ERRORA - ("No chat with dialog_partner='%s' was found. (If you're using mod_sms this is a bug of mod_skypopen when using mod_sms, from next incoming message it will probably work...)\n", - SKYPOPEN_P_LOG, to); - break; - } - switch_sleep(50000); - } - - } - end: - switch_safe_free(user); - switch_safe_free(f_user); - return SWITCH_STATUS_SUCCESS; -} - - -SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load) -{ - switch_api_interface_t *commands_api_interface; - switch_chat_interface_t *chat_interface; - - skypopen_module_pool = pool; - memset(&globals, '\0', sizeof(globals)); - - // CLOUDTREE (Thomas Hazel) -#ifndef WIN32 - // XXX: these assumes no one will override - //XSetErrorHandler(X11_errors_handler); - //XXX giovanni: seems that if Xserver is up, but skype client is crashed, the error is non fatal. Let's use Thomas handler in this case too - XSetErrorHandler(xio_error_handler2); - XSetIOErrorHandler(xio_error_handler); - - memset(&global_handles_list, 0, sizeof(global_handles_list)); - switch_mutex_init(&globals.list_mutex, SWITCH_MUTEX_NESTED, skypopen_module_pool); -#endif - - running = 1; - - if (load_config(FULL_RELOAD) == SWITCH_STATUS_SUCCESS) { - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - skypopen_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - skypopen_endpoint_interface->interface_name = "skypopen"; - skypopen_endpoint_interface->io_routines = &skypopen_io_routines; - skypopen_endpoint_interface->state_handler = &skypopen_state_handlers; - - if (running) { - - SWITCH_ADD_API(commands_api_interface, "sk", "Skypopen console commands", sk_function, SK_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "skypopen", "Skypopen interface commands", skypopen_function, SKYPOPEN_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "skypopen_chat", "Skypopen_chat interface remote_skypename TEXT", skypopen_chat_function, - SKYPOPEN_CHAT_SYNTAX); - SWITCH_ADD_CHAT(chat_interface, SKYPE_CHAT_PROTO, chat_send); - - if (switch_event_reserve_subclass(MY_EVENT_INCOMING_CHATMESSAGE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_FALSE; - } - - if (switch_event_reserve_subclass(MY_EVENT_INCOMING_RAW) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_FALSE; - } - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; - } - } else { - running = 0; - switch_sleep(1000000); //1 full second - return SWITCH_STATUS_FALSE; - } - return SWITCH_STATUS_FALSE; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypopen_shutdown) -{ - int x; - private_t *tech_pvt = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_size_t howmany = 8; - int interface_id; - - running = 0; - - for (interface_id = 0; interface_id < SKYPOPEN_MAX_INTERFACES; interface_id++) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id]; - - - if (strlen(globals.SKYPOPEN_INTERFACES[interface_id].name)) { - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread) { -#ifdef WIN32 - skypopen_signaling_write(tech_pvt, "DIE"); - switch_sleep(20000); - switch_file_write(tech_pvt->SkypopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die - -#else /* WIN32 */ - skypopen_signaling_write(tech_pvt, "DIE"); - switch_sleep(20000); - howmany = write(tech_pvt->SkypopenHandles.fdesc[1], "sciutati", howmany); -#endif /* WIN32 */ - } - - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread) { -#ifdef WIN32 - if (SendMessage(tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) { // let's the skypopen_api_thread_func die - DEBUGA_SKYPE("got FALSE here, thread probably was already dead. GetLastError returned: %d\n", SKYPOPEN_P_LOG, GetLastError()); - tech_pvt->skypopen_api_thread = NULL; - } -#else - if (tech_pvt->SkypopenHandles.disp) { - XEvent e; - Atom atom1 = XInternAtom(tech_pvt->SkypopenHandles.disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", - False); - switch_sleep(20000); - XFlush(tech_pvt->SkypopenHandles.disp); - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.message_type = atom1; /* leading message */ - e.xclient.display = tech_pvt->SkypopenHandles.disp; - e.xclient.window = tech_pvt->SkypopenHandles.skype_win; - e.xclient.format = 8; - - XSendEvent(tech_pvt->SkypopenHandles.disp, tech_pvt->SkypopenHandles.win, False, 0, &e); - XFlush(tech_pvt->SkypopenHandles.disp); - } -#endif - } - x = 10; - while (x) { - x--; - switch_yield(50000); - } -#ifndef WIN32 - if (tech_pvt->SkypopenHandles.disp) { - DEBUGA_SKYPE("CLOSIN X\n", SKYPOPEN_P_LOG); - XCloseDisplay(tech_pvt->SkypopenHandles.disp); - DEBUGA_SKYPE("CLOSIN X END\n", SKYPOPEN_P_LOG); - } -#endif - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread) { - switch_thread_join(&status, globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread); - } - if (status != SWITCH_STATUS_SUCCESS) - DEBUGA_SKYPE("got FALSE here, thread was not joined\n", SKYPOPEN_P_LOG); - if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread) { - switch_thread_join(&status, globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread); - } - if (status != SWITCH_STATUS_SUCCESS) - DEBUGA_SKYPE("got FALSE here, thread was not joined\n", SKYPOPEN_P_LOG); -#ifndef WIN32 - WARNINGA("SHUTDOWN interface_id=%d\n", SKYPOPEN_P_LOG, interface_id); - shutdown(tech_pvt->audiopipe_cli[0], 2); - close(tech_pvt->audiopipe_cli[0]); - shutdown(tech_pvt->audiopipe_cli[1], 2); - close(tech_pvt->audiopipe_cli[1]); - shutdown(tech_pvt->audiopipe_srv[0], 2); - close(tech_pvt->audiopipe_srv[0]); - shutdown(tech_pvt->audiopipe_srv[1], 2); - close(tech_pvt->audiopipe_srv[1]); - shutdown(tech_pvt->SkypopenHandles.fdesc[0], 2); - close(tech_pvt->SkypopenHandles.fdesc[0]); - shutdown(tech_pvt->SkypopenHandles.fdesc[1], 2); - close(tech_pvt->SkypopenHandles.fdesc[1]); -#endif /* WIN32 */ - } - - } - switch_event_free_subclass(MY_EVENT_INCOMING_CHATMESSAGE); - switch_event_free_subclass(MY_EVENT_INCOMING_RAW); - - switch_safe_free(globals.context); - switch_safe_free(globals.dialplan); - switch_safe_free(globals.destination); - switch_safe_free(globals.skype_user); - switch_safe_free(globals.report_incoming_chatmessages); - switch_safe_free(globals.silent_mode); - switch_safe_free(globals.write_silence_when_idle); - switch_safe_free(globals.setsockopt); - - return SWITCH_STATUS_SUCCESS; -} - -void *SWITCH_THREAD_FUNC skypopen_do_tcp_srv_thread(switch_thread_t *thread, void *obj) -{ - return skypopen_do_tcp_srv_thread_func(obj); -} - -void *SWITCH_THREAD_FUNC skypopen_do_tcp_cli_thread(switch_thread_t *thread, void *obj) -{ - return skypopen_do_tcp_cli_thread_func(obj); -} - -void *SWITCH_THREAD_FUNC skypopen_do_skypeapi_thread(switch_thread_t *thread, void *obj) -{ - return skypopen_do_skypeapi_thread_func(obj); -} - -int dtmf_received(private_t *tech_pvt, char *value) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - - if (channel) { - - if (switch_channel_test_flag(channel, CF_BRIDGED) - && !switch_true(switch_channel_get_variable(channel, "skype_add_outband_dtmf_also_when_bridged"))) { - - - NOTICA - ("received DTMF '%c' on channel %s, but we're BRIDGED, so we DO NOT relay it out of band. If you DO want to relay it out of band when bridged too, on top of audio DTMF, set the channel variable 'skype_add_outband_dtmf_also_when_bridged=true' \n", - SKYPOPEN_P_LOG, value[0], switch_channel_get_name(channel)); - - } else { - - - - switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; - DEBUGA_SKYPE("received DTMF %c on channel %s\n", SKYPOPEN_P_LOG, dtmf.digit, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_channel_queue_dtmf(channel, &dtmf); - switch_set_flag(tech_pvt, TFLAG_DTMF); - switch_mutex_unlock(tech_pvt->flag_mutex); - } - } else { - WARNINGA("received %c DTMF, but no channel?\n", SKYPOPEN_P_LOG, value[0]); - } - switch_core_session_rwunlock(session); - } else { - WARNINGA("received %c DTMF, but no session?\n", SKYPOPEN_P_LOG, value[0]); - } - - return 0; -} - -void *SWITCH_THREAD_FUNC skypopen_do_mod_sms_thread(switch_thread_t *thread, void *obj) -{ - switch_event_t *event; - - - event = obj; - switch_core_chat_send("GLOBAL", event); /* mod_sms */ - - return event; - -} - - - -int start_mod_sms_thread(private_t *tech_pvt, switch_event_t *event) -{ - switch_threadattr_t *mod_sms_thread_thd_attr = NULL; - switch_thread_t *mod_sms_thread; - - - switch_threadattr_create(&mod_sms_thread_thd_attr, skypopen_module_pool); - switch_threadattr_detach_set(mod_sms_thread_thd_attr, 0); - switch_threadattr_stacksize_set(mod_sms_thread_thd_attr, SWITCH_THREAD_STACKSIZE); - if (switch_thread_create(&mod_sms_thread, mod_sms_thread_thd_attr, skypopen_do_mod_sms_thread, event, skypopen_module_pool) == SWITCH_STATUS_SUCCESS) { - DEBUGA_SKYPE("started mod_sms_thread thread.\n", SKYPOPEN_P_LOG); - } else { - ERRORA("failed to start mod_sms_thread thread.\n", SKYPOPEN_P_LOG); - return -1; - } - if (mod_sms_thread == NULL) { - WARNINGA("mod_sms_thread exited\n", SKYPOPEN_P_LOG); - return -1; - } - - return 0; -} - - -int start_audio_threads(private_t *tech_pvt) -{ - switch_threadattr_t *tcp_srv_thread_thd_attr = NULL; - switch_threadattr_t *tcp_cli_thread_thd_attr = NULL; - - tech_pvt->begin_to_write = 0; - tech_pvt->begin_to_read = 0; - - if (switch_core_timer_init(&tech_pvt->timer_read, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_read); - - if (switch_core_timer_init(&tech_pvt->timer_read_srv, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_read_srv); - - if (switch_core_timer_init(&tech_pvt->timer_write, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_write); - - switch_threadattr_create(&tcp_srv_thread_thd_attr, skypopen_module_pool); - switch_threadattr_detach_set(tcp_srv_thread_thd_attr, 0); - switch_threadattr_stacksize_set(tcp_srv_thread_thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(tcp_srv_thread_thd_attr, SWITCH_PRI_REALTIME); - switch_mutex_lock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv lock\n", SKYPOPEN_P_LOG); - if (switch_thread_create(&tech_pvt->tcp_srv_thread, tcp_srv_thread_thd_attr, skypopen_do_tcp_srv_thread, tech_pvt, skypopen_module_pool) == - SWITCH_STATUS_SUCCESS) { - DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPOPEN_P_LOG); - } else { - ERRORA("failed to start tcp_srv_thread thread.\n", SKYPOPEN_P_LOG); - switch_mutex_unlock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv unlock\n", SKYPOPEN_P_LOG); - return -1; - } - switch_mutex_unlock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv unlock\n", SKYPOPEN_P_LOG); - - switch_threadattr_create(&tcp_cli_thread_thd_attr, skypopen_module_pool); - switch_threadattr_detach_set(tcp_cli_thread_thd_attr, 0); - switch_threadattr_stacksize_set(tcp_cli_thread_thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(tcp_cli_thread_thd_attr, SWITCH_PRI_REALTIME); - switch_mutex_lock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli lock\n", SKYPOPEN_P_LOG); - if (switch_thread_create(&tech_pvt->tcp_cli_thread, tcp_cli_thread_thd_attr, skypopen_do_tcp_cli_thread, tech_pvt, skypopen_module_pool) == - SWITCH_STATUS_SUCCESS) { - DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPOPEN_P_LOG); - } else { - ERRORA("failed to start tcp_cli_thread thread.\n", SKYPOPEN_P_LOG); - switch_mutex_unlock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli unlock\n", SKYPOPEN_P_LOG); - return -1; - } - switch_mutex_unlock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli unlock\n", SKYPOPEN_P_LOG); - switch_sleep(100000); - - if (tech_pvt->tcp_cli_thread == NULL || tech_pvt->tcp_srv_thread == NULL) { - WARNINGA("tcp_cli_thread or tcp_srv_thread exited\n", SKYPOPEN_P_LOG); - return -1; - } - - return 0; -} - -int new_inbound_channel(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if ((session = switch_core_session_request(skypopen_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)) != 0) { - DEBUGA_SKYPE("2 SESSION_REQUEST %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(session)); - switch_core_session_add_stream(session, NULL); - channel = switch_core_session_get_channel(session); - if (!channel) { - ERRORA("Doh! no channel?\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - switch_channel_set_variable(channel, "waste", "false"); - if (skypopen_tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Doh! no tech_init?\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - - if ((tech_pvt->caller_profile = - switch_caller_profile_new(switch_core_session_get_pool(session), "skypopen", - tech_pvt->dialplan, tech_pvt->callid_name, - tech_pvt->callid_number, NULL, NULL, NULL, NULL, "mod_skypopen", tech_pvt->context, tech_pvt->destination)) != 0) { - char name[128]; - switch_snprintf(name, sizeof(name), "skypopen/%s", tech_pvt->name); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - } - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Error spawning thread\n", SKYPOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - } - if (channel) { - switch_channel_set_variable(channel, "skype_user", tech_pvt->skype_user); - switch_channel_set_variable(channel, "initial_skype_user", tech_pvt->initial_skype_user); - } - - DEBUGA_SKYPE("new_inbound_channel\n", SKYPOPEN_P_LOG); - - return 0; -} - -int remote_party_is_ringing(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session_uuid_str???\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No session???\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - if (channel) { - switch_channel_mark_ring_ready(channel); - DEBUGA_SKYPE("skype_call: REMOTE PARTY RINGING\n", SKYPOPEN_P_LOG); - } else { - ERRORA("No channel???\n", SKYPOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - return SWITCH_STATUS_SUCCESS; -} - -int remote_party_is_early_media(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session_uuid_str???\n\n\n", SKYPOPEN_P_LOG); - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_add_stream(session, NULL); - } else { - ERRORA("No session???\n", SKYPOPEN_P_LOG); - goto done; - } - if (channel) { - switch_channel_mark_pre_answered(channel); - DEBUGA_SKYPE("skype_call: REMOTE PARTY EARLY MEDIA\n", SKYPOPEN_P_LOG); - } else { - ERRORA("No channel???\n", SKYPOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - done: - return 0; -} - -int outbound_channel_answered(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n", SKYPOPEN_P_LOG); - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No channel???\n", SKYPOPEN_P_LOG); - goto done; - } - if (channel) { - switch_channel_mark_answered(channel); - } else { - ERRORA("No channel???\n", SKYPOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - done: - DEBUGA_SKYPE("outbound_channel_answered!\n", SKYPOPEN_P_LOG); - - return 0; -} - -private_t *find_available_skypopen_interface_rr(private_t *tech_pvt_calling) -{ - private_t *tech_pvt = NULL; - int i; - - switch_mutex_lock(globals.mutex); - - /* Fact is the real interface start from 1 */ - //XXX no, is just a convention, but you can have it start from 0. I do not, for aestetic reasons :-) - - for (i = 0; i < SKYPOPEN_MAX_INTERFACES; i++) { - int interface_id; - - interface_id = globals.next_interface; - globals.next_interface = interface_id + 1 < SKYPOPEN_MAX_INTERFACES ? interface_id + 1 : 0; - - if (strlen(globals.SKYPOPEN_INTERFACES[interface_id].name)) { - int skype_state = 0; - - tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id]; - skype_state = tech_pvt->interface_state; - if ((tech_pvt_calling ? strcmp(tech_pvt->skype_user, tech_pvt_calling->skype_user) : 1) - && (SKYPOPEN_STATE_IDLE == skype_state)) { - DEBUGA_SKYPE("returning as available skype interface name: %s, state: %d callflow: %d\n", SKYPOPEN_P_LOG, tech_pvt->name, skype_state, - tech_pvt->skype_callflow); - if (tech_pvt_calling == NULL) { - tech_pvt->interface_state = SKYPOPEN_STATE_SELECTED; - } - - switch_mutex_unlock(globals.mutex); - return tech_pvt; - } - } - } - - switch_mutex_unlock(globals.mutex); - return NULL; -} - -SWITCH_STANDARD_API(sk_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - int tmp_i = 0; - char tmp_message[4096]; - - if (globals.sk_console) - stream->write_function(stream, "sk console is: |||%s|||\n", globals.sk_console->name); - else - stream->write_function(stream, "sk console is NOT yet assigned\n"); - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc || !argv[0]) { - stream->write_function(stream, "%s", SK_SYNTAX); - goto end; - } - - - if (!strcasecmp(argv[0], "balances")) { - stream->write_function(stream, " Name \tBalance\tCurrency\n"); - stream->write_function(stream, " ==== \t=======\t========\n"); - - for (tmp_i = 0; tmp_i < SKYPOPEN_MAX_INTERFACES; tmp_i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[tmp_i].name)) { - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[tmp_i], "GET PROFILE PSTN_BALANCE"); - switch_sleep(20000); - - strncpy(tmp_message, globals.SKYPOPEN_INTERFACES[tmp_i].message, sizeof(globals.SKYPOPEN_INTERFACES[tmp_i].message)); - - skypopen_signaling_write(&globals.SKYPOPEN_INTERFACES[tmp_i], "GET PROFILE PSTN_BALANCE_CURRENCY"); - switch_sleep(20000); - if (strlen(tmp_message) > 21 && strlen(globals.SKYPOPEN_INTERFACES[tmp_i].message) > 30) - stream->write_function(stream, " %s \t%s\t%s\n", globals.SKYPOPEN_INTERFACES[tmp_i].name, tmp_message + 21, - globals.SKYPOPEN_INTERFACES[tmp_i].message + 30); - } - } - } else if (!strcasecmp(argv[0], "list")) { - int i; - unsigned int ib = 0; - unsigned int ib_failed = 0; - unsigned int ob = 0; - unsigned int ob_failed = 0; - char next_flag_char = ' '; - - stream->write_function(stream, "F ID\t Name \tIB (F/T) OB (F/T)\tState\tCallFlw\t\tUUID\n"); - stream->write_function(stream, "= ====\t ======== \t======= =======\t======\t============\t======\n"); - - for (i = 0; i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - next_flag_char = i == globals.next_interface ? '*' : ' '; - ib += globals.SKYPOPEN_INTERFACES[i].ib_calls; - ib_failed += globals.SKYPOPEN_INTERFACES[i].ib_failed_calls; - ob += globals.SKYPOPEN_INTERFACES[i].ob_calls; - ob_failed += globals.SKYPOPEN_INTERFACES[i].ob_failed_calls; - - stream->write_function(stream, - "%c %d\t[%6s]\t%3u/%u\t%6u/%u\t%s\t%s\t%s\n", - next_flag_char, - i, globals.SKYPOPEN_INTERFACES[i].name, - globals.SKYPOPEN_INTERFACES[i].ib_failed_calls, - globals.SKYPOPEN_INTERFACES[i].ib_calls, - globals.SKYPOPEN_INTERFACES[i].ob_failed_calls, - globals.SKYPOPEN_INTERFACES[i].ob_calls, - interface_status[globals.SKYPOPEN_INTERFACES[i].interface_state], - skype_callflow[globals.SKYPOPEN_INTERFACES[i].skype_callflow], globals.SKYPOPEN_INTERFACES[i].session_uuid_str); - } else if (argc > 1 && !strcasecmp(argv[1], "full")) { - stream->write_function(stream, "%c %d\n", next_flag_char, i); - } - - } - stream->write_function(stream, "\nTotal Interfaces: %d IB Calls(Failed/Total): %u/%u OB Calls(Failed/Total): %u/%u\n", - globals.real_interfaces > 0 ? globals.real_interfaces - 1 : 0, ib_failed, ib, ob_failed, ob); - - } else if (!strcasecmp(argv[0], "console")) { - int i; - int found = 0; - - if (argc == 2) { - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.SKYPOPEN_INTERFACES[i].name) - && (strncmp(globals.SKYPOPEN_INTERFACES[i].name, argv[1], strlen(argv[1])) == 0)) { - globals.sk_console = &globals.SKYPOPEN_INTERFACES[i]; - stream->write_function(stream, - "sk console is now: globals.SKYPOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.SKYPOPEN_INTERFACES[i].name); - stream->write_function(stream, "sk console is: |||%s|||\n", globals.sk_console->name); - found = 1; - break; - } - - } - if (!found) - stream->write_function(stream, "ERROR: A Skypopen interface with name='%s' was not found\n", argv[1]); - } else { - - stream->write_function(stream, "-ERR Usage: sk console interface_name\n"); - goto end; - } - - } else if (!strcasecmp(argv[0], "reload")) { - if (load_config(SOFT_RELOAD) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "sk reload failed\n"); - } else { - stream->write_function(stream, "sk reload success\n"); - } - } else if (!strcasecmp(argv[0], "remove")) { - if (argc == 2) { - if (remove_interface(argv[1], FALSE) == SWITCH_STATUS_SUCCESS) { - if (interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "sk remove '%s' failed\n", argv[1]); - } else { - stream->write_function(stream, "sk remove '%s' success\n", argv[1]); - } - } - } else { - stream->write_function(stream, "-ERR Usage: sk remove interface_name\n"); - goto end; - } - - } else { - if (globals.sk_console) - skypopen_signaling_write(globals.sk_console, (char *) cmd); - else - stream->write_function(stream, "sk console is NOT yet assigned\n"); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(skypopen_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", SKYPOPEN_SYNTAX); - goto end; - } - - if (argc < 2) { - stream->write_function(stream, "ERROR, usage: %s", SKYPOPEN_SYNTAX); - goto end; - } - - if (argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.SKYPOPEN_INTERFACES[i].name) - && (strncmp(globals.SKYPOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.SKYPOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.SKYPOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A Skypopen interface with name='%s' was not found\n", argv[0]); - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; - } else { - skypopen_signaling_write(tech_pvt, (char *) &cmd[strlen(argv[0]) + 1]); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", SKYPOPEN_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - - -int skypopen_partner_handle_ring(private_t *tech_pvt) -{ - char msg_to_skype[1024]; - int i; - int found = 0; - private_t *giovatech; - struct timeval timenow; - char *id = tech_pvt->ring_id; - char *value = tech_pvt->ring_value; - switch_core_session_t *session = NULL; - - switch_mutex_lock(globals.mutex); - - gettimeofday(&timenow, NULL); - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - - giovatech = &globals.SKYPOPEN_INTERFACES[i]; - if ((giovatech->interface_state != SKYPOPEN_STATE_DEAD) && (giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (giovatech->interface_state != SKYPOPEN_STATE_IDLE) && (strcmp(giovatech->name, tech_pvt->name)) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->ring_value, value)) && ((((timenow.tv_sec - giovatech->ring_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->ring_time.tv_usec)) < 1000000)) { //XXX 1.0sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.0 seconds - found = 1; - DEBUGA_SKYPE - ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", - SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, - value); - if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } else if (tech_pvt->interface_state != 0 && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN) { - WARNINGA("Why an interface_state %d HERE?\n", SKYPOPEN_P_LOG, tech_pvt->interface_state); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - - *tech_pvt->answer_id = '\0'; - *tech_pvt->answer_value = '\0'; - *tech_pvt->ring_id = '\0'; - *tech_pvt->ring_value = '\0'; - break; - } - } - } - - if (found) { - switch_mutex_unlock(globals.mutex); - return 0; - } - DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG); - - // CLOUDTREE (Thomas Hazel) - if (tech_pvt && tech_pvt->ringing_state == SKYPOPEN_RINGING_INIT) { - /* we are not inside an active call */ - - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = SKYPOPEN_STATE_PRERING; - gettimeofday(&tech_pvt->ring_time, NULL); - switch_copy_string(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1); - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - switch_core_session_rwunlock(session); - return 0; - } - - new_inbound_channel(tech_pvt); - - switch_sleep(10000); - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING); - if (channel) { - switch_channel_mark_ring_ready(channel); - DEBUGA_SKYPE("switch_channel_mark_ring_ready(channel);\n", SKYPOPEN_P_LOG); - } else { - ERRORA("no channel\n", SKYPOPEN_P_LOG); - } - switch_core_session_rwunlock(session); - } else { - ERRORA("no session\n", SKYPOPEN_P_LOG); - } - } else if (!tech_pvt || !tech_pvt->skype_call_id[0]) { - ERRORA("No Call ID?\n", SKYPOPEN_P_LOG); - } else { - DEBUGA_SKYPE("We're in a call now (%s), let's refuse this one (%s)\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - - switch_mutex_unlock(globals.mutex); - return 0; -} - -int skypopen_answer(private_t *tech_pvt) -{ - char msg_to_skype[1024]; - int i; - int found = 0; - private_t *giovatech; - struct timeval timenow; - char *id = tech_pvt->answer_id; - char *value = tech_pvt->answer_value; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - switch_mutex_lock(globals.mutex); - - gettimeofday(&timenow, NULL); - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - - giovatech = &globals.SKYPOPEN_INTERFACES[i]; - if (strlen(giovatech->skype_call_id) && (giovatech->interface_state != SKYPOPEN_STATE_DEAD) && (giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (giovatech->interface_state != SKYPOPEN_STATE_IDLE) && (strcmp(giovatech->name, tech_pvt->name)) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 1000000)) { //XXX 1.0sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.0 seconds - found = 1; - DEBUGA_SKYPE - ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", - SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, - value); - if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } else if (tech_pvt->interface_state != 0 && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN) { - WARNINGA("Why an interface_state %d HERE?\n", SKYPOPEN_P_LOG, tech_pvt->interface_state); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session_uuid_str???\n", SKYPOPEN_P_LOG); - break; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No session???\n", SKYPOPEN_P_LOG); - switch_core_session_rwunlock(session); - break; - } - if (channel) { - switch_channel_set_state(channel, CS_RESET); - } else { - ERRORA("No channel???\n", SKYPOPEN_P_LOG); - switch_core_session_rwunlock(session); - break; - } - - switch_core_session_rwunlock(session); - - break; - } - } - } - - if (found) { - switch_mutex_unlock(globals.mutex); - return 0; - } - DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG); - - // CLOUDTREE (Thomas Hazel) - if (tech_pvt && tech_pvt->ringing_state == SKYPOPEN_RINGING_INIT) { - /* we are not inside an active call */ - - tech_pvt->ib_calls++; - - tech_pvt->interface_state = SKYPOPEN_STATE_PREANSWER; - sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPOPEN_P_LOG, id); - gettimeofday(&tech_pvt->answer_time, NULL); - switch_copy_string(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - - switch_copy_string(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1); - - DEBUGA_SKYPE - ("NEW! name: %s, state: %d, value=%s, tech_pvt->callid_number=%s, tech_pvt->skype_user=%s\n", - SKYPOPEN_P_LOG, tech_pvt->name, tech_pvt->interface_state, value, tech_pvt->callid_number, tech_pvt->skype_user); - } else if (!tech_pvt || !tech_pvt->skype_call_id[0]) { - ERRORA("No Call ID?\n", SKYPOPEN_P_LOG); - } else { - DEBUGA_SKYPE("We're in a call now (%s), let's refuse this one (%s)\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - - switch_mutex_unlock(globals.mutex); - return 0; -} - -int skypopen_transfer(private_t *tech_pvt) -{ - char msg_to_skype[1024]; - int i; - int found = 0; - private_t *giovatech; - struct timeval timenow; - char *id = tech_pvt->ring_id; - char *value = tech_pvt->ring_value; - - switch_mutex_lock(globals.mutex); - - gettimeofday(&timenow, NULL); - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - - giovatech = &globals.SKYPOPEN_INTERFACES[i]; - /* let's look for a RINGING one */ - if ((giovatech->interface_state != SKYPOPEN_STATE_DEAD) && (giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (giovatech->interface_state != SKYPOPEN_STATE_IDLE) && (strcmp(giovatech->name, tech_pvt->name)) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->ring_value, value)) && ((((timenow.tv_sec - giovatech->ring_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->ring_time.tv_usec)) < 1000000)) { //XXX 1.0sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.0 seconds - found = 1; - DEBUGA_SKYPE - ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", - SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, - value); - if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - break; - } - } - } - - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - - giovatech = &globals.SKYPOPEN_INTERFACES[i]; - /* let's look for a IDLE one */ - if ((giovatech->interface_state == SKYPOPEN_STATE_IDLE) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user))) { - found = 1; - DEBUGA_SKYPE - ("FOUND (name=%s, giovatech->interface_state=%d == SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", - SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, - value); - if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - break; - } - } - } - - - if (found) { - switch_mutex_unlock(globals.mutex); - return 0; - } - DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG); - - if (!tech_pvt || !tech_pvt->skype_call_id[0]) { - /* we are not inside an active call */ - DEBUGA_SKYPE("We're NO MORE in a call now %s\n", SKYPOPEN_P_LOG, tech_pvt ? tech_pvt->skype_call_id : ""); - switch_mutex_unlock(globals.mutex); - - } else { - - /* we're in a call, let's try to transfer */ - /************************** TODO - Checking here if it is possible to transfer this call to Test2 - -> GET CALL 288 CAN_TRANSFER Test2 - <- CALL 288 CAN_TRANSFER test2 TRUE - **********************************/ - - private_t *available_skypopen_interface = NULL; - - gettimeofday(&timenow, NULL); - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) { - - giovatech = &globals.SKYPOPEN_INTERFACES[i]; - if (strlen(giovatech->skype_transfer_call_id) && (giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (giovatech->interface_state != SKYPOPEN_STATE_DEAD) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->transfer_callid_number, value)) && ((((timenow.tv_sec - giovatech->transfer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->transfer_time.tv_usec)) < 1000000)) { //1.0 sec - found = 1; - DEBUGA_SKYPE - ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->transfer_callid_number=%s == value=%s)\n", - SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, - giovatech->skype_user, tech_pvt->skype_user, giovatech->transfer_callid_number, value) - break; - } - } - } - - if (found) { - switch_mutex_unlock(globals.mutex); - return 0; - } - DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG); - - available_skypopen_interface = find_available_skypopen_interface_rr(tech_pvt); - if (available_skypopen_interface) { - /* there is a skypopen interface idle, let's transfer the call to it */ - - switch_copy_string(available_skypopen_interface->initial_skype_user, tech_pvt->skype_user, sizeof(tech_pvt->skype_user) - 1); - - gettimeofday(&tech_pvt->transfer_time, NULL); - switch_copy_string(tech_pvt->skype_transfer_call_id, id, sizeof(tech_pvt->skype_transfer_call_id) - 1); - - switch_copy_string(tech_pvt->transfer_callid_number, value, sizeof(tech_pvt->transfer_callid_number) - 1); - - DEBUGA_SKYPE - ("Let's transfer the skype_call %s to %s interface (with skype_user: %s), because we are already in a skypopen call(%s)\n", - SKYPOPEN_P_LOG, tech_pvt->skype_call_id, available_skypopen_interface->name, available_skypopen_interface->skype_user, id); - - - sprintf(msg_to_skype, "ALTER CALL %s TRANSFER %s", id, available_skypopen_interface->skype_user); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } else { - /* no skypopen interfaces idle, do hangup */ - DEBUGA_SKYPE - ("Not answering the skype_call %s, because we are already in a skypopen call(%s) and not transferring, because no other skypopen interfaces are available\n", - SKYPOPEN_P_LOG, id, tech_pvt->skype_call_id); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - switch_sleep(20000); - DEBUGA_SKYPE - ("We have NOT answered a Skype RING from skype_call %s, because we are already in a skypopen call (%s)\n", - SKYPOPEN_P_LOG, id, tech_pvt->skype_call_id); - - switch_mutex_unlock(globals.mutex); - } - return 0; -} - -int incoming_chatmessage(private_t *tech_pvt, int which) -{ - switch_event_t *event; - switch_core_session_t *session = NULL; - int event_sent_to_esl = 0; - - DEBUGA_SKYPE("received CHATMESSAGE on interface %s\n", SKYPOPEN_P_LOG, tech_pvt->name); - - if (!tech_pvt->report_incoming_chatmessages) { - DEBUGA_SKYPE("I will not generate an Event, report_incoming_chatmessages is %d\n", SKYPOPEN_P_LOG, tech_pvt->report_incoming_chatmessages); - return 0; - } - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SKYPE_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id); -/* mod_sms begin */ - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", tech_pvt->skype_user); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_proto", SKYPE_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", tech_pvt->chatmessages[which].from_handle); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_host", "from_host"); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", "from_full"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_user", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_host", "to_host"); -/* mod_sms end */ - - switch_event_add_body(event, "%s", tech_pvt->chatmessages[which].body); - - if (session) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true"); - if (switch_core_session_queue_event(session, &event) != SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true"); - switch_event_fire(&event); - } - } else { //no session - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false"); - switch_event_fire(&event); - event_sent_to_esl = 1; - } - - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", SKYPOPEN_P_LOG, tech_pvt->name); - } - - if (!event_sent_to_esl) { - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SKYPE_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id); - switch_event_add_body(event, "%s", tech_pvt->chatmessages[which].body); - if (session) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true"); - } else { //no session - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false"); - } - switch_event_fire(&event); - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", SKYPOPEN_P_LOG, tech_pvt->name); - } - } - - if (session) { - switch_core_session_rwunlock(session); - } - - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SKYPE_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id); -/* mod_sms begin */ - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", tech_pvt->skype_user); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_proto", SKYPE_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", tech_pvt->chatmessages[which].from_handle); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_host", "from_host"); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", "from_full"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_user", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_host", "to_host"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", tech_pvt->context); -/* mod_sms end */ - - switch_event_add_body(event, "%s", tech_pvt->chatmessages[which].body); - //switch_core_chat_send("GLOBAL", event); /* mod_sms */ - start_mod_sms_thread(tech_pvt, event); - //usleep(20000); - - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", SKYPOPEN_P_LOG, tech_pvt->name); - } - - return 0; -} - -static switch_status_t compat_chat_send(const char *proto, const char *from, const char *to, - const char *subject, const char *body, const char *type, const char *hint) -{ - switch_event_t *message_event; - switch_status_t status; - - if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint); - - if (body) { - switch_event_add_body(message_event, "%s", body); - } - } else { - abort(); - } - - status = chat_send(message_event); - switch_event_destroy(&message_event); - - return status; - -} - -SWITCH_STANDARD_API(skypopen_chat_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - int i; - int found = 0; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", SKYPOPEN_CHAT_SYNTAX); - goto end; - } - - if (argc < 3) { - stream->write_function(stream, "ERROR, usage: %s", SKYPOPEN_CHAT_SYNTAX); - goto end; - } - - if (argv[0]) { - for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.SKYPOPEN_INTERFACES[i].name) - && (strncmp(globals.SKYPOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.SKYPOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.SKYPOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.SKYPOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A Skypopen interface with name='%s' was not found\n", argv[0]); - goto end; - } else { - - NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", SKYPOPEN_P_LOG, SKYPE_CHAT_PROTO, - tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE", switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), - tech_pvt->name); - - compat_chat_send(SKYPE_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE", - switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, tech_pvt->name); - - } - } else { - stream->write_function(stream, "ERROR, usage: %s", SKYPOPEN_CHAT_SYNTAX); - goto end; - } - - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -int next_port(void) -{ - switch_mutex_lock(globals.mutex); - globals.start_port++; - if (globals.start_port == 65000) - globals.start_port = 32769; - switch_mutex_unlock(globals.mutex); - return (globals.start_port - 1); -} - -#ifndef WIN32 -// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list? -struct SkypopenHandles *skypopen_list_add(struct SkypopenList *list, struct SkypopenHandles *handle) -{ - switch_mutex_lock(globals.list_mutex); - - if (handle->managed == SWITCH_TRUE) { - // already added - switch_mutex_unlock(globals.list_mutex); - return 0; - } - - if (list->head == 0) { - list->head = handle; - handle->prev = 0; - - } else { - ((struct SkypopenHandles *) list->tail)->next = handle; - ((struct SkypopenHandles *) handle)->prev = list->tail; - } - - list->tail = handle; - handle->next = 0; - - handle->managed = SWITCH_TRUE; - - list->entries++; - - switch_mutex_unlock(globals.list_mutex); - - return handle; -} - -// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list? -struct SkypopenHandles *skypopen_list_remove_by_value(struct SkypopenList *list, Display * display) -{ - struct SkypopenHandles *iter; - struct SkypopenHandles *handle = 0; - - switch_mutex_lock(globals.list_mutex); - - iter = (struct SkypopenHandles *) list->head; - while (iter != 0) { - if (iter->disp == display) { - handle = iter; - break; - } - - iter = (struct SkypopenHandles *) iter->next; - } - - if ((handle != 0) && (handle->managed == SWITCH_TRUE)) { - if (handle->prev == 0) { - list->head = ((struct SkypopenHandles *) handle)->next; - - } else { - ((struct SkypopenHandles *) handle->prev)->next = ((struct SkypopenHandles *) handle)->next; - } - - if (handle->next == 0) { - list->tail = ((struct SkypopenHandles *) handle)->prev; - - } else { - ((struct SkypopenHandles *) handle->next)->prev = ((struct SkypopenHandles *) handle)->prev; - } - - handle->managed = SWITCH_FALSE; - handle->next = 0; - handle->prev = 0; - - list->entries--; - } - - switch_mutex_unlock(globals.list_mutex); - - return handle; -} - -// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list? -struct SkypopenHandles *skypopen_list_remove_by_reference(struct SkypopenList *list, struct SkypopenHandles *handle) -{ - private_t *tech_pvt = NULL; - - switch_mutex_lock(globals.list_mutex); - - DEBUGA_SKYPE("BEGIN REMOVE\n", SKYPOPEN_P_LOG); - if (handle->managed == SWITCH_FALSE) { - // already removed - switch_mutex_unlock(globals.list_mutex); - DEBUGA_SKYPE("EXIT REMOVE\n", SKYPOPEN_P_LOG); - return 0; - } - - if (handle->prev == 0) { - list->head = ((struct SkypopenHandles *) handle)->next; - - } else { - ((struct SkypopenHandles *) handle->prev)->next = ((struct SkypopenHandles *) handle)->next; - } - - if (handle->next == 0) { - list->tail = ((struct SkypopenHandles *) handle)->prev; - - } else { - ((struct SkypopenHandles *) handle->next)->prev = ((struct SkypopenHandles *) handle)->prev; - } - - handle->managed = SWITCH_FALSE; - handle->next = 0; - handle->prev = 0; - - list->entries--; - - switch_mutex_unlock(globals.list_mutex); - DEBUGA_SKYPE("EXIT REMOVE\n", SKYPOPEN_P_LOG); - - return handle; -} - -// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list? -#ifdef XIO_ERROR_BY_UCONTEXT -struct SkypopenHandles *skypopen_list_find(struct SkypopenList *list, struct SkypopenHandles *find) -{ - struct SkypopenHandles *iter; - struct SkypopenHandles *handle = NULL; - - switch_mutex_lock(globals.list_mutex); - - iter = (struct SkypopenHandles *) list->head; - while (iter != NULL) { - if (iter == find) { - handle = iter; - break; - } - - iter = (struct SkypopenHandles *) iter->next; - } - - switch_mutex_unlock(globals.list_mutex); - - return handle; -} -#endif - -// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list? -int skypopen_list_size(struct SkypopenList *list) -{ - return list->entries; -} -#endif /* NOT WIN32 */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile deleted file mode 100644 index 86aab9175e..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# -# Asterisk -- A telephony toolkit for Linux. -# -# Makefile for channel drivers -# -# Copyright (C) 1999-2005, Mark Spencer -# -# Mark Spencer -# -# Edited By Belgarath <> Aug 28 2004 -# Added bare bones ultrasparc-linux support. -# -# This program is free software, distributed under the terms of -# the GNU General Public License -# - -#ASTERISK INCLUDE FILES -#The directory that contains the Asterisk include files (eg: /usr/include or /usr/include/asterisk or /usr/src/asterisk/include or ...) -#AST_INCLUDE_DIR=/usr/src/asterisk/include -#AST_INCLUDE_DIR=/home/maruzz/devel/svn_asterisk_trunk/include -#AST_INCLUDE_DIR=/home/maruzz/devel/svn_asterisk_branches_160/include -#AST_INCLUDE_DIR=/home/maruzz/devel/svn_asterisk_branches_12/include -#AST_INCLUDE_DIR=/home/maruzz/devel/svn_asterisk_branches_14/include -#AST_INCLUDE_DIR=/home/maruzz/devel/svn_celliax_trunk/asterisk-1.2.rev137401/include -AST_INCLUDE_DIR=/home/user/devel/asterisk-1.4.23.1/include - -#ASTERISK -CFLAGS+=-DASTERISK - -#ASTERISK VERSION -#Uncomment one of the following lines to match your Asterisk series -CFLAGS+=-DASTERISK_VERSION_1_4 -#CFLAGS+=-DASTERISK_VERSION_1_6 -#CFLAGS+=-DASTERISK_VERSION_1_2 - -#LINUX SKYPE SUPPORT (Celliax for Cygwin always supports Skype) -SKYPE_LIB=-L/usr/X11R6/lib -lX11 - -CFLAGS+=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -CFLAGS+=-g3 - - - -CFLAGS+=-I$(AST_INCLUDE_DIR) -I. -CFLAGS+=-D_REENTRANT -D_GNU_SOURCE -#CFLAGS+=-O6 -CFLAGS+=-march=i686 -CFLAGS+=-fomit-frame-pointer -ifeq ($(shell uname -m),x86_64) -CFLAGS+=-fPIC -endif - -SVNDEF := -D'SKYPIAX_SVN_VERSION="$(shell svnversion -n ..)"' -CFLAGS += $(SVNDEF) - - -SOLINK=-shared -Xlinker -x -CHANNEL_LIBS=chan_skypiax.so -CC=gcc - -OSARCH=$(shell uname -s) - -ifeq ($(findstring CYGWIN,$(OSARCH)),CYGWIN) -# definition of pthread_kill as a printf (or as a noop) is required for Asterisk (and skypiax) to run on Cygwin -# without it, each time (often) pthread_kill is called (by any thread, with any signal, URG included), bad things happen -CC=gcc -D pthread_kill=cyg_no_pthreadkill -AST_DLL_DIR=/home/maruzz/devel/svn_asterisk_branches_12 -CYGSOLINK=-Wl,--out-implib=lib$@.a -Wl,--export-all-symbols cyg_no_pthread_kill.o -CYGSOLIB=-L/usr/lib/w32api -lrpcrt4 -L/lib/mingw -lwinmm -L$(AST_DLL_DIR) -lasterisk.dll -L$(AST_DLL_DIR)/res -lres_features.so -SKYPE_LIB= -CHANNEL_LIBS=cyg_no_pthread_kill.o chan_skypiax.so -endif - -all: $(CHANNEL_LIBS) - -clean: - rm -f *.so *.o *.so.a - - -#chan_skypiax section begins - -#to debug threads and lock on 1.4 uncomment the following -#CFLAGS+=-include /usr/src/asterisk/include/asterisk/autoconfig.h - - -cyg_no_pthread_kill.o: cyg_no_pthread_kill.c - $(CC) $(CFLAGS) -c -o cyg_no_pthread_kill.o cyg_no_pthread_kill.c -chan_skypiax.o: chan_skypiax.c - $(CC) $(CFLAGS) -c -o chan_skypiax.o chan_skypiax.c -chan_skypiax.so: chan_skypiax.o skypiax_protocol.o - $(CC) $(SOLINK) -o $@ ${CYGSOLINK} chan_skypiax.o skypiax_protocol.o -lm -ldl $(SKYPE_LIB) ${CYGSOLIB} -#chan_skypiax section ends - diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README deleted file mode 100644 index a3d352e0c6..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README +++ /dev/null @@ -1 +0,0 @@ -Skypopen for asterisk does not work yet. diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c deleted file mode 100644 index 52101f171b..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c +++ /dev/null @@ -1,2315 +0,0 @@ -//indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90 -#include "skypiax.h" - -/* LOCKS */ -/*! \brief Protect the skypiax_usecnt */ -AST_MUTEX_DEFINE_STATIC(skypiax_usecnt_lock); -/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not - * when it's doing something critical. */ -AST_MUTEX_DEFINE_STATIC(skypiax_monlock); -/*! \brief Protect the interfaces list */ -AST_MUTEX_DEFINE_STATIC(skypiax_iflock); - -/* GLOBAL VARIABLES */ -int running = 1; -int skypiax_dir_entry_extension = 1; //FIXME one var for each interface! -char skypiax_console_active_array[50] = ""; -char *skypiax_console_active = skypiax_console_active_array; -/*! \brief Count of active channels for this module */ -int skypiax_usecnt = 0; -int skypiax_debug = 0; -/*! \brief This is the thread for the monitor which checks for input on the channels - * which are not currently in use. */ -pthread_t skypiax_monitor_thread = AST_PTHREADT_NULL; -pthread_t skypiax_monitor_audio_thread = AST_PTHREADT_NULL; - -/* CONSTANTS */ -/*! \brief Textual description for this module */ -const char skypiax_desc[] = "Skypiax, Skype Driver"; -/*! \brief Textual type for this module */ -const char skypiax_type[] = "Skypiax"; -/*! \brief Name of configuration file for this module */ -const char skypiax_config[] = "skypiax.conf"; - -char skypiax_console_skypiax_usage[] = - " \n" "chan_skypiax commands info\n" " \n" - " chan_skypiax adds to Asterisk the following CLI commands:\n" " \n" - " CLI COMMANDS:\n" " skypiax_hangup\n" " skypiax_dial\n" - " skypiax_console\n" " skypiax_playback_boost\n" - " skypiax_capture_boost\n" " skypiax_skype\n" - " skypiax_dir_import\n" "\n" " You can type 'help [command]' to obtain more specific info on usage.\n" " \n"; -char skypiax_console_hangup_usage[] = - "Usage: skypiax_hangup\n" - " Hangs up any call currently placed on the \"current\" skypiax_console (Skypiax) channel.\n" - " Enter 'help skypiax_console' on how to change the \"current\" skypiax_console\n"; -char skypiax_console_playback_boost_usage[] = - "Usage: skypiax_playback_boost [value]\n" - " Shows or set the value of boost applied to the outgoing sound (voice). Possible values are: 0 (no boost applied), -40 to 40 (negative to positive range, in db). Without specifying a value, it just shows the current value. The value is for the \"current\" skypiax_console (Skypiax) channel.\n" - " Enter 'help skypiax_console' on how to change the \"current\" skypiax_console\n"; -char skypiax_console_capture_boost_usage[] = - "Usage: skypiax_capture_boost [value]\n" - " Shows or set the value of boost applied to the incoming sound (voice). Possible values are: 0 (no boost applied), -40 to 40 (negative to positive range, in db). Without specifying a value, it just shows the current value. The value is for the \"current\" skypiax_console (Skypiax) channel.\n" - " Enter 'help skypiax_console' on how to change the \"current\" skypiax_console\n"; - -char skypiax_console_dial_usage[] = - "Usage: skypiax_dial [DTMFs]\n" - " Dials a given DTMF string in the call currently placed on the\n" - " \"current\" skypiax_console (Skypiax) channel.\n" " Enter 'help skypiax_console' on how to change the \"current\" skypiax_console\n"; - -char skypiax_console_skypiax_console_usage[] = - "Usage: skypiax_console [interface] | [show]\n" - " If used without a parameter, displays which interface is the \"current\"\n" - " skypiax_console. If a device is specified, the \"current\" skypiax_console is changed to\n" - " the interface specified.\n" " If the parameter is \"show\", the available interfaces are listed\n"; - -char skypiax_console_skype_usage[] = - "Usage: skypiax_skype [command string]\n" - " Send the 'command string' skype_msg to the Skype client connected to the \"current\" skypiax_console (Skypiax) channel.\n" - " Enter 'help skypiax_console' on how to change the \"current\" skypiax_console\n"; - -char skypiax_console_skypiax_dir_import_usage[] = - "Usage: skypiax_dir_import [add | replace]\n" - " Write in the directoriax.conf config file all the entries found in 'Contacts' list of the Skype client connected to the \"current\" skypiax_console.\n" - " You can choose between 'add' to the end of the directoriax.conf file, or 'replace' the whole file with this new content.\n" - " Enter 'help skypiax_console' on how to change the \"current\" skypiax_console\n"; - -/*! \brief Definition of this channel for PBX channel registration */ -const struct ast_channel_tech skypiax_tech = { - .type = skypiax_type, - .description = skypiax_desc, - .capabilities = AST_FORMAT_SLINEAR, - .requester = skypiax_request, - .hangup = skypiax_hangup, - .answer = skypiax_answer, - .read = skypiax_read, - .call = skypiax_originate_call, - .write = skypiax_write, - .indicate = skypiax_indicate, - .fixup = skypiax_fixup, - .devicestate = skypiax_devicestate, -#ifdef ASTERISK_VERSION_1_4 - .send_digit_begin = skypiax_digitsend_begin, - .send_digit_end = skypiax_digitsend_end, -#else /* ASTERISK_VERSION_1_4 */ - .send_digit = skypiax_digitsend, -#endif /* ASTERISK_VERSION_1_4 */ -}; - -/*! \brief fake skypiax_pvt structure values, - * just for logging purposes */ -struct skypiax_pvt skypiax_log_struct = { - .name = "none", -}; - -/*! \brief Default skypiax_pvt structure values, - * used by skypiax_mkif to initialize the interfaces */ -struct skypiax_pvt skypiax_default = { - .interface_state = SKYPIAX_STATE_DOWN, - .skype_callflow = 0, - .context = "default", - .language = "en", - .exten = "s", - .next = NULL, - .owner = NULL, - .controldev_thread = AST_PTHREADT_NULL, - .skypiax_sound_rate = 8000, - .skypiax_sound_capt_fd = -1, - .capture_boost = 0, - .playback_boost = 0, - .stripmsd = 0, - .skype = 0, - .skypiax_dir_entry_extension_prefix = 6, -}; - -/*! - * \brief PVT structure for a skypiax interface (channel), created by skypiax_mkif - */ -struct skypiax_pvt *skypiax_iflist = NULL; - -#ifdef ASTERISK_VERSION_1_6 -struct ast_cli_entry myclis[] = { -/* - * CLI do not works since some time on 1.6, they changed the CLI mechanism - */ -#if 0 - AST_CLI_DEFINE(skypiax_console_hangup, "Hangup a call on the console"), - AST_CLI_DEFINE(skypiax_console_dial, "Dial an extension on the console"), - AST_CLI_DEFINE(skypiax_console_playback_boost, "Sets/displays spk boost in dB"), - AST_CLI_DEFINE(skypiax_console_capture_boost, "Sets/displays mic boost in dB"), - AST_CLI_DEFINE(skypiax_console_set_active, "Sets/displays active console"), - AST_CLI_DEFINE(skypiax_console_skype, "Sends a Skype command"), - AST_CLI_DEFINE(skypiax_console_skypiax_dir_import, "imports entries from cellphone"), - AST_CLI_DEFINE(skypiax_console_skypiax, "all things skypiax"), -#endif -}; -#else -struct ast_cli_entry myclis[] = { - {{"skypiax_hangup", NULL}, skypiax_console_hangup, - "Hangup a call on the skypiax_console", - skypiax_console_hangup_usage}, - {{"skypiax_playback_boost", NULL}, skypiax_console_playback_boost, "playback boost", - skypiax_console_playback_boost_usage}, - {{"skypiax_capture_boost", NULL}, skypiax_console_capture_boost, "capture boost", - skypiax_console_capture_boost_usage}, - {{"skypiax_usage", NULL}, skypiax_console_skypiax, "chan_skypiax commands info", - skypiax_console_skypiax_usage}, - {{"skypiax_skype", NULL}, skypiax_console_skype, "Skype msg", - skypiax_console_skype_usage}, - {{"skypiax_dial", NULL}, skypiax_console_dial, - "Dial an extension on the skypiax_console", - skypiax_console_dial_usage}, - {{"skypiax_console", NULL}, skypiax_console_set_active, - "Sets/displays active skypiax_console", - skypiax_console_skypiax_console_usage}, - {{"skypiax_dir_import", NULL}, skypiax_console_skypiax_dir_import, - "Write the directoriax.conf file, used by directoriax app", - skypiax_console_skypiax_dir_import_usage}, -}; -#endif - -/* IMPLEMENTATION */ - -void skypiax_unlocka_log(void *x) -{ - ast_mutex_t *y; - y = x; - int i; - - for (i = 0; i < 5; i++) { //let's be generous - - ast_log(LOG_DEBUG, - SKYPIAX_SVN_VERSION - "[%-7lx] I'm a dying thread, and I'm to go unlocking mutex %p for the %dth time\n", (unsigned long int) pthread_self(), y, i); - - ast_mutex_unlock(y); - } - ast_log(LOG_DEBUG, SKYPIAX_SVN_VERSION "[%-7lx] I'm a dying thread, I've finished unlocking mutex %p\n", (unsigned long int) pthread_self(), y); -} - -int skypiax_queue_control(struct ast_channel *c, int control) -{ - struct skypiax_pvt *p = c->tech_pvt; - -/* queue the frame */ - if (p) - p->control_to_send = control; - else { - return 0; - } - DEBUGA_PBX("Queued CONTROL FRAME %d\n", SKYPIAX_P_LOG, control); - -/* wait for the frame to be sent */ - while (p->control_to_send) - usleep(1); - - return 0; -} - -int skypiax_devicestate(void *data) -{ - struct skypiax_pvt *p = NULL; - char *name = data; - int res = AST_DEVICE_INVALID; - - if (!data) { - ERRORA("Devicestate requested with no data\n", SKYPIAX_P_LOG); - return res; - } - - /* lock the interfaces' list */ - LOKKA(&skypiax_iflock); - /* make a pointer to the first interface in the interfaces list */ - p = skypiax_iflist; - /* Search for the requested interface and verify if is unowned */ - while (p) { - size_t length = strlen(p->name); - /* is this the requested interface? */ - if (strncmp(name, p->name, length) == 0) { - /* is this interface unowned? */ - if (!p->owner) { - res = AST_DEVICE_NOT_INUSE; - DEBUGA_PBX("Interface is NOT OWNED by a channel\n", SKYPIAX_P_LOG); - } else { - /* interface owned by a channel */ - res = AST_DEVICE_INUSE; - DEBUGA_PBX("Interface is OWNED by a channel\n", SKYPIAX_P_LOG); - } - - /* we found the requested interface, bail out from the while loop */ - break; - } - /* not yet found, next please */ - p = p->next; - } - /* unlock the interfaces' list */ - UNLOCKA(&skypiax_iflock); - - if (res == AST_DEVICE_INVALID) { - ERRORA("Checking device state for interface [%s] returning AST_DEVICE_INVALID\n", SKYPIAX_P_LOG, name); - } - return res; -} - -#ifndef ASTERISK_VERSION_1_4 -int skypiax_indicate(struct ast_channel *c, int cond) -#else -int skypiax_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen) -#endif -{ - struct skypiax_pvt *p = c->tech_pvt; - int res = 0; - - NOTICA("Let's INDICATE %d\n", SKYPIAX_P_LOG, cond); - - switch (cond) { - case AST_CONTROL_BUSY: - case AST_CONTROL_CONGESTION: - case AST_CONTROL_RINGING: - case -1: - res = -1; /* Ask for inband indications */ - break; - case AST_CONTROL_PROGRESS: - case AST_CONTROL_PROCEEDING: - case AST_CONTROL_VIDUPDATE: - case AST_CONTROL_HOLD: - case AST_CONTROL_UNHOLD: -#ifdef ASTERISK_VERSION_1_4 - case AST_CONTROL_SRCUPDATE: -#endif /* ASTERISK_VERSION_1_4 */ - break; - default: - WARNINGA("Don't know how to display condition %d on %s\n", SKYPIAX_P_LOG, cond, c->name); - /* The core will play inband indications for us if appropriate */ - res = -1; - } - - return res; -} - -/*! \brief PBX interface function -build skypiax pvt structure - * skypiax calls initiated by the PBX arrive here */ -struct ast_channel *skypiax_request(const char *type, int format, void *data, int *cause) -{ - struct skypiax_pvt *p = NULL; - struct ast_channel *tmp = NULL; - char *name = data; - int found = 0; - - DEBUGA_PBX("Try to request type: %s, name: %s, cause: %d," " format: %d\n", SKYPIAX_P_LOG, type, name, *cause, format); - - if (!data) { - ERRORA("Channel requested with no data\n", SKYPIAX_P_LOG); - return NULL; - } - - char interface[256]; - int i; - memset(interface, '\0', sizeof(interface)); - - for (i = 0; i < sizeof(interface); i++) { - if (name[i] == '/') - break; - interface[i] = name[i]; - } - /* lock the interfaces' list */ - LOKKA(&skypiax_iflock); - /* make a pointer to the first interface in the interfaces list */ - p = skypiax_iflist; - - if (strcmp("ANY", interface) == 0) { - /* we've been asked for the "ANY" interface, let's find the first idle interface */ - DEBUGA_SKYPE("Finding one available skype interface\n", SKYPIAX_P_LOG); - p = find_available_skypiax_interface(); - if (p) { - found = 1; - - /* create a new channel owning this interface */ - tmp = skypiax_new(p, SKYPIAX_STATE_DOWN, p->context); - if (!tmp) { - /* the channel was not created, probable memory allocation error */ - *cause = AST_CAUSE_SWITCH_CONGESTION; - } - - } - - } - - /* Search for the requested interface and verify if is unowned and format compatible */ - while (p && !found) { - //size_t length = strlen(p->name); - /* is this the requested interface? */ - if (strcmp(interface, p->name) == 0) { - /* is the requested format supported by this interface? */ - if ((format & AST_FORMAT_SLINEAR) != 0) { - /* is this interface unowned? */ - if (!p->owner) { - DEBUGA_PBX("Requesting: %s, name: %s, format: %d\n", SKYPIAX_P_LOG, type, name, format); - /* create a new channel owning this interface */ - tmp = skypiax_new(p, SKYPIAX_STATE_DOWN, p->context); - if (!tmp) { - /* the channel was not created, probable memory allocation error */ - *cause = AST_CAUSE_SWITCH_CONGESTION; - } - } else { - /* interface owned by another channel */ - WARNINGA("owned by another channel\n", SKYPIAX_P_LOG); - *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; - } - } else { - /* requested format not supported */ - WARNINGA("format %d not supported\n", SKYPIAX_P_LOG, format); - *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; - } - /* we found the requested interface, bail out from the while loop */ - break; - } - /* not yet found, next please */ - p = p->next; - } - /* unlock the interfaces' list */ - UNLOCKA(&skypiax_iflock); - /* restart the monitor so it will watch only the remaining unowned interfaces */ - skypiax_restart_monitor(); - if (tmp == NULL) { - /* new channel was not created */ - WARNINGA("Unable to create new Skypiax channel %s\n", SKYPIAX_P_LOG, name); - } - /* return the newly created channel */ - return tmp; -} - -/*! \brief Hangup skypiax call - * Part of PBX interface, called from ast_hangup */ - -int skypiax_hangup(struct ast_channel *c) -{ - struct skypiax_pvt *p; - - /* get our skypiax pvt interface from channel */ - p = c->tech_pvt; - /* if there is not skypiax pvt why we are here ? */ - if (!p) { - ERRORA("Asked to hangup channel not connected\n", SKYPIAX_P_LOG); - return 0; - } - - if (p->skype && p->interface_state != SKYPIAX_STATE_DOWN) { - char msg_to_skype[1024]; - p->interface_state = SKYPIAX_STATE_HANGUP_REQUESTED; - DEBUGA_SKYPE("hanging up skype call: %s\n", SKYPIAX_P_LOG, p->skype_call_id); - //sprintf(msg_to_skype, "SET CALL %s STATUS FINISHED", p->skype_call_id); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", p->skype_call_id); - skypiax_signaling_write(p, msg_to_skype); - } - - while (p->interface_state != SKYPIAX_STATE_DOWN) { - usleep(10000); - } - DEBUGA_SKYPE("Now is really DOWN\n", SKYPIAX_P_LOG); - /* shutdown the serial monitoring thread */ - if (p->controldev_thread && (p->controldev_thread != AST_PTHREADT_NULL) - && (p->controldev_thread != AST_PTHREADT_STOP)) { - if (pthread_cancel(p->controldev_thread)) { - ERRORA("controldev_thread pthread_cancel failed, maybe he killed himself?\n", SKYPIAX_P_LOG); - } - /* push it, maybe is stuck in a select or so */ - if (pthread_kill(p->controldev_thread, SIGURG)) { - DEBUGA_SERIAL("controldev_thread pthread_kill failed, no problem\n", SKYPIAX_P_LOG); - } -#ifndef __CYGWIN__ /* under cygwin, this seems to be not reliable, get stuck at times */ - /* wait for it to die */ - if (pthread_join(p->controldev_thread, NULL)) { - ERRORA("controldev_thread pthread_join failed, BAD\n", SKYPIAX_P_LOG); - } -#else /* __CYGWIN__ */ -/* allow the serial thread to die */ - usleep(300000); //300msecs -#endif /* __CYGWIN__ */ - } - p->controldev_thread = AST_PTHREADT_NULL; - - p->interface_state = SKYPIAX_STATE_DOWN; - p->skype_callflow = CALLFLOW_CALL_IDLE; - - DEBUGA_PBX("I'll send AST_CONTROL_HANGUP\n", SKYPIAX_P_LOG); - ast_queue_control(p->owner, AST_CONTROL_HANGUP); - DEBUGA_PBX("I've sent AST_CONTROL_HANGUP\n", SKYPIAX_P_LOG); - - /* subtract one to the usage count of Skypiax-type channels */ - LOKKA(&skypiax_usecnt_lock); - skypiax_usecnt--; - if (skypiax_usecnt < 0) - ERRORA("Usecnt < 0???\n", SKYPIAX_P_LOG); - UNLOCKA(&skypiax_usecnt_lock); - ast_update_use_count(); - - /* our skypiax pvt interface is no more part of a channel */ - p->owner = NULL; - /* our channel has no more this skypiax pvt interface to manage */ - c->tech_pvt = NULL; - /* set the channel state to DOWN, eg. available, not in active use */ - if (ast_setstate(c, SKYPIAX_STATE_DOWN)) { - ERRORA("ast_setstate failed, BAD\n", SKYPIAX_P_LOG); - return -1; - } - - /* restart the monitor thread, so it can recheck which interfaces it have to watch during its loop (the interfaces that are not owned by channels) */ - if (skypiax_restart_monitor()) { - ERRORA("skypiax_restart_monitor failed, BAD\n", SKYPIAX_P_LOG); - return -1; - } - - return 0; -} - -/*! \brief Answer incoming call, - * Part of PBX interface */ -int skypiax_answer(struct ast_channel *c) -{ - struct skypiax_pvt *p = c->tech_pvt; - int res; - - /* whle ringing, we just wait, the skype thread will answer */ - while (p->interface_state == SKYPIAX_STATE_RING) { - usleep(10000); //10msec - } - if (p->interface_state != SKYPIAX_STATE_UP) { - ERRORA("call answering failed, we want it to be into interface_state=%d, got %d\n", SKYPIAX_P_LOG, SKYPIAX_STATE_UP, p->interface_state); - res = -1; - } else { - DEBUGA_PBX("call answered\n", SKYPIAX_P_LOG); - res = 0; - } - return res; -} - -#ifdef ASTERISK_VERSION_1_4 -int skypiax_digitsend_begin(struct ast_channel *c, char digit) -{ - struct skypiax_pvt *p = c->tech_pvt; - - DEBUGA_PBX("DIGIT BEGIN received: %c\n", SKYPIAX_P_LOG, digit); - - return 0; -} - -int skypiax_digitsend_end(struct ast_channel *c, char digit, unsigned int duration) -{ - struct skypiax_pvt *p = c->tech_pvt; - char msg_to_skype[1024]; - - NOTICA("DIGIT END received: %c %d\n", SKYPIAX_P_LOG, digit, duration); - - sprintf(msg_to_skype, "SET CALL %s DTMF %c", p->skype_call_id, digit); - - skypiax_signaling_write(p, msg_to_skype); - - return 0; -} -#else /* ASTERISK_VERSION_1_4 */ -int skypiax_digitsend(struct ast_channel *c, char digit) -{ - struct skypiax_pvt *p = c->tech_pvt; - char msg_to_skype[1024]; - - NOTICA("DIGIT received: %c\n", SKYPIAX_P_LOG, digit); - - sprintf(msg_to_skype, "SET CALL %s DTMF %c", p->skype_call_id, digit); - - skypiax_signaling_write(p, msg_to_skype); - - return 0; -} - -#endif /* ASTERISK_VERSION_1_4 */ -//struct ast_frame *skypiax_audio_read(struct skypiax_pvt *p) -//#define SAMPLES_PER_FRAME 160 -/*! \brief Read audio frames from channel */ -struct ast_frame *skypiax_read(struct ast_channel *c) -{ - struct skypiax_pvt *p = c->tech_pvt; - static struct ast_frame f; - static short __buf[SKYPIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - short *buf; - int samples; - -/* if there are control frames queued to be sent by skypiax_queue_control, send it the first */ -//TODO maybe better a real queue? - if (p && p->owner && p->control_to_send) { - ast_queue_control(p->owner, p->control_to_send); - DEBUGA_PBX("Sent CONTROL FRAME %d\n", SKYPIAX_P_LOG, p->control_to_send); - p->control_to_send = 0; - } - - memset(__buf, '\0', (SKYPIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2)); - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - - f.frametype = AST_FRAME_NULL; - f.subclass = 0; - f.samples = 0; - f.datalen = 0; - f.data = NULL; - f.offset = 0; - f.src = skypiax_type; - f.mallocd = 0; - f.delivery.tv_sec = 0; - f.delivery.tv_usec = 0; - -/* if the call is not active (ie: answered), do not send audio frames, they would pile up in a lag queue */ - if (p->owner && p->owner->_state != SKYPIAX_STATE_UP) { - return &f; - } - - if ((samples = read(p->audiopipe[0], buf, SAMPLES_PER_FRAME * sizeof(short))) != 320) { - DEBUGA_SOUND("read=====> NOT GOOD samples=%d expected=%d\n", SKYPIAX_P_LOG, samples, SAMPLES_PER_FRAME * sizeof(short)); - usleep(100); - //do nothing - } else { - //DEBUGA_SOUND("read=====> GOOD samples=%d\n", SKYPIAX_P_LOG, samples); - /* A real frame */ - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = SKYPIAX_FRAME_SIZE; - f.datalen = SKYPIAX_FRAME_SIZE * 2; - f.data = buf; - f.offset = AST_FRIENDLY_OFFSET; - f.src = skypiax_type; - f.mallocd = 0; - - if (p->capture_boost) - skypiax_sound_boost(&f, p->capture_boost); - } - - return &f; -} - -/*! \brief Initiate skypiax call from PBX - * used from the dial() application - */ -int skypiax_originate_call(struct ast_channel *c, char *idest, int timeout) -{ - struct skypiax_pvt *p = NULL; - p = c->tech_pvt; - char rdest[80], *where, dstr[100] = ""; - char *stringp = NULL; - int status; - - if ((c->_state != SKYPIAX_STATE_DOWN) - && (c->_state != SKYPIAX_STATE_RESERVED)) { - ERRORA("skypiax_originate_call called on %s, neither down nor reserved\n", SKYPIAX_P_LOG, c->name); - return -1; - } - - DEBUGA_PBX("skypiax_originate_call to call idest: %s, timeout: %d!\n", SKYPIAX_P_LOG, idest, timeout); - - strncpy(rdest, idest, sizeof(rdest) - 1); - stringp = rdest; - strsep(&stringp, "/"); - where = strsep(&stringp, "/"); - if (!where) { - ERRORA("Destination %s requires an actual destination (Skypiax/device/destination)\n", SKYPIAX_P_LOG, idest); - return -1; - } - - strncpy(dstr, where + p->stripmsd, sizeof(dstr) - 1); - DEBUGA_PBX("skypiax_originate_call dialing idest: %s, timeout: %d, dstr: %s!\n", SKYPIAX_P_LOG, idest, timeout, dstr); - - strcpy(p->session_uuid_str, "dialing"); - status = skypiax_call(p, dstr, timeout); - if (status) { - WARNINGA("skypiax_originate_call dialing failed: %d!\n", SKYPIAX_P_LOG, status); - return -1; - } - - DEBUGA_PBX("skypiax_originate_call dialed idest: %s, timeout: %d, dstr: %s!\n", SKYPIAX_P_LOG, idest, timeout, dstr); - - ast_setstate(p->owner, SKYPIAX_STATE_DIALING); - return 0; -} - -int skypiax_sound_boost(struct ast_frame *f, double boost) -{ -/* LUIGI RIZZO's magic */ - if (boost != 0) { /* scale and clip values */ - int i, x; - int16_t *ptr = (int16_t *) f->data; - for (i = 0; i < f->samples; i++) { - x = (ptr[i] * boost) / BOOST_SCALE; - if (x > 32767) { - x = 32767; - } else if (x < -32768) { - x = -32768; - } - ptr[i] = x; - } - } - return 0; -} - -/*! \brief Send audio frame to channel */ -int skypiax_write(struct ast_channel *c, struct ast_frame *f) -{ - struct skypiax_pvt *p = c->tech_pvt; - int sent; - - if (p->owner && p->owner->_state != SKYPIAX_STATE_UP) { - return 0; - } - if (p->playback_boost) - skypiax_sound_boost(f, p->playback_boost); - - sent = write(p->audioskypepipe[1], (short *) f->data, f->datalen); - //skypiax_sound_write(p, f); - - return 0; -} - -/*! \brief Fix up a channel: If a channel is consumed, this is called. - * Basically update any ->owner links */ -int skypiax_fixup(struct ast_channel *oldchan, struct ast_channel *newchan) -{ - struct skypiax_pvt *p = newchan->tech_pvt; - - if (!p) { - ERRORA("No pvt after masquerade. Strange things may happen\n", SKYPIAX_P_LOG); - return -1; - } - - if (p->owner != oldchan) { - ERRORA("old channel wasn't %p but was %p\n", SKYPIAX_P_LOG, oldchan, p->owner); - return -1; - } - - p->owner = newchan; - return 0; -} - -struct ast_channel *skypiax_new(struct skypiax_pvt *p, int state, char *context) -{ - struct ast_channel *tmp; - - /* alloc a generic channel struct */ -#ifndef ASTERISK_VERSION_1_4 - tmp = ast_channel_alloc(1); -#else - //tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, ""); - //tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Skypiax/%s", p->name); - tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "Skypiax/%s", p->name); - -#endif /* ASTERISK_VERSION_1_4 */ - if (tmp) { - - /* give a name to the newly created channel */ -#ifndef ASTERISK_VERSION_1_4 - snprintf(tmp->name, sizeof(tmp->name), "Skypiax/%s", p->name); - tmp->type = skypiax_type; -#else /* ASTERISK_VERSION_1_4 */ - ast_string_field_build(tmp, name, "Skypiax/%s", p->name); -#endif /* ASTERISK_VERSION_1_4 */ - - DEBUGA_PBX("new channel: name=%s requested_state=%d\n", SKYPIAX_P_LOG, tmp->name, state); - - /* fd for the channel to poll for incoming audio */ - tmp->fds[0] = p->skypiax_sound_capt_fd; - - /* audio formats managed */ - tmp->nativeformats = AST_FORMAT_SLINEAR; - tmp->readformat = AST_FORMAT_SLINEAR; - tmp->writeformat = AST_FORMAT_SLINEAR; - /* the technology description (eg. the interface type) of the newly created channel is the Skypiax's one */ - tmp->tech = &skypiax_tech; - /* the technology pvt (eg. the interface) of the newly created channel is this interface pvt */ - tmp->tech_pvt = p; - - /* copy this interface default context, extension, language to the newly created channel */ - if (strlen(p->context)) - strncpy(tmp->context, p->context, sizeof(tmp->context) - 1); - if (strlen(p->exten)) - strncpy(tmp->exten, p->exten, sizeof(tmp->exten) - 1); -#ifndef ASTERISK_VERSION_1_4 - if (strlen(p->language)) - strncpy(tmp->language, p->language, sizeof(tmp->language) - 1); -#else - if (strlen(p->language)) - ast_string_field_set(tmp, language, p->language); -#endif /* ASTERISK_VERSION_1_4 */ - /* copy the requested context (not necessarily the interface default) to the newly created channel */ - if (strlen(context)) - strncpy(tmp->context, context, sizeof(tmp->context) - 1); - - /* copy this interface default callerid in the newly created channel */ - ast_set_callerid(tmp, !ast_strlen_zero(p->callid_number) ? p->callid_number : NULL, - !ast_strlen_zero(p->callid_name) ? p->callid_name : NULL, !ast_strlen_zero(p->callid_number) ? p->callid_number : NULL); - - DEBUGA_PBX("callid_number=%s, callid_name=%s\n", SKYPIAX_P_LOG, p->callid_number, p->callid_name); - - /* the owner of this interface pvt is the newly created channel */ - p->owner = tmp; - /* set the newly created channel state to the requested state */ - if (ast_setstate(tmp, state)) { - ERRORA("ast_setstate failed, BAD\n", SKYPIAX_P_LOG); - //ast_dsp_free(p->dsp); - ast_channel_free(tmp); - return NULL; - } - /* if the requested state is different from DOWN, let the pbx manage this interface (now part of the newly created channel) */ - if (state != SKYPIAX_STATE_DOWN) { - DEBUGA_PBX("Try to start PBX on %s, state=%d\n", SKYPIAX_P_LOG, tmp->name, state); - if (ast_pbx_start(tmp)) { - ERRORA("Unable to start PBX on %s\n", SKYPIAX_P_LOG, tmp->name); - ast_channel_free(tmp); - return NULL; - } - } - /* let's start the serial monitoring thread too, so we can have serial signaling */ - if (ast_pthread_create(&p->controldev_thread, NULL, skypiax_do_controldev_thread, p) < 0) { - ERRORA("Unable to start controldev thread.\n", SKYPIAX_P_LOG); - ast_channel_free(tmp); - tmp = NULL; - } - DEBUGA_SERIAL("STARTED controldev_thread=%lu STOP=%lu NULL=%lu\n", SKYPIAX_P_LOG, - (unsigned long) p->controldev_thread, (unsigned long) AST_PTHREADT_STOP, (unsigned long) AST_PTHREADT_NULL); - - /* add one to the usage count of Skypiax-type channels */ - LOKKA(&skypiax_usecnt_lock); - skypiax_usecnt++; - UNLOCKA(&skypiax_usecnt_lock); - ast_update_use_count(); - - /* return the newly created channel */ - return tmp; - } - ERRORA("failed memory allocation for Skypiax channel\n", SKYPIAX_P_LOG); - return NULL; -} - -/*! - * \brief Load the module into Asterisk and start its threads - * - * This function register the module into Asterisk, - * create the interfaces for the channels, - * start the auxiliary threads for the interfaces, - * then start a monitor thread. The monitor thread - * will signal Asterisk when an interface receive a call. - * - * - * \return zero on success, -1 on error. - */ -int load_module(void) -{ - int i; - struct ast_config *cfg; - struct skypiax_pvt *tmp; - struct skypiax_pvt *p = NULL; - struct skypiax_pvt *p2 = NULL; -#ifdef ASTERISK_VERSION_1_6 - struct ast_flags config_flags = { 0 }; -#endif /* ASTERISK_VERSION_1_6 */ - -#if defined(WANT_SKYPE_X11) || defined(__CYGWIN__) -#ifndef __CYGWIN__ - if (!XInitThreads()) - ast_log(LOG_ERROR, "Not initialized XInitThreads!\n"); -#endif /* __CYGWIN__ */ -#if 0 - ast_register_atexit(skypiax_disconnect); - ast_register_application(skype2skypiaxapp, skype2skypiax, skype2skypiaxsynopsis, skype2skypiaxdescrip); - ast_register_application(skypiax2skypeapp, skypiax2skype, skypiax2skypesynopsis, skypiax2skypedescrip); -#endif -#endif /* defined(WANT_SKYPE_X11) || defined(__CYGWIN__) */ - - /* make sure we can register our channel type with Asterisk */ - i = ast_channel_register(&skypiax_tech); - if (i < 0) { - ERRORA("Unable to register channel type '%s'\n", SKYPIAX_P_LOG, skypiax_type); - return -1; - } - /* load skypiax.conf config file */ -#ifdef ASTERISK_VERSION_1_6 - cfg = ast_config_load(skypiax_config, config_flags); -#else - cfg = ast_config_load(skypiax_config); -#endif /* ASTERISK_VERSION_1_6 */ - if (cfg != NULL) { - char *ctg = NULL; - int is_first_category = 1; - while ((ctg = ast_category_browse(cfg, ctg)) != NULL) { - /* create one interface for each category in skypiax.conf config file, first one set the defaults */ - tmp = skypiax_mkif(cfg, ctg, is_first_category); - if (tmp) { - DEBUGA_PBX("Created channel Skypiax: skypiax.conf category '[%s]', channel name '%s'" "\n", SKYPIAX_P_LOG, ctg, tmp->name); - /* add interface to skypiax_iflist */ - tmp->next = skypiax_iflist; - skypiax_iflist = tmp; - /* next one will not be the first ;) */ - if (is_first_category == 1) { - is_first_category = 0; - skypiax_console_active = tmp->name; - } - } else { - ERRORA("Unable to create channel Skypiax from skypiax.conf category '[%s]'\n", SKYPIAX_P_LOG, ctg); - /* if error, unload config from memory and return */ - ast_config_destroy(cfg); - ast_channel_unregister(&skypiax_tech); - return -1; - } - /* do it for each category described in config */ - } - - /* we finished, unload config from memory */ - ast_config_destroy(cfg); - } else { - ERRORA("Unable to load skypiax_config skypiax.conf\n", SKYPIAX_P_LOG); - ast_channel_unregister(&skypiax_tech); - return -1; - } -#ifndef ASTERISK_VERSION_1_6 - ast_cli_register_multiple(myclis, sizeof(myclis) / sizeof(struct ast_cli_entry)); -#endif /* ASTERISK_VERSION_1_6 */ - /* start to monitor the interfaces (skypiax_iflist) for the first time */ - if (skypiax_restart_monitor()) { - ERRORA("skypiax_restart_monitor failed, BAD\n", SKYPIAX_P_LOG); - return -1; - } - /* go through the interfaces list (skypiax_iflist) WITHOUT locking */ - p = skypiax_iflist; - while (p) { - int i; - /* for each interface in list */ - p2 = p->next; - NOTICA("STARTING interface %s, please be patient\n", SKYPIAX_P_LOG, p->name); - i = 0; - while (p->SkypiaxHandles.api_connected == 0 && running && i < 60000) { // 60sec FIXME - usleep(1000); - i++; - } - if (p->SkypiaxHandles.api_connected) { - NOTICA("STARTED interface %s\n", SKYPIAX_P_LOG, p->name); - } else { - ERRORA("Interface %s FAILED to start\n", SKYPIAX_P_LOG, p->name); - running = 0; - return -1; - } - /* next one, please */ - p = p2; - } - return 0; -} - -/*! - * \brief Unload the module from Asterisk and shutdown its threads - * - * This function unregister the module from Asterisk, - * destroy the interfaces for the channels, - * shutdown the auxiliary threads for the interfaces, - * then shutdown its monitor thread. - * - * \return zero on success, -1 on error. - */ -int unload_module(void) -{ - struct skypiax_pvt *p = NULL, *p2 = NULL; - int res; - - /* unregister our channel type with Asterisk */ - ast_channel_unregister(&skypiax_tech); - ast_cli_unregister_multiple(myclis, sizeof(myclis) / sizeof(struct ast_cli_entry)); - -#if defined(WANT_SKYPE_X11) || defined(__CYGWIN__) -#ifndef __CYGWIN__ - //FIXME what to do? if (!XInitThreads()) - //FIXME what to do? ast_log(LOG_ERROR, "Not initialized XInitThreads!\n"); -#endif /* __CYGWIN__ */ -#if 0 - ast_unregister_atexit(skypiax_disconnect); - ast_unregister_application(skype2skypiaxapp); - ast_unregister_application(skypiax2skypeapp); -#endif -#endif /* defined(WANT_SKYPE_X11) || defined(__CYGWIN__) */ - - /* lock the skypiax_monlock, kill the monitor thread, unlock the skypiax_monlock */ - LOKKA(&skypiax_monlock); - if (skypiax_monitor_thread && (skypiax_monitor_thread != AST_PTHREADT_NULL) - && (skypiax_monitor_thread != AST_PTHREADT_STOP)) { - if (pthread_cancel(skypiax_monitor_thread)) { - ERRORA("pthread_cancel failed, BAD\n", SKYPIAX_P_LOG); - return -1; - } - if (pthread_kill(skypiax_monitor_thread, SIGURG)) { - DEBUGA_PBX("pthread_kill failed\n", SKYPIAX_P_LOG); //maybe it just died - } -#ifndef __CYGWIN__ /* under cygwin, this seems to be not reliable, get stuck at times */ - if (pthread_join(skypiax_monitor_thread, NULL)) { - ERRORA("pthread_join failed, BAD\n", SKYPIAX_P_LOG); - return -1; - } -#endif /* __CYGWIN__ */ - } - skypiax_monitor_thread = AST_PTHREADT_STOP; - UNLOCKA(&skypiax_monlock); - - if (skypiax_monitor_audio_thread && (skypiax_monitor_audio_thread != AST_PTHREADT_NULL) - && (skypiax_monitor_audio_thread != AST_PTHREADT_STOP)) { - - if (pthread_cancel(skypiax_monitor_audio_thread)) { - ERRORA("pthread_cancel skypiax_monitor_audio_thread failed, BAD\n", SKYPIAX_P_LOG); - } - if (pthread_kill(skypiax_monitor_audio_thread, SIGURG)) { - DEBUGA_PBX("pthread_kill skypiax_monitor_audio_thread failed, no problem\n", SKYPIAX_P_LOG); //maybe it just died - } - - if (pthread_join(skypiax_monitor_audio_thread, NULL)) { - ERRORA("pthread_join failed, BAD\n", SKYPIAX_P_LOG); - } - } - /* lock the skypiax_iflock, and go through the interfaces list (skypiax_iflist) */ - LOKKA(&skypiax_iflock); - p = skypiax_iflist; - while (p) { - /* for each interface in list */ - p2 = p->next; - /* shutdown the sound system, close sound fds, and if exist shutdown the sound managing threads */ - DEBUGA_SOUND("shutting down sound\n", SKYPIAX_P_LOG); - res = skypiax_sound_shutdown(p); - if (res == -1) { - ERRORA("Failed to shutdown sound\n", SKYPIAX_P_LOG); - } -#if 0 - /* if a dsp struct has been allocated, free it */ - if (p->dsp) { - ast_dsp_free(p->dsp); - p->dsp = NULL; - } -#endif - DEBUGA_PBX("freeing PVT\n", SKYPIAX_P_LOG); - /* free the pvt allocated memory */ - free(p); - /* next one, please */ - p = p2; - } - /* finished with the interfaces list, unlock the skypiax_iflock */ - UNLOCKA(&skypiax_iflock); - -#ifdef __CYGWIN__ - NOTICA("Sleping 5 secs, please wait...\n", SKYPIAX_P_LOG); - sleep(5); /* without this pause, for some unknown (to me) reason it crashes on cygwin */ -#endif /* __CYGWIN__ */ - NOTICA("Unloaded Skypiax Module\n", SKYPIAX_P_LOG); - return 0; -} - -/*! - * \brief Return the count of active channels for this module - * - * \return the count of active channels for this module - */ -int usecount() -{ - int res; - static struct skypiax_pvt *p = &skypiax_log_struct; -/* lock the skypiax_usecnt lock */ - LOKKA(&skypiax_usecnt_lock); - /* retrieve the skypiax_usecnt */ - res = skypiax_usecnt; -/* unlock the skypiax_usecnt lock */ - UNLOCKA(&skypiax_usecnt_lock); - /* return the skypiax_usecnt */ - return res; -} - -/*! - * \brief Return the textual description of the module - * - * \return the textual description of the module - */ -char *description() -{ - return (char *) skypiax_desc; -} - -/*! - * \brief Return the ASTERISK_GPL_KEY - * - * \return the ASTERISK_GPL_KEY - */ -char *key() -{ - struct skypiax_pvt *p = NULL; - - NOTICA("Returning Key\n", SKYPIAX_P_LOG); - - return ASTERISK_GPL_KEY; -} - -/*! - * \brief Create and initialize one interface for the module - * \param cfg pointer to configuration data from skypiax.conf - * \param ctg pointer to a category name to be found in cfg - * \param is_first_category is this the first category in cfg - * - * This function create and initialize one interface for the module - * - * \return a pointer to the PVT structure of interface on success, NULL on error. - */ -struct skypiax_pvt *skypiax_mkif(struct ast_config *cfg, char *ctg, int is_first_category) -{ - struct skypiax_pvt *tmp; - struct ast_variable *v; - int res; - - int debug_all = 0; - int debug_at = 0; - int debug_fbus2 = 0; - int debug_serial = 0; - int debug_sound = 0; - int debug_pbx = 0; - int debug_skype = 0; - int debug_call = 0; - int debug_locks = 0; - int debug_monitorlocks = 0; - - ast_log(LOG_DEBUG, "ENTERING FUNC\n"); - /* alloc memory for PVT */ - tmp = malloc(sizeof(struct skypiax_pvt)); - if (tmp == NULL) { /* fail */ - return NULL; - } - /* clear memory for PVT */ - memset(tmp, 0, sizeof(struct skypiax_pvt)); - - /* if we are reading the "first" category of the config file, take SELECTED values as defaults, overriding the values in skypiax_default */ - if (is_first_category == 1) { - /* for each variable in category, copy it in the skypiax_default struct */ - for (v = ast_variable_browse(cfg, ctg); v; v = v->next) { - M_START(v->name, v->value); - - M_STR("context", skypiax_default.context) - M_STR("language", skypiax_default.language) - M_STR("extension", skypiax_default.exten) - M_F("playback_boost", skypiax_store_boost(v->value, &skypiax_default.playback_boost)) - M_F("capture_boost", skypiax_store_boost(v->value, &skypiax_default.capture_boost)) - M_UINT("skypiax_dir_entry_extension_prefix", skypiax_default.skypiax_dir_entry_extension_prefix) - M_END(; - ); - } - } - - /* initialize the newly created PVT from the skypiax_default values */ - *tmp = skypiax_default; - - /* the category name becomes the interface name */ - tmp->name = strdup(ctg); - - /* for each category in config file, "first" included, read in ALL the values */ - for (v = ast_variable_browse(cfg, ctg); v; v = v->next) { - M_START(v->name, v->value); - - M_BOOL("debug_all", debug_all) - M_BOOL("debug_at", debug_at) - M_BOOL("debug_fbus2", debug_fbus2) - M_BOOL("debug_serial", debug_serial) - M_BOOL("debug_sound", debug_sound) - M_BOOL("debug_pbx", debug_pbx) - M_BOOL("debug_skype", debug_skype) - M_BOOL("debug_call", debug_call) - M_BOOL("debug_locks", debug_locks) - M_BOOL("debug_monitorlocks", debug_monitorlocks) - M_BOOL("skype", tmp->skype) - M_STR("context", tmp->context) - M_STR("language", tmp->language) - M_STR("extension", tmp->exten) - M_STR("X11_display", tmp->X11_display) - M_UINT("tcp_cli_port", tmp->tcp_cli_port) - M_UINT("tcp_srv_port", tmp->tcp_srv_port) - M_F("playback_boost", skypiax_store_boost(v->value, &tmp->playback_boost)) - M_F("capture_boost", skypiax_store_boost(v->value, &tmp->capture_boost)) - M_STR("skype_user", tmp->skype_user) - M_UINT("skypiax_dir_entry_extension_prefix", tmp->skypiax_dir_entry_extension_prefix) - M_END(; - ); - } - - if (debug_all) { - skypiax_debug = skypiax_debug | DEBUG_ALL; - if (!option_debug) { - WARNINGA - ("DEBUG_ALL activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_ALL debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_ALL activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_fbus2) { - skypiax_debug = skypiax_debug | DEBUG_FBUS2; - if (!option_debug) { - WARNINGA - ("DEBUG_FBUS2 activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_FBUS2 debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_FBUS2 activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_serial) { - skypiax_debug = skypiax_debug | DEBUG_SERIAL; - if (!option_debug) { - WARNINGA - ("DEBUG_SERIAL activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_SERIAL debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_SERIAL activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_sound) { - skypiax_debug = skypiax_debug | DEBUG_SOUND; - if (!option_debug) { - WARNINGA - ("DEBUG_SOUND activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_SOUND debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_SOUND activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_pbx) { - skypiax_debug = skypiax_debug | DEBUG_PBX; - if (!option_debug) { - WARNINGA - ("DEBUG_PBX activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_PBX debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_PBX activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_skype) { - skypiax_debug = skypiax_debug | DEBUG_SKYPE; - if (!option_debug) { - WARNINGA - ("DEBUG_SKYPE activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_SKYPE debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_SKYPE activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_call) { - skypiax_debug = skypiax_debug | DEBUG_CALL; - if (!option_debug) { - WARNINGA - ("DEBUG_CALL activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_CALL debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_CALL activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_locks) { - skypiax_debug = skypiax_debug | DEBUG_LOCKS; - if (!option_debug) { - WARNINGA - ("DEBUG_LOCKS activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_LOCKS debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_LOCKS activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (debug_monitorlocks) { - skypiax_debug = skypiax_debug | DEBUG_MONITORLOCKS; - if (!option_debug) { - WARNINGA - ("DEBUG_MONITORLOCKS activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_MONITORLOCKS debugging output.\n", - SKYPIAX_TMP_LOG); - } else { - NOTICA("DEBUG_MONITORLOCKS activated. \n", SKYPIAX_TMP_LOG); - } - } - - if (option_debug > 1) { - DEBUGA_SOUND("playback_boost is %f\n", SKYPIAX_TMP_LOG, tmp->playback_boost); - DEBUGA_SOUND("capture_boost is %f\n", SKYPIAX_TMP_LOG, tmp->capture_boost); - } -/* initialize the soundcard channels (input and output) used by this interface (a multichannel soundcard can be used by multiple interfaces), optionally starting the sound managing threads */ - res = skypiax_sound_init(tmp); - if (res == -1) { - ERRORA("Failed initializing sound device\n", SKYPIAX_TMP_LOG); - /* we failed, free the PVT */ - free(tmp); - return NULL; - } - /* - res = pipe(tmp->SkypiaxHandles.fdesc); - if (res) { - ast_log(LOG_ERROR, "Unable to create skype pipe\n"); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_TMP_LOG); - } - free(tmp); - return NULL; - } - fcntl(tmp->SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK); - fcntl(tmp->SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK); - */ - tmp->skype_thread = AST_PTHREADT_NULL; - - if (tmp->skype) { - ast_log(LOG_DEBUG, "TO BE started skype_thread=%lu STOP=%lu NULL=%lu\n", - (unsigned long) tmp->skype_thread, (unsigned long) AST_PTHREADT_STOP, (unsigned long) AST_PTHREADT_NULL); -#ifdef __CYGWIN__ - if (ast_pthread_create(&tmp->skype_thread, NULL, do_skypeapi_thread, tmp) < 0) { - ast_log(LOG_ERROR, "Unable to start skype_main thread.\n"); - free(tmp); - return NULL; - } -#else /* __CYGWIN__ */ -#ifdef WANT_SKYPE_X11 - ast_log(LOG_DEBUG, "AsteriskHandlesfd: %d\n", tmp->SkypiaxHandles.fdesc[1]); - if (ast_pthread_create(&tmp->skype_thread, NULL, do_skypeapi_thread, tmp) < 0) { - ast_log(LOG_ERROR, "Unable to start skype_main thread.\n"); - free(tmp); - return NULL; - } -#endif /* WANT_SKYPE_X11 */ -#endif /* __CYGWIN__ */ - usleep(100000); //0.1 sec - if (tmp->skype_thread == AST_PTHREADT_NULL) { - ast_log(LOG_ERROR, "Unable to start skype_main thread.\n"); - free(tmp); - return NULL; - } - ast_log(LOG_DEBUG, "STARTED skype_thread=%lu STOP=%lu NULL=%lu\n", - (unsigned long) tmp->skype_thread, (unsigned long) AST_PTHREADT_STOP, (unsigned long) AST_PTHREADT_NULL); - } -#if 0 - if (tmp->skype) { -#if 0 - if (option_debug > 1) - ast_log(LOG_DEBUG, "TO BE started skype_thread=%lu STOP=%lu NULL=%lu\n", - (unsigned long) tmp->skype_thread, (unsigned long) AST_PTHREADT_STOP, (unsigned long) AST_PTHREADT_NULL); -#endif -#ifdef __CYGWIN__ - if (ast_pthread_create(&tmp->skype_thread, NULL, do_skypeapi_thread, &tmp->SkypiaxHandles) < 0) { - ast_log(LOG_ERROR, "Unable to start skype_main thread.\n"); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_TMP_LOG); - } - free(tmp); - return NULL; - } -#else /* __CYGWIN__ */ -#ifdef WANT_SKYPE_X11 - if (ast_pthread_create(&tmp->signaling_thread, NULL, do_signaling_thread_fnc, tmp) < 0) { - ast_log(LOG_ERROR, "Unable to start skype_main thread.\n"); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_TMP_LOG); - } - free(tmp); - return NULL; - } -#endif /* WANT_SKYPE_X11 */ -#endif /* __CYGWIN__ */ - usleep(100000); //0.1 sec - if (tmp->skype_thread == AST_PTHREADT_NULL) { - ast_log(LOG_ERROR, "Unable to start skype_main thread.\n"); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_TMP_LOG); - } - free(tmp); - return NULL; - } - if (option_debug > 1) - ast_log(LOG_DEBUG, "STARTED signaling_thread=%lu STOP=%lu NULL=%lu\n", - (unsigned long) tmp->signaling_thread, (unsigned long) AST_PTHREADT_STOP, (unsigned long) AST_PTHREADT_NULL); - } -#endif - - /* return the newly created skypiax_pvt */ - return tmp; -} - -/*! \brief (Re)Start the module main monitor thread, watching for incoming calls on the interfaces */ -int skypiax_restart_monitor(void) -{ - static struct skypiax_pvt *p = &skypiax_log_struct; - - /* If we're supposed to be stopped -- stay stopped */ - if (skypiax_monitor_thread == AST_PTHREADT_STOP) { - return 0; - } - LOKKA(&skypiax_monlock); - /* Do not seems possible to me that this function can be called by the very same monitor thread, but let's be paranoid */ - if (skypiax_monitor_thread == pthread_self()) { - UNLOCKA(&skypiax_monlock); - ERRORA("Cannot kill myself\n", SKYPIAX_P_LOG); - return -1; - } - /* if the monitor thread exists */ - if (skypiax_monitor_thread != AST_PTHREADT_NULL) { - /* Wake up the thread, it can be stuck waiting in a select or so */ - pthread_kill(skypiax_monitor_thread, SIGURG); - } else { - /* the monitor thread does not exists, start a new monitor */ - if (ast_pthread_create(&skypiax_monitor_thread, NULL, skypiax_do_monitor, NULL) < 0) { - UNLOCKA(&skypiax_monlock); - ERRORA("Unable to start monitor thread.\n", SKYPIAX_P_LOG); - return -1; - } - } - UNLOCKA(&skypiax_monlock); - return 0; -} - -/*! \brief The skypiax monitoring thread - * \note This thread monitors all the skypiax interfaces that are not in a call - * (and thus do not have a separate thread) indefinitely - * */ -void *skypiax_do_monitor(void *data) -{ - fd_set rfds; - int res; - struct skypiax_pvt *p = NULL; - int max = -1; - struct timeval to; - time_t now_timestamp; - - if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { - ERRORA("Unable to set cancel type to deferred\n", SKYPIAX_P_LOG); - return NULL; - } - - for (;;) { - pthread_testcancel(); - /* Don't let anybody kill us right away. Nobody should lock the interface list - and wait for the monitor list, but the other way around is okay. */ - PUSHA_UNLOCKA(&skypiax_monlock); - MONITORLOKKA(&skypiax_monlock); - /* Lock the interface list */ - PUSHA_UNLOCKA(&skypiax_iflock); - MONITORLOKKA(&skypiax_iflock); - /* Build the stuff we're going to select on, that is the skypiax_serial_fd of every - skypiax_pvt that does not have an associated owner channel. In the case of FBUS2 3310 - and in the case of PROTOCOL_NO_SERIAL we add the audio_fd as well, because there is not serial signaling of incoming calls */ - FD_ZERO(&rfds); - - time(&now_timestamp); - p = skypiax_iflist; - while (p) { - if (!p->owner) { - /* This interface needs to be watched, as it lacks an owner */ - - if (p->skype) { - if (FD_ISSET(p->SkypiaxHandles.fdesc[0], &rfds)) - ERRORA("Descriptor %d (SkypiaxHandles.fdesc[0]) appears twice ?\n", SKYPIAX_P_LOG, p->SkypiaxHandles.fdesc[0]); - - if (p->SkypiaxHandles.fdesc[0] > 0) { - FD_SET(p->SkypiaxHandles.fdesc[0], &rfds); - if (p->SkypiaxHandles.fdesc[0] > max) - max = p->SkypiaxHandles.fdesc[0]; - - } - } - - } - /* next interface, please */ - p = p->next; - } - /* Okay, now that we know what to do, release the interface lock */ - MONITORUNLOCKA(&skypiax_iflock); - POPPA_UNLOCKA(&skypiax_iflock); - /* And from now on, we're okay to be killed, so release the monitor lock as well */ - MONITORUNLOCKA(&skypiax_monlock); - POPPA_UNLOCKA(&skypiax_monlock); - - /* you want me to die? */ - pthread_testcancel(); - - /* Wait for something to happen */ - to.tv_sec = 0; - to.tv_usec = 500000; /* we select with this timeout because under cygwin we avoid the signal usage, so there is no way to end the thread if it is stuck waiting for select */ - res = ast_select(max + 1, &rfds, NULL, NULL, &to); - - /* you want me to die? */ - pthread_testcancel(); - - /* Okay, select has finished. Let's see what happened. */ - - /* If there are errors... */ - if (res < 0) { - if (errno == EINTR) /* EINTR is just the select - being interrupted by a SIGURG, or so */ - continue; - else { - ERRORA("select returned %d: %s\n", SKYPIAX_P_LOG, res, strerror(errno)); - return NULL; - } - } - - /* must not be killed while skypiax_iflist is locked */ - PUSHA_UNLOCKA(&skypiax_monlock); - MONITORLOKKA(&skypiax_monlock); - /* Alright, lock the interface list again, and let's look and see what has - happened */ - PUSHA_UNLOCKA(&skypiax_iflock); - MONITORLOKKA(&skypiax_iflock); - - p = skypiax_iflist; - for (; p; p = p->next) { - - if (p->skype) { - if (FD_ISSET(p->SkypiaxHandles.fdesc[0], &rfds)) { - res = skypiax_signaling_read(p); - if (res == CALLFLOW_INCOMING_CALLID || res == CALLFLOW_INCOMING_RING) { - //ast_log(LOG_NOTICE, "CALLFLOW_INCOMING_RING SKYPE\n"); - DEBUGA_SKYPE("CALLFLOW_INCOMING_RING\n", SKYPIAX_P_LOG); - skypiax_new(p, SKYPIAX_STATE_RING, p->context /* p->context */ ); - } - } - } - - } - MONITORUNLOCKA(&skypiax_iflock); - POPPA_UNLOCKA(&skypiax_iflock); - MONITORUNLOCKA(&skypiax_monlock); - POPPA_UNLOCKA(&skypiax_monlock); - pthread_testcancel(); - } -/* Never reached */ - return NULL; - -} - -/*! - * \brief Initialize the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the skypiax_pvt of the interface - * - * This function initialize the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces). It simply pass its parameters to the right function for the sound system for which has been compiled, eg. alsa_init for ALSA, oss_init for OSS, winmm_init for Windows Multimedia, etc and return the result - * - * \return zero on success, -1 on error. - */ - -int skypiax_sound_init(struct skypiax_pvt *p) -{ - return skypiax_audio_init(p); -} - -/*! - * \brief Shutdown the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the skypiax_pvt of the interface - * - * This function shutdown the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces). It simply pass its parameters to the right function for the sound system for which has been compiled, eg. alsa_shutdown for ALSA, oss_shutdown for OSS, winmm_shutdown for Windows Multimedia, etc and return the result - * - * \return zero on success, -1 on error. - */ - -int skypiax_sound_shutdown(struct skypiax_pvt *p) -{ - - //return skypiax_portaudio_shutdown(p); - - return -1; -} - -/*! \brief Read audio frames from interface */ -struct ast_frame *skypiax_sound_read(struct skypiax_pvt *p) -{ - struct ast_frame *f = NULL; - int res; - - res = skypiax_audio_read(p); - f = &p->read_frame; - return f; -} - -/*! \brief Send audio frame to interface */ -int skypiax_sound_write(struct skypiax_pvt *p, struct ast_frame *f) -{ - int ret = -1; - - ret = skypiax_audio_write(p, f); - return ret; -} - -/*! - * \brief This thread runs during a call, and monitor the interface serial port for signaling, like hangup, caller id, etc - * - */ -void *skypiax_do_controldev_thread(void *data) -{ - struct skypiax_pvt *p = data; - int res; - - DEBUGA_SERIAL("In skypiax_do_controldev_thread: started, p=%p\n", SKYPIAX_P_LOG, p); - - if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { - ERRORA("Unable to set cancel type to deferred\n", SKYPIAX_P_LOG); - return NULL; - } - - while (1) { - usleep(1000); - pthread_testcancel(); - if (p->skype) { - res = skypiax_signaling_read(p); - if (res == CALLFLOW_INCOMING_HANGUP) { - DEBUGA_SKYPE("skype call ended\n", SKYPIAX_P_LOG); - if (p->owner) { - pthread_testcancel(); - ast_queue_control(p->owner, AST_CONTROL_HANGUP); - } - } - } - } - - return NULL; - -} - -/************************************************/ - -/* LUIGI RIZZO's magic */ -/* - * store the boost factor - */ -#ifdef ASTERISK_VERSION_1_6 -void skypiax_store_boost(const char *s, double *boost) -#else -void skypiax_store_boost(char *s, double *boost) -#endif /* ASTERISK_VERSION_1_6 */ -{ - struct skypiax_pvt *p = NULL; - - if (sscanf(s, "%lf", boost) != 1) { - ERRORA("invalid boost <%s>\n", SKYPIAX_P_LOG, s); - return; - } - if (*boost < -BOOST_MAX) { - WARNINGA("boost %s too small, using %d\n", SKYPIAX_P_LOG, s, -BOOST_MAX); - *boost = -BOOST_MAX; - } else if (*boost > BOOST_MAX) { - WARNINGA("boost %s too large, using %d\n", SKYPIAX_P_LOG, s, BOOST_MAX); - *boost = BOOST_MAX; - } - *boost = exp(log(10) * *boost / 20) * BOOST_SCALE; - DEBUGA_SOUND("setting boost %s to %f\n", SKYPIAX_P_LOG, s, *boost); -} - -/* - * returns a pointer to the descriptor with the given name - */ -struct skypiax_pvt *skypiax_console_find_desc(char *dev) -{ - struct skypiax_pvt *p = NULL; - - for (p = skypiax_iflist; p && strcmp(p->name, dev) != 0; p = p->next); - if (p == NULL) - WARNINGA("could not find <%s>\n", SKYPIAX_P_LOG, dev); - - return p; -} -int skypiax_console_playback_boost(int fd, int argc, char *argv[]) -{ - struct skypiax_pvt *p = skypiax_console_find_desc(skypiax_console_active); - - if (argc > 2) { - return RESULT_SHOWUSAGE; - } - if (!p) { - ast_cli(fd, "No \"current\" skypiax_console for playback_boost, please enter 'help skypiax_console'\n"); - return RESULT_SUCCESS; - } - - if (argc == 1) { - ast_cli(fd, "playback_boost on the active skypiax_console, that is [%s], is: %5.1f\n", - skypiax_console_active, 20 * log10(((double) p->playback_boost / (double) BOOST_SCALE))); - } else if (argc == 2) { - skypiax_store_boost(argv[1], &p->playback_boost); - - ast_cli(fd, - "playback_boost on the active skypiax_console, that is [%s], is now: %5.1f\n", - skypiax_console_active, 20 * log10(((double) p->playback_boost / (double) BOOST_SCALE))); - } - - return RESULT_SUCCESS; -} -int skypiax_console_capture_boost(int fd, int argc, char *argv[]) -{ - struct skypiax_pvt *p = skypiax_console_find_desc(skypiax_console_active); - - if (argc > 2) { - return RESULT_SHOWUSAGE; - } - if (!p) { - ast_cli(fd, "No \"current\" skypiax_console for capture_boost, please enter 'help skypiax_console'\n"); - return RESULT_SUCCESS; - } - - if (argc == 1) { - ast_cli(fd, "capture_boost on the active skypiax_console, that is [%s], is: %5.1f\n", - skypiax_console_active, 20 * log10(((double) p->capture_boost / (double) BOOST_SCALE))); - } else if (argc == 2) { - skypiax_store_boost(argv[1], &p->capture_boost); - - ast_cli(fd, - "capture_boost on the active skypiax_console, that is [%s], is now: %5.1f\n", - skypiax_console_active, 20 * log10(((double) p->capture_boost / (double) BOOST_SCALE))); - } - - return RESULT_SUCCESS; -} - -int skypiax_console_hangup(int fd, int argc, char *argv[]) -{ - struct skypiax_pvt *p = skypiax_console_find_desc(skypiax_console_active); - - if (argc != 1) { - return RESULT_SHOWUSAGE; - } - if (!p) { - ast_cli(fd, "No \"current\" skypiax_console for hanging up, please enter 'help skypiax_console'\n"); - return RESULT_SUCCESS; - } - if (!p->owner) { - ast_cli(fd, "No call to hangup on the active skypiax_console, that is [%s]\n", skypiax_console_active); - return RESULT_FAILURE; - } - if (p->owner) - ast_queue_hangup(p->owner); - return RESULT_SUCCESS; -} - -int skypiax_console_dial(int fd, int argc, char *argv[]) -{ - char *s = NULL; - struct skypiax_pvt *p = skypiax_console_find_desc(skypiax_console_active); - - if (argc != 2) { - return RESULT_SHOWUSAGE; - } - if (!p) { - ast_cli(fd, "No \"current\" skypiax_console for dialing, please enter 'help skypiax_console'\n"); - return RESULT_SUCCESS; - } - - if (p->owner) { /* already in a call */ - int i; - struct ast_frame f = { AST_FRAME_DTMF, 0 }; - - s = argv[1]; - /* send the string one char at a time */ - for (i = 0; i < strlen(s); i++) { - f.subclass = s[i]; - ast_queue_frame(p->owner, &f); - } - return RESULT_SUCCESS; - } else - ast_cli(fd, "No call in which to dial on the \"current\" skypiax_console, that is [%s]\n", skypiax_console_active); - if (s) - free(s); - return RESULT_SUCCESS; -} -int skypiax_console_set_active(int fd, int argc, char *argv[]) -{ - if (argc == 1) - ast_cli(fd, - "\"current\" skypiax_console is [%s]\n Enter 'skypiax_console show' to see the available interfaces.\n Enter 'skypiax_console interfacename' to change the \"current\" skypiax_console.\n", - skypiax_console_active); - else if (argc != 2) { - return RESULT_SHOWUSAGE; - } else { - struct skypiax_pvt *p; - if (strcmp(argv[1], "show") == 0) { - ast_cli(fd, "Available interfaces:\n"); - for (p = skypiax_iflist; p; p = p->next) - ast_cli(fd, " [%s]\n", p->name); - return RESULT_SUCCESS; - } - p = skypiax_console_find_desc(argv[1]); - if (p == NULL) - ast_cli(fd, "Interface [%s] do not exists!\n", argv[1]); - else { - skypiax_console_active = p->name; - ast_cli(fd, "\"current\" skypiax_console is now: [%s]\n", argv[1]); - } - } - return RESULT_SUCCESS; -} - -int skypiax_console_skypiax(int fd, int argc, char *argv[]) -{ - return RESULT_SHOWUSAGE; -} - -void *do_skypeapi_thread(void *obj) -{ - return skypiax_do_skypeapi_thread_func(obj); -} - -int dtmf_received(private_t * p, char *value) -{ - - struct ast_frame f2 = { AST_FRAME_DTMF, value[0], }; - DEBUGA_SKYPE("Received DTMF: %s\n", SKYPIAX_P_LOG, value); - ast_queue_frame(p->owner, &f2); - - return 0; - -} - -int start_audio_threads(private_t * p) -{ - //if (!p->tcp_srv_thread) { - if (ast_pthread_create(&p->tcp_srv_thread, NULL, skypiax_do_tcp_srv_thread, p) < 0) { - ERRORA("Unable to start tcp_srv_thread thread.\n", SKYPIAX_P_LOG); - return -1; - } else { - DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); - } - //} - //if (!p->tcp_cli_thread) { - if (ast_pthread_create(&p->tcp_cli_thread, NULL, skypiax_do_tcp_cli_thread, p) < 0) { - ERRORA("Unable to start tcp_cli_thread thread.\n", SKYPIAX_P_LOG); - return -1; - } else { - DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); - } - //} - -#ifdef NOTDEF - switch_threadattr_t *thd_attr = NULL; - - switch_threadattr_create(&thd_attr, skypiax_module_pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&tech_pvt->tcp_srv_thread, thd_attr, skypiax_do_tcp_srv_thread, tech_pvt, skypiax_module_pool); - DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); - - switch_threadattr_create(&thd_attr, skypiax_module_pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&tech_pvt->tcp_cli_thread, thd_attr, skypiax_do_tcp_cli_thread, tech_pvt, skypiax_module_pool); - DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); - switch_sleep(100000); - -#endif - - return 0; -} - -int new_inbound_channel(private_t * p) -{ - -#ifdef NOTDEF - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if ((session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)) != 0) { - switch_core_session_add_stream(session, NULL); - channel = switch_core_session_get_channel(session); - skypiax_tech_init(tech_pvt, session); - - if ((tech_pvt->caller_profile = - switch_caller_profile_new(switch_core_session_get_pool(session), "skypiax", - tech_pvt->dialplan, tech_pvt->callid_name, - tech_pvt->callid_number, NULL, NULL, NULL, NULL, "mod_skypiax", tech_pvt->context, tech_pvt->destination)) != 0) { - char name[128]; - //switch_snprintf(name, sizeof(name), "skypiax/%s/%s", tech_pvt->name, tech_pvt->caller_profile->destination_number); - switch_snprintf(name, sizeof(name), "skypiax/%s", tech_pvt->name); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - } - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Error spawning thread\n", SKYPIAX_P_LOG); - switch_core_session_destroy(&session); - } - } - switch_channel_mark_answered(channel); - -#endif - return 0; -} - -int remote_party_is_ringing(private_t * p) -{ - if (p->owner) { - ast_queue_control(p->owner, AST_CONTROL_RINGING); - } - - return 0; -} - -int remote_party_is_early_media(private_t * p) -{ - if (p->owner) { - ast_queue_control(p->owner, AST_CONTROL_RINGING); - } - - return 0; -} - -int outbound_channel_answered(private_t * p) -{ - - if (p->owner) { - ast_queue_control(p->owner, AST_CONTROL_ANSWER); - } - - return 0; -} -void *skypiax_do_tcp_srv_thread(void *obj) -{ - return skypiax_do_tcp_srv_thread_func(obj); -} -void *skypiax_do_tcp_cli_thread(void *obj) -{ - return skypiax_do_tcp_cli_thread_func(obj); -} - -int skypiax_audio_write(struct skypiax_pvt *p, struct ast_frame *f) -{ - int sent; - - sent = write(p->audioskypepipe[1], (short *) f->data, f->datalen); - - return 0; -} -int skypiax_console_skype(int fd, int argc, char *argv[]) -{ - struct skypiax_pvt *p = skypiax_console_find_desc(skypiax_console_active); - char skype_msg[1024]; - int i, a, c; - - if (argc == 1) { - return RESULT_SHOWUSAGE; - } - if (!p) { - ast_cli(fd, "No \"current\" console for skypiax_, please enter 'help console'\n"); - return RESULT_SUCCESS; - } - if (!p->skype) { - ast_cli(fd, "The \"current\" console is not connected to a Skype client'\n"); - return RESULT_SUCCESS; - } - - memset(skype_msg, 0, sizeof(skype_msg)); - c = 0; - for (i = 1; i < argc; i++) { - for (a = 0; a < strlen(argv[i]); a++) { - skype_msg[c] = argv[i][a]; - c++; - if (c == 1022) - break; - } - if (i != argc - 1) { - skype_msg[c] = ' '; - c++; - } - if (c == 1023) - break; - } - skypiax_signaling_write(p, skype_msg); - return RESULT_SUCCESS; -} - -int skypiax_console_skypiax_dir_import(int fd, int argc, char *argv[]) -{ - //int res; - struct skypiax_pvt *p = skypiax_console_find_desc(skypiax_console_active); - //char list_command[64]; - char fn[256]; - char date[256] = ""; - time_t t; - char *configfile = SKYPIAX_DIR_CONFIG; - int add_to_skypiax_dir_conf = 1; - //int fromskype = 0; - //int fromcell = 0; - -#if 0 - if (directoriax_entry_extension) { - skypiax_dir_entry_extension = directoriax_entry_extension; - } else { - ast_cli(fd, "No 'directoriax_entry_extension', you MUST have loaded directoriax.so\n"); - return RESULT_SUCCESS; - } -#endif - - if (argc != 2) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, "No \"current\" console ???, please enter 'help skypiax_console'\n"); - return RESULT_SUCCESS; - } - - if (!strcasecmp(argv[1], "add")) - add_to_skypiax_dir_conf = 1; - else if (!strcasecmp(argv[1], "replace")) - add_to_skypiax_dir_conf = 0; - else { - ast_cli(fd, "\n\nYou have neither specified 'add' nor 'replace'\n\n"); - return RESULT_SHOWUSAGE; - } - -#if 0 - if (!strcasecmp(argv[2], "fromskype")) - fromskype = 1; - else if (!strcasecmp(argv[2], "fromcell")) - fromcell = 1; - else { - ast_cli(fd, "\n\nYou have neither specified 'fromskype' nor 'fromcell'\n\n"); - return RESULT_SHOWUSAGE; - } - - if (fromcell) { - ast_cli(fd, "Importing from cellphone is currently supported only on \"AT\" cellphones :( !\n"); - //fclose(p->phonebook_writing_fp); - //skypiax_dir_create_extensions(); - return RESULT_SUCCESS; - } - - if (fromskype) - if (!p->skype) { - ast_cli(fd, "Importing from skype is supported by skypiax_dir on chan_skypiax!\n"); - //fclose(p->phonebook_writing_fp); - //skypiax_dir_create_extensions(); - return RESULT_SUCCESS; - } - - if (fromcell || fromskype) - if (argc != 3) { - ast_cli(fd, "\n\nYou don't have to specify a filename with 'fromcell' or with 'fromskype'\n\n"); - return RESULT_SHOWUSAGE; - } -#endif - - /*******************************************************************************************/ - - if (configfile[0] == '/') { - ast_copy_string(fn, configfile, sizeof(fn)); - } else { - snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, configfile); - } - NOTICA("Opening '%s'\n", SKYPIAX_P_LOG, fn); - time(&t); - ast_copy_string(date, ctime(&t), sizeof(date)); - - if (add_to_skypiax_dir_conf) - p->phonebook_writing_fp = fopen(fn, "a+"); - else - p->phonebook_writing_fp = fopen(fn, "w+"); - - if (p->phonebook_writing_fp) { - if (add_to_skypiax_dir_conf) { - NOTICA("Opened '%s' for appending \n", SKYPIAX_P_LOG, fn); - fprintf(p->phonebook_writing_fp, ";!\n"); - fprintf(p->phonebook_writing_fp, ";! Update Date: %s", date); - fprintf(p->phonebook_writing_fp, ";! Updated by: %s, %d\n", __FILE__, __LINE__); - fprintf(p->phonebook_writing_fp, ";!\n"); - } else { - NOTICA("Opened '%s' for writing \n", SKYPIAX_P_LOG, fn); - fprintf(p->phonebook_writing_fp, ";!\n"); - fprintf(p->phonebook_writing_fp, ";! Automatically generated configuration file\n"); - fprintf(p->phonebook_writing_fp, ";! Filename: %s (%s)\n", configfile, fn); - fprintf(p->phonebook_writing_fp, ";! Creation Date: %s", date); - fprintf(p->phonebook_writing_fp, ";! Generated by: %s, %d\n", __FILE__, __LINE__); - fprintf(p->phonebook_writing_fp, ";!\n"); - fprintf(p->phonebook_writing_fp, "[general]\n\n"); - fprintf(p->phonebook_writing_fp, "[default]\n"); - } - - /*******************************************************************************************/ - //if (fromskype) { - if (p->skype) { - WARNINGA("About to querying the Skype client 'Contacts', it may take some moments... Don't worry.\n", SKYPIAX_P_LOG); - if (p->skype_thread != AST_PTHREADT_NULL) { - char msg_to_skype[1024]; - - p->skype_friends[0] = '\0'; - sprintf(msg_to_skype, "#333 SEARCH FRIENDS"); - if (skypiax_signaling_write(p, msg_to_skype) < 0) { - return -1; - } - - int friends_count = 0; - while (p->skype_friends[0] == '\0') { - /* FIXME needs a timeout, can't wait forever! - * eg. when skype is running but not connected! */ - usleep(100); - friends_count++; - if (friends_count > 20000) { - return -1; /* FIXME */ - } - } - - } - - if (p->skype_thread != AST_PTHREADT_NULL) { - char msg_to_skype[1024]; - - if (p->skype_friends[0] != '\0') { - char *buf, *where; - char **stringp; - int skype_dir_file_written = 0; - - buf = p->skype_friends; - stringp = &buf; - where = strsep(stringp, ", "); - while (where) { - if (where[0] != '\0') { - /* - * So, we have the Skype username (the HANDLE, I think is called). - * But we want to call the names we see in the Skype contact list - * So, let's check the DISPLAYNAME (the end user modified contact name) - * Then, we check the FULLNAME (that appears as it was the DISPLAYNAME - * if the end user has not modify it) - * If we still have neither DISPLAYNAME nor FULLNAME, we'll use the - * Skipe username (the HANDLE) - */ - - p->skype_displayname[0] = '\0'; - sprintf(msg_to_skype, "#765 GET USER %s DISPLAYNAME", where); - skypiax_signaling_write(p, msg_to_skype); - int displayname_count = 0; - while (p->skype_displayname[0] == '\0') { - /* FIXME needs a timeout, can't wait forever! - * eg. when skype is running but not connected! */ - usleep(100); - displayname_count++; - if (displayname_count > 20000) - return -1; /* FIXME */ - } - if (p->skype_displayname[0] != '\0') { - char *where2; - char sanitized[300]; - - sanitized[0] = '\0'; - - where2 = strstr(p->skype_displayname, "DISPLAYNAME "); - if (where2) { - - /* there can be some *smart* that makes a displayname - * that is different than firstlast, */ - /* maybe initials, simbols, slashes, - * something smartish... let's check */ - - if (where2[12] != '\0') { - int i = 12; - int x = 0; - int spaces = 0; - int last_char_was_space = 0; - - for (i = 12; i < strlen(where2) && x < 299; i++) { - if (!isalnum(where2[i])) { - if (!isblank(where2[i])) { - /* bad char */ - continue; - } - /* is a space */ - if (last_char_was_space == 1) /* do not write 2 consecutive spaces */ - continue; - last_char_was_space = 1; - sanitized[x] = ' '; - x++; - continue; - } - /* is alphanum */ - last_char_was_space = 0; - sanitized[x] = where2[i]; - x++; - continue; - } - - sanitized[x] = '\0'; - if (spaces == 0) { - } - DEBUGA_SKYPE("sanitized=|%s|, where=|%s|, where2=|%s|\n", SKYPIAX_P_LOG, sanitized, where, &where2[12]); - } - - if (where2[12] != '\0') { - skypiax_dir_entry_extension++; - if (where[0] == '+' || isdigit(where[0])) { /* is a skypeout number */ - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromskype=%s|phonebook_entry_owner=%s\n", - where, sanitized, "no", - p->skypiax_dir_entry_extension_prefix, "2", skypiax_dir_entry_extension, "yes", "not_specified"); - } else { /* is a skype name */ - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKY,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromskype=%s|phonebook_entry_owner=%s\n", - where, sanitized, "no", - p->skypiax_dir_entry_extension_prefix, "1", skypiax_dir_entry_extension, "yes", "not_specified"); - } - skype_dir_file_written = 1; - - } - } - } - p->skype_displayname[0] = '\0'; - - p->skype_fullname[0] = '\0'; - sprintf(msg_to_skype, "#222 GET USER %s FULLNAME", where); - skypiax_signaling_write(p, msg_to_skype); - int fullname_count = 0; - while (p->skype_fullname[0] == '\0') { - /* FIXME needs a timeout, can't wait forever! - * eg. when skype is running but not connected! */ - usleep(100); - fullname_count++; - if (fullname_count > 20000) - return -1; /* FIXME */ - } - if (p->skype_fullname[0] != '\0') { - char *where2; - char sanitized[300]; - - where2 = strstr(p->skype_fullname, "FULLNAME "); - if (where2) { - - /* there can be some *smart* that makes a fullname - * that is different than firstlast, */ - /* maybe initials, simbols, slashes, - * something smartish... let's check */ - - if (where2[9] != '\0') { - int i = 9; - int x = 0; - int spaces = 0; - int last_char_was_space = 0; - - for (i = 9; i < strlen(where2) && x < 299; i++) { - if (!isalnum(where2[i])) { - if (!isblank(where2[i])) { - /* bad char */ - continue; - } - /* is a space */ - if (last_char_was_space == 1) /* do not write 2 consecutive spaces */ - continue; - last_char_was_space = 1; - sanitized[x] = ' '; - x++; - continue; - } - /* alphanum */ - last_char_was_space = 0; - sanitized[x] = where2[i]; - x++; - continue; - } - - sanitized[x] = '\0'; - if (spaces == 0) { - } - DEBUGA_SKYPE("sanitized=|%s|, where=|%s|, where2=|%s|\n", SKYPIAX_P_LOG, sanitized, where, &where2[9]); - } - - if (skype_dir_file_written == 0) { - skypiax_dir_entry_extension++; - if (where2[9] != '\0') { - if (where[0] == '+' || isdigit(where[0])) { /* is a skypeout number */ - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromskype=%s|phonebook_entry_owner=%s\n", - where, sanitized, "no", - p->skypiax_dir_entry_extension_prefix, "2", skypiax_dir_entry_extension, "yes", "not_specified"); - } else { /* is a skype name */ - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKY,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromskype=%s|phonebook_entry_owner=%s\n", - where, sanitized, "no", - p->skypiax_dir_entry_extension_prefix, "1", skypiax_dir_entry_extension, "yes", "not_specified"); - - } - - } else { - if (where[0] == '+' || isdigit(where[0])) { /* is a skypeout number */ - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromskype=%s|phonebook_entry_owner=%s\n", - where, where, "no", p->skypiax_dir_entry_extension_prefix, - "2", skypiax_dir_entry_extension, "yes", "not_specified"); - } else { /* is a skype name */ - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKY,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromskype=%s|phonebook_entry_owner=%s\n", - where, where, "no", p->skypiax_dir_entry_extension_prefix, - "1", skypiax_dir_entry_extension, "yes", "not_specified"); - - } - } - } - - skype_dir_file_written = 0; - - } - - } - p->skype_fullname[0] = '\0'; - - } - where = strsep(stringp, ", "); - } - - p->skype_friends[0] = '\0'; - } - } - } else { - - ast_cli(fd, "Skype not configured on the 'current' console, not importing from Skype client!\n"); - } - //} - /*******************************************************************************************/ - /*******************************************************************************************/ - } else { - ast_cli(fd, "\n\nfailed to open the skypiax_dir.conf configuration file: %s\n", fn); - ERRORA("failed to open the skypiax_dir.conf configuration file: %s\n", SKYPIAX_P_LOG, fn); - return RESULT_FAILURE; - } - - fclose(p->phonebook_writing_fp); - //skypiax_dir_create_extensions(); - - return RESULT_SUCCESS; -} - -private_t *find_available_skypiax_interface(void) -{ - private_t *p; - int found = 0; - - /* lock the interfaces' list */ - LOKKA(&skypiax_iflock); - /* make a pointer to the first interface in the interfaces list */ - p = skypiax_iflist; - /* Search for the requested interface and verify if is unowned */ - while (p) { - if (!p->owner) { - DEBUGA_PBX("Interface is NOT OWNED by a channel\n", SKYPIAX_P_LOG); - found = 1; - /* we found the requested interface, bail out from the while loop */ - break; - } else { - /* interface owned by a channel */ - DEBUGA_PBX("Interface is OWNED by a channel\n", SKYPIAX_P_LOG); - } - /* not yet found, next please */ - p = p->next; - } - - /* lock the interfaces' list */ - UNLOCKA(&skypiax_iflock); - - if (found) - return p; - else - return NULL; -} - -/************************************************/ -#ifdef ASTERISK_VERSION_1_4 -#ifndef AST_MODULE -#define AST_MODULE "chan_skypiax" -#endif -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Skypiax, Audio-Serial Driver"); -#endif /* ASTERISK_VERSION_1_4 */ - -/* rewriting end */ -/*******************************************************************************/ diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c deleted file mode 100644 index df2da1868a..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#define PRINTMSGCYG - -extern int option_debug; -int cyg_no_pthreadkill(int thread, int sig); - -int cyg_no_pthreadkill(int thread, int sig) -{ -#ifdef PRINTMSGCYG - if (option_debug) { - printf - ("\n\nHere there would have been a pthread_kill() on thread [%-7lx], with sig=%d, but it has been substituted by this printf in file cyg_no_pthread_kill.c because CYGWIN does not support sending a signal to a one only thread :-(\n\n", - (unsigned long int) thread, sig); - } -#endif // PRINTMSGCYG - return 0; -} diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf deleted file mode 100644 index 445c65536a..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf +++ /dev/null @@ -1,207 +0,0 @@ -;;;;;;;; -;;;;;;;; -;;;;;;; Skypiax Asterisk Driver -;;;;;;; -;;;;;;; Configuration file -;;;;;;; lines beginning with semicolon (" are ignored (commented out) -;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; -;;;;;;; The first interface (named skypeclient) -;;;;;;[skypeclient] -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; general settings, valid on all platforms -;;;;;;; -;;;;;;; -;;;;;;; Default language -;;;;;;; -;;;;;;language=en -;;;;;;; -;;;;;;; Default context (in extensions.conf, can be overridden with @context syntax) -;;;;;;; -;;;;;;context=default -;;;;;;; -;;;;;;; Default extension (in extensions.conf) where incoming calls land -;;;;;;; -;;;;;;extension=s -;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; Debugging settings, valid globally for all interfaces on all platforms -;;;;;;; -;;;;;;; the debug values are global for all the interfaces. -;;;;;;; -;;;;;;; default is no skypiax debugging output, you **have** to activate debugging here to obtain debugging from skypiax -;;;;;;; -;;;;;;; To see the debugging output you have to "set debug 100" from the Asterisk CLI or launch -;;;;;;; Asterisk with -ddddddddddd option, and have the logger.conf file activating debug info for console and messages -;;;;;;; -;;;;;;; You can activate each of the following separately, but you can't disactivate. Eg: debug_at=no does not subtract debug_at from debug_all -;;;;;;; debug_all activate all possible debugging info -;;;;;;; -;;;;;;;debug_all=yes -;;;;;;debug_skype=yes -;;;;;;debug_pbx=yes -;;;;;;;debug_sound=yes -;;;;;;;debug_locks=yes -;;;;;;;debug_monitorlocks=yes -;;;;;; -;;;;;;skype=yes ; legacy setting, leave it to yes -;;;;;;X11_display=:101 -;;;;;;tcp_cli_port=11234 -;;;;;;tcp_srv_port=11235 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; audio boost settings, valid for all platforms, to compensate for different input/output audio signal levels -;;;;;;; tweak it if you get horrible (or not hearable) sound -;;;;;;; -;;;;;;;boost can be positive or negative (-40 to +40) in db -;;;;;;;experiment to find which values are best for your computer -;;;;;;playback_boost=0 ; -;;;;;;capture_boost=0 ; -;;;;;; -;;; [skypiax1] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:101 -;;; tcp_cli_port=15576 -;;; tcp_srv_port=15577 -;;; skype_user=skypiax1 -;;; -;;; [skypiax2] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:102 -;;; tcp_cli_port=15578 -;;; tcp_srv_port=15579 -;;; skype_user=skypiax2 -;;; -;;; [skypiax3] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:103 -;;; tcp_cli_port=15580 -;;; tcp_srv_port=15581 -;;; skype_user=skypiax3 -;;; -[skypiax4] -language=en -context=default -extension=s -debug_skype=yes -debug_pbx=yes -skype=yes ; legacy setting, leave it to yes -playback_boost=0 ; -capture_boost=0 ; -X11_display=:104 -tcp_cli_port=15582 -tcp_srv_port=15583 -skype_user=skypiax4 - -[skypiax5] -language=en -context=default -extension=s -debug_skype=yes -debug_pbx=yes -skype=yes ; legacy setting, leave it to yes -playback_boost=0 ; -capture_boost=0 ; -X11_display=:105 -tcp_cli_port=15584 -tcp_srv_port=15585 -skype_user=skypiax5 - -[skypiax6] -language=en -context=default -extension=s -debug_skype=yes -debug_pbx=yes -skype=yes ; legacy setting, leave it to yes -playback_boost=0 ; -capture_boost=0 ; -X11_display=:106 -tcp_cli_port=15586 -tcp_srv_port=16586 -skype_user=skypiax6 - -;;; [skypiax17] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:117 -;;; tcp_cli_port=15587 -;;; tcp_srv_port=15588 -;;; skype_user=skypiax17 -;;; -;;; [skypiax18] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:118 -;;; tcp_cli_port=15589 -;;; tcp_srv_port=15590 -;;; skype_user=skypiax18 -;;; -;;; [skypiax19] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:119 -;;; tcp_cli_port=15591 -;;; tcp_srv_port=15592 -;;; skype_user=skypiax19 -;;; -;;; [skypiax20] -;;; language=en -;;; context=default -;;; extension=s -;;; debug_skype=yes -;;; debug_pbx=yes -;;; skype=yes ; legacy setting, leave it to yes -;;; playback_boost=0 ; -;;; capture_boost=0 ; -;;; X11_display=:120 -;;; tcp_cli_port=15593 -;;; tcp_srv_port=15594 -;;; skype_user=skypiax20 -;;; -;;; -;;; diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h deleted file mode 100644 index d960f80a07..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h +++ /dev/null @@ -1,427 +0,0 @@ -//indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90 -#ifndef _SKYPIAX_H_ -#define _SKYPIAX_H_ - -#ifndef SKYPIAX_SVN_VERSION -#define SKYPIAX_SVN_VERSION "????NO_REVISION???" -#endif - -#include /* needed here for conditional compilation on version.h */ - /* the following #defs are for LINUX */ -#ifndef __CYGWIN__ -#ifndef ASTERISK_VERSION_1_6 -#ifndef ASTERISK_VERSION_1_4 -#ifndef ASTERISK_VERSION_1_2 -#define ASTERISK_VERSION_1_4 -#if(ASTERISK_VERSION_NUM == 999999) -#undef ASTERISK_VERSION_1_4 -#elif(ASTERISK_VERSION_NUM < 10400) -#undef ASTERISK_VERSION_1_4 -#endif /* ASTERISK_VERSION_NUM == 999999 || ASTERISK_VERSION_NUM < 10400 */ -#endif /* ASTERISK_VERSION_1_2 */ -#endif /* ASTERISK_VERSION_1_4 */ -#endif /* ASTERISK_VERSION_1_6 */ -#ifdef ASTERISK_VERSION_1_2 -#undef ASTERISK_VERSION_1_4 -#endif /* ASTERISK_VERSION_1_2 */ -#ifdef ASTERISK_VERSION_1_6 -#define ASTERISK_VERSION_1_4 -#endif /* ASTERISK_VERSION_1_6 */ -#define SKYPIAX_SKYPE -#define WANT_SKYPE_X11 -#endif /* NOT __CYGWIN__ */ - /* the following #defs are for WINDOWS */ -#ifdef __CYGWIN__ -#undef ASTERISK_VERSION_1_4 -#undef ASTERISK_VERSION_1_6 -#define SKYPIAX_SKYPE -#undef WANT_SKYPE_X11 -#endif /* __CYGWIN__ */ - -/* INCLUDES */ -#ifdef ASTERISK_VERSION_1_6 -#include /* some asterisk-devel package do not contains asterisk.h, but seems that is needed for the 1.6 series, at least from trunk */ -#endif /* ASTERISK_VERSION_1_6 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef ASTERISK_VERSION_1_4 -#include -#include -#endif /* ASTERISK_VERSION_1_4 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ASTERISK_VERSION_1_6 -#include -#include -#endif /* ASTERISK_VERSION_1_6 */ -#ifdef ASTERISK_VERSION_1_4 -#include -#include -#include -#include -#endif /* ASTERISK_VERSION_1_4 */ -#ifdef ASTERISK_VERSION_1_2 -#include -#include -#endif /* ASTERISK_VERSION_1_2 */ -#ifdef HAVE_CONFIG_H -#include -#endif -//#include "skypiax_spandsp.h" -#ifdef __CYGWIN__ -#include -#endif /* __CYGWIN__ */ -#ifdef WANT_SKYPE_X11 -#include -#include -#include -#endif /* WANT_SKYPE_X11 */ -#ifndef AST_DIGIT_ANYDIG -#define AST_DIGIT_ANYDIG "0123456789*#" -#else -#warning Please review Skypiax AST_DIGIT_ANYDIG -#endif -#ifndef _ASTERISK_H -#define AST_CONFIG_MAX_PATH 255 /* defined in asterisk.h, but some asterisk-devel package do not contains asterisk.h */ -extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH]; -int ast_register_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */ -void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */ -#endif - -/* DEFINITIONS */ -#define SAMPLERATE_SKYPIAX 8000 -#define SAMPLES_PER_FRAME SAMPLERATE_SKYPIAX/50 -#define SKYPIAX_DIR_CONFIG "directoriax.conf" - -/* LUIGI RIZZO's magic */ -/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must - * be representable in 16 bits to avoid overflows. - */ -#define BOOST_SCALE (1<<9) -#define BOOST_MAX 40 /* slightly less than 7 bits */ -/* call flow from the device */ -#define CALLFLOW_CALL_IDLE AST_STATE_DOWN -#define CALLFLOW_INCOMING_RING AST_STATE_RING -#define CALLFLOW_CALL_DIALING AST_STATE_DIALING -#define CALLFLOW_CALL_LINEBUSY AST_STATE_BUSY -#define CALLFLOW_CALL_ACTIVE 300 -#define CALLFLOW_INCOMING_HANGUP 100 -#define CALLFLOW_CALL_RELEASED 101 -#define CALLFLOW_CALL_NOCARRIER 102 -#define CALLFLOW_CALL_INFLUX 103 -#define CALLFLOW_CALL_INCOMING 104 -#define CALLFLOW_CALL_FAILED 105 -#define CALLFLOW_CALL_NOSERVICE 106 -#define CALLFLOW_CALL_OUTGOINGRESTRICTED 107 -#define CALLFLOW_CALL_SECURITYFAIL 108 -#define CALLFLOW_CALL_NOANSWER 109 -#define CALLFLOW_STATUS_FINISHED 110 -#define CALLFLOW_STATUS_CANCELLED 111 -#define CALLFLOW_STATUS_FAILED 112 -#define CALLFLOW_STATUS_REFUSED 113 -#define CALLFLOW_STATUS_RINGING 114 -#define CALLFLOW_STATUS_INPROGRESS 115 -#define CALLFLOW_STATUS_UNPLACED 116 -#define CALLFLOW_STATUS_ROUTING 117 -#define CALLFLOW_STATUS_EARLYMEDIA 118 -#define AST_STATE_HANGUP_REQUESTED 200 - //FIXME CALLFLOW_INCOMING_CALLID to be removed -#define CALLFLOW_INCOMING_CALLID 1019 -/* debugging bitmask */ -#define DEBUG_SOUND 1 -#define DEBUG_SERIAL 2 -#define DEBUG_SKYPE 4 -#define DEBUG_AT 8 -#define DEBUG_FBUS2 16 -#define DEBUG_CALL 32 -#define DEBUG_LOCKS 64 -#define DEBUG_PBX 128 -#define DEBUG_MONITORLOCKS 256 -#define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS -/* wrappers for ast_log */ -#define DEBUGA_SOUND(...) if (skypiax_debug & DEBUG_SOUND) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SOUND %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_SERIAL(...) if (skypiax_debug & DEBUG_SERIAL) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SERIAL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_SKYPE(...) if (skypiax_debug & DEBUG_SKYPE) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SKYPE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_AT(...) if (skypiax_debug & DEBUG_AT) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_AT %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_FBUS2(...) if (skypiax_debug & DEBUG_FBUS2) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_FBUS2 %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_CALL(...) if (skypiax_debug & DEBUG_CALL) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_PBX(...) if (skypiax_debug & DEBUG_PBX) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define ERRORA(...) ast_log(LOG_ERROR, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][ERROR %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define NOTICA(...) ast_log(LOG_NOTICE, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][NOTICE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define WARNINGA(...) ast_log(LOG_WARNING, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][WARNING %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -/* macros for logging */ -#define SKYPIAX_P_LOG p ? p->owner : NULL, (unsigned long)pthread_self(), __LINE__, p ? p->name ? p->name : "none" : "none", p ? p->owner ? p->owner->_state : -1 : -1, p ? p->interface_state : -1, p ? p->skype_callflow : -1 -#define SKYPIAX_TMP_LOG tmp ? tmp->owner : NULL, (unsigned long)pthread_self(), __LINE__, tmp ? tmp->name ? tmp->name : "none" : "none", tmp ? tmp->owner ? tmp->owner->_state : -1 : -1, tmp ? tmp->interface_state : -1, tmp ? tmp->skype_callflow : -1 -/* logging wrappers for ast_mutex_lock and ast_mutex_unlock */ -#define LOKKA(x) if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); -#define UNLOCKA(x) if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); -#define PUSHA_UNLOCKA(x) pthread_cleanup_push(skypiax_unlocka_log, (void *) x); -#define POPPA_UNLOCKA(x) pthread_cleanup_pop(0); -#define MONITORLOKKA(x) if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); -#define MONITORUNLOCKA(x) if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); -/* macros used for config file parsing (luigi rizzo)*/ -#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) ) -#define M_END(x) x; -#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else -#ifdef ASTERISK_VERSION_1_6 -#define M_START(var, val) const char *__s = var; const char *__val = val; -#else -#define M_START(var, val) char *__s = var; char *__val = val; -#endif /* ASTERISK_VERSION_1_6 */ -#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst))) -#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) ) - -#define SKYPIAX_FRAME_SIZE 160 - -/* SKYPIAX INTERNAL STRUCTS */ -/*! - * \brief structure for exchanging messages with the skype client - */ -#ifdef WANT_SKYPE_X11 -struct AsteriskHandles { - Window skype_win; - Display *disp; - Window win; - int fdesc[2]; -}; -#else /* WANT_SKYPE_X11 */ -struct AsteriskHandles { - HWND win32_hInit_MainWindowHandle; - HWND win32_hGlobal_SkypeAPIWindowHandle; - int fdesc[2]; -}; -#endif /* WANT_SKYPE_X11 */ - -#ifndef WIN32 -struct SkypiaxHandles { - Window skype_win; - Display *disp; - Window win; - int api_connected; - int fdesc[2]; -}; -#else //WIN32 - -struct SkypiaxHandles { - HWND win32_hInit_MainWindowHandle; - HWND win32_hGlobal_SkypeAPIWindowHandle; - HINSTANCE win32_hInit_ProcessHandle; - char win32_acInit_WindowClassName[128]; - UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach; - UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover; - int api_connected; - int fdesc[2]; -}; - -#endif //WIN32 - -/*! - * \brief PVT structure for a skypiax interface (channel), created by skypiax_mkif - */ -struct skypiax_pvt { - char *name; /*!< \brief 'name' of the interface (channel) */ - int interface_state; /*!< \brief 'state' of the interface (channel) */ - struct ast_channel *owner; /*!< \brief channel we belong to, possibly NULL */ - struct skypiax_pvt *next; /*!< \brief Next interface (channel) in list */ - char context[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan context for this interface */ - char language[MAX_LANGUAGE]; /*!< \brief default Asterisk dialplan language for this interface */ - char exten[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan extension for this interface */ - int skypiax_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */ - int skypiax_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ - char callid_name[50]; - char callid_number[50]; - pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */ - double playback_boost; - double capture_boost; - int stripmsd; - pthread_t skype_thread; - struct AsteriskHandles AsteriskHandlesAst; - struct SkypiaxHandles SkypiaxHandles; - char skype_call_id[512]; - int skype_call_ongoing; - char skype_friends[4096]; - char skype_fullname[512]; - char skype_displayname[512]; - int skype_callflow; /*!< \brief 'callflow' of the skype interface (as opposed to phone interface) */ - int skype; /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */ - int control_to_send; - int audiopipe[2]; - int audioskypepipe[2]; - pthread_t tcp_srv_thread; - pthread_t tcp_cli_thread; - short audiobuf[160]; - int audiobuf_is_loaded; - - //int phonebook_listing; - //int phonebook_querying; - //int phonebook_listing_received_calls; - - //int phonebook_first_entry; - //int phonebook_last_entry; - //int phonebook_number_lenght; - //int phonebook_text_lenght; - FILE *phonebook_writing_fp; - int skypiax_dir_entry_extension_prefix; -#ifdef WIN32 - unsigned short tcp_cli_port; - unsigned short tcp_srv_port; -#else - int tcp_cli_port; - int tcp_srv_port; -#endif - char X11_display[256]; - - struct ast_frame read_frame; - - char skype_user[256]; - char skype_password[256]; - char destination[256]; - char session_uuid_str[512 + 1]; - pthread_t signaling_thread; -}; - -typedef struct skypiax_pvt private_t; -/* FUNCTIONS */ - -/* module helpers functions */ -int load_module(void); -int unload_module(void); -int usecount(void); -char *description(void); -char *key(void); - -/* chan_skypiax internal functions */ -void skypiax_unlocka_log(void *x); - -void *do_skypeapi_thread(void *data); -//int skypiax2skype(struct ast_channel *c, void *data); -//int skype2skypiax(struct ast_channel *c, void *data); -//void skypiax_disconnect(void); -int skypiax_signaling_write(struct skypiax_pvt *p, char *msg_to_skype); -int skypiax_signaling_read(struct skypiax_pvt *p); -int skypiax_console_skype(int fd, int argc, char *argv[]); -#ifdef WANT_SKYPE_X11 -int X11_errors_handler(Display * dpy, XErrorEvent * err); -int skypiax_send_message(struct SkypiaxHandles *SkypiaxHandles, const char *message_P); -int skypiax_present(struct SkypiaxHandles *SkypiaxHandles); -void skypiax_clean_disp(void *data); -#endif /* WANT_SKYPE_X11 */ -#ifdef __CYGWIN__ - -int win32_Initialize_CreateWindowClass(private_t * tech_pvt); -void win32_DeInitialize_DestroyWindowClass(private_t * tech_pvt); -int win32_Initialize_CreateMainWindow(private_t * tech_pvt); -void win32_DeInitialize_DestroyMainWindow(private_t * tech_pvt); -#endif /* __CYGWIN__ */ - -/* CHAN_SKYPIAX.C */ -int skypiax_queue_control(struct ast_channel *chan, int control); -struct skypiax_pvt *skypiax_console_find_desc(char *dev); -int skypiax_serial_call(struct skypiax_pvt *p, char *dstr); - -/* FUNCTIONS */ -/* PBX interface functions */ -struct ast_channel *skypiax_request(const char *type, int format, void *data, int *cause); -int skypiax_answer(struct ast_channel *c); -int skypiax_hangup(struct ast_channel *c); -int skypiax_originate_call(struct ast_channel *c, char *idest, int timeout); -struct ast_frame *skypiax_read(struct ast_channel *chan); -int skypiax_write(struct ast_channel *c, struct ast_frame *f); -int skypiax_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); -#ifndef ASTERISK_VERSION_1_4 -int skypiax_indicate(struct ast_channel *c, int cond); -#else -int skypiax_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen); -#endif -int skypiax_devicestate(void *data); -#ifdef ASTERISK_VERSION_1_4 -int skypiax_digitsend_begin(struct ast_channel *ast, char digit); -int skypiax_digitsend_end(struct ast_channel *ast, char digit, unsigned int duration); -#else /* ASTERISK_VERSION_1_4 */ -int skypiax_digitsend(struct ast_channel *ast, char digit); -#endif /* ASTERISK_VERSION_1_4 */ - -/* chan_skypiax internal functions */ - -struct skypiax_pvt *skypiax_mkif(struct ast_config *cfg, char *ctg, int is_first_category); -struct ast_channel *skypiax_new(struct skypiax_pvt *p, int state, char *context); -int skypiax_restart_monitor(void); -void *skypiax_do_monitor(void *data); -int skypiax_sound_boost(struct ast_frame *f, double boost); -int skypiax_sound_init(struct skypiax_pvt *p); -int skypiax_sound_shutdown(struct skypiax_pvt *p); -struct ast_frame *skypiax_sound_read(struct skypiax_pvt *p); -int skypiax_sound_write(struct skypiax_pvt *p, struct ast_frame *f); -void *skypiax_do_controldev_thread(void *data); -#ifdef ASTERISK_VERSION_1_6 -void skypiax_store_boost(const char *s, double *boost); -#else -void skypiax_store_boost(char *s, double *boost); -#endif /* ASTERISK_VERSION_1_6 */ -int skypiax_console_set_active(int fd, int argc, char *argv[]); -int skypiax_console_hangup(int fd, int argc, char *argv[]); -int skypiax_console_playback_boost(int fd, int argc, char *argv[]); -int skypiax_console_capture_boost(int fd, int argc, char *argv[]); -int skypiax_console_skypiax(int fd, int argc, char *argv[]); -int skypiax_console_dial(int fd, int argc, char *argv[]); -int skypiax_audio_init(struct skypiax_pvt *p); -//struct ast_frame *skypiax_audio_read(struct skypiax_pvt *p); -int skypiax_audio_read(struct skypiax_pvt *p); -void *skypiax_do_tcp_srv_thread(void *data); -int skypiax_audio_write(struct skypiax_pvt *p, struct ast_frame *f); -void *skypiax_do_tcp_cli_thread(void *data); -int skypiax_call(struct skypiax_pvt *p, char *idest, int timeout); -int skypiax_console_skypiax_dir_import(int fd, int argc, char *argv[]); - -void *skypiax_do_tcp_srv_thread_func(void *obj); -void *skypiax_do_tcp_cli_thread_func(void *obj); -void *skypiax_do_skypeapi_thread_func(void *obj); -int dtmf_received(private_t * tech_pvt, char *value); -int start_audio_threads(private_t * tech_pvt); -int new_inbound_channel(private_t * tech_pvt); -int outbound_channel_answered(private_t * tech_pvt); -int skypiax_senddigit(struct skypiax_pvt *p, char digit); -int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype); -#if defined(WIN32) && !defined(__CYGWIN__) -int skypiax_pipe_read(switch_file_t * pipe, short *buf, int howmany); -int skypiax_pipe_write(switch_file_t * pipe, short *buf, int howmany); -/* Visual C do not have strsep ? */ -char *strsep(char **stringp, const char *delim); -#else -int skypiax_pipe_read(int pipe, short *buf, int howmany); -int skypiax_pipe_write(int pipe, short *buf, int howmany); -#endif /* WIN32 */ -int skypiax_close_socket(unsigned int fd); -private_t *find_available_skypiax_interface(void); -int remote_party_is_ringing(private_t * tech_pvt); -int remote_party_is_early_media(private_t * tech_pvt); -#define SKYPIAX_STATE_DOWN AST_STATE_DOWN -#define SKYPIAX_STATE_RING AST_STATE_RING -#define SKYPIAX_STATE_DIALING AST_STATE_DIALING -#define SKYPIAX_STATE_BUSY AST_STATE_BUSY -#define SKYPIAX_STATE_UP AST_STATE_UP -#define SKYPIAX_STATE_RINGING AST_STATE_RINGING -#define SKYPIAX_STATE_PRERING AST_STATE_PRERING -#define SKYPIAX_STATE_RESERVED AST_STATE_RESERVED -#define SKYPIAX_STATE_HANGUP_REQUESTED 200 -#endif /* _SKYPIAX_H_ */ diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/dummy.c b/src/mod/endpoints/mod_skypopen/old-stuff/dummy.c deleted file mode 100644 index 1a369dcc4f..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/dummy.c +++ /dev/null @@ -1,821 +0,0 @@ -/* - * Dummy soundcard - * Copyright (c) by Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Dummy soundcard (/dev/null)"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}"); - -#define MAX_PCM_DEVICES 4 -#define MAX_PCM_SUBSTREAMS 128 -#define MAX_MIDI_DEVICES 2 - - -/* defaults */ -#ifndef MAX_BUFFER_SIZE -#define MAX_BUFFER_SIZE (64*1024) -#endif -#ifndef MAX_PERIOD_SIZE -#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE -#endif -#ifndef USE_FORMATS -#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE) -#endif -#ifndef USE_RATE -#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000 -#define USE_RATE_MIN 5500 -#define USE_RATE_MAX 48000 -#endif -#ifndef USE_CHANNELS_MIN -#define USE_CHANNELS_MIN 1 -#endif -#ifndef USE_CHANNELS_MAX -#define USE_CHANNELS_MAX 2 -#endif -#ifndef USE_PERIODS_MIN -#define USE_PERIODS_MIN 10 -#endif -#ifndef USE_PERIODS_MAX -#define USE_PERIODS_MAX 1024 -#endif -#ifndef add_playback_constraints -#define add_playback_constraints(x) 0 -#endif -#ifndef add_capture_constraints -#define add_capture_constraints(x) 0 -#endif - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 0 }; -static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 }; -static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128 }; - - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for dummy soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for dummy soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); -module_param_array(pcm_devs, int, NULL, 0444); -MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); -module_param_array(pcm_substreams, int, NULL, 0444); -MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-64) for dummy driver."); - -static struct platform_device *devices[SNDRV_CARDS]; -static struct timer_list dummytimer; -static int dummystarted = 0; -static int dummyindex = 0; -static spinlock_t dummylock; -struct dummydpcm { - struct snd_pcm_substream *substream; - struct snd_dummy_pcm *dpcm; - int started; - int elapsed; -}; -static struct dummydpcm dummydpcms[MAX_PCM_SUBSTREAMS]; - -#define MIXER_ADDR_MASTER 0 -#define MIXER_ADDR_LINE 1 -#define MIXER_ADDR_MIC 2 -#define MIXER_ADDR_SYNTH 3 -#define MIXER_ADDR_CD 4 -#define MIXER_ADDR_LAST 4 - -static void snd_card_dummy_pcm_timer_function(unsigned long data); -struct snd_dummy { - struct snd_card *card; - struct snd_pcm *pcm; - spinlock_t mixer_lock; - int mixer_volume[MIXER_ADDR_LAST + 1][2]; - int capture_source[MIXER_ADDR_LAST + 1][2]; -}; - -struct snd_dummy_pcm { - struct snd_dummy *dummy; - //spinlock_t lock; - //struct timer_list timer; - unsigned int pcm_buffer_size; - unsigned int pcm_period_size; - unsigned int pcm_bps; /* bytes per second */ - unsigned int pcm_hz; /* HZ */ - unsigned int pcm_irq_pos; /* IRQ position */ - unsigned int pcm_buf_pos; /* position in buffer */ - struct snd_pcm_substream *substream; -}; - - -static inline void snd_card_dummy_pcm_timer_start(struct snd_dummy_pcm *dpcm) -{ - int i; - int found = 0; - - for (i = 0; i < dummyindex + 1; i++) { - //if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - //printk("dummy, %s:%d, i=%d, dummyindex=%d dpcm=%p\n", __FILE__, __LINE__, i, dummyindex, dpcm); - //} - - if (dummydpcms[i].dpcm == dpcm) { - dummydpcms[i].started = 1; - found = 1; - } - } - //if (!found) { - //printk("skypopen: start, NOT found?\n"); - //} -} - -static inline void snd_card_dummy_pcm_timer_stop(struct snd_dummy_pcm *dpcm) -{ - int i; - int found = 0; - - for (i = 0; i < dummyindex + 1; i++) { - - //if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - //printk("dummy, %s:%d, i=%d, dummyindex=%d dpcm=%p\n", __FILE__, __LINE__, i, dummyindex, dpcm); - //} - if (dummydpcms[i].dpcm == dpcm) { - dummydpcms[i].started = 0; - dummydpcms[i].elapsed = 0; - found = 1; - } - } - if (!found) { - } else { - } -} - -static int snd_card_dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_dummy_pcm *dpcm = runtime->private_data; - int err = 0; - - spin_lock_bh(&dummylock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - snd_card_dummy_pcm_timer_start(dpcm); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - snd_card_dummy_pcm_timer_stop(dpcm); - break; - default: - err = -EINVAL; - break; - } - spin_unlock_bh(&dummylock); - return 0; -} - -static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_dummy_pcm *dpcm = runtime->private_data; - int bps; - - bps = snd_pcm_format_width(runtime->format) * runtime->rate * runtime->channels / 8; - - if (bps <= 0) - return -EINVAL; - - dpcm->pcm_bps = bps; - dpcm->pcm_hz = HZ; - dpcm->pcm_buffer_size = snd_pcm_lib_buffer_bytes(substream); - dpcm->pcm_period_size = snd_pcm_lib_period_bytes(substream); - dpcm->pcm_irq_pos = 0; - dpcm->pcm_buf_pos = 0; - snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes)); - - return 0; -} - -static void snd_card_dummy_pcm_timer_function(unsigned long data) -{ - struct snd_dummy_pcm *dpcm = NULL; - int i; - - - dummytimer.expires = 1 + jiffies; - add_timer(&dummytimer); - - //spin_lock_bh(&dummylock); - for (i = 0; i < dummyindex + 1; i++) { - -#if 0 - if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - printk("dummy, %s:%d, i=%d, dummyindex=%d dpcm=%p\n", __FILE__, __LINE__, i, dummyindex, dpcm); - } -#endif - if (dummydpcms[i].started != 1) - continue; - dpcm = dummydpcms[i].dpcm; -#if 0 - if (dpcm == NULL) { - printk("dummy: timer_func %d %d NULL: continue\n", __LINE__, i); - continue; - } -#endif - //spin_lock_bh(&dpcm->lock); - dpcm->pcm_irq_pos += dpcm->pcm_bps * 1; - dpcm->pcm_buf_pos += dpcm->pcm_bps * 1; - dpcm->pcm_buf_pos %= dpcm->pcm_buffer_size * dpcm->pcm_hz; - if (dpcm->pcm_irq_pos >= dpcm->pcm_period_size * dpcm->pcm_hz) { - dpcm->pcm_irq_pos %= dpcm->pcm_period_size * dpcm->pcm_hz; - //spin_unlock_bh(&dpcm->lock); - //snd_pcm_period_elapsed(dpcm->substream); - dummydpcms[i].elapsed = 1; - } else { - //spin_unlock_bh(&dpcm->lock); - } - } - //spin_unlock_bh(&dummylock); - for (i = 0; i < dummyindex + 1; i++) { - -#if 0 - if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - printk("dummy, %s:%d, i=%d, dummyindex=%d dpcm=%p\n", __FILE__, __LINE__, i, dummyindex, dpcm); - } -#endif - if (dummydpcms[i].started != 1) - continue; - dpcm = dummydpcms[i].dpcm; -#if 0 - if (dpcm == NULL) { - printk("dummy: timer_func %d %d NULL: continue\n", __LINE__, i); - continue; - } -#endif - if (dummydpcms[i].elapsed){ - snd_pcm_period_elapsed(dpcm->substream); - dummydpcms[i].elapsed = 0; - } - } - -} - -static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_dummy_pcm *dpcm = runtime->private_data; - - //return bytes_to_frames(runtime, dpcm->pcm_buf_pos / dpcm->pcm_hz); - return (dpcm->pcm_buf_pos / dpcm->pcm_hz) / 2; -} - -static struct snd_pcm_hardware snd_card_dummy_playback = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), - //.info = (SNDRV_PCM_INFO_INTERLEAVED), - .formats = USE_FORMATS, - .rates = USE_RATE, - .rate_min = USE_RATE_MIN, - .rate_max = USE_RATE_MAX, - .channels_min = USE_CHANNELS_MIN, - .channels_max = USE_CHANNELS_MAX, - .buffer_bytes_max = MAX_BUFFER_SIZE, - //.period_bytes_min = 256, - .period_bytes_min = 2048, - .period_bytes_max = MAX_PERIOD_SIZE, - .periods_min = USE_PERIODS_MIN, - .periods_max = USE_PERIODS_MAX, - .fifo_size = 0, -}; - -static struct snd_pcm_hardware snd_card_dummy_capture = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), - //.info = (SNDRV_PCM_INFO_INTERLEAVED), - .formats = USE_FORMATS, - .rates = USE_RATE, - .rate_min = USE_RATE_MIN, - .rate_max = USE_RATE_MAX, - .channels_min = USE_CHANNELS_MIN, - .channels_max = USE_CHANNELS_MAX, - .buffer_bytes_max = MAX_BUFFER_SIZE, - //.period_bytes_min = 256, - .period_bytes_min = 2048, - .period_bytes_max = MAX_PERIOD_SIZE, - .periods_min = USE_PERIODS_MIN, - .periods_max = USE_PERIODS_MAX, - .fifo_size = 0, -}; - -static void snd_card_dummy_runtime_free(struct snd_pcm_runtime *runtime) -{ - int i; - - spin_lock_bh(&dummylock); - - for (i = 0; i < dummyindex; i++) { - - if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - printk("dummy, %s:%d, i=%d, dummyindex=%d \n", __FILE__, __LINE__, i, dummyindex); - } - if ((dummydpcms[i].dpcm == runtime->private_data)) { - dummydpcms[i].started = 0; - dummydpcms[i].elapsed = 0; - } else { - } - } - - spin_unlock_bh(&dummylock); - kfree(runtime->private_data); -} - -static int snd_card_dummy_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static int snd_card_dummy_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static struct snd_dummy_pcm *new_pcm_stream(struct snd_pcm_substream *substream) -{ - struct snd_dummy_pcm *dpcm; - int i; - int found = 0; - - dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); - if (!dpcm) { - printk("dummy, %s:%d, dummyindex=%d NO MEMORY!!!!\n", __FILE__, __LINE__, dummyindex); - return dpcm; - } - //init_timer(&dpcm->timer); - //spin_lock_init(&dpcm->lock); - dpcm->substream = substream; - - spin_lock_bh(&dummylock); - for (i = 0; i < dummyindex; i++) { - - //if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - //printk("dummy, %s:%d, i=%d, dummyindex=%d dpcm=%p\n", __FILE__, __LINE__, i, dummyindex, dpcm); - //} - if ((dummydpcms[i].substream == substream)) { - found = 1; - break; - } - - } - - if (!found) { - - dummydpcms[dummyindex].substream = substream; - dummyindex++; - } - - - - found = 0; - for (i = 0; i < dummyindex; i++) { - - //if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - //printk("dummy, %s:%d, i=%d, dummyindex=%d dpcm=%p\n", __FILE__, __LINE__, i, dummyindex, dpcm); - //} - if (dummydpcms[i].substream == substream) { - dummydpcms[i].dpcm = dpcm; - dummydpcms[i].started = 0; - dummydpcms[i].elapsed = 0; - found = 1; - break; - } - - } - - spin_unlock_bh(&dummylock); - //if (!found) { - //printk("skypopen dummyindex=%d NOT found????\n", dummyindex); - //} - return dpcm; -} - -static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_dummy_pcm *dpcm; - int err; - - if ((dpcm = new_pcm_stream(substream)) == NULL) - return -ENOMEM; - runtime->private_data = dpcm; - /* makes the infrastructure responsible for freeing dpcm */ - runtime->private_free = snd_card_dummy_runtime_free; - runtime->hw = snd_card_dummy_playback; - if (substream->pcm->device & 1) { - runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; - runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; - } - if (substream->pcm->device & 2) - runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID); - err = add_playback_constraints(runtime); - if (err < 0) - return err; - - return 0; -} - -static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_dummy_pcm *dpcm; - int err; - - if ((dpcm = new_pcm_stream(substream)) == NULL) - return -ENOMEM; - runtime->private_data = dpcm; - /* makes the infrastructure responsible for freeing dpcm */ - runtime->private_free = snd_card_dummy_runtime_free; - runtime->hw = snd_card_dummy_capture; - if (substream->pcm->device == 1) { - runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; - runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; - } - if (substream->pcm->device & 2) - runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID); - err = add_capture_constraints(runtime); - if (err < 0) - return err; - - return 0; -} - -static int snd_card_dummy_playback_close(struct snd_pcm_substream *substream) -{ - snd_card_dummy_pcm_timer_stop(substream->private_data); - return 0; -} - -static int snd_card_dummy_capture_close(struct snd_pcm_substream *substream) -{ - snd_card_dummy_pcm_timer_stop(substream->private_data); - return 0; -} - -static struct snd_pcm_ops snd_card_dummy_playback_ops = { - .open = snd_card_dummy_playback_open, - .close = snd_card_dummy_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_card_dummy_hw_params, - .hw_free = snd_card_dummy_hw_free, - .prepare = snd_card_dummy_pcm_prepare, - .trigger = snd_card_dummy_pcm_trigger, - .pointer = snd_card_dummy_pcm_pointer, -}; - -static struct snd_pcm_ops snd_card_dummy_capture_ops = { - .open = snd_card_dummy_capture_open, - .close = snd_card_dummy_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_card_dummy_hw_params, - .hw_free = snd_card_dummy_hw_free, - .prepare = snd_card_dummy_pcm_prepare, - .trigger = snd_card_dummy_pcm_trigger, - .pointer = snd_card_dummy_pcm_pointer, -}; - -static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device, int substreams) -{ - struct snd_pcm *pcm; - int err; - - err = snd_pcm_new(dummy->card, "Dummy PCM", device, substreams, substreams, &pcm); - if (err < 0) - return err; - dummy->pcm = pcm; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_dummy_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_dummy_capture_ops); - pcm->private_data = dummy; - pcm->info_flags = 0; - strcpy(pcm->name, "Dummy PCM"); - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), 128 * 1024, 1024 * 1024); - - return 0; -} - -#define DUMMY_VOLUME(xname, xindex, addr) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .name = xname, .index = xindex, \ - .info = snd_dummy_volume_info, \ - .get = snd_dummy_volume_get, .put = snd_dummy_volume_put, \ - .private_value = addr, \ - .tlv = { .p = db_scale_dummy } } - -static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = -50; - uinfo->value.integer.max = 100; - return 0; -} - -static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol); - int addr = kcontrol->private_value; - - if (in_irq()) - printk("dummy: line %d we are in HARDWARE IRQ\n", __LINE__); - spin_lock_bh(&dummy->mixer_lock); - ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0]; - ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1]; - spin_unlock_bh(&dummy->mixer_lock); - return 0; -} - -static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol); - int change, addr = kcontrol->private_value; - int left, right; - - if (in_irq()) - printk("dummy: line %d we are in HARDWARE IRQ\n", __LINE__); - left = ucontrol->value.integer.value[0]; - if (left < -50) - left = -50; - if (left > 100) - left = 100; - right = ucontrol->value.integer.value[1]; - if (right < -50) - right = -50; - if (right > 100) - right = 100; - spin_lock_bh(&dummy->mixer_lock); - change = dummy->mixer_volume[addr][0] != left || dummy->mixer_volume[addr][1] != right; - dummy->mixer_volume[addr][0] = left; - dummy->mixer_volume[addr][1] = right; - spin_unlock_bh(&dummy->mixer_lock); - return change; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0); - -#define DUMMY_CAPSRC(xname, xindex, addr) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_dummy_capsrc_info, \ - .get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \ - .private_value = addr } - -#define snd_dummy_capsrc_info snd_ctl_boolean_stereo_info - -static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol); - int addr = kcontrol->private_value; - - if (in_irq()) - printk("dummy: line %d we are in HARDWARE IRQ\n", __LINE__); - spin_lock_bh(&dummy->mixer_lock); - ucontrol->value.integer.value[0] = dummy->capture_source[addr][0]; - ucontrol->value.integer.value[1] = dummy->capture_source[addr][1]; - spin_unlock_bh(&dummy->mixer_lock); - return 0; -} - -static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol); - int change, addr = kcontrol->private_value; - int left, right; - - if (in_irq()) - printk("dummy: line %d we are in HARDWARE IRQ\n", __LINE__); - left = ucontrol->value.integer.value[0] & 1; - right = ucontrol->value.integer.value[1] & 1; - spin_lock_bh(&dummy->mixer_lock); - change = dummy->capture_source[addr][0] != left && dummy->capture_source[addr][1] != right; - dummy->capture_source[addr][0] = left; - dummy->capture_source[addr][1] = right; - spin_unlock_bh(&dummy->mixer_lock); - return change; -} - -static struct snd_kcontrol_new snd_dummy_controls[] = { - DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER), - DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER), - DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH), - DUMMY_CAPSRC("Synth Capture Switch", 0, MIXER_ADDR_SYNTH), - DUMMY_VOLUME("Line Volume", 0, MIXER_ADDR_LINE), - DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE), - DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC), - DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC), - DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD), - DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD) -}; - -static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy) -{ - struct snd_card *card = dummy->card; - unsigned int idx; - int err; - - return 0; //XXX no mixer - spin_lock_init(&dummy->mixer_lock); - strcpy(card->mixername, "Dummy Mixer"); - - for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy)); - if (err < 0) - return err; - } - return 0; -} - -static int __devinit snd_dummy_probe(struct platform_device *devptr) -{ - struct snd_card *card; - struct snd_dummy *dummy; - int idx, err; - int dev = devptr->id; - - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_dummy), &card); - if (err < 0) - return err; - - dummy = card->private_data; - dummy->card = card; - for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { - if (pcm_substreams[dev] < 1) - pcm_substreams[dev] = 1; - if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS) - pcm_substreams[dev] = MAX_PCM_SUBSTREAMS; - err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]); - if (err < 0) - goto __nodev; - } - //err = snd_card_dummy_new_mixer(dummy); - //if (err < 0) - //goto __nodev; - strcpy(card->driver, "Dummy"); - strcpy(card->shortname, "Dummy"); - sprintf(card->longname, "Dummy %i", dev + 1); - - snd_card_set_dev(card, &devptr->dev); - - err = snd_card_register(card); - if (err == 0) { - platform_set_drvdata(devptr, card); - return 0; - } - __nodev: - snd_card_free(card); - return err; -} - -static int __devexit snd_dummy_remove(struct platform_device *devptr) -{ - - del_timer(&dummytimer); - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); - return 0; -} - -#ifdef CONFIG_PM -static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct snd_dummy *dummy = card->private_data; - - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(dummy->pcm); - return 0; -} - -static int snd_dummy_resume(struct platform_device *pdev) -{ - struct snd_card *card = platform_get_drvdata(pdev); - - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} -#endif - -#define SND_DUMMY_DRIVER "snd_dummy" - -static struct platform_driver snd_dummy_driver = { - .probe = snd_dummy_probe, - .remove = __devexit_p(snd_dummy_remove), -#ifdef CONFIG_PM - .suspend = snd_dummy_suspend, - .resume = snd_dummy_resume, -#endif - .driver = { - .name = SND_DUMMY_DRIVER}, -}; - -static void snd_dummy_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_dummy_driver); -} - -static int __init alsa_card_dummy_init(void) -{ - int i, cards, err; - - err = platform_driver_register(&snd_dummy_driver); - if (err < 0) - return err; - - if (!dummystarted) { - dummystarted = 1; - spin_lock_init(&dummylock); - - spin_lock_bh(&dummylock); - for (i = 0; i < MAX_PCM_SUBSTREAMS; i++) { - - //if (i > MAX_PCM_SUBSTREAMS || dummyindex > MAX_PCM_SUBSTREAMS) { - //printk("dummy, %s:%d, i=%d, dummyindex=%d \n", __FILE__, __LINE__, i, dummyindex); - //} - dummydpcms[i].substream = NULL; - dummydpcms[i].dpcm = NULL; - dummydpcms[i].started = 0; - dummydpcms[i].elapsed = 0; - } - init_timer(&dummytimer); - dummytimer.data = (unsigned long) &dummydpcms; - dummytimer.function = snd_card_dummy_pcm_timer_function; - dummytimer.expires = 1 + jiffies; - add_timer(&dummytimer); - printk("snd-dummy skypopen driver version: 9, %s:%d working on a machine with %dHZ kernel\n", __FILE__, __LINE__, HZ); - spin_unlock_bh(&dummylock); - } - - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (!enable[i]) - continue; - device = platform_device_register_simple(SND_DUMMY_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "Dummy soundcard not found or device busy\n"); -#endif - snd_dummy_unregister_all(); - return -ENODEV; - } - return 0; -} - -static void __exit alsa_card_dummy_exit(void) -{ - del_timer(&dummytimer); - snd_dummy_unregister_all(); -} - -module_init(alsa_card_dummy_init) - module_exit(alsa_card_dummy_exit) diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c deleted file mode 100644 index 3155bf05e9..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c +++ /dev/null @@ -1,2182 +0,0 @@ -/* - * Digital Audio (PCM) abstract layer - * Copyright (c) by Jaroslav Kysela - * Abramo Bagnara - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * fill ring buffer with silence - * runtime->silence_start: starting pointer to silence area - * runtime->silence_filled: size filled with silence - * runtime->silence_threshold: threshold from application - * runtime->silence_size: maximal size from application - * - * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately - */ -void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t frames, ofs, transfer; - - if (runtime->silence_size < runtime->boundary) { - snd_pcm_sframes_t noise_dist, n; - if (runtime->silence_start != runtime->control->appl_ptr) { - n = runtime->control->appl_ptr - runtime->silence_start; - if (n < 0) - n += runtime->boundary; - if ((snd_pcm_uframes_t)n < runtime->silence_filled) - runtime->silence_filled -= n; - else - runtime->silence_filled = 0; - runtime->silence_start = runtime->control->appl_ptr; - } - if (runtime->silence_filled >= runtime->buffer_size) - return; - noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled; - if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold) - return; - frames = runtime->silence_threshold - noise_dist; - if (frames > runtime->silence_size) - frames = runtime->silence_size; - } else { - if (new_hw_ptr == ULONG_MAX) { /* initialization */ - snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime); - runtime->silence_filled = avail > 0 ? avail : 0; - runtime->silence_start = (runtime->status->hw_ptr + - runtime->silence_filled) % - runtime->boundary; - } else { - ofs = runtime->status->hw_ptr; - frames = new_hw_ptr - ofs; - if ((snd_pcm_sframes_t)frames < 0) - frames += runtime->boundary; - runtime->silence_filled -= frames; - if ((snd_pcm_sframes_t)runtime->silence_filled < 0) { - runtime->silence_filled = 0; - runtime->silence_start = new_hw_ptr; - } else { - runtime->silence_start = ofs; - } - } - frames = runtime->buffer_size - runtime->silence_filled; - } - if (snd_BUG_ON(frames > runtime->buffer_size)) - return; - if (frames == 0) - return; - ofs = runtime->silence_start % runtime->buffer_size; - while (frames > 0) { - transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames; - if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || - runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { - if (substream->ops->silence) { - int err; - err = substream->ops->silence(substream, -1, ofs, transfer); - snd_BUG_ON(err < 0); - } else { - char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); - snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); - } - } else { - unsigned int c; - unsigned int channels = runtime->channels; - if (substream->ops->silence) { - for (c = 0; c < channels; ++c) { - int err; - err = substream->ops->silence(substream, c, ofs, transfer); - snd_BUG_ON(err < 0); - } - } else { - size_t dma_csize = runtime->dma_bytes / channels; - for (c = 0; c < channels; ++c) { - char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs); - snd_pcm_format_set_silence(runtime->format, hwbuf, transfer); - } - } - } - runtime->silence_filled += transfer; - frames -= transfer; - ofs = 0; - } -} - -static void pcm_debug_name(struct snd_pcm_substream *substream, - char *name, size_t len) -{ - snprintf(name, len, "pcmC%dD%d%c:%d", - substream->pcm->card->number, - substream->pcm->device, - substream->stream ? 'c' : 'p', - substream->number); -} - -#define XRUN_DEBUG_BASIC (1<<0) -#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */ -#define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */ -#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */ -#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */ -#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */ -#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */ - -#ifdef CONFIG_SND_PCM_XRUN_DEBUG - -#define xrun_debug(substream, mask) \ - ((substream)->pstr->xrun_debug & (mask)) -#else -#define xrun_debug(substream, mask) 0 -#endif - -#define dump_stack_on_xrun(substream) do { \ - if (xrun_debug(substream, XRUN_DEBUG_STACK)) \ - dump_stack(); \ - } while (0) - -static void xrun(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) - snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { - char name[16]; - pcm_debug_name(substream, name, sizeof(name)); - snd_printd(KERN_DEBUG "XRUN: %s\n", name); - dump_stack_on_xrun(substream); - } -} - -#ifdef CONFIG_SND_PCM_XRUN_DEBUG -#define hw_ptr_error(substream, fmt, args...) \ - do { \ - if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ - xrun_log_show(substream); \ - if (printk_ratelimit()) { \ - snd_printd("PCM: " fmt, ##args); \ - } \ - dump_stack_on_xrun(substream); \ - } \ - } while (0) - -#define XRUN_LOG_CNT 10 - -struct hwptr_log_entry { - unsigned long jiffies; - snd_pcm_uframes_t pos; - snd_pcm_uframes_t period_size; - snd_pcm_uframes_t buffer_size; - snd_pcm_uframes_t old_hw_ptr; - snd_pcm_uframes_t hw_ptr_base; -}; - -struct snd_pcm_hwptr_log { - unsigned int idx; - unsigned int hit: 1; - struct hwptr_log_entry entries[XRUN_LOG_CNT]; -}; - -static void xrun_log(struct snd_pcm_substream *substream, - snd_pcm_uframes_t pos) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_pcm_hwptr_log *log = runtime->hwptr_log; - struct hwptr_log_entry *entry; - - if (log == NULL) { - log = kzalloc(sizeof(*log), GFP_ATOMIC); - if (log == NULL) - return; - runtime->hwptr_log = log; - } else { - if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) - return; - } - entry = &log->entries[log->idx]; - entry->jiffies = jiffies; - entry->pos = pos; - entry->period_size = runtime->period_size; - entry->buffer_size = runtime->buffer_size;; - entry->old_hw_ptr = runtime->status->hw_ptr; - entry->hw_ptr_base = runtime->hw_ptr_base; - log->idx = (log->idx + 1) % XRUN_LOG_CNT; -} - -static void xrun_log_show(struct snd_pcm_substream *substream) -{ - struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log; - struct hwptr_log_entry *entry; - char name[16]; - unsigned int idx; - int cnt; - - if (log == NULL) - return; - if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) - return; - pcm_debug_name(substream, name, sizeof(name)); - for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) { - entry = &log->entries[idx]; - if (entry->period_size == 0) - break; - snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " - "hwptr=%ld/%ld\n", - name, entry->jiffies, (unsigned long)entry->pos, - (unsigned long)entry->period_size, - (unsigned long)entry->buffer_size, - (unsigned long)entry->old_hw_ptr, - (unsigned long)entry->hw_ptr_base); - idx++; - idx %= XRUN_LOG_CNT; - } - log->hit = 1; -} - -#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ - -#define hw_ptr_error(substream, fmt, args...) do { } while (0) -#define xrun_log(substream, pos) do { } while (0) -#define xrun_log_show(substream) do { } while (0) - -#endif - -int snd_pcm_update_state(struct snd_pcm_substream *substream, - struct snd_pcm_runtime *runtime) -{ - snd_pcm_uframes_t avail; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - avail = snd_pcm_playback_avail(runtime); - else - avail = snd_pcm_capture_avail(runtime); - if (avail > runtime->avail_max) - runtime->avail_max = avail; - if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { - if (avail >= runtime->buffer_size) { - snd_pcm_drain_done(substream); - return -EPIPE; - } - } else { - if (avail >= runtime->stop_threshold) { - xrun(substream); - return -EPIPE; - } - } - if (avail >= runtime->control->avail_min) - wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); - return 0; -} - -static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, - unsigned int in_interrupt) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t pos; - snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base; - snd_pcm_sframes_t hdelta, delta; - unsigned long jdelta; - - old_hw_ptr = runtime->status->hw_ptr; - pos = substream->ops->pointer(substream); - if (pos == SNDRV_PCM_POS_XRUN) { - xrun(substream); - return -EPIPE; - } - if (pos >= runtime->buffer_size) { - if (printk_ratelimit()) { - char name[16]; - pcm_debug_name(substream, name, sizeof(name)); - xrun_log_show(substream); - snd_printd(KERN_ERR "BUG: %s, pos = %ld, " - "buffer size = %ld, period size = %ld\n", - name, pos, runtime->buffer_size, - runtime->period_size); - } - pos = 0; - } - pos -= pos % runtime->min_align; - if (xrun_debug(substream, XRUN_DEBUG_LOG)) - xrun_log(substream, pos); - hw_base = runtime->hw_ptr_base; - new_hw_ptr = hw_base + pos; - if (in_interrupt) { - /* we know that one period was processed */ - /* delta = "expected next hw_ptr" for in_interrupt != 0 */ - delta = runtime->hw_ptr_interrupt + runtime->period_size; - if (delta > new_hw_ptr) { - hw_base += runtime->buffer_size; - if (hw_base >= runtime->boundary) - hw_base = 0; - new_hw_ptr = hw_base + pos; - goto __delta; - } - } - /* new_hw_ptr might be lower than old_hw_ptr in case when */ - /* pointer crosses the end of the ring buffer */ - if (new_hw_ptr < old_hw_ptr) { - hw_base += runtime->buffer_size; - if (hw_base >= runtime->boundary) - hw_base = 0; - new_hw_ptr = hw_base + pos; - } - __delta: - delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary; - if (xrun_debug(substream, in_interrupt ? - XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { - char name[16]; - pcm_debug_name(substream, name, sizeof(name)); - snd_printd("%s_update: %s: pos=%u/%u/%u, " - "hwptr=%ld/%ld/%ld/%ld\n", - in_interrupt ? "period" : "hwptr", - name, - (unsigned int)pos, - (unsigned int)runtime->period_size, - (unsigned int)runtime->buffer_size, - (unsigned long)delta, - (unsigned long)old_hw_ptr, - (unsigned long)new_hw_ptr, - (unsigned long)runtime->hw_ptr_base); - } - /* something must be really wrong */ - if (delta >= runtime->buffer_size + runtime->period_size) { - hw_ptr_error(substream, - "Unexpected hw_pointer value %s" - "(stream=%i, pos=%ld, new_hw_ptr=%ld, " - "old_hw_ptr=%ld)\n", - in_interrupt ? "[Q] " : "[P]", - substream->stream, (long)pos, - (long)new_hw_ptr, (long)old_hw_ptr); - return 0; - } - - /* Do jiffies check only in xrun_debug mode */ - if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK)) - goto no_jiffies_check; - - /* Skip the jiffies check for hardwares with BATCH flag. - * Such hardware usually just increases the position at each IRQ, - * thus it can't give any strange position. - */ - if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) - goto no_jiffies_check; - hdelta = delta; - if (hdelta < runtime->delay) - goto no_jiffies_check; - hdelta -= runtime->delay; - jdelta = jiffies - runtime->hw_ptr_jiffies; - if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) { - delta = jdelta / - (((runtime->period_size * HZ) / runtime->rate) - + HZ/100); - /* move new_hw_ptr according jiffies not pos variable */ - new_hw_ptr = old_hw_ptr; - hw_base = delta; - /* use loop to avoid checks for delta overflows */ - /* the delta value is small or zero in most cases */ - while (delta > 0) { - new_hw_ptr += runtime->period_size; - if (new_hw_ptr >= runtime->boundary) - new_hw_ptr -= runtime->boundary; - delta--; - } - /* align hw_base to buffer_size */ - hw_ptr_error(substream, - "hw_ptr skipping! %s" - "(pos=%ld, delta=%ld, period=%ld, " - "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n", - in_interrupt ? "[Q] " : "", - (long)pos, (long)hdelta, - (long)runtime->period_size, jdelta, - ((hdelta * HZ) / runtime->rate), hw_base, - (unsigned long)old_hw_ptr, - (unsigned long)new_hw_ptr); - /* reset values to proper state */ - delta = 0; - hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size); - } - no_jiffies_check: - if (delta > runtime->period_size + runtime->period_size / 2) { - hw_ptr_error(substream, - "Lost interrupts? %s" - "(stream=%i, delta=%ld, new_hw_ptr=%ld, " - "old_hw_ptr=%ld)\n", - in_interrupt ? "[Q] " : "", - substream->stream, (long)delta, - (long)new_hw_ptr, - (long)old_hw_ptr); - } - - if (runtime->status->hw_ptr == new_hw_ptr) - return 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - runtime->silence_size > 0) - snd_pcm_playback_silence(substream, new_hw_ptr); - - if (in_interrupt) { - runtime->hw_ptr_interrupt = new_hw_ptr - - (new_hw_ptr % runtime->period_size); - } - runtime->hw_ptr_base = hw_base; - runtime->status->hw_ptr = new_hw_ptr; - runtime->hw_ptr_jiffies = jiffies; - if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) - snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); - - return snd_pcm_update_state(substream, runtime); -} - -/* CAUTION: call it with irq disabled */ -int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) -{ - return snd_pcm_update_hw_ptr0(substream, 0); -} - -/** - * snd_pcm_set_ops - set the PCM operators - * @pcm: the pcm instance - * @direction: stream direction, SNDRV_PCM_STREAM_XXX - * @ops: the operator table - * - * Sets the given PCM operators to the pcm instance. - */ -void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops) -{ - struct snd_pcm_str *stream = &pcm->streams[direction]; - struct snd_pcm_substream *substream; - - for (substream = stream->substream; substream != NULL; substream = substream->next) - substream->ops = ops; -} - -EXPORT_SYMBOL(snd_pcm_set_ops); - -/** - * snd_pcm_sync - set the PCM sync id - * @substream: the pcm substream - * - * Sets the PCM sync identifier for the card. - */ -void snd_pcm_set_sync(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->sync.id32[0] = substream->pcm->card->number; - runtime->sync.id32[1] = -1; - runtime->sync.id32[2] = -1; - runtime->sync.id32[3] = -1; -} - -EXPORT_SYMBOL(snd_pcm_set_sync); - -/* - * Standard ioctl routine - */ - -static inline unsigned int div32(unsigned int a, unsigned int b, - unsigned int *r) -{ - if (b == 0) { - *r = 0; - return UINT_MAX; - } - *r = a % b; - return a / b; -} - -static inline unsigned int div_down(unsigned int a, unsigned int b) -{ - if (b == 0) - return UINT_MAX; - return a / b; -} - -static inline unsigned int div_up(unsigned int a, unsigned int b) -{ - unsigned int r; - unsigned int q; - if (b == 0) - return UINT_MAX; - q = div32(a, b, &r); - if (r) - ++q; - return q; -} - -static inline unsigned int mul(unsigned int a, unsigned int b) -{ - if (a == 0) - return 0; - if (div_down(UINT_MAX, a) < b) - return UINT_MAX; - return a * b; -} - -static inline unsigned int muldiv32(unsigned int a, unsigned int b, - unsigned int c, unsigned int *r) -{ - uint64_t n = (u_int64_t) a * b; - if (c == 0) { - snd_BUG_ON(!n); - *r = 0; - return UINT_MAX; - } - n = div_u64_rem(n, c, r); - if (n >= UINT_MAX) { - *r = 0; - return UINT_MAX; - } - return n; -} - -/** - * snd_interval_refine - refine the interval value of configurator - * @i: the interval value to refine - * @v: the interval value to refer to - * - * Refines the interval value with the reference value. - * The interval is changed to the range satisfying both intervals. - * The interval status (min, max, integer, etc.) are evaluated. - * - * Returns non-zero if the value is changed, zero if not changed. - */ -int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) -{ - int changed = 0; - if (snd_BUG_ON(snd_interval_empty(i))) - return -EINVAL; - if (i->min < v->min) { - i->min = v->min; - i->openmin = v->openmin; - changed = 1; - } else if (i->min == v->min && !i->openmin && v->openmin) { - i->openmin = 1; - changed = 1; - } - if (i->max > v->max) { - i->max = v->max; - i->openmax = v->openmax; - changed = 1; - } else if (i->max == v->max && !i->openmax && v->openmax) { - i->openmax = 1; - changed = 1; - } - if (!i->integer && v->integer) { - i->integer = 1; - changed = 1; - } - if (i->integer) { - if (i->openmin) { - i->min++; - i->openmin = 0; - } - if (i->openmax) { - i->max--; - i->openmax = 0; - } - } else if (!i->openmin && !i->openmax && i->min == i->max) - i->integer = 1; - if (snd_interval_checkempty(i)) { - snd_interval_none(i); - return -EINVAL; - } - return changed; -} - -EXPORT_SYMBOL(snd_interval_refine); - -static int snd_interval_refine_first(struct snd_interval *i) -{ - if (snd_BUG_ON(snd_interval_empty(i))) - return -EINVAL; - if (snd_interval_single(i)) - return 0; - i->max = i->min; - i->openmax = i->openmin; - if (i->openmax) - i->max++; - return 1; -} - -static int snd_interval_refine_last(struct snd_interval *i) -{ - if (snd_BUG_ON(snd_interval_empty(i))) - return -EINVAL; - if (snd_interval_single(i)) - return 0; - i->min = i->max; - i->openmin = i->openmax; - if (i->openmin) - i->min--; - return 1; -} - -void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) -{ - if (a->empty || b->empty) { - snd_interval_none(c); - return; - } - c->empty = 0; - c->min = mul(a->min, b->min); - c->openmin = (a->openmin || b->openmin); - c->max = mul(a->max, b->max); - c->openmax = (a->openmax || b->openmax); - c->integer = (a->integer && b->integer); -} - -/** - * snd_interval_div - refine the interval value with division - * @a: dividend - * @b: divisor - * @c: quotient - * - * c = a / b - * - * Returns non-zero if the value is changed, zero if not changed. - */ -void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) -{ - unsigned int r; - if (a->empty || b->empty) { - snd_interval_none(c); - return; - } - c->empty = 0; - c->min = div32(a->min, b->max, &r); - c->openmin = (r || a->openmin || b->openmax); - if (b->min > 0) { - c->max = div32(a->max, b->min, &r); - if (r) { - c->max++; - c->openmax = 1; - } else - c->openmax = (a->openmax || b->openmin); - } else { - c->max = UINT_MAX; - c->openmax = 0; - } - c->integer = 0; -} - -/** - * snd_interval_muldivk - refine the interval value - * @a: dividend 1 - * @b: dividend 2 - * @k: divisor (as integer) - * @c: result - * - * c = a * b / k - * - * Returns non-zero if the value is changed, zero if not changed. - */ -void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b, - unsigned int k, struct snd_interval *c) -{ - unsigned int r; - if (a->empty || b->empty) { - snd_interval_none(c); - return; - } - c->empty = 0; - c->min = muldiv32(a->min, b->min, k, &r); - c->openmin = (r || a->openmin || b->openmin); - c->max = muldiv32(a->max, b->max, k, &r); - if (r) { - c->max++; - c->openmax = 1; - } else - c->openmax = (a->openmax || b->openmax); - c->integer = 0; -} - -/** - * snd_interval_mulkdiv - refine the interval value - * @a: dividend 1 - * @k: dividend 2 (as integer) - * @b: divisor - * @c: result - * - * c = a * k / b - * - * Returns non-zero if the value is changed, zero if not changed. - */ -void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k, - const struct snd_interval *b, struct snd_interval *c) -{ - unsigned int r; - if (a->empty || b->empty) { - snd_interval_none(c); - return; - } - c->empty = 0; - c->min = muldiv32(a->min, k, b->max, &r); - c->openmin = (r || a->openmin || b->openmax); - if (b->min > 0) { - c->max = muldiv32(a->max, k, b->min, &r); - if (r) { - c->max++; - c->openmax = 1; - } else - c->openmax = (a->openmax || b->openmin); - } else { - c->max = UINT_MAX; - c->openmax = 0; - } - c->integer = 0; -} - -/* ---- */ - - -/** - * snd_interval_ratnum - refine the interval value - * @i: interval to refine - * @rats_count: number of ratnum_t - * @rats: ratnum_t array - * @nump: pointer to store the resultant numerator - * @denp: pointer to store the resultant denominator - * - * Returns non-zero if the value is changed, zero if not changed. - */ -int snd_interval_ratnum(struct snd_interval *i, - unsigned int rats_count, struct snd_ratnum *rats, - unsigned int *nump, unsigned int *denp) -{ - unsigned int best_num, best_den; - int best_diff; - unsigned int k; - struct snd_interval t; - int err; - unsigned int result_num, result_den; - int result_diff; - - best_num = best_den = best_diff = 0; - for (k = 0; k < rats_count; ++k) { - unsigned int num = rats[k].num; - unsigned int den; - unsigned int q = i->min; - int diff; - if (q == 0) - q = 1; - den = div_up(num, q); - if (den < rats[k].den_min) - continue; - if (den > rats[k].den_max) - den = rats[k].den_max; - else { - unsigned int r; - r = (den - rats[k].den_min) % rats[k].den_step; - if (r != 0) - den -= r; - } - diff = num - q * den; - if (diff < 0) - diff = -diff; - if (best_num == 0 || - diff * best_den < best_diff * den) { - best_diff = diff; - best_den = den; - best_num = num; - } - } - if (best_den == 0) { - i->empty = 1; - return -EINVAL; - } - t.min = div_down(best_num, best_den); - t.openmin = !!(best_num % best_den); - - result_num = best_num; - result_diff = best_diff; - result_den = best_den; - best_num = best_den = best_diff = 0; - for (k = 0; k < rats_count; ++k) { - unsigned int num = rats[k].num; - unsigned int den; - unsigned int q = i->max; - int diff; - if (q == 0) { - i->empty = 1; - return -EINVAL; - } - den = div_down(num, q); - if (den > rats[k].den_max) - continue; - if (den < rats[k].den_min) - den = rats[k].den_min; - else { - unsigned int r; - r = (den - rats[k].den_min) % rats[k].den_step; - if (r != 0) - den += rats[k].den_step - r; - } - diff = q * den - num; - if (diff < 0) - diff = -diff; - if (best_num == 0 || - diff * best_den < best_diff * den) { - best_diff = diff; - best_den = den; - best_num = num; - } - } - if (best_den == 0) { - i->empty = 1; - return -EINVAL; - } - t.max = div_up(best_num, best_den); - t.openmax = !!(best_num % best_den); - t.integer = 0; - err = snd_interval_refine(i, &t); - if (err < 0) - return err; - - if (snd_interval_single(i)) { - if (best_diff * result_den < result_diff * best_den) { - result_num = best_num; - result_den = best_den; - } - if (nump) - *nump = result_num; - if (denp) - *denp = result_den; - } - return err; -} - -EXPORT_SYMBOL(snd_interval_ratnum); - -/** - * snd_interval_ratden - refine the interval value - * @i: interval to refine - * @rats_count: number of struct ratden - * @rats: struct ratden array - * @nump: pointer to store the resultant numerator - * @denp: pointer to store the resultant denominator - * - * Returns non-zero if the value is changed, zero if not changed. - */ -static int snd_interval_ratden(struct snd_interval *i, - unsigned int rats_count, struct snd_ratden *rats, - unsigned int *nump, unsigned int *denp) -{ - unsigned int best_num, best_diff, best_den; - unsigned int k; - struct snd_interval t; - int err; - - best_num = best_den = best_diff = 0; - for (k = 0; k < rats_count; ++k) { - unsigned int num; - unsigned int den = rats[k].den; - unsigned int q = i->min; - int diff; - num = mul(q, den); - if (num > rats[k].num_max) - continue; - if (num < rats[k].num_min) - num = rats[k].num_max; - else { - unsigned int r; - r = (num - rats[k].num_min) % rats[k].num_step; - if (r != 0) - num += rats[k].num_step - r; - } - diff = num - q * den; - if (best_num == 0 || - diff * best_den < best_diff * den) { - best_diff = diff; - best_den = den; - best_num = num; - } - } - if (best_den == 0) { - i->empty = 1; - return -EINVAL; - } - t.min = div_down(best_num, best_den); - t.openmin = !!(best_num % best_den); - - best_num = best_den = best_diff = 0; - for (k = 0; k < rats_count; ++k) { - unsigned int num; - unsigned int den = rats[k].den; - unsigned int q = i->max; - int diff; - num = mul(q, den); - if (num < rats[k].num_min) - continue; - if (num > rats[k].num_max) - num = rats[k].num_max; - else { - unsigned int r; - r = (num - rats[k].num_min) % rats[k].num_step; - if (r != 0) - num -= r; - } - diff = q * den - num; - if (best_num == 0 || - diff * best_den < best_diff * den) { - best_diff = diff; - best_den = den; - best_num = num; - } - } - if (best_den == 0) { - i->empty = 1; - return -EINVAL; - } - t.max = div_up(best_num, best_den); - t.openmax = !!(best_num % best_den); - t.integer = 0; - err = snd_interval_refine(i, &t); - if (err < 0) - return err; - - if (snd_interval_single(i)) { - if (nump) - *nump = best_num; - if (denp) - *denp = best_den; - } - return err; -} - -/** - * snd_interval_list - refine the interval value from the list - * @i: the interval value to refine - * @count: the number of elements in the list - * @list: the value list - * @mask: the bit-mask to evaluate - * - * Refines the interval value from the list. - * When mask is non-zero, only the elements corresponding to bit 1 are - * evaluated. - * - * Returns non-zero if the value is changed, zero if not changed. - */ -int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) -{ - unsigned int k; - struct snd_interval list_range; - - if (!count) { - i->empty = 1; - return -EINVAL; - } - snd_interval_any(&list_range); - list_range.min = UINT_MAX; - list_range.max = 0; - for (k = 0; k < count; k++) { - if (mask && !(mask & (1 << k))) - continue; - if (!snd_interval_test(i, list[k])) - continue; - list_range.min = min(list_range.min, list[k]); - list_range.max = max(list_range.max, list[k]); - } - return snd_interval_refine(i, &list_range); -} - -EXPORT_SYMBOL(snd_interval_list); - -static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) -{ - unsigned int n; - int changed = 0; - n = (i->min - min) % step; - if (n != 0 || i->openmin) { - i->min += step - n; - changed = 1; - } - n = (i->max - min) % step; - if (n != 0 || i->openmax) { - i->max -= n; - changed = 1; - } - if (snd_interval_checkempty(i)) { - i->empty = 1; - return -EINVAL; - } - return changed; -} - -/* Info constraints helpers */ - -/** - * snd_pcm_hw_rule_add - add the hw-constraint rule - * @runtime: the pcm runtime instance - * @cond: condition bits - * @var: the variable to evaluate - * @func: the evaluation function - * @private: the private data pointer passed to function - * @dep: the dependent variables - * - * Returns zero if successful, or a negative error code on failure. - */ -int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, - int var, - snd_pcm_hw_rule_func_t func, void *private, - int dep, ...) -{ - struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; - struct snd_pcm_hw_rule *c; - unsigned int k; - va_list args; - va_start(args, dep); - if (constrs->rules_num >= constrs->rules_all) { - struct snd_pcm_hw_rule *new; - unsigned int new_rules = constrs->rules_all + 16; - new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); - if (!new) - return -ENOMEM; - if (constrs->rules) { - memcpy(new, constrs->rules, - constrs->rules_num * sizeof(*c)); - kfree(constrs->rules); - } - constrs->rules = new; - constrs->rules_all = new_rules; - } - c = &constrs->rules[constrs->rules_num]; - c->cond = cond; - c->func = func; - c->var = var; - c->private = private; - k = 0; - while (1) { - if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) - return -EINVAL; - c->deps[k++] = dep; - if (dep < 0) - break; - dep = va_arg(args, int); - } - constrs->rules_num++; - va_end(args); - return 0; -} - -EXPORT_SYMBOL(snd_pcm_hw_rule_add); - -/** - * snd_pcm_hw_constraint_mask - apply the given bitmap mask constraint - * @runtime: PCM runtime instance - * @var: hw_params variable to apply the mask - * @mask: the bitmap mask - * - * Apply the constraint of the given bitmap mask to a 32-bit mask parameter. - */ -int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, - uint32_t mask) -{ - struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; - struct snd_mask *maskp = constrs_mask(constrs, var); - *maskp->bits &= mask; - memset(maskp->bits + 1, 0, (SNDRV_MASK_MAX-32) / 8); /* clear rest */ - if (*maskp->bits == 0) - return -EINVAL; - return 0; -} - -/** - * snd_pcm_hw_constraint_mask64 - apply the given bitmap mask constraint - * @runtime: PCM runtime instance - * @var: hw_params variable to apply the mask - * @mask: the 64bit bitmap mask - * - * Apply the constraint of the given bitmap mask to a 64-bit mask parameter. - */ -int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, - uint64_t mask) -{ - struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; - struct snd_mask *maskp = constrs_mask(constrs, var); - maskp->bits[0] &= (uint32_t)mask; - maskp->bits[1] &= (uint32_t)(mask >> 32); - memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */ - if (! maskp->bits[0] && ! maskp->bits[1]) - return -EINVAL; - return 0; -} - -/** - * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval - * @runtime: PCM runtime instance - * @var: hw_params variable to apply the integer constraint - * - * Apply the constraint of integer to an interval parameter. - */ -int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var) -{ - struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; - return snd_interval_setinteger(constrs_interval(constrs, var)); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); - -/** - * snd_pcm_hw_constraint_minmax - apply a min/max range constraint to an interval - * @runtime: PCM runtime instance - * @var: hw_params variable to apply the range - * @min: the minimal value - * @max: the maximal value - * - * Apply the min/max range constraint to an interval parameter. - */ -int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, - unsigned int min, unsigned int max) -{ - struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; - struct snd_interval t; - t.min = min; - t.max = max; - t.openmin = t.openmax = 0; - t.integer = 0; - return snd_interval_refine(constrs_interval(constrs, var), &t); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax); - -static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_pcm_hw_constraint_list *list = rule->private; - return snd_interval_list(hw_param_interval(params, rule->var), list->count, list->list, list->mask); -} - - -/** - * snd_pcm_hw_constraint_list - apply a list of constraints to a parameter - * @runtime: PCM runtime instance - * @cond: condition bits - * @var: hw_params variable to apply the list constraint - * @l: list - * - * Apply the list of constraints to an interval parameter. - */ -int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, - unsigned int cond, - snd_pcm_hw_param_t var, - struct snd_pcm_hw_constraint_list *l) -{ - return snd_pcm_hw_rule_add(runtime, cond, var, - snd_pcm_hw_rule_list, l, - var, -1); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_list); - -static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_pcm_hw_constraint_ratnums *r = rule->private; - unsigned int num = 0, den = 0; - int err; - err = snd_interval_ratnum(hw_param_interval(params, rule->var), - r->nrats, r->rats, &num, &den); - if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) { - params->rate_num = num; - params->rate_den = den; - } - return err; -} - -/** - * snd_pcm_hw_constraint_ratnums - apply ratnums constraint to a parameter - * @runtime: PCM runtime instance - * @cond: condition bits - * @var: hw_params variable to apply the ratnums constraint - * @r: struct snd_ratnums constriants - */ -int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, - unsigned int cond, - snd_pcm_hw_param_t var, - struct snd_pcm_hw_constraint_ratnums *r) -{ - return snd_pcm_hw_rule_add(runtime, cond, var, - snd_pcm_hw_rule_ratnums, r, - var, -1); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums); - -static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_pcm_hw_constraint_ratdens *r = rule->private; - unsigned int num = 0, den = 0; - int err = snd_interval_ratden(hw_param_interval(params, rule->var), - r->nrats, r->rats, &num, &den); - if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) { - params->rate_num = num; - params->rate_den = den; - } - return err; -} - -/** - * snd_pcm_hw_constraint_ratdens - apply ratdens constraint to a parameter - * @runtime: PCM runtime instance - * @cond: condition bits - * @var: hw_params variable to apply the ratdens constraint - * @r: struct snd_ratdens constriants - */ -int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, - unsigned int cond, - snd_pcm_hw_param_t var, - struct snd_pcm_hw_constraint_ratdens *r) -{ - return snd_pcm_hw_rule_add(runtime, cond, var, - snd_pcm_hw_rule_ratdens, r, - var, -1); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens); - -static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - unsigned int l = (unsigned long) rule->private; - int width = l & 0xffff; - unsigned int msbits = l >> 16; - struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); - if (snd_interval_single(i) && snd_interval_value(i) == width) - params->msbits = msbits; - return 0; -} - -/** - * snd_pcm_hw_constraint_msbits - add a hw constraint msbits rule - * @runtime: PCM runtime instance - * @cond: condition bits - * @width: sample bits width - * @msbits: msbits width - */ -int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, - unsigned int cond, - unsigned int width, - unsigned int msbits) -{ - unsigned long l = (msbits << 16) | width; - return snd_pcm_hw_rule_add(runtime, cond, -1, - snd_pcm_hw_rule_msbits, - (void*) l, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits); - -static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - unsigned long step = (unsigned long) rule->private; - return snd_interval_step(hw_param_interval(params, rule->var), 0, step); -} - -/** - * snd_pcm_hw_constraint_step - add a hw constraint step rule - * @runtime: PCM runtime instance - * @cond: condition bits - * @var: hw_params variable to apply the step constraint - * @step: step size - */ -int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime, - unsigned int cond, - snd_pcm_hw_param_t var, - unsigned long step) -{ - return snd_pcm_hw_rule_add(runtime, cond, var, - snd_pcm_hw_rule_step, (void *) step, - var, -1); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_step); - -static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) -{ - static unsigned int pow2_sizes[] = { - 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7, - 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, - 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23, - 1<<24, 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30 - }; - return snd_interval_list(hw_param_interval(params, rule->var), - ARRAY_SIZE(pow2_sizes), pow2_sizes, 0); -} - -/** - * snd_pcm_hw_constraint_pow2 - add a hw constraint power-of-2 rule - * @runtime: PCM runtime instance - * @cond: condition bits - * @var: hw_params variable to apply the power-of-2 constraint - */ -int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, - unsigned int cond, - snd_pcm_hw_param_t var) -{ - return snd_pcm_hw_rule_add(runtime, cond, var, - snd_pcm_hw_rule_pow2, NULL, - var, -1); -} - -EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); - -static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var) -{ - if (hw_is_mask(var)) { - snd_mask_any(hw_param_mask(params, var)); - params->cmask |= 1 << var; - params->rmask |= 1 << var; - return; - } - if (hw_is_interval(var)) { - snd_interval_any(hw_param_interval(params, var)); - params->cmask |= 1 << var; - params->rmask |= 1 << var; - return; - } - snd_BUG(); -} - -void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) -{ - unsigned int k; - memset(params, 0, sizeof(*params)); - for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) - _snd_pcm_hw_param_any(params, k); - for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) - _snd_pcm_hw_param_any(params, k); - params->info = ~0U; -} - -EXPORT_SYMBOL(_snd_pcm_hw_params_any); - -/** - * snd_pcm_hw_param_value - return @params field @var value - * @params: the hw_params instance - * @var: parameter to retrieve - * @dir: pointer to the direction (-1,0,1) or %NULL - * - * Return the value for field @var if it's fixed in configuration space - * defined by @params. Return -%EINVAL otherwise. - */ -int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var, int *dir) -{ - if (hw_is_mask(var)) { - const struct snd_mask *mask = hw_param_mask_c(params, var); - if (!snd_mask_single(mask)) - return -EINVAL; - if (dir) - *dir = 0; - return snd_mask_value(mask); - } - if (hw_is_interval(var)) { - const struct snd_interval *i = hw_param_interval_c(params, var); - if (!snd_interval_single(i)) - return -EINVAL; - if (dir) - *dir = i->openmin; - return snd_interval_value(i); - } - return -EINVAL; -} - -EXPORT_SYMBOL(snd_pcm_hw_param_value); - -void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var) -{ - if (hw_is_mask(var)) { - snd_mask_none(hw_param_mask(params, var)); - params->cmask |= 1 << var; - params->rmask |= 1 << var; - } else if (hw_is_interval(var)) { - snd_interval_none(hw_param_interval(params, var)); - params->cmask |= 1 << var; - params->rmask |= 1 << var; - } else { - snd_BUG(); - } -} - -EXPORT_SYMBOL(_snd_pcm_hw_param_setempty); - -static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var) -{ - int changed; - if (hw_is_mask(var)) - changed = snd_mask_refine_first(hw_param_mask(params, var)); - else if (hw_is_interval(var)) - changed = snd_interval_refine_first(hw_param_interval(params, var)); - else - return -EINVAL; - if (changed) { - params->cmask |= 1 << var; - params->rmask |= 1 << var; - } - return changed; -} - - -/** - * snd_pcm_hw_param_first - refine config space and return minimum value - * @pcm: PCM instance - * @params: the hw_params instance - * @var: parameter to retrieve - * @dir: pointer to the direction (-1,0,1) or %NULL - * - * Inside configuration space defined by @params remove from @var all - * values > minimum. Reduce configuration space accordingly. - * Return the minimum. - */ -int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, - struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var, int *dir) -{ - int changed = _snd_pcm_hw_param_first(params, var); - if (changed < 0) - return changed; - if (params->rmask) { - int err = snd_pcm_hw_refine(pcm, params); - if (snd_BUG_ON(err < 0)) - return err; - } - return snd_pcm_hw_param_value(params, var, dir); -} - -EXPORT_SYMBOL(snd_pcm_hw_param_first); - -static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var) -{ - int changed; - if (hw_is_mask(var)) - changed = snd_mask_refine_last(hw_param_mask(params, var)); - else if (hw_is_interval(var)) - changed = snd_interval_refine_last(hw_param_interval(params, var)); - else - return -EINVAL; - if (changed) { - params->cmask |= 1 << var; - params->rmask |= 1 << var; - } - return changed; -} - - -/** - * snd_pcm_hw_param_last - refine config space and return maximum value - * @pcm: PCM instance - * @params: the hw_params instance - * @var: parameter to retrieve - * @dir: pointer to the direction (-1,0,1) or %NULL - * - * Inside configuration space defined by @params remove from @var all - * values < maximum. Reduce configuration space accordingly. - * Return the maximum. - */ -int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, - struct snd_pcm_hw_params *params, - snd_pcm_hw_param_t var, int *dir) -{ - int changed = _snd_pcm_hw_param_last(params, var); - if (changed < 0) - return changed; - if (params->rmask) { - int err = snd_pcm_hw_refine(pcm, params); - if (snd_BUG_ON(err < 0)) - return err; - } - return snd_pcm_hw_param_value(params, var, dir); -} - -EXPORT_SYMBOL(snd_pcm_hw_param_last); - -/** - * snd_pcm_hw_param_choose - choose a configuration defined by @params - * @pcm: PCM instance - * @params: the hw_params instance - * - * Choose one configuration from configuration space defined by @params. - * The configuration chosen is that obtained fixing in this order: - * first access, first format, first subformat, min channels, - * min rate, min period time, max buffer size, min tick time - */ -int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, - struct snd_pcm_hw_params *params) -{ - static int vars[] = { - SNDRV_PCM_HW_PARAM_ACCESS, - SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_HW_PARAM_SUBFORMAT, - SNDRV_PCM_HW_PARAM_CHANNELS, - SNDRV_PCM_HW_PARAM_RATE, - SNDRV_PCM_HW_PARAM_PERIOD_TIME, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, - SNDRV_PCM_HW_PARAM_TICK_TIME, - -1 - }; - int err, *v; - - for (v = vars; *v != -1; v++) { - if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE) - err = snd_pcm_hw_param_first(pcm, params, *v, NULL); - else - err = snd_pcm_hw_param_last(pcm, params, *v, NULL); - if (snd_BUG_ON(err < 0)) - return err; - } - return 0; -} - -static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, - void *arg) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long flags; - snd_pcm_stream_lock_irqsave(substream, flags); - if (snd_pcm_running(substream) && - snd_pcm_update_hw_ptr(substream) >= 0) - runtime->status->hw_ptr %= runtime->buffer_size; - else - runtime->status->hw_ptr = 0; - snd_pcm_stream_unlock_irqrestore(substream, flags); - return 0; -} - -static int snd_pcm_lib_ioctl_channel_info(struct snd_pcm_substream *substream, - void *arg) -{ - struct snd_pcm_channel_info *info = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - int width; - if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) { - info->offset = -1; - return 0; - } - width = snd_pcm_format_physical_width(runtime->format); - if (width < 0) - return width; - info->offset = 0; - switch (runtime->access) { - case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED: - case SNDRV_PCM_ACCESS_RW_INTERLEAVED: - info->first = info->channel * width; - info->step = runtime->channels * width; - break; - case SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED: - case SNDRV_PCM_ACCESS_RW_NONINTERLEAVED: - { - size_t size = runtime->dma_bytes / runtime->channels; - info->first = info->channel * size * 8; - info->step = width; - break; - } - default: - snd_BUG(); - break; - } - return 0; -} - -static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream, - void *arg) -{ - struct snd_pcm_hw_params *params = arg; - snd_pcm_format_t format; - int channels, width; - - params->fifo_size = substream->runtime->hw.fifo_size; - if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_FIFO_IN_FRAMES)) { - format = params_format(params); - channels = params_channels(params); - width = snd_pcm_format_physical_width(format); - params->fifo_size /= width * channels; - } - return 0; -} - -/** - * snd_pcm_lib_ioctl - a generic PCM ioctl callback - * @substream: the pcm substream instance - * @cmd: ioctl command - * @arg: ioctl argument - * - * Processes the generic ioctl commands for PCM. - * Can be passed as the ioctl callback for PCM ops. - * - * Returns zero if successful, or a negative error code on failure. - */ -int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - switch (cmd) { - case SNDRV_PCM_IOCTL1_INFO: - return 0; - case SNDRV_PCM_IOCTL1_RESET: - return snd_pcm_lib_ioctl_reset(substream, arg); - case SNDRV_PCM_IOCTL1_CHANNEL_INFO: - return snd_pcm_lib_ioctl_channel_info(substream, arg); - case SNDRV_PCM_IOCTL1_FIFO_SIZE: - return snd_pcm_lib_ioctl_fifo_size(substream, arg); - } - return -ENXIO; -} - -EXPORT_SYMBOL(snd_pcm_lib_ioctl); - -/** - * snd_pcm_period_elapsed - update the pcm status for the next period - * @substream: the pcm substream instance - * - * This function is called from the interrupt handler when the - * PCM has processed the period size. It will update the current - * pointer, wake up sleepers, etc. - * - * Even if more than one periods have elapsed since the last call, you - * have to call this only once. - */ -void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime; - unsigned long flags; - - if (PCM_RUNTIME_CHECK(substream)) - return; - runtime = substream->runtime; - - if (runtime->transfer_ack_begin) - runtime->transfer_ack_begin(substream); - - //giovanni snd_pcm_stream_lock_irqsave(substream, flags); //giovanni - if (!snd_pcm_running(substream) || - snd_pcm_update_hw_ptr0(substream, 1) < 0) - goto _end; - - if (substream->timer_running) - snd_timer_interrupt(substream->timer, 1); - _end: - //giovanni snd_pcm_stream_unlock_irqrestore(substream, flags); //giovanni - if (runtime->transfer_ack_end) - runtime->transfer_ack_end(substream); - kill_fasync(&runtime->fasync, SIGIO, POLL_IN); -} - -EXPORT_SYMBOL(snd_pcm_period_elapsed); - -/* - * Wait until avail_min data becomes available - * Returns a negative error code if any error occurs during operation. - * The available space is stored on availp. When err = 0 and avail = 0 - * on the capture stream, it indicates the stream is in DRAINING state. - */ -static int wait_for_avail_min(struct snd_pcm_substream *substream, - snd_pcm_uframes_t *availp) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - wait_queue_t wait; - int err = 0; - snd_pcm_uframes_t avail = 0; - long tout; - - init_waitqueue_entry(&wait, current); - add_wait_queue(&runtime->tsleep, &wait); - for (;;) { - if (signal_pending(current)) { - err = -ERESTARTSYS; - break; - } - set_current_state(TASK_INTERRUPTIBLE); - //giovanni snd_pcm_stream_unlock_irq(substream); - tout = schedule_timeout(msecs_to_jiffies(10000)); - //giovanni snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_SUSPENDED: - err = -ESTRPIPE; - goto _endloop; - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - goto _endloop; - case SNDRV_PCM_STATE_DRAINING: - if (is_playback) - err = -EPIPE; - else - avail = 0; /* indicate draining */ - goto _endloop; - case SNDRV_PCM_STATE_OPEN: - case SNDRV_PCM_STATE_SETUP: - case SNDRV_PCM_STATE_DISCONNECTED: - err = -EBADFD; - goto _endloop; - } - if (!tout) { - snd_printd("%s write error (DMA or IRQ trouble?)\n", - is_playback ? "playback" : "capture"); - err = -EIO; - break; - } - if (is_playback) - avail = snd_pcm_playback_avail(runtime); - else - avail = snd_pcm_capture_avail(runtime); - if (avail >= runtime->control->avail_min) - break; - } - _endloop: - remove_wait_queue(&runtime->tsleep, &wait); - *availp = avail; - return err; -} - -static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, - unsigned int hwoff, - unsigned long data, unsigned int off, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - char __user *buf = (char __user *) data + frames_to_bytes(runtime, off); - if (substream->ops->copy) { - if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0) - return err; - } else { - char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); - if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) - return -EFAULT; - } - return 0; -} - -typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff, - unsigned long data, unsigned int off, - snd_pcm_uframes_t size); - -static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, - unsigned long data, - snd_pcm_uframes_t size, - int nonblock, - transfer_f transfer) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t xfer = 0; - snd_pcm_uframes_t offset = 0; - int err = 0; - - if (size == 0) - return 0; - - //giovanni snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_RUNNING: - case SNDRV_PCM_STATE_PAUSED: - break; - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - goto _end_unlock; - case SNDRV_PCM_STATE_SUSPENDED: - err = -ESTRPIPE; - goto _end_unlock; - default: - err = -EBADFD; - goto _end_unlock; - } - - runtime->twake = 1; - while (size > 0) { - snd_pcm_uframes_t frames, appl_ptr, appl_ofs; - snd_pcm_uframes_t avail; - snd_pcm_uframes_t cont; - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) - snd_pcm_update_hw_ptr(substream); - avail = snd_pcm_playback_avail(runtime); - if (!avail) { - if (nonblock) { - err = -EAGAIN; - goto _end_unlock; - } - err = wait_for_avail_min(substream, &avail); - if (err < 0) - goto _end_unlock; - } - frames = size > avail ? avail : size; - cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; - if (frames > cont) - frames = cont; - if (snd_BUG_ON(!frames)) { - runtime->twake = 0; - //giovanni snd_pcm_stream_unlock_irq(substream); - return -EINVAL; - } - appl_ptr = runtime->control->appl_ptr; - appl_ofs = appl_ptr % runtime->buffer_size; - //giovanni snd_pcm_stream_unlock_irq(substream); - err = transfer(substream, appl_ofs, data, offset, frames); - //giovanni snd_pcm_stream_lock_irq(substream); - if (err < 0) - goto _end_unlock; - switch (runtime->status->state) { - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - goto _end_unlock; - case SNDRV_PCM_STATE_SUSPENDED: - err = -ESTRPIPE; - goto _end_unlock; - default: - break; - } - appl_ptr += frames; - if (appl_ptr >= runtime->boundary) - appl_ptr -= runtime->boundary; - runtime->control->appl_ptr = appl_ptr; - if (substream->ops->ack) - substream->ops->ack(substream); - - offset += frames; - size -= frames; - xfer += frames; - if (runtime->status->state == SNDRV_PCM_STATE_PREPARED && - snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { - err = snd_pcm_start(substream); - if (err < 0) - goto _end_unlock; - } - } - _end_unlock: - runtime->twake = 0; - if (xfer > 0 && err >= 0) - snd_pcm_update_state(substream, runtime); - //giovanni snd_pcm_stream_unlock_irq(substream); - return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; -} - -/* sanity-check for read/write methods */ -static int pcm_sanity_check(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area)) - return -EINVAL; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - return 0; -} - -snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) -{ - struct snd_pcm_runtime *runtime; - int nonblock; - int err; - - err = pcm_sanity_check(substream); - if (err < 0) - return err; - runtime = substream->runtime; - nonblock = !!(substream->f_flags & O_NONBLOCK); - - if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && - runtime->channels > 1) - return -EINVAL; - return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock, - snd_pcm_lib_write_transfer); -} - -EXPORT_SYMBOL(snd_pcm_lib_write); - -static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, - unsigned int hwoff, - unsigned long data, unsigned int off, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - void __user **bufs = (void __user **)data; - int channels = runtime->channels; - int c; - if (substream->ops->copy) { - if (snd_BUG_ON(!substream->ops->silence)) - return -EINVAL; - for (c = 0; c < channels; ++c, ++bufs) { - if (*bufs == NULL) { - if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) - return err; - } else { - char __user *buf = *bufs + samples_to_bytes(runtime, off); - if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0) - return err; - } - } - } else { - /* default transfer behaviour */ - size_t dma_csize = runtime->dma_bytes / channels; - for (c = 0; c < channels; ++c, ++bufs) { - char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); - if (*bufs == NULL) { - snd_pcm_format_set_silence(runtime->format, hwbuf, frames); - } else { - char __user *buf = *bufs + samples_to_bytes(runtime, off); - if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) - return -EFAULT; - } - } - } - return 0; -} - -snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, - void __user **bufs, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime; - int nonblock; - int err; - - err = pcm_sanity_check(substream); - if (err < 0) - return err; - runtime = substream->runtime; - nonblock = !!(substream->f_flags & O_NONBLOCK); - - if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) - return -EINVAL; - return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames, - nonblock, snd_pcm_lib_writev_transfer); -} - -EXPORT_SYMBOL(snd_pcm_lib_writev); - -static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, - unsigned int hwoff, - unsigned long data, unsigned int off, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - char __user *buf = (char __user *) data + frames_to_bytes(runtime, off); - if (substream->ops->copy) { - if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0) - return err; - } else { - char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); - if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) - return -EFAULT; - } - return 0; -} - -static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, - unsigned long data, - snd_pcm_uframes_t size, - int nonblock, - transfer_f transfer) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t xfer = 0; - snd_pcm_uframes_t offset = 0; - int err = 0; - - if (size == 0) - return 0; - - //giovanni snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - if (size >= runtime->start_threshold) { - err = snd_pcm_start(substream); - if (err < 0) - goto _end_unlock; - } - break; - case SNDRV_PCM_STATE_DRAINING: - case SNDRV_PCM_STATE_RUNNING: - case SNDRV_PCM_STATE_PAUSED: - break; - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - goto _end_unlock; - case SNDRV_PCM_STATE_SUSPENDED: - err = -ESTRPIPE; - goto _end_unlock; - default: - err = -EBADFD; - goto _end_unlock; - } - - runtime->twake = 1; - while (size > 0) { - snd_pcm_uframes_t frames, appl_ptr, appl_ofs; - snd_pcm_uframes_t avail; - snd_pcm_uframes_t cont; - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) - snd_pcm_update_hw_ptr(substream); - avail = snd_pcm_capture_avail(runtime); - if (!avail) { - if (runtime->status->state == - SNDRV_PCM_STATE_DRAINING) { - snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); - goto _end_unlock; - } - if (nonblock) { - err = -EAGAIN; - goto _end_unlock; - } - err = wait_for_avail_min(substream, &avail); - if (err < 0) - goto _end_unlock; - if (!avail) - continue; /* draining */ - } - frames = size > avail ? avail : size; - cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; - if (frames > cont) - frames = cont; - if (snd_BUG_ON(!frames)) { - runtime->twake = 0; - //giovanni snd_pcm_stream_unlock_irq(substream); - return -EINVAL; - } - appl_ptr = runtime->control->appl_ptr; - appl_ofs = appl_ptr % runtime->buffer_size; - //giovanni snd_pcm_stream_unlock_irq(substream); - err = transfer(substream, appl_ofs, data, offset, frames); - //giovanni snd_pcm_stream_lock_irq(substream); - if (err < 0) - goto _end_unlock; - switch (runtime->status->state) { - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - goto _end_unlock; - case SNDRV_PCM_STATE_SUSPENDED: - err = -ESTRPIPE; - goto _end_unlock; - default: - break; - } - appl_ptr += frames; - if (appl_ptr >= runtime->boundary) - appl_ptr -= runtime->boundary; - runtime->control->appl_ptr = appl_ptr; - if (substream->ops->ack) - substream->ops->ack(substream); - - offset += frames; - size -= frames; - xfer += frames; - } - _end_unlock: - runtime->twake = 0; - if (xfer > 0 && err >= 0) - snd_pcm_update_state(substream, runtime); - //giovanni snd_pcm_stream_unlock_irq(substream); - return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; -} - -snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size) -{ - struct snd_pcm_runtime *runtime; - int nonblock; - int err; - - err = pcm_sanity_check(substream); - if (err < 0) - return err; - runtime = substream->runtime; - nonblock = !!(substream->f_flags & O_NONBLOCK); - if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) - return -EINVAL; - return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); -} - -EXPORT_SYMBOL(snd_pcm_lib_read); - -static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, - unsigned int hwoff, - unsigned long data, unsigned int off, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - void __user **bufs = (void __user **)data; - int channels = runtime->channels; - int c; - if (substream->ops->copy) { - for (c = 0; c < channels; ++c, ++bufs) { - char __user *buf; - if (*bufs == NULL) - continue; - buf = *bufs + samples_to_bytes(runtime, off); - if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0) - return err; - } - } else { - snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; - for (c = 0; c < channels; ++c, ++bufs) { - char *hwbuf; - char __user *buf; - if (*bufs == NULL) - continue; - - hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); - buf = *bufs + samples_to_bytes(runtime, off); - if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) - return -EFAULT; - } - } - return 0; -} - -snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, - void __user **bufs, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime; - int nonblock; - int err; - - err = pcm_sanity_check(substream); - if (err < 0) - return err; - runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - - nonblock = !!(substream->f_flags & O_NONBLOCK); - if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) - return -EINVAL; - return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); -} - -EXPORT_SYMBOL(snd_pcm_lib_readv); diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c deleted file mode 100644 index 36ee1efba4..0000000000 --- a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c +++ /dev/null @@ -1,3493 +0,0 @@ -/* - * Digital Audio (PCM) abstract layer - * Copyright (c) by Jaroslav Kysela - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Compatibility - */ - -struct snd_pcm_hw_params_old { - unsigned int flags; - unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT - - SNDRV_PCM_HW_PARAM_ACCESS + 1]; - struct snd_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME - - SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1]; - unsigned int rmask; - unsigned int cmask; - unsigned int info; - unsigned int msbits; - unsigned int rate_num; - unsigned int rate_den; - snd_pcm_uframes_t fifo_size; - unsigned char reserved[64]; -}; - -#ifdef CONFIG_SND_SUPPORT_OLD_API -#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct snd_pcm_hw_params_old) -#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct snd_pcm_hw_params_old) - -static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params_old __user * _oparams); -static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params_old __user * _oparams); -#endif -static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); - -/* - * - */ - -DEFINE_RWLOCK(snd_pcm_link_rwlock); -EXPORT_SYMBOL(snd_pcm_link_rwlock); - -static DECLARE_RWSEM(snd_pcm_link_rwsem); - -static inline mm_segment_t snd_enter_user(void) -{ - mm_segment_t fs = get_fs(); - set_fs(get_ds()); - return fs; -} - -static inline void snd_leave_user(mm_segment_t fs) -{ - set_fs(fs); -} - - - -int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) -{ - struct snd_pcm_runtime *runtime; - struct snd_pcm *pcm = substream->pcm; - struct snd_pcm_str *pstr = substream->pstr; - - memset(info, 0, sizeof(*info)); - info->card = pcm->card->number; - info->device = pcm->device; - info->stream = substream->stream; - info->subdevice = substream->number; - strlcpy(info->id, pcm->id, sizeof(info->id)); - strlcpy(info->name, pcm->name, sizeof(info->name)); - info->dev_class = pcm->dev_class; - info->dev_subclass = pcm->dev_subclass; - info->subdevices_count = pstr->substream_count; - info->subdevices_avail = pstr->substream_count - pstr->substream_opened; - strlcpy(info->subname, substream->name, sizeof(info->subname)); - runtime = substream->runtime; - /* AB: FIXME!!! This is definitely nonsense */ - if (runtime) { - info->sync = runtime->sync; - substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info); - } - return 0; -} - -int snd_pcm_info_user(struct snd_pcm_substream *substream, - struct snd_pcm_info __user * _info) -{ - struct snd_pcm_info *info; - int err; - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (! info) - return -ENOMEM; - err = snd_pcm_info(substream, info); - if (err >= 0) { - if (copy_to_user(_info, info, sizeof(*info))) - err = -EFAULT; - } - kfree(info); - return err; -} - -#undef RULES_DEBUG - -#ifdef RULES_DEBUG -#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v -char *snd_pcm_hw_param_names[] = { - HW_PARAM(ACCESS), - HW_PARAM(FORMAT), - HW_PARAM(SUBFORMAT), - HW_PARAM(SAMPLE_BITS), - HW_PARAM(FRAME_BITS), - HW_PARAM(CHANNELS), - HW_PARAM(RATE), - HW_PARAM(PERIOD_TIME), - HW_PARAM(PERIOD_SIZE), - HW_PARAM(PERIOD_BYTES), - HW_PARAM(PERIODS), - HW_PARAM(BUFFER_TIME), - HW_PARAM(BUFFER_SIZE), - HW_PARAM(BUFFER_BYTES), - HW_PARAM(TICK_TIME), -}; -#endif - -int snd_pcm_hw_refine(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - unsigned int k; - struct snd_pcm_hardware *hw; - struct snd_interval *i = NULL; - struct snd_mask *m = NULL; - struct snd_pcm_hw_constraints *constrs = &substream->runtime->hw_constraints; - unsigned int rstamps[constrs->rules_num]; - unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1]; - unsigned int stamp = 2; - int changed, again; - - params->info = 0; - params->fifo_size = 0; - if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) - params->msbits = 0; - if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { - params->rate_num = 0; - params->rate_den = 0; - } - - for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) { - m = hw_param_mask(params, k); - if (snd_mask_empty(m)) - return -EINVAL; - if (!(params->rmask & (1 << k))) - continue; -#ifdef RULES_DEBUG - printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]); - printk("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]); -#endif - changed = snd_mask_refine(m, constrs_mask(constrs, k)); -#ifdef RULES_DEBUG - printk("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]); -#endif - if (changed) - params->cmask |= 1 << k; - if (changed < 0) - return changed; - } - - for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) { - i = hw_param_interval(params, k); - if (snd_interval_empty(i)) - return -EINVAL; - if (!(params->rmask & (1 << k))) - continue; -#ifdef RULES_DEBUG - printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]); - if (i->empty) - printk("empty"); - else - printk("%c%u %u%c", - i->openmin ? '(' : '[', i->min, - i->max, i->openmax ? ')' : ']'); - printk(" -> "); -#endif - changed = snd_interval_refine(i, constrs_interval(constrs, k)); -#ifdef RULES_DEBUG - if (i->empty) - printk("empty\n"); - else - printk("%c%u %u%c\n", - i->openmin ? '(' : '[', i->min, - i->max, i->openmax ? ')' : ']'); -#endif - if (changed) - params->cmask |= 1 << k; - if (changed < 0) - return changed; - } - - for (k = 0; k < constrs->rules_num; k++) - rstamps[k] = 0; - for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) - vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0; - do { - again = 0; - for (k = 0; k < constrs->rules_num; k++) { - struct snd_pcm_hw_rule *r = &constrs->rules[k]; - unsigned int d; - int doit = 0; - if (r->cond && !(r->cond & params->flags)) - continue; - for (d = 0; r->deps[d] >= 0; d++) { - if (vstamps[r->deps[d]] > rstamps[k]) { - doit = 1; - break; - } - } - if (!doit) - continue; -#ifdef RULES_DEBUG - printk(KERN_DEBUG "Rule %d [%p]: ", k, r->func); - if (r->var >= 0) { - printk("%s = ", snd_pcm_hw_param_names[r->var]); - if (hw_is_mask(r->var)) { - m = hw_param_mask(params, r->var); - printk("%x", *m->bits); - } else { - i = hw_param_interval(params, r->var); - if (i->empty) - printk("empty"); - else - printk("%c%u %u%c", - i->openmin ? '(' : '[', i->min, - i->max, i->openmax ? ')' : ']'); - } - } -#endif - changed = r->func(params, r); -#ifdef RULES_DEBUG - if (r->var >= 0) { - printk(" -> "); - if (hw_is_mask(r->var)) - printk("%x", *m->bits); - else { - if (i->empty) - printk("empty"); - else - printk("%c%u %u%c", - i->openmin ? '(' : '[', i->min, - i->max, i->openmax ? ')' : ']'); - } - } - printk("\n"); -#endif - rstamps[k] = stamp; - if (changed && r->var >= 0) { - params->cmask |= (1 << r->var); - vstamps[r->var] = stamp; - again = 1; - } - if (changed < 0) - return changed; - stamp++; - } - } while (again); - if (!params->msbits) { - i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); - if (snd_interval_single(i)) - params->msbits = snd_interval_value(i); - } - - if (!params->rate_den) { - i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (snd_interval_single(i)) { - params->rate_num = snd_interval_value(i); - params->rate_den = 1; - } - } - - hw = &substream->runtime->hw; - if (!params->info) - params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; - if (!params->fifo_size) { - m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - if (snd_mask_min(m) == snd_mask_max(m) && - snd_interval_min(i) == snd_interval_max(i)) { - changed = substream->ops->ioctl(substream, - SNDRV_PCM_IOCTL1_FIFO_SIZE, params); - if (changed < 0) - return changed; - } - } - params->rmask = 0; - return 0; -} - -EXPORT_SYMBOL(snd_pcm_hw_refine); - -static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params __user * _params) -{ - struct snd_pcm_hw_params *params; - int err; - - params = memdup_user(_params, sizeof(*params)); - if (IS_ERR(params)) - return PTR_ERR(params); - - err = snd_pcm_hw_refine(substream, params); - if (copy_to_user(_params, params, sizeof(*params))) { - if (!err) - err = -EFAULT; - } - - kfree(params); - return err; -} - -static int period_to_usecs(struct snd_pcm_runtime *runtime) -{ - int usecs; - - if (! runtime->rate) - return -1; /* invalid */ - - /* take 75% of period time as the deadline */ - usecs = (750000 / runtime->rate) * runtime->period_size; - usecs += ((750000 % runtime->rate) * runtime->period_size) / - runtime->rate; - - return usecs; -} - -static int calc_boundary(struct snd_pcm_runtime *runtime) -{ - uint64_t boundary; - - boundary = (uint64_t)runtime->buffer_size * - (uint64_t)runtime->period_size; -#if BITS_PER_LONG < 64 - /* try to find lowest common multiple for buffer and period */ - if (boundary > LONG_MAX - runtime->buffer_size) { - uint32_t remainder = -1; - uint32_t divident = runtime->buffer_size; - uint32_t divisor = runtime->period_size; - while (remainder) { - remainder = divident % divisor; - if (remainder) { - divident = divisor; - divisor = remainder; - } - } - boundary = div_u64(boundary, divisor); - if (boundary > LONG_MAX - runtime->buffer_size) - return -ERANGE; - } -#endif - if (boundary == 0) - return -ERANGE; - runtime->boundary = boundary; - while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) - runtime->boundary *= 2; - return 0; -} - -static int snd_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime; - int err, usecs; - unsigned int bits; - snd_pcm_uframes_t frames; - - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_OPEN: - case SNDRV_PCM_STATE_SETUP: - case SNDRV_PCM_STATE_PREPARED: - break; - default: - snd_pcm_stream_unlock_irq(substream); - return -EBADFD; - } - snd_pcm_stream_unlock_irq(substream); -#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) - if (!substream->oss.oss) -#endif - if (atomic_read(&substream->mmap_count)) - return -EBADFD; - - params->rmask = ~0U; - err = snd_pcm_hw_refine(substream, params); - if (err < 0) - goto _error; - - err = snd_pcm_hw_params_choose(substream, params); - if (err < 0) - goto _error; - - if (substream->ops->hw_params != NULL) { - err = substream->ops->hw_params(substream, params); - if (err < 0) - goto _error; - } - - runtime->access = params_access(params); - runtime->format = params_format(params); - runtime->subformat = params_subformat(params); - runtime->channels = params_channels(params); - runtime->rate = params_rate(params); - runtime->period_size = params_period_size(params); - runtime->periods = params_periods(params); - runtime->buffer_size = params_buffer_size(params); - runtime->info = params->info; - runtime->rate_num = params->rate_num; - runtime->rate_den = params->rate_den; - - bits = snd_pcm_format_physical_width(runtime->format); - runtime->sample_bits = bits; - bits *= runtime->channels; - runtime->frame_bits = bits; - frames = 1; - while (bits % 8 != 0) { - bits *= 2; - frames *= 2; - } - runtime->byte_align = bits / 8; - runtime->min_align = frames; - - /* Default sw params */ - runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; - runtime->period_step = 1; - runtime->control->avail_min = runtime->period_size; - runtime->start_threshold = 1; - runtime->stop_threshold = runtime->buffer_size; - runtime->silence_threshold = 0; - runtime->silence_size = 0; - err = calc_boundary(runtime); - if (err < 0) - goto _error; - - snd_pcm_timer_resolution_change(substream); - runtime->status->state = SNDRV_PCM_STATE_SETUP; - - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, - substream->latency_id); - if ((usecs = period_to_usecs(runtime)) >= 0) - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, - substream->latency_id, usecs); - return 0; - _error: - /* hardware might be unuseable from this time, - so we force application to retry to set - the correct hardware parameter settings */ - runtime->status->state = SNDRV_PCM_STATE_OPEN; - if (substream->ops->hw_free != NULL) - substream->ops->hw_free(substream); - return err; -} - -static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params __user * _params) -{ - struct snd_pcm_hw_params *params; - int err; - - params = memdup_user(_params, sizeof(*params)); - if (IS_ERR(params)) - return PTR_ERR(params); - - err = snd_pcm_hw_params(substream, params); - if (copy_to_user(_params, params, sizeof(*params))) { - if (!err) - err = -EFAULT; - } - - kfree(params); - return err; -} - -static int snd_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime; - int result = 0; - - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_SETUP: - case SNDRV_PCM_STATE_PREPARED: - break; - default: - snd_pcm_stream_unlock_irq(substream); - return -EBADFD; - } - snd_pcm_stream_unlock_irq(substream); - if (atomic_read(&substream->mmap_count)) - return -EBADFD; - if (substream->ops->hw_free) - result = substream->ops->hw_free(substream); - runtime->status->state = SNDRV_PCM_STATE_OPEN; - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, - substream->latency_id); - return result; -} - -static int snd_pcm_sw_params(struct snd_pcm_substream *substream, - struct snd_pcm_sw_params *params) -{ - struct snd_pcm_runtime *runtime; - int err; - - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - snd_pcm_stream_lock_irq(substream); - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { - snd_pcm_stream_unlock_irq(substream); - return -EBADFD; - } - snd_pcm_stream_unlock_irq(substream); - - if (params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST) - return -EINVAL; - if (params->avail_min == 0) - return -EINVAL; - if (params->silence_size >= runtime->boundary) { - if (params->silence_threshold != 0) - return -EINVAL; - } else { - if (params->silence_size > params->silence_threshold) - return -EINVAL; - if (params->silence_threshold > runtime->buffer_size) - return -EINVAL; - } - err = 0; - snd_pcm_stream_lock_irq(substream); - runtime->tstamp_mode = params->tstamp_mode; - runtime->period_step = params->period_step; - runtime->control->avail_min = params->avail_min; - runtime->start_threshold = params->start_threshold; - runtime->stop_threshold = params->stop_threshold; - runtime->silence_threshold = params->silence_threshold; - runtime->silence_size = params->silence_size; - params->boundary = runtime->boundary; - if (snd_pcm_running(substream)) { - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - runtime->silence_size > 0) - snd_pcm_playback_silence(substream, ULONG_MAX); - err = snd_pcm_update_state(substream, runtime); - } - snd_pcm_stream_unlock_irq(substream); - return err; -} - -static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream, - struct snd_pcm_sw_params __user * _params) -{ - struct snd_pcm_sw_params params; - int err; - if (copy_from_user(¶ms, _params, sizeof(params))) - return -EFAULT; - err = snd_pcm_sw_params(substream, ¶ms); - if (copy_to_user(_params, ¶ms, sizeof(params))) - return -EFAULT; - return err; -} - -int snd_pcm_status(struct snd_pcm_substream *substream, - struct snd_pcm_status *status) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - //giovanni snd_pcm_stream_lock_irq(substream); - status->state = runtime->status->state; - status->suspended_state = runtime->status->suspended_state; - if (status->state == SNDRV_PCM_STATE_OPEN) - goto _end; - status->trigger_tstamp = runtime->trigger_tstamp; - if (snd_pcm_running(substream)) { - snd_pcm_update_hw_ptr(substream); - if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) { - status->tstamp = runtime->status->tstamp; - goto _tstamp_end; - } - } - snd_pcm_gettime(runtime, &status->tstamp); - _tstamp_end: - status->appl_ptr = runtime->control->appl_ptr; - status->hw_ptr = runtime->status->hw_ptr; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - status->avail = snd_pcm_playback_avail(runtime); - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING || - runtime->status->state == SNDRV_PCM_STATE_DRAINING) { - status->delay = runtime->buffer_size - status->avail; - status->delay += runtime->delay; - } else - status->delay = 0; - } else { - status->avail = snd_pcm_capture_avail(runtime); - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) - status->delay = status->avail + runtime->delay; - else - status->delay = 0; - } - status->avail_max = runtime->avail_max; - status->overrange = runtime->overrange; - runtime->avail_max = 0; - runtime->overrange = 0; - _end: - //giovanni snd_pcm_stream_unlock_irq(substream); - return 0; -} - -static int snd_pcm_status_user(struct snd_pcm_substream *substream, - struct snd_pcm_status __user * _status) -{ - struct snd_pcm_status status; - int res; - - memset(&status, 0, sizeof(status)); - res = snd_pcm_status(substream, &status); - if (res < 0) - return res; - if (copy_to_user(_status, &status, sizeof(status))) - return -EFAULT; - return 0; -} - -static int snd_pcm_channel_info(struct snd_pcm_substream *substream, - struct snd_pcm_channel_info * info) -{ - struct snd_pcm_runtime *runtime; - unsigned int channel; - - channel = info->channel; - runtime = substream->runtime; - //giovanni snd_pcm_stream_lock_irq(substream); - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { - //giovanni snd_pcm_stream_unlock_irq(substream); - return -EBADFD; - } - //giovanni snd_pcm_stream_unlock_irq(substream); - if (channel >= runtime->channels) - return -EINVAL; - memset(info, 0, sizeof(*info)); - info->channel = channel; - return substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info); -} - -static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream, - struct snd_pcm_channel_info __user * _info) -{ - struct snd_pcm_channel_info info; - int res; - - if (copy_from_user(&info, _info, sizeof(info))) - return -EFAULT; - res = snd_pcm_channel_info(substream, &info); - if (res < 0) - return res; - if (copy_to_user(_info, &info, sizeof(info))) - return -EFAULT; - return 0; -} - -static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->trigger_master == NULL) - return; - if (runtime->trigger_master == substream) { - snd_pcm_gettime(runtime, &runtime->trigger_tstamp); - } else { - snd_pcm_trigger_tstamp(runtime->trigger_master); - runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp; - } - runtime->trigger_master = NULL; -} - -struct action_ops { - int (*pre_action)(struct snd_pcm_substream *substream, int state); - int (*do_action)(struct snd_pcm_substream *substream, int state); - void (*undo_action)(struct snd_pcm_substream *substream, int state); - void (*post_action)(struct snd_pcm_substream *substream, int state); -}; - -/* - * this functions is core for handling of linked stream - * Note: the stream state might be changed also on failure - * Note2: call with calling stream lock + link lock - */ -static int snd_pcm_action_group(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state, int do_lock) -{ - struct snd_pcm_substream *s = NULL; - struct snd_pcm_substream *s1; - int res = 0; - - snd_pcm_group_for_each_entry(s, substream) { - if (do_lock && s != substream) - spin_lock_nested(&s->self_group.lock, - SINGLE_DEPTH_NESTING); - res = ops->pre_action(s, state); - if (res < 0) - goto _unlock; - } - snd_pcm_group_for_each_entry(s, substream) { - res = ops->do_action(s, state); - if (res < 0) { - if (ops->undo_action) { - snd_pcm_group_for_each_entry(s1, substream) { - if (s1 == s) /* failed stream */ - break; - ops->undo_action(s1, state); - } - } - s = NULL; /* unlock all */ - goto _unlock; - } - } - snd_pcm_group_for_each_entry(s, substream) { - ops->post_action(s, state); - } - _unlock: - if (do_lock) { - /* unlock streams */ - snd_pcm_group_for_each_entry(s1, substream) { - if (s1 != substream) - spin_unlock(&s1->self_group.lock); - if (s1 == s) /* end */ - break; - } - } - return res; -} - -/* - * Note: call with stream lock - */ -static int snd_pcm_action_single(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) -{ - int res; - - res = ops->pre_action(substream, state); - if (res < 0) - return res; - res = ops->do_action(substream, state); - if (res == 0) - ops->post_action(substream, state); - else if (ops->undo_action) - ops->undo_action(substream, state); - return res; -} - -/* - * Note: call with stream lock - */ -static int snd_pcm_action(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) -{ - int res; - - if (snd_pcm_stream_linked(substream)) { - if (!spin_trylock(&substream->group->lock)) { - spin_unlock(&substream->self_group.lock); - spin_lock(&substream->group->lock); - spin_lock(&substream->self_group.lock); - } - res = snd_pcm_action_group(ops, substream, state, 1); - spin_unlock(&substream->group->lock); - } else { - res = snd_pcm_action_single(ops, substream, state); - } - return res; -} - -/* - * Note: don't use any locks before - */ -static int snd_pcm_action_lock_irq(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) -{ - int res; - - read_lock_irq(&snd_pcm_link_rwlock); - if (snd_pcm_stream_linked(substream)) { - spin_lock(&substream->group->lock); - spin_lock(&substream->self_group.lock); - res = snd_pcm_action_group(ops, substream, state, 1); - spin_unlock(&substream->self_group.lock); - spin_unlock(&substream->group->lock); - } else { - spin_lock(&substream->self_group.lock); - res = snd_pcm_action_single(ops, substream, state); - spin_unlock(&substream->self_group.lock); - } - read_unlock_irq(&snd_pcm_link_rwlock); - return res; -} - -/* - */ -static int snd_pcm_action_nonatomic(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) -{ - int res; - - down_read(&snd_pcm_link_rwsem); - if (snd_pcm_stream_linked(substream)) - res = snd_pcm_action_group(ops, substream, state, 0); - else - res = snd_pcm_action_single(ops, substream, state); - up_read(&snd_pcm_link_rwsem); - return res; -} - -/* - * start callbacks - */ -static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state != SNDRV_PCM_STATE_PREPARED) - return -EBADFD; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - !snd_pcm_playback_data(substream)) - return -EPIPE; - runtime->trigger_master = substream; - return 0; -} - -static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state) -{ - if (substream->runtime->trigger_master != substream) - return 0; - return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START); -} - -static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state) -{ - if (substream->runtime->trigger_master == substream) - substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); -} - -static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_trigger_tstamp(substream); - runtime->hw_ptr_jiffies = jiffies; - runtime->status->state = state; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - runtime->silence_size > 0) - snd_pcm_playback_silence(substream, ULONG_MAX); - if (substream->timer) - snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART, - &runtime->trigger_tstamp); -} - -static struct action_ops snd_pcm_action_start = { - .pre_action = snd_pcm_pre_start, - .do_action = snd_pcm_do_start, - .undo_action = snd_pcm_undo_start, - .post_action = snd_pcm_post_start -}; - -/** - * snd_pcm_start - start all linked streams - * @substream: the PCM substream instance - */ -int snd_pcm_start(struct snd_pcm_substream *substream) -{ - return snd_pcm_action(&snd_pcm_action_start, substream, - SNDRV_PCM_STATE_RUNNING); -} - -/* - * stop callbacks - */ -static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - runtime->trigger_master = substream; - return 0; -} - -static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state) -{ - if (substream->runtime->trigger_master == substream && - snd_pcm_running(substream)) - substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); - return 0; /* unconditonally stop all substreams */ -} - -static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state != state) { - snd_pcm_trigger_tstamp(substream); - if (substream->timer) - snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, - &runtime->trigger_tstamp); - runtime->status->state = state; - } - wake_up(&runtime->sleep); - wake_up(&runtime->tsleep); -} - -static struct action_ops snd_pcm_action_stop = { - .pre_action = snd_pcm_pre_stop, - .do_action = snd_pcm_do_stop, - .post_action = snd_pcm_post_stop -}; - -/** - * snd_pcm_stop - try to stop all running streams in the substream group - * @substream: the PCM substream instance - * @state: PCM state after stopping the stream - * - * The state of each stream is then changed to the given state unconditionally. - */ -int snd_pcm_stop(struct snd_pcm_substream *substream, int state) -{ - return snd_pcm_action(&snd_pcm_action_stop, substream, state); -} - -EXPORT_SYMBOL(snd_pcm_stop); - -/** - * snd_pcm_drain_done - stop the DMA only when the given stream is playback - * @substream: the PCM substream - * - * After stopping, the state is changed to SETUP. - * Unlike snd_pcm_stop(), this affects only the given stream. - */ -int snd_pcm_drain_done(struct snd_pcm_substream *substream) -{ - return snd_pcm_action_single(&snd_pcm_action_stop, substream, - SNDRV_PCM_STATE_SETUP); -} - -/* - * pause callbacks - */ -static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (!(runtime->info & SNDRV_PCM_INFO_PAUSE)) - return -ENOSYS; - if (push) { - if (runtime->status->state != SNDRV_PCM_STATE_RUNNING) - return -EBADFD; - } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED) - return -EBADFD; - runtime->trigger_master = substream; - return 0; -} - -static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) -{ - if (substream->runtime->trigger_master != substream) - return 0; - /* The jiffies check in snd_pcm_update_hw_ptr*() is done by - * a delta betwen the current jiffies, this gives a large enough - * delta, effectively to skip the check once. - */ - substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000; - return substream->ops->trigger(substream, - push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH : - SNDRV_PCM_TRIGGER_PAUSE_RELEASE); -} - -static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push) -{ - if (substream->runtime->trigger_master == substream) - substream->ops->trigger(substream, - push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE : - SNDRV_PCM_TRIGGER_PAUSE_PUSH); -} - -static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_trigger_tstamp(substream); - if (push) { - runtime->status->state = SNDRV_PCM_STATE_PAUSED; - if (substream->timer) - snd_timer_notify(substream->timer, - SNDRV_TIMER_EVENT_MPAUSE, - &runtime->trigger_tstamp); - wake_up(&runtime->sleep); - wake_up(&runtime->tsleep); - } else { - runtime->status->state = SNDRV_PCM_STATE_RUNNING; - if (substream->timer) - snd_timer_notify(substream->timer, - SNDRV_TIMER_EVENT_MCONTINUE, - &runtime->trigger_tstamp); - } -} - -static struct action_ops snd_pcm_action_pause = { - .pre_action = snd_pcm_pre_pause, - .do_action = snd_pcm_do_pause, - .undo_action = snd_pcm_undo_pause, - .post_action = snd_pcm_post_pause -}; - -/* - * Push/release the pause for all linked streams. - */ -static int snd_pcm_pause(struct snd_pcm_substream *substream, int push) -{ - return snd_pcm_action(&snd_pcm_action_pause, substream, push); -} - -#ifdef CONFIG_PM -/* suspend */ - -static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) - return -EBUSY; - runtime->trigger_master = substream; - return 0; -} - -static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->trigger_master != substream) - return 0; - if (! snd_pcm_running(substream)) - return 0; - substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); - return 0; /* suspend unconditionally */ -} - -static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_trigger_tstamp(substream); - if (substream->timer) - snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND, - &runtime->trigger_tstamp); - runtime->status->suspended_state = runtime->status->state; - runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; - wake_up(&runtime->sleep); - wake_up(&runtime->tsleep); -} - -static struct action_ops snd_pcm_action_suspend = { - .pre_action = snd_pcm_pre_suspend, - .do_action = snd_pcm_do_suspend, - .post_action = snd_pcm_post_suspend -}; - -/** - * snd_pcm_suspend - trigger SUSPEND to all linked streams - * @substream: the PCM substream - * - * After this call, all streams are changed to SUSPENDED state. - */ -int snd_pcm_suspend(struct snd_pcm_substream *substream) -{ - int err; - unsigned long flags; - - if (! substream) - return 0; - - snd_pcm_stream_lock_irqsave(substream, flags); - err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0); - snd_pcm_stream_unlock_irqrestore(substream, flags); - return err; -} - -EXPORT_SYMBOL(snd_pcm_suspend); - -/** - * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm - * @pcm: the PCM instance - * - * After this call, all streams are changed to SUSPENDED state. - */ -int snd_pcm_suspend_all(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - int stream, err = 0; - - if (! pcm) - return 0; - - for (stream = 0; stream < 2; stream++) { - for (substream = pcm->streams[stream].substream; - substream; substream = substream->next) { - /* FIXME: the open/close code should lock this as well */ - if (substream->runtime == NULL) - continue; - err = snd_pcm_suspend(substream); - if (err < 0 && err != -EBUSY) - return err; - } - } - return 0; -} - -EXPORT_SYMBOL(snd_pcm_suspend_all); - -/* resume */ - -static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (!(runtime->info & SNDRV_PCM_INFO_RESUME)) - return -ENOSYS; - runtime->trigger_master = substream; - return 0; -} - -static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->trigger_master != substream) - return 0; - /* DMA not running previously? */ - if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING && - (runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING || - substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) - return 0; - return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME); -} - -static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state) -{ - if (substream->runtime->trigger_master == substream && - snd_pcm_running(substream)) - substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); -} - -static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_trigger_tstamp(substream); - if (substream->timer) - snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME, - &runtime->trigger_tstamp); - runtime->status->state = runtime->status->suspended_state; -} - -static struct action_ops snd_pcm_action_resume = { - .pre_action = snd_pcm_pre_resume, - .do_action = snd_pcm_do_resume, - .undo_action = snd_pcm_undo_resume, - .post_action = snd_pcm_post_resume -}; - -static int snd_pcm_resume(struct snd_pcm_substream *substream) -{ - struct snd_card *card = substream->pcm->card; - int res; - - snd_power_lock(card); - if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) - res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0); - snd_power_unlock(card); - return res; -} - -#else - -static int snd_pcm_resume(struct snd_pcm_substream *substream) -{ - return -ENOSYS; -} - -#endif /* CONFIG_PM */ - -/* - * xrun ioctl - * - * Change the RUNNING stream(s) to XRUN state. - */ -static int snd_pcm_xrun(struct snd_pcm_substream *substream) -{ - struct snd_card *card = substream->pcm->card; - struct snd_pcm_runtime *runtime = substream->runtime; - int result; - - snd_power_lock(card); - if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result < 0) - goto _unlock; - } - - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_XRUN: - result = 0; /* already there */ - break; - case SNDRV_PCM_STATE_RUNNING: - result = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - break; - default: - result = -EBADFD; - } - snd_pcm_stream_unlock_irq(substream); - _unlock: - snd_power_unlock(card); - return result; -} - -/* - * reset ioctl - */ -static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - switch (runtime->status->state) { - case SNDRV_PCM_STATE_RUNNING: - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_PAUSED: - case SNDRV_PCM_STATE_SUSPENDED: - return 0; - default: - return -EBADFD; - } -} - -static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); - if (err < 0) - return err; - runtime->hw_ptr_base = 0; - runtime->hw_ptr_interrupt = runtime->status->hw_ptr - - runtime->status->hw_ptr % runtime->period_size; - runtime->silence_start = runtime->status->hw_ptr; - runtime->silence_filled = 0; - return 0; -} - -static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - runtime->control->appl_ptr = runtime->status->hw_ptr; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - runtime->silence_size > 0) - snd_pcm_playback_silence(substream, ULONG_MAX); -} - -static struct action_ops snd_pcm_action_reset = { - .pre_action = snd_pcm_pre_reset, - .do_action = snd_pcm_do_reset, - .post_action = snd_pcm_post_reset -}; - -static int snd_pcm_reset(struct snd_pcm_substream *substream) -{ - return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0); -} - -/* - * prepare ioctl - */ -/* we use the second argument for updating f_flags */ -static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, - int f_flags) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN || - runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) - return -EBADFD; - if (snd_pcm_running(substream)) - return -EBUSY; - substream->f_flags = f_flags; - return 0; -} - -static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state) -{ - int err; - err = substream->ops->prepare(substream); - if (err < 0) - return err; - return snd_pcm_do_reset(substream, 0); -} - -static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - runtime->control->appl_ptr = runtime->status->hw_ptr; - runtime->status->state = SNDRV_PCM_STATE_PREPARED; -} - -static struct action_ops snd_pcm_action_prepare = { - .pre_action = snd_pcm_pre_prepare, - .do_action = snd_pcm_do_prepare, - .post_action = snd_pcm_post_prepare -}; - -/** - * snd_pcm_prepare - prepare the PCM substream to be triggerable - * @substream: the PCM substream instance - * @file: file to refer f_flags - */ -static int snd_pcm_prepare(struct snd_pcm_substream *substream, - struct file *file) -{ - int res; - struct snd_card *card = substream->pcm->card; - int f_flags; - - if (file) - f_flags = file->f_flags; - else - f_flags = substream->f_flags; - - snd_power_lock(card); - if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) - res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, - substream, f_flags); - snd_power_unlock(card); - return res; -} - -/* - * drain ioctl - */ - -static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) -{ - substream->runtime->trigger_master = substream; - return 0; -} - -static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - /* start playback stream if possible */ - if (! snd_pcm_playback_empty(substream)) { - snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); - snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); - } - break; - case SNDRV_PCM_STATE_RUNNING: - runtime->status->state = SNDRV_PCM_STATE_DRAINING; - break; - default: - break; - } - } else { - /* stop running stream */ - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) { - int new_state = snd_pcm_capture_avail(runtime) > 0 ? - SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP; - snd_pcm_do_stop(substream, new_state); - snd_pcm_post_stop(substream, new_state); - } - } - return 0; -} - -static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state) -{ -} - -static struct action_ops snd_pcm_action_drain_init = { - .pre_action = snd_pcm_pre_drain_init, - .do_action = snd_pcm_do_drain_init, - .post_action = snd_pcm_post_drain_init -}; - -static int snd_pcm_drop(struct snd_pcm_substream *substream); - -/* - * Drain the stream(s). - * When the substream is linked, sync until the draining of all playback streams - * is finished. - * After this call, all streams are supposed to be either SETUP or DRAINING - * (capture only) state. - */ -static int snd_pcm_drain(struct snd_pcm_substream *substream, - struct file *file) -{ - struct snd_card *card; - struct snd_pcm_runtime *runtime; - struct snd_pcm_substream *s; - wait_queue_t wait; - int result = 0; - int nonblock = 0; - - card = substream->pcm->card; - runtime = substream->runtime; - - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - - snd_power_lock(card); - if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result < 0) { - snd_power_unlock(card); - return result; - } - } - - if (file) { - if (file->f_flags & O_NONBLOCK) - nonblock = 1; - } else if (substream->f_flags & O_NONBLOCK) - nonblock = 1; - - down_read(&snd_pcm_link_rwsem); - snd_pcm_stream_lock_irq(substream); - /* resume pause */ - if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) - snd_pcm_pause(substream, 0); - - /* pre-start/stop - all running streams are changed to DRAINING state */ - result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); - if (result < 0) - goto unlock; - /* in non-blocking, we don't wait in ioctl but let caller poll */ - if (nonblock) { - result = -EAGAIN; - goto unlock; - } - - for (;;) { - long tout; - struct snd_pcm_runtime *to_check; - if (signal_pending(current)) { - result = -ERESTARTSYS; - break; - } - /* find a substream to drain */ - to_check = NULL; - snd_pcm_group_for_each_entry(s, substream) { - if (s->stream != SNDRV_PCM_STREAM_PLAYBACK) - continue; - runtime = s->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { - to_check = runtime; - break; - } - } - if (!to_check) - break; /* all drained */ - init_waitqueue_entry(&wait, current); - add_wait_queue(&to_check->sleep, &wait); - set_current_state(TASK_INTERRUPTIBLE); - snd_pcm_stream_unlock_irq(substream); - up_read(&snd_pcm_link_rwsem); - snd_power_unlock(card); - tout = schedule_timeout(10 * HZ); - snd_power_lock(card); - down_read(&snd_pcm_link_rwsem); - snd_pcm_stream_lock_irq(substream); - remove_wait_queue(&to_check->sleep, &wait); - if (tout == 0) { - if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) - result = -ESTRPIPE; - else { - snd_printd("playback drain error (DMA or IRQ trouble?)\n"); - snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); - result = -EIO; - } - break; - } - } - - unlock: - snd_pcm_stream_unlock_irq(substream); - up_read(&snd_pcm_link_rwsem); - snd_power_unlock(card); - - return result; -} - -/* - * drop ioctl - * - * Immediately put all linked substreams into SETUP state. - */ -static int snd_pcm_drop(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime; - struct snd_card *card; - int result = 0; - - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - card = substream->pcm->card; - - if (runtime->status->state == SNDRV_PCM_STATE_OPEN || - runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED || - runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) - return -EBADFD; - - snd_pcm_stream_lock_irq(substream); - /* resume pause */ - if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) - snd_pcm_pause(substream, 0); - - snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); - /* runtime->control->appl_ptr = runtime->status->hw_ptr; */ - snd_pcm_stream_unlock_irq(substream); - - return result; -} - - -/* WARNING: Don't forget to fput back the file */ -static struct file *snd_pcm_file_fd(int fd) -{ - struct file *file; - struct inode *inode; - unsigned int minor; - - file = fget(fd); - if (!file) - return NULL; - inode = file->f_path.dentry->d_inode; - if (!S_ISCHR(inode->i_mode) || - imajor(inode) != snd_major) { - fput(file); - return NULL; - } - minor = iminor(inode); - if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) && - !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) { - fput(file); - return NULL; - } - return file; -} - -/* - * PCM link handling - */ -static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) -{ - int res = 0; - struct file *file; - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream1; - - file = snd_pcm_file_fd(fd); - if (!file) - return -EBADFD; - pcm_file = file->private_data; - substream1 = pcm_file->substream; - down_write(&snd_pcm_link_rwsem); - write_lock_irq(&snd_pcm_link_rwlock); - if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || - substream->runtime->status->state != substream1->runtime->status->state) { - res = -EBADFD; - goto _end; - } - if (snd_pcm_stream_linked(substream1)) { - res = -EALREADY; - goto _end; - } - if (!snd_pcm_stream_linked(substream)) { - substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC); - if (substream->group == NULL) { - res = -ENOMEM; - goto _end; - } - spin_lock_init(&substream->group->lock); - INIT_LIST_HEAD(&substream->group->substreams); - list_add_tail(&substream->link_list, &substream->group->substreams); - substream->group->count = 1; - } - list_add_tail(&substream1->link_list, &substream->group->substreams); - substream->group->count++; - substream1->group = substream->group; - _end: - write_unlock_irq(&snd_pcm_link_rwlock); - up_write(&snd_pcm_link_rwsem); - fput(file); - return res; -} - -static void relink_to_local(struct snd_pcm_substream *substream) -{ - substream->group = &substream->self_group; - INIT_LIST_HEAD(&substream->self_group.substreams); - list_add_tail(&substream->link_list, &substream->self_group.substreams); -} - -static int snd_pcm_unlink(struct snd_pcm_substream *substream) -{ - struct snd_pcm_substream *s; - int res = 0; - - down_write(&snd_pcm_link_rwsem); - write_lock_irq(&snd_pcm_link_rwlock); - if (!snd_pcm_stream_linked(substream)) { - res = -EALREADY; - goto _end; - } - list_del(&substream->link_list); - substream->group->count--; - if (substream->group->count == 1) { /* detach the last stream, too */ - snd_pcm_group_for_each_entry(s, substream) { - relink_to_local(s); - break; - } - kfree(substream->group); - } - relink_to_local(substream); - _end: - write_unlock_irq(&snd_pcm_link_rwlock); - up_write(&snd_pcm_link_rwsem); - return res; -} - -/* - * hw configurator - */ -static int snd_pcm_hw_rule_mul(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval t; - snd_interval_mul(hw_param_interval_c(params, rule->deps[0]), - hw_param_interval_c(params, rule->deps[1]), &t); - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -static int snd_pcm_hw_rule_div(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval t; - snd_interval_div(hw_param_interval_c(params, rule->deps[0]), - hw_param_interval_c(params, rule->deps[1]), &t); - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -static int snd_pcm_hw_rule_muldivk(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval t; - snd_interval_muldivk(hw_param_interval_c(params, rule->deps[0]), - hw_param_interval_c(params, rule->deps[1]), - (unsigned long) rule->private, &t); - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -static int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval t; - snd_interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]), - (unsigned long) rule->private, - hw_param_interval_c(params, rule->deps[1]), &t); - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - unsigned int k; - struct snd_interval *i = hw_param_interval(params, rule->deps[0]); - struct snd_mask m; - struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - snd_mask_any(&m); - for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) { - int bits; - if (! snd_mask_test(mask, k)) - continue; - bits = snd_pcm_format_physical_width(k); - if (bits <= 0) - continue; /* ignore invalid formats */ - if ((unsigned)bits < i->min || (unsigned)bits > i->max) - snd_mask_reset(&m, k); - } - return snd_mask_refine(mask, &m); -} - -static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval t; - unsigned int k; - t.min = UINT_MAX; - t.max = 0; - t.openmin = 0; - t.openmax = 0; - for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) { - int bits; - if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k)) - continue; - bits = snd_pcm_format_physical_width(k); - if (bits <= 0) - continue; /* ignore invalid formats */ - if (t.min > (unsigned)bits) - t.min = bits; - if (t.max < (unsigned)bits) - t.max = bits; - } - t.integer = 1; - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 -#error "Change this table" -#endif - -static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, - 48000, 64000, 88200, 96000, 176400, 192000 }; - -const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, -}; - -static int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_pcm_hardware *hw = rule->private; - return snd_interval_list(hw_param_interval(params, rule->var), - snd_pcm_known_rates.count, - snd_pcm_known_rates.list, hw->rates); -} - -static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval t; - struct snd_pcm_substream *substream = rule->private; - t.min = 0; - t.max = substream->buffer_bytes_max; - t.openmin = 0; - t.openmax = 0; - t.integer = 1; - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; - int k, err; - - for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) { - snd_mask_any(constrs_mask(constrs, k)); - } - - for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) { - snd_interval_any(constrs_interval(constrs, k)); - } - - snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_CHANNELS)); - snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_BUFFER_SIZE)); - snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_BUFFER_BYTES)); - snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)); - snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_FRAME_BITS)); - - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, - snd_pcm_hw_rule_format, NULL, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - snd_pcm_hw_rule_sample_bits, NULL, - SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - snd_pcm_hw_rule_div, NULL, - SNDRV_PCM_HW_PARAM_FRAME_BITS, SNDRV_PCM_HW_PARAM_CHANNELS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS, - snd_pcm_hw_rule_mul, NULL, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, SNDRV_PCM_HW_PARAM_CHANNELS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS, - snd_pcm_hw_rule_mulkdiv, (void*) 8, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS, - snd_pcm_hw_rule_mulkdiv, (void*) 8, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_pcm_hw_rule_div, NULL, - SNDRV_PCM_HW_PARAM_FRAME_BITS, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_pcm_hw_rule_mulkdiv, (void*) 1000000, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_PERIOD_TIME, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_pcm_hw_rule_mulkdiv, (void*) 1000000, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_BUFFER_TIME, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS, - snd_pcm_hw_rule_div, NULL, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, - snd_pcm_hw_rule_div, NULL, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_PERIODS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, - snd_pcm_hw_rule_mulkdiv, (void*) 8, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, - snd_pcm_hw_rule_muldivk, (void*) 1000000, - SNDRV_PCM_HW_PARAM_PERIOD_TIME, SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, - snd_pcm_hw_rule_mul, NULL, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_PERIODS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, - snd_pcm_hw_rule_mulkdiv, (void*) 8, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, - snd_pcm_hw_rule_muldivk, (void*) 1000000, - SNDRV_PCM_HW_PARAM_BUFFER_TIME, SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - snd_pcm_hw_rule_muldivk, (void*) 8, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - snd_pcm_hw_rule_muldivk, (void*) 8, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_TIME, - snd_pcm_hw_rule_mulkdiv, (void*) 1000000, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_TIME, - snd_pcm_hw_rule_mulkdiv, (void*) 1000000, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) - return err; - return 0; -} - -int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_pcm_hardware *hw = &runtime->hw; - int err; - unsigned int mask = 0; - - if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; - if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; - if (hw->info & SNDRV_PCM_INFO_MMAP) { - if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; - if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED; - if (hw->info & SNDRV_PCM_INFO_COMPLEX) - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; - } - err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, - hw->channels_min, hw->channels_max); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, - hw->rate_min, hw->rate_max); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - hw->period_bytes_min, hw->period_bytes_max); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, - hw->periods_min, hw->periods_max); - if (err < 0) - return err; - - err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - hw->period_bytes_min, hw->buffer_bytes_max); - if (err < 0) - return err; - - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - snd_pcm_hw_rule_buffer_bytes_max, substream, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1); - if (err < 0) - return err; - - /* FIXME: remove */ - if (runtime->dma_bytes) { - err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes); - if (err < 0) - return -EINVAL; - } - - if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) { - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_pcm_hw_rule_rate, hw, - SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) - return err; - } - - /* FIXME: this belong to lowlevel */ - snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); - - return 0; -} - -static void pcm_release_private(struct snd_pcm_substream *substream) -{ - snd_pcm_unlink(substream); -} - -void snd_pcm_release_substream(struct snd_pcm_substream *substream) -{ - substream->ref_count--; - if (substream->ref_count > 0) - return; - - snd_pcm_drop(substream); - if (substream->hw_opened) { - if (substream->ops->hw_free != NULL) - substream->ops->hw_free(substream); - substream->ops->close(substream); - substream->hw_opened = 0; - } - if (substream->pcm_release) { - substream->pcm_release(substream); - substream->pcm_release = NULL; - } - snd_pcm_detach_substream(substream); -} - -EXPORT_SYMBOL(snd_pcm_release_substream); - -int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, - struct file *file, - struct snd_pcm_substream **rsubstream) -{ - struct snd_pcm_substream *substream; - int err; - - err = snd_pcm_attach_substream(pcm, stream, file, &substream); - if (err < 0) - return err; - if (substream->ref_count > 1) { - *rsubstream = substream; - return 0; - } - - err = snd_pcm_hw_constraints_init(substream); - if (err < 0) { - snd_printd("snd_pcm_hw_constraints_init failed\n"); - goto error; - } - - if ((err = substream->ops->open(substream)) < 0) - goto error; - - substream->hw_opened = 1; - - err = snd_pcm_hw_constraints_complete(substream); - if (err < 0) { - snd_printd("snd_pcm_hw_constraints_complete failed\n"); - goto error; - } - - *rsubstream = substream; - return 0; - - error: - snd_pcm_release_substream(substream); - return err; -} - -EXPORT_SYMBOL(snd_pcm_open_substream); - -static int snd_pcm_open_file(struct file *file, - struct snd_pcm *pcm, - int stream, - struct snd_pcm_file **rpcm_file) -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_str *str; - int err; - - if (rpcm_file) - *rpcm_file = NULL; - - err = snd_pcm_open_substream(pcm, stream, file, &substream); - if (err < 0) - return err; - - pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); - if (pcm_file == NULL) { - snd_pcm_release_substream(substream); - return -ENOMEM; - } - pcm_file->substream = substream; - if (substream->ref_count == 1) { - str = substream->pstr; - substream->file = pcm_file; - substream->pcm_release = pcm_release_private; - } - file->private_data = pcm_file; - if (rpcm_file) - *rpcm_file = pcm_file; - return 0; -} - -static int snd_pcm_playback_open(struct inode *inode, struct file *file) -{ - struct snd_pcm *pcm; - int err = nonseekable_open(inode, file); - if (err < 0) - return err; - pcm = snd_lookup_minor_data(iminor(inode), - SNDRV_DEVICE_TYPE_PCM_PLAYBACK); - return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); -} - -static int snd_pcm_capture_open(struct inode *inode, struct file *file) -{ - struct snd_pcm *pcm; - int err = nonseekable_open(inode, file); - if (err < 0) - return err; - pcm = snd_lookup_minor_data(iminor(inode), - SNDRV_DEVICE_TYPE_PCM_CAPTURE); - return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); -} - -static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) -{ - int err; - struct snd_pcm_file *pcm_file; - wait_queue_t wait; - - if (pcm == NULL) { - err = -ENODEV; - goto __error1; - } - err = snd_card_file_add(pcm->card, file); - if (err < 0) - goto __error1; - if (!try_module_get(pcm->card->module)) { - err = -EFAULT; - goto __error2; - } - init_waitqueue_entry(&wait, current); - add_wait_queue(&pcm->open_wait, &wait); - mutex_lock(&pcm->open_mutex); - while (1) { - err = snd_pcm_open_file(file, pcm, stream, &pcm_file); - if (err >= 0) - break; - if (err == -EAGAIN) { - if (file->f_flags & O_NONBLOCK) { - err = -EBUSY; - break; - } - } else - break; - set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&pcm->open_mutex); - schedule(); - mutex_lock(&pcm->open_mutex); - if (signal_pending(current)) { - err = -ERESTARTSYS; - break; - } - } - remove_wait_queue(&pcm->open_wait, &wait); - mutex_unlock(&pcm->open_mutex); - if (err < 0) - goto __error; - return err; - - __error: - module_put(pcm->card->module); - __error2: - snd_card_file_remove(pcm->card, file); - __error1: - return err; -} - -static int snd_pcm_release(struct inode *inode, struct file *file) -{ - struct snd_pcm *pcm; - struct snd_pcm_substream *substream; - struct snd_pcm_file *pcm_file; - - pcm_file = file->private_data; - substream = pcm_file->substream; - if (snd_BUG_ON(!substream)) - return -ENXIO; - pcm = substream->pcm; - mutex_lock(&pcm->open_mutex); - snd_pcm_release_substream(substream); - kfree(pcm_file); - mutex_unlock(&pcm->open_mutex); - wake_up(&pcm->open_wait); - module_put(pcm->card->module); - snd_card_file_remove(pcm->card, file); - return 0; -} - -static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t appl_ptr; - snd_pcm_sframes_t ret; - snd_pcm_sframes_t hw_avail; - - if (frames == 0) - return 0; - - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - break; - case SNDRV_PCM_STATE_DRAINING: - case SNDRV_PCM_STATE_RUNNING: - if (snd_pcm_update_hw_ptr(substream) >= 0) - break; - /* Fall through */ - case SNDRV_PCM_STATE_XRUN: - ret = -EPIPE; - goto __end; - case SNDRV_PCM_STATE_SUSPENDED: - ret = -ESTRPIPE; - goto __end; - default: - ret = -EBADFD; - goto __end; - } - - hw_avail = snd_pcm_playback_hw_avail(runtime); - if (hw_avail <= 0) { - ret = 0; - goto __end; - } - if (frames > (snd_pcm_uframes_t)hw_avail) - frames = hw_avail; - appl_ptr = runtime->control->appl_ptr - frames; - if (appl_ptr < 0) - appl_ptr += runtime->boundary; - runtime->control->appl_ptr = appl_ptr; - ret = frames; - __end: - snd_pcm_stream_unlock_irq(substream); - return ret; -} - -static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t appl_ptr; - snd_pcm_sframes_t ret; - snd_pcm_sframes_t hw_avail; - - if (frames == 0) - return 0; - - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_DRAINING: - break; - case SNDRV_PCM_STATE_RUNNING: - if (snd_pcm_update_hw_ptr(substream) >= 0) - break; - /* Fall through */ - case SNDRV_PCM_STATE_XRUN: - ret = -EPIPE; - goto __end; - case SNDRV_PCM_STATE_SUSPENDED: - ret = -ESTRPIPE; - goto __end; - default: - ret = -EBADFD; - goto __end; - } - - hw_avail = snd_pcm_capture_hw_avail(runtime); - if (hw_avail <= 0) { - ret = 0; - goto __end; - } - if (frames > (snd_pcm_uframes_t)hw_avail) - frames = hw_avail; - appl_ptr = runtime->control->appl_ptr - frames; - if (appl_ptr < 0) - appl_ptr += runtime->boundary; - runtime->control->appl_ptr = appl_ptr; - ret = frames; - __end: - snd_pcm_stream_unlock_irq(substream); - return ret; -} - -static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t appl_ptr; - snd_pcm_sframes_t ret; - snd_pcm_sframes_t avail; - - if (frames == 0) - return 0; - - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_PAUSED: - break; - case SNDRV_PCM_STATE_DRAINING: - case SNDRV_PCM_STATE_RUNNING: - if (snd_pcm_update_hw_ptr(substream) >= 0) - break; - /* Fall through */ - case SNDRV_PCM_STATE_XRUN: - ret = -EPIPE; - goto __end; - case SNDRV_PCM_STATE_SUSPENDED: - ret = -ESTRPIPE; - goto __end; - default: - ret = -EBADFD; - goto __end; - } - - avail = snd_pcm_playback_avail(runtime); - if (avail <= 0) { - ret = 0; - goto __end; - } - if (frames > (snd_pcm_uframes_t)avail) - frames = avail; - appl_ptr = runtime->control->appl_ptr + frames; - if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) - appl_ptr -= runtime->boundary; - runtime->control->appl_ptr = appl_ptr; - ret = frames; - __end: - snd_pcm_stream_unlock_irq(substream); - return ret; -} - -static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream, - snd_pcm_uframes_t frames) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t appl_ptr; - snd_pcm_sframes_t ret; - snd_pcm_sframes_t avail; - - if (frames == 0) - return 0; - - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_DRAINING: - case SNDRV_PCM_STATE_PAUSED: - break; - case SNDRV_PCM_STATE_RUNNING: - if (snd_pcm_update_hw_ptr(substream) >= 0) - break; - /* Fall through */ - case SNDRV_PCM_STATE_XRUN: - ret = -EPIPE; - goto __end; - case SNDRV_PCM_STATE_SUSPENDED: - ret = -ESTRPIPE; - goto __end; - default: - ret = -EBADFD; - goto __end; - } - - avail = snd_pcm_capture_avail(runtime); - if (avail <= 0) { - ret = 0; - goto __end; - } - if (frames > (snd_pcm_uframes_t)avail) - frames = avail; - appl_ptr = runtime->control->appl_ptr + frames; - if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) - appl_ptr -= runtime->boundary; - runtime->control->appl_ptr = appl_ptr; - ret = frames; - __end: - snd_pcm_stream_unlock_irq(substream); - return ret; -} - -static int snd_pcm_hwsync(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_DRAINING: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - goto __badfd; - case SNDRV_PCM_STATE_RUNNING: - if ((err = snd_pcm_update_hw_ptr(substream)) < 0) - break; - /* Fall through */ - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_SUSPENDED: - err = 0; - break; - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - break; - default: - __badfd: - err = -EBADFD; - break; - } - snd_pcm_stream_unlock_irq(substream); - return err; -} - -static int snd_pcm_delay(struct snd_pcm_substream *substream, - snd_pcm_sframes_t __user *res) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - snd_pcm_sframes_t n = 0; - - //giovanni snd_pcm_stream_lock_irq(substream); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_DRAINING: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - goto __badfd; - case SNDRV_PCM_STATE_RUNNING: - if ((err = snd_pcm_update_hw_ptr(substream)) < 0) - break; - /* Fall through */ - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_SUSPENDED: - err = 0; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - n = snd_pcm_playback_hw_avail(runtime); - else - n = snd_pcm_capture_avail(runtime); - n += runtime->delay; - break; - case SNDRV_PCM_STATE_XRUN: - err = -EPIPE; - break; - default: - __badfd: - err = -EBADFD; - break; - } - //giovanni snd_pcm_stream_unlock_irq(substream); - if (!err) - if (put_user(n, res)) - err = -EFAULT; - return err; -} - -static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, - struct snd_pcm_sync_ptr __user *_sync_ptr) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_pcm_sync_ptr sync_ptr; - volatile struct snd_pcm_mmap_status *status; - volatile struct snd_pcm_mmap_control *control; - int err; - - memset(&sync_ptr, 0, sizeof(sync_ptr)); - if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags))) - return -EFAULT; - if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct snd_pcm_mmap_control))) - return -EFAULT; - status = runtime->status; - control = runtime->control; - if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) { - err = snd_pcm_hwsync(substream); - if (err < 0) - return err; - } - //giovanni snd_pcm_stream_lock_irq(substream); - if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) - control->appl_ptr = sync_ptr.c.control.appl_ptr; - else - sync_ptr.c.control.appl_ptr = control->appl_ptr; - if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) - control->avail_min = sync_ptr.c.control.avail_min; - else - sync_ptr.c.control.avail_min = control->avail_min; - sync_ptr.s.status.state = status->state; - sync_ptr.s.status.hw_ptr = status->hw_ptr; - sync_ptr.s.status.tstamp = status->tstamp; - sync_ptr.s.status.suspended_state = status->suspended_state; - //giovanni snd_pcm_stream_unlock_irq(substream); - if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr))) - return -EFAULT; - return 0; -} - -static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int arg; - - if (get_user(arg, _arg)) - return -EFAULT; - if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST) - return -EINVAL; - runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY; - if (arg == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC) - runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC; - return 0; -} - -static int snd_pcm_common_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - switch (cmd) { - case SNDRV_PCM_IOCTL_PVERSION: - return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; - case SNDRV_PCM_IOCTL_INFO: - return snd_pcm_info_user(substream, arg); - case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */ - return 0; - case SNDRV_PCM_IOCTL_TTSTAMP: - return snd_pcm_tstamp(substream, arg); - case SNDRV_PCM_IOCTL_HW_REFINE: - return snd_pcm_hw_refine_user(substream, arg); - case SNDRV_PCM_IOCTL_HW_PARAMS: - return snd_pcm_hw_params_user(substream, arg); - case SNDRV_PCM_IOCTL_HW_FREE: - return snd_pcm_hw_free(substream); - case SNDRV_PCM_IOCTL_SW_PARAMS: - return snd_pcm_sw_params_user(substream, arg); - case SNDRV_PCM_IOCTL_STATUS: - return snd_pcm_status_user(substream, arg); - case SNDRV_PCM_IOCTL_CHANNEL_INFO: - return snd_pcm_channel_info_user(substream, arg); - case SNDRV_PCM_IOCTL_PREPARE: - return snd_pcm_prepare(substream, file); - case SNDRV_PCM_IOCTL_RESET: - return snd_pcm_reset(substream); - case SNDRV_PCM_IOCTL_START: - return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING); - case SNDRV_PCM_IOCTL_LINK: - return snd_pcm_link(substream, (int)(unsigned long) arg); - case SNDRV_PCM_IOCTL_UNLINK: - return snd_pcm_unlink(substream); - case SNDRV_PCM_IOCTL_RESUME: - return snd_pcm_resume(substream); - case SNDRV_PCM_IOCTL_XRUN: - return snd_pcm_xrun(substream); - case SNDRV_PCM_IOCTL_HWSYNC: - return snd_pcm_hwsync(substream); - case SNDRV_PCM_IOCTL_DELAY: - return snd_pcm_delay(substream, arg); - case SNDRV_PCM_IOCTL_SYNC_PTR: - return snd_pcm_sync_ptr(substream, arg); -#ifdef CONFIG_SND_SUPPORT_OLD_API - case SNDRV_PCM_IOCTL_HW_REFINE_OLD: - return snd_pcm_hw_refine_old_user(substream, arg); - case SNDRV_PCM_IOCTL_HW_PARAMS_OLD: - return snd_pcm_hw_params_old_user(substream, arg); -#endif - case SNDRV_PCM_IOCTL_DRAIN: - return snd_pcm_drain(substream, file); - case SNDRV_PCM_IOCTL_DROP: - return snd_pcm_drop(substream); - case SNDRV_PCM_IOCTL_PAUSE: - { - int res; - snd_pcm_stream_lock_irq(substream); - res = snd_pcm_pause(substream, (int)(unsigned long)arg); - snd_pcm_stream_unlock_irq(substream); - return res; - } - } - snd_printd("unknown ioctl = 0x%x\n", cmd); - return -ENOTTY; -} - -static int snd_pcm_playback_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - if (snd_BUG_ON(!substream)) - return -ENXIO; - if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) - return -EINVAL; - switch (cmd) { - case SNDRV_PCM_IOCTL_WRITEI_FRAMES: - { - struct snd_xferi xferi; - struct snd_xferi __user *_xferi = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (put_user(0, &_xferi->result)) - return -EFAULT; - if (copy_from_user(&xferi, _xferi, sizeof(xferi))) - return -EFAULT; - result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames); - __put_user(result, &_xferi->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_WRITEN_FRAMES: - { - struct snd_xfern xfern; - struct snd_xfern __user *_xfern = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - void __user **bufs; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (runtime->channels > 128) - return -EINVAL; - if (put_user(0, &_xfern->result)) - return -EFAULT; - if (copy_from_user(&xfern, _xfern, sizeof(xfern))) - return -EFAULT; - - bufs = memdup_user(xfern.bufs, - sizeof(void *) * runtime->channels); - if (IS_ERR(bufs)) - return PTR_ERR(bufs); - result = snd_pcm_lib_writev(substream, bufs, xfern.frames); - kfree(bufs); - __put_user(result, &_xfern->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_REWIND: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_playback_rewind(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_FORWARD: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_playback_forward(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - } - return snd_pcm_common_ioctl1(file, substream, cmd, arg); -} - -static int snd_pcm_capture_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - if (snd_BUG_ON(!substream)) - return -ENXIO; - if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) - return -EINVAL; - switch (cmd) { - case SNDRV_PCM_IOCTL_READI_FRAMES: - { - struct snd_xferi xferi; - struct snd_xferi __user *_xferi = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (put_user(0, &_xferi->result)) - return -EFAULT; - if (copy_from_user(&xferi, _xferi, sizeof(xferi))) - return -EFAULT; - result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames); - __put_user(result, &_xferi->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_READN_FRAMES: - { - struct snd_xfern xfern; - struct snd_xfern __user *_xfern = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - void *bufs; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (runtime->channels > 128) - return -EINVAL; - if (put_user(0, &_xfern->result)) - return -EFAULT; - if (copy_from_user(&xfern, _xfern, sizeof(xfern))) - return -EFAULT; - - bufs = memdup_user(xfern.bufs, - sizeof(void *) * runtime->channels); - if (IS_ERR(bufs)) - return PTR_ERR(bufs); - result = snd_pcm_lib_readv(substream, bufs, xfern.frames); - kfree(bufs); - __put_user(result, &_xfern->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_REWIND: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_capture_rewind(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_FORWARD: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_capture_forward(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - } - return snd_pcm_common_ioctl1(file, substream, cmd, arg); -} - -static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct snd_pcm_file *pcm_file; - - pcm_file = file->private_data; - - if (((cmd >> 8) & 0xff) != 'A') - return -ENOTTY; - - return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd, - (void __user *)arg); -} - -static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct snd_pcm_file *pcm_file; - - pcm_file = file->private_data; - - if (((cmd >> 8) & 0xff) != 'A') - return -ENOTTY; - - return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd, - (void __user *)arg); -} - -int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - mm_segment_t fs; - int result; - - fs = snd_enter_user(); - switch (substream->stream) { - case SNDRV_PCM_STREAM_PLAYBACK: - result = snd_pcm_playback_ioctl1(NULL, substream, cmd, - (void __user *)arg); - break; - case SNDRV_PCM_STREAM_CAPTURE: - result = snd_pcm_capture_ioctl1(NULL, substream, cmd, - (void __user *)arg); - break; - default: - result = -EINVAL; - break; - } - snd_leave_user(fs); - return result; -} - -EXPORT_SYMBOL(snd_pcm_kernel_ioctl); - -static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, - loff_t * offset) -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - snd_pcm_sframes_t result; - - pcm_file = file->private_data; - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (!frame_aligned(runtime, count)) - return -EINVAL; - count = bytes_to_frames(runtime, count); - result = snd_pcm_lib_read(substream, buf, count); - if (result > 0) - result = frames_to_bytes(runtime, result); - return result; -} - -static ssize_t snd_pcm_write(struct file *file, const char __user *buf, - size_t count, loff_t * offset) -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - snd_pcm_sframes_t result; - - pcm_file = file->private_data; - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (!frame_aligned(runtime, count)) - return -EINVAL; - count = bytes_to_frames(runtime, count); - result = snd_pcm_lib_write(substream, buf, count); - if (result > 0) - result = frames_to_bytes(runtime, result); - return result; -} - -static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) - -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - snd_pcm_sframes_t result; - unsigned long i; - void __user **bufs; - snd_pcm_uframes_t frames; - - pcm_file = iocb->ki_filp->private_data; - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (nr_segs > 1024 || nr_segs != runtime->channels) - return -EINVAL; - if (!frame_aligned(runtime, iov->iov_len)) - return -EINVAL; - frames = bytes_to_samples(runtime, iov->iov_len); - bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); - if (bufs == NULL) - return -ENOMEM; - for (i = 0; i < nr_segs; ++i) - bufs[i] = iov[i].iov_base; - result = snd_pcm_lib_readv(substream, bufs, frames); - if (result > 0) - result = frames_to_bytes(runtime, result); - kfree(bufs); - return result; -} - -static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - snd_pcm_sframes_t result; - unsigned long i; - void __user **bufs; - snd_pcm_uframes_t frames; - - pcm_file = iocb->ki_filp->private_data; - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (nr_segs > 128 || nr_segs != runtime->channels || - !frame_aligned(runtime, iov->iov_len)) - return -EINVAL; - frames = bytes_to_samples(runtime, iov->iov_len); - bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); - if (bufs == NULL) - return -ENOMEM; - for (i = 0; i < nr_segs; ++i) - bufs[i] = iov[i].iov_base; - result = snd_pcm_lib_writev(substream, bufs, frames); - if (result > 0) - result = frames_to_bytes(runtime, result); - kfree(bufs); - return result; -} - -static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait) -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - unsigned int mask; - snd_pcm_uframes_t avail; - - pcm_file = file->private_data; - - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - - poll_wait(file, &runtime->sleep, wait); - - //giovanni snd_pcm_stream_lock_irq(substream); - avail = snd_pcm_playback_avail(runtime); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_RUNNING: - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_PAUSED: - if (avail >= runtime->control->avail_min) { - mask = POLLOUT | POLLWRNORM; - break; - } - /* Fall through */ - case SNDRV_PCM_STATE_DRAINING: - mask = 0; - break; - default: - mask = POLLOUT | POLLWRNORM | POLLERR; - break; - } - //giovanni snd_pcm_stream_unlock_irq(substream); - return mask; -} - -static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait) -{ - struct snd_pcm_file *pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - unsigned int mask; - snd_pcm_uframes_t avail; - - pcm_file = file->private_data; - - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - - poll_wait(file, &runtime->sleep, wait); - - //giovanni snd_pcm_stream_lock_irq(substream); - avail = snd_pcm_capture_avail(runtime); - switch (runtime->status->state) { - case SNDRV_PCM_STATE_RUNNING: - case SNDRV_PCM_STATE_PREPARED: - case SNDRV_PCM_STATE_PAUSED: - if (avail >= runtime->control->avail_min) { - mask = POLLIN | POLLRDNORM; - break; - } - mask = 0; - break; - case SNDRV_PCM_STATE_DRAINING: - if (avail > 0) { - mask = POLLIN | POLLRDNORM; - break; - } - /* Fall through */ - default: - mask = POLLIN | POLLRDNORM | POLLERR; - break; - } - //giovanni snd_pcm_stream_unlock_irq(substream); - return mask; -} - -/* - * mmap support - */ - -/* - * Only on coherent architectures, we can mmap the status and the control records - * for effcient data transfer. On others, we have to use HWSYNC ioctl... - */ -#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA) -/* - * mmap status record - */ -static int snd_pcm_mmap_status_fault(struct vm_area_struct *area, - struct vm_fault *vmf) -{ - struct snd_pcm_substream *substream = area->vm_private_data; - struct snd_pcm_runtime *runtime; - - if (substream == NULL) - return VM_FAULT_SIGBUS; - runtime = substream->runtime; - vmf->page = virt_to_page(runtime->status); - get_page(vmf->page); - return 0; -} - -static const struct vm_operations_struct snd_pcm_vm_ops_status = -{ - .fault = snd_pcm_mmap_status_fault, -}; - -static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, - struct vm_area_struct *area) -{ - struct snd_pcm_runtime *runtime; - long size; - if (!(area->vm_flags & VM_READ)) - return -EINVAL; - runtime = substream->runtime; - size = area->vm_end - area->vm_start; - if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) - return -EINVAL; - area->vm_ops = &snd_pcm_vm_ops_status; - area->vm_private_data = substream; - area->vm_flags |= VM_RESERVED; - return 0; -} - -/* - * mmap control record - */ -static int snd_pcm_mmap_control_fault(struct vm_area_struct *area, - struct vm_fault *vmf) -{ - struct snd_pcm_substream *substream = area->vm_private_data; - struct snd_pcm_runtime *runtime; - - if (substream == NULL) - return VM_FAULT_SIGBUS; - runtime = substream->runtime; - vmf->page = virt_to_page(runtime->control); - get_page(vmf->page); - return 0; -} - -static const struct vm_operations_struct snd_pcm_vm_ops_control = -{ - .fault = snd_pcm_mmap_control_fault, -}; - -static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, - struct vm_area_struct *area) -{ - struct snd_pcm_runtime *runtime; - long size; - if (!(area->vm_flags & VM_READ)) - return -EINVAL; - runtime = substream->runtime; - size = area->vm_end - area->vm_start; - if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) - return -EINVAL; - area->vm_ops = &snd_pcm_vm_ops_control; - area->vm_private_data = substream; - area->vm_flags |= VM_RESERVED; - return 0; -} -#else /* ! coherent mmap */ -/* - * don't support mmap for status and control records. - */ -static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, - struct vm_area_struct *area) -{ - return -ENXIO; -} -static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, - struct vm_area_struct *area) -{ - return -ENXIO; -} -#endif /* coherent mmap */ - -static inline struct page * -snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) -{ - void *vaddr = substream->runtime->dma_area + ofs; -#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) - if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) - return virt_to_page(CAC_ADDR(vaddr)); -#endif -#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE) - if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) { - dma_addr_t addr = substream->runtime->dma_addr + ofs; - addr -= get_dma_offset(substream->dma_buffer.dev.dev); - /* assume dma_handle set via pfn_to_phys() in - * mm/dma-noncoherent.c - */ - return pfn_to_page(addr >> PAGE_SHIFT); - } -#endif - return virt_to_page(vaddr); -} - -/* - * fault callback for mmapping a RAM page - */ -static int snd_pcm_mmap_data_fault(struct vm_area_struct *area, - struct vm_fault *vmf) -{ - struct snd_pcm_substream *substream = area->vm_private_data; - struct snd_pcm_runtime *runtime; - unsigned long offset; - struct page * page; - size_t dma_bytes; - - if (substream == NULL) - return VM_FAULT_SIGBUS; - runtime = substream->runtime; - offset = vmf->pgoff << PAGE_SHIFT; - dma_bytes = PAGE_ALIGN(runtime->dma_bytes); - if (offset > dma_bytes - PAGE_SIZE) - return VM_FAULT_SIGBUS; - if (substream->ops->page) - page = substream->ops->page(substream, offset); - else - page = snd_pcm_default_page_ops(substream, offset); - if (!page) - return VM_FAULT_SIGBUS; - get_page(page); - vmf->page = page; - return 0; -} - -static const struct vm_operations_struct snd_pcm_vm_ops_data = { - .open = snd_pcm_mmap_data_open, - .close = snd_pcm_mmap_data_close, -}; - -static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { - .open = snd_pcm_mmap_data_open, - .close = snd_pcm_mmap_data_close, - .fault = snd_pcm_mmap_data_fault, -}; - -#ifndef ARCH_HAS_DMA_MMAP_COHERENT -/* This should be defined / handled globally! */ -#ifdef CONFIG_ARM -#define ARCH_HAS_DMA_MMAP_COHERENT -#endif -#endif - -/* - * mmap the DMA buffer on RAM - */ -static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *area) -{ - area->vm_flags |= VM_RESERVED; -#ifdef ARCH_HAS_DMA_MMAP_COHERENT - if (!substream->ops->page && - substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) - return dma_mmap_coherent(substream->dma_buffer.dev.dev, - area, - substream->runtime->dma_area, - substream->runtime->dma_addr, - area->vm_end - area->vm_start); -#endif /* ARCH_HAS_DMA_MMAP_COHERENT */ - /* mmap with fault handler */ - area->vm_ops = &snd_pcm_vm_ops_data_fault; - return 0; -} - -/* - * mmap the DMA buffer on I/O memory area - */ -#if SNDRV_PCM_INFO_MMAP_IOMEM -int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, - struct vm_area_struct *area) -{ - long size; - unsigned long offset; - - area->vm_page_prot = pgprot_noncached(area->vm_page_prot); - area->vm_flags |= VM_IO; - size = area->vm_end - area->vm_start; - offset = area->vm_pgoff << PAGE_SHIFT; - if (io_remap_pfn_range(area, area->vm_start, - (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, - size, area->vm_page_prot)) - return -EAGAIN; - return 0; -} - -EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); -#endif /* SNDRV_PCM_INFO_MMAP */ - -/* mmap callback with pgprot_noncached */ -int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, - struct vm_area_struct *area) -{ - area->vm_page_prot = pgprot_noncached(area->vm_page_prot); - return snd_pcm_default_mmap(substream, area); -} -EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached); - -/* - * mmap DMA buffer - */ -int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, - struct vm_area_struct *area) -{ - struct snd_pcm_runtime *runtime; - long size; - unsigned long offset; - size_t dma_bytes; - int err; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (!(area->vm_flags & (VM_WRITE|VM_READ))) - return -EINVAL; - } else { - if (!(area->vm_flags & VM_READ)) - return -EINVAL; - } - runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) - return -ENXIO; - if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || - runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) - return -EINVAL; - size = area->vm_end - area->vm_start; - offset = area->vm_pgoff << PAGE_SHIFT; - dma_bytes = PAGE_ALIGN(runtime->dma_bytes); - if ((size_t)size > dma_bytes) - return -EINVAL; - if (offset > dma_bytes - size) - return -EINVAL; - - area->vm_ops = &snd_pcm_vm_ops_data; - area->vm_private_data = substream; - if (substream->ops->mmap) - err = substream->ops->mmap(substream, area); - else - err = snd_pcm_default_mmap(substream, area); - if (!err) - atomic_inc(&substream->mmap_count); - return err; -} - -EXPORT_SYMBOL(snd_pcm_mmap_data); - -static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) -{ - struct snd_pcm_file * pcm_file; - struct snd_pcm_substream *substream; - unsigned long offset; - - pcm_file = file->private_data; - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - - offset = area->vm_pgoff << PAGE_SHIFT; - switch (offset) { - case SNDRV_PCM_MMAP_OFFSET_STATUS: - if (pcm_file->no_compat_mmap) - return -ENXIO; - return snd_pcm_mmap_status(substream, file, area); - case SNDRV_PCM_MMAP_OFFSET_CONTROL: - if (pcm_file->no_compat_mmap) - return -ENXIO; - return snd_pcm_mmap_control(substream, file, area); - default: - return snd_pcm_mmap_data(substream, file, area); - } - return 0; -} - -static int snd_pcm_fasync(int fd, struct file * file, int on) -{ - struct snd_pcm_file * pcm_file; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - - pcm_file = file->private_data; - substream = pcm_file->substream; - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - runtime = substream->runtime; - return fasync_helper(fd, file, on, &runtime->fasync); -} - -/* - * ioctl32 compat - */ -#ifdef CONFIG_COMPAT -#include "pcm_compat.c" -#else -#define snd_pcm_ioctl_compat NULL -#endif - -/* - * To be removed helpers to keep binary compatibility - */ - -#ifdef CONFIG_SND_SUPPORT_OLD_API -#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5)) -#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5)) - -static void snd_pcm_hw_convert_from_old_params(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_params_old *oparams) -{ - unsigned int i; - - memset(params, 0, sizeof(*params)); - params->flags = oparams->flags; - for (i = 0; i < ARRAY_SIZE(oparams->masks); i++) - params->masks[i].bits[0] = oparams->masks[i]; - memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals)); - params->rmask = __OLD_TO_NEW_MASK(oparams->rmask); - params->cmask = __OLD_TO_NEW_MASK(oparams->cmask); - params->info = oparams->info; - params->msbits = oparams->msbits; - params->rate_num = oparams->rate_num; - params->rate_den = oparams->rate_den; - params->fifo_size = oparams->fifo_size; -} - -static void snd_pcm_hw_convert_to_old_params(struct snd_pcm_hw_params_old *oparams, - struct snd_pcm_hw_params *params) -{ - unsigned int i; - - memset(oparams, 0, sizeof(*oparams)); - oparams->flags = params->flags; - for (i = 0; i < ARRAY_SIZE(oparams->masks); i++) - oparams->masks[i] = params->masks[i].bits[0]; - memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals)); - oparams->rmask = __NEW_TO_OLD_MASK(params->rmask); - oparams->cmask = __NEW_TO_OLD_MASK(params->cmask); - oparams->info = params->info; - oparams->msbits = params->msbits; - oparams->rate_num = params->rate_num; - oparams->rate_den = params->rate_den; - oparams->fifo_size = params->fifo_size; -} - -static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params_old __user * _oparams) -{ - struct snd_pcm_hw_params *params; - struct snd_pcm_hw_params_old *oparams = NULL; - int err; - - params = kmalloc(sizeof(*params), GFP_KERNEL); - if (!params) - return -ENOMEM; - - oparams = memdup_user(_oparams, sizeof(*oparams)); - if (IS_ERR(oparams)) { - err = PTR_ERR(oparams); - goto out; - } - snd_pcm_hw_convert_from_old_params(params, oparams); - err = snd_pcm_hw_refine(substream, params); - snd_pcm_hw_convert_to_old_params(oparams, params); - if (copy_to_user(_oparams, oparams, sizeof(*oparams))) { - if (!err) - err = -EFAULT; - } - - kfree(oparams); -out: - kfree(params); - return err; -} - -static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params_old __user * _oparams) -{ - struct snd_pcm_hw_params *params; - struct snd_pcm_hw_params_old *oparams = NULL; - int err; - - params = kmalloc(sizeof(*params), GFP_KERNEL); - if (!params) - return -ENOMEM; - - oparams = memdup_user(_oparams, sizeof(*oparams)); - if (IS_ERR(oparams)) { - err = PTR_ERR(oparams); - goto out; - } - snd_pcm_hw_convert_from_old_params(params, oparams); - err = snd_pcm_hw_params(substream, params); - snd_pcm_hw_convert_to_old_params(oparams, params); - if (copy_to_user(_oparams, oparams, sizeof(*oparams))) { - if (!err) - err = -EFAULT; - } - - kfree(oparams); -out: - kfree(params); - return err; -} -#endif /* CONFIG_SND_SUPPORT_OLD_API */ - -#ifndef CONFIG_MMU -static unsigned long snd_pcm_get_unmapped_area(struct file *file, - unsigned long addr, - unsigned long len, - unsigned long pgoff, - unsigned long flags) -{ - struct snd_pcm_file *pcm_file = file->private_data; - struct snd_pcm_substream *substream = pcm_file->substream; - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long offset = pgoff << PAGE_SHIFT; - - switch (offset) { - case SNDRV_PCM_MMAP_OFFSET_STATUS: - return (unsigned long)runtime->status; - case SNDRV_PCM_MMAP_OFFSET_CONTROL: - return (unsigned long)runtime->control; - default: - return (unsigned long)runtime->dma_area + offset; - } -} -#else -# define snd_pcm_get_unmapped_area NULL -#endif - -/* - * Register section - */ - -const struct file_operations snd_pcm_f_ops[2] = { - { - .owner = THIS_MODULE, - .write = snd_pcm_write, - .aio_write = snd_pcm_aio_write, - .open = snd_pcm_playback_open, - .release = snd_pcm_release, - .llseek = no_llseek, - .poll = snd_pcm_playback_poll, - .unlocked_ioctl = snd_pcm_playback_ioctl, - .compat_ioctl = snd_pcm_ioctl_compat, - .mmap = snd_pcm_mmap, - .fasync = snd_pcm_fasync, - .get_unmapped_area = snd_pcm_get_unmapped_area, - }, - { - .owner = THIS_MODULE, - .read = snd_pcm_read, - .aio_read = snd_pcm_aio_read, - .open = snd_pcm_capture_open, - .release = snd_pcm_release, - .llseek = no_llseek, - .poll = snd_pcm_capture_poll, - .unlocked_ioctl = snd_pcm_capture_ioctl, - .compat_ioctl = snd_pcm_ioctl_compat, - .mmap = snd_pcm_mmap, - .fasync = snd_pcm_fasync, - .get_unmapped_area = snd_pcm_get_unmapped_area, - } -}; diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile deleted file mode 100644 index 40b25f0e25..0000000000 --- a/src/mod/endpoints/mod_skypopen/oss/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Comment/uncomment the following line to disable/enable debugging -#DEBUG = y -#LDDINC= - -# Add your debugging flag (or not) to CFLAGS -ifeq ($(DEBUG),y) - DEBFLAGS = -O -g -DSKYPOPEN_DEBUG # "-O" is needed to expand inlines -else - DEBFLAGS = -O2 -Wall -endif - -EXTRA_CFLAGS += $(DEBFLAGS) -EXTRA_CFLAGS += -I$(LDDINC) - -ifneq ($(KERNELRELEASE),) -# call from kernel build system - -skypopen-objs := main.o - -obj-m := skypopen.o - -else - -KERNELDIR ?= /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) - -modules: - $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules - -endif - - - -clean: - rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions - -depend .depend dep: - $(CC) $(EXTRA_CFLAGS) -M *.c > .depend - - -ifeq (.depend,$(wildcard .depend)) -include .depend -endif diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c deleted file mode 100644 index 32acb46790..0000000000 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * main.c -- the bare skypopen char module - * - * Copyright (C) 2010 Giovanni Maruzzelli - * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet - * Copyright (C) 2001 O'Reilly & Associates - * - * The source code in this file can be freely used, adapted, - * and redistributed in source or binary form, so long as an - * acknowledgment appears in derived source files. The citation - * should list that the code comes from the book "Linux Device - * Drivers" by Alessandro Rubini and Jonathan Corbet, published - * by O'Reilly & Associates. No warranty is attached; - * we cannot take responsibility for errors or fitness for use. - * - */ - -#include -#include -#include - -#include /* printk() */ -#include /* kmalloc() */ -#include /* everything... */ -#include /* error codes */ -#include /* size_t */ -#include -#include /* O_ACCMODE */ -#include -#include - -#include /* copy_*_user */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "skypopen.h" /* local definitions */ - - -/* - * Our parameters which can be set at load time. - */ - -int skypopen_major = SKYPOPEN_MAJOR; -int skypopen_minor = SKYPOPEN_MINOR; -int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */ - -module_param(skypopen_major, int, S_IRUGO); -module_param(skypopen_minor, int, S_IRUGO); -module_param(skypopen_nr_devs, int, S_IRUGO); - -MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Modified by: Giovanni Maruzzelli for FreeSWITCH skypopen"); -MODULE_LICENSE("Dual BSD/GPL"); - -static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */ - -static int unload = 0; - -#ifndef WANT_HRTIMER -void my_timer_callback_inq( unsigned long data ) -{ - struct skypopen_dev *dev = (void *)data; - - wake_up_interruptible(&dev->inq); - mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); - -} - -void my_timer_callback_outq( unsigned long data ) -{ - struct skypopen_dev *dev = (void *)data; - - wake_up_interruptible(&dev->outq); - mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); -} -#else// WANT_HRTIMER - -#ifndef CENTOS_5 -static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq ) -{ - struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); - - if(unload) - return HRTIMER_NORESTART; - - hrtimer_forward(&dev->timer_inq, timer_inq->_softexpires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); - wake_up_interruptible(&dev->inq); - - return HRTIMER_RESTART; -} -static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq ) -{ - struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq); - - if(unload) - return HRTIMER_NORESTART; - - hrtimer_forward(&dev->timer_outq, timer_outq->_softexpires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); - wake_up_interruptible(&dev->outq); - - return HRTIMER_RESTART; -} -#else// CENTOS_5 -static int my_hrtimer_callback_inq( struct hrtimer *timer_inq ) -{ - struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); - - if(unload) - return HRTIMER_NORESTART; - - hrtimer_forward(&dev->timer_inq, timer_inq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); - wake_up_interruptible(&dev->inq); - - return HRTIMER_RESTART; -} -static int my_hrtimer_callback_outq( struct hrtimer *timer_outq ) -{ - struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq); - - if(unload) - return HRTIMER_NORESTART; - - hrtimer_forward(&dev->timer_outq, timer_outq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); - wake_up_interruptible(&dev->outq); - - return HRTIMER_RESTART; -} -#endif// CENTOS_5 -#endif// WANT_HRTIMER - -/* The clone-specific data structure includes a key field */ - -struct skypopen_listitem { - struct skypopen_dev device; - dev_t key; - struct list_head list; - -}; - -/* The list of devices, and a lock to protect it */ -static LIST_HEAD(skypopen_c_list); -#ifdef WANT_DEFINE_SPINLOCK -static DEFINE_SPINLOCK(skypopen_c_lock); -#else // WANT_DEFINE_SPINLOCK -static spinlock_t skypopen_c_lock = SPIN_LOCK_UNLOCKED; -#endif // WANT_DEFINE_SPINLOCK - -/* Look for a device or create one if missing */ -static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) -{ - struct skypopen_listitem *lptr; -#ifdef WANT_HRTIMER -#endif// WANT_HRTIMER - - list_for_each_entry(lptr, &skypopen_c_list, list) { - if (lptr->key == key) - return &(lptr->device); - } - - /* not found */ - lptr = kmalloc(sizeof(struct skypopen_listitem), GFP_KERNEL); - if (!lptr) - return NULL; - - /* initialize the device */ - memset(lptr, 0, sizeof(struct skypopen_listitem)); - lptr->key = key; - - init_waitqueue_head(&lptr->device.inq); - init_waitqueue_head(&lptr->device.outq); - -#ifndef WANT_HRTIMER - setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); - setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); - printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); - mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); - printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); - mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); -#endif// WANT_HRTIMER - - /* place it in the list */ - list_add(&lptr->list, &skypopen_c_list); - - return &(lptr->device); -} - -/* - * Open and close - */ -static int skypopen_c_open(struct inode *inode, struct file *filp) -{ - struct skypopen_dev *dev; - dev_t key; - - key = current->tgid; - - /* look for a skypopenc device in the list */ - spin_lock(&skypopen_c_lock); - dev = skypopen_c_lookfor_device(key); - if (dev){ - dev->opened++; - } - spin_unlock(&skypopen_c_lock); - - if (!dev) - return -ENOMEM; - - /* then, everything else is copied from the bare skypopen device */ - filp->private_data = dev; - return 0; /* success */ -} - -static int skypopen_c_release(struct inode *inode, struct file *filp) -{ - dev_t key; - struct skypopen_dev *dev = filp->private_data; - int ret; - - key = current->tgid; - - spin_lock(&skypopen_c_lock); - dev->opened--; - spin_unlock(&skypopen_c_lock); - - if(!dev->opened){ -#ifdef WANT_HRTIMER - if(dev->timer_inq_started){ - ret = hrtimer_cancel( &dev->timer_inq ); - //printk( "Stopped skypopen OSS driver read HRtimer skype client:(%d) ret=%d\n", key, ret); - dev->timer_inq_started=0; - } - if(dev->timer_outq_started){ - ret = hrtimer_cancel( &dev->timer_outq ); - //printk( "Stopped skypopen OSS driver write HRtimer skype client:(%d) ret=%d\n", key, ret); - dev->timer_outq_started=0; - } -#endif// WANT_HRTIMER - } - return 0; -} - - - -/*************************************************************/ - -static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, - loff_t *f_pos) -{ - DEFINE_WAIT(wait); - struct skypopen_dev *dev = filp->private_data; - dev_t key; - - key = current->tgid; - - if(unload) - return -1; - -#ifdef WANT_HRTIMER - if(dev->timer_inq_started == 0){ - ktime_t ktime_inq; - - ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); - hrtimer_init( &dev->timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); - dev->timer_inq.function = &my_hrtimer_callback_inq; - hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL ); - dev->timer_inq_started = 1; - //printk( "Started skypopen OSS driver read HRtimer skype client:(%d) \n", key); - } -#endif// WANT_HRTIMER - - //printk("READ\n"); - prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&dev->inq, &wait); - return count; -} - -static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos) -{ - DEFINE_WAIT(wait); - struct skypopen_dev *dev = filp->private_data; - dev_t key; - - key = current->tgid; - - if(unload) - return -1; - -#ifdef WANT_HRTIMER - if(dev->timer_outq_started == 0){ - ktime_t ktime_outq; - - ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); - hrtimer_init( &dev->timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); - dev->timer_outq.function = &my_hrtimer_callback_outq; - hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL ); - dev->timer_outq_started = 1; - //printk( "Started skypopen OSS driver write HRtimer skype client:(%d) \n", key); - } -#endif// WANT_HRTIMER - - //printk("WRITE\n"); - prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&dev->outq, &wait); - return count; - -} -/* - * The ioctl() implementation - */ - -#ifndef HAVE_UNLOCKED_IOCTL -static int skypopen_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - - switch (cmd) { - case OSS_GETVERSION: - return put_user(SOUND_VERSION, p); - case SNDCTL_DSP_GETBLKSIZE: - return put_user(SKYPOPEN_BLK, p); - case SNDCTL_DSP_GETFMTS: - return put_user(28731, p); - - default: - return 0; - } - -} -#else// HAVE_UNLOCKED_IOCTL -static long skypopen_unlocked_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - - switch (cmd) { - case OSS_GETVERSION: - return put_user(SOUND_VERSION, p); - case SNDCTL_DSP_GETBLKSIZE: - return put_user(SKYPOPEN_BLK, p); - case SNDCTL_DSP_GETFMTS: - return put_user(28731, p); - - default: - return 0; - } - -} -#endif// HAVE_UNLOCKED_IOCTL - -struct file_operations skypopen_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = skypopen_read, - .write = skypopen_write, -#ifndef HAVE_UNLOCKED_IOCTL - .ioctl = skypopen_ioctl, -#else// HAVE_UNLOCKED_IOCTL - .unlocked_ioctl = skypopen_unlocked_ioctl, -#endif// HAVE_UNLOCKED_IOCTL - .open = skypopen_c_open, - .release = skypopen_c_release, -}; - -/* - * Finally, the module stuff - */ - -/* - * The cleanup function is used to handle initialization failures as well. - * Thefore, it must be careful to work correctly even if some of the items - * have not been initialized - */ - -void skypopen_cleanup_module(void) -{ - int i; - int ret; - struct skypopen_listitem *lptr, *next; - dev_t devno = MKDEV(skypopen_major, skypopen_minor); - - - unload = 1; - - msleep(100); - - /* Get rid of our char dev entries */ - if (skypopen_devices) { - for (i = 0; i < skypopen_nr_devs; i++) { - cdev_del(&skypopen_devices[i].cdev); - } - kfree(skypopen_devices); - } - - /* And all the cloned devices */ - list_for_each_entry_safe(lptr, next, &skypopen_c_list, list) { -#ifndef WANT_HRTIMER - ret= del_timer( &lptr->device.timer_inq ); - printk( "Stopped skypopen OSS driver read timer\n"); - ret= del_timer( &lptr->device.timer_outq ); - printk( "Stopped skypopen OSS driver write timer\n"); -#else// WANT_HRTIMER - if(lptr->device.timer_inq_started){ - ret = hrtimer_cancel( &lptr->device.timer_inq ); - printk( "Stopped skypopen OSS driver read HRtimer\n"); - } - if(lptr->device.timer_outq_started){ - ret = hrtimer_cancel( &lptr->device.timer_outq ); - printk( "Stopped skypopen OSS driver write HRtimer\n"); - } - -#endif// WANT_HRTIMER - list_del(&lptr->list); - kfree(lptr); - } - /* cleanup_module is never called if registering failed */ - unregister_chrdev_region(devno, skypopen_nr_devs); - printk("skypopen OSS driver unloaded\n"); - -} - - -/* - * Set up the char_dev structure for this device. - */ -static void skypopen_setup_cdev(struct skypopen_dev *dev, int index) -{ - int err, devno = MKDEV(skypopen_major, skypopen_minor + index); - - cdev_init(&dev->cdev, &skypopen_fops); - dev->cdev.owner = THIS_MODULE; - dev->cdev.ops = &skypopen_fops; - err = cdev_add (&dev->cdev, devno, 1); - /* Fail gracefully if need be */ - if (err) - printk(KERN_NOTICE "Error %d adding skypopen%d", err, index); -} - - - -int skypopen_init_module(void) -{ - int result, i; - dev_t dev = 0; - - printk("skypopen OSS driver loading (www.freeswitch.org)\n"); - - /* - * Get a range of minor numbers to work with, asking for a dynamic - * major unless directed otherwise at load time. - */ - if (skypopen_major) { - dev = MKDEV(skypopen_major, skypopen_minor); - result = register_chrdev_region(dev, skypopen_nr_devs, "dsp"); - } else { - result = alloc_chrdev_region(&dev, skypopen_minor, skypopen_nr_devs, - "dsp"); - skypopen_major = MAJOR(dev); - } - if (result < 0) { - printk(KERN_WARNING "skypopen OSS driver: can't get major %d\n", skypopen_major); - return result; - } - - /* - * allocate the devices -- we can't have them static, as the number - * can be specified at load time - */ - skypopen_devices = kmalloc(skypopen_nr_devs * sizeof(struct skypopen_dev), GFP_KERNEL); - if (!skypopen_devices) { - result = -ENOMEM; - goto fail; /* Make this more graceful */ - } - memset(skypopen_devices, 0, skypopen_nr_devs * sizeof(struct skypopen_dev)); - - /* Initialize each device. */ - for (i = 0; i < skypopen_nr_devs; i++) { - skypopen_setup_cdev(&skypopen_devices[i], i); - } - - /* At this point call the init function for any friend device */ - dev = MKDEV(skypopen_major, skypopen_minor + skypopen_nr_devs); - return 0; /* succeed */ - -fail: - skypopen_cleanup_module(); - return result; -} - -module_init(skypopen_init_module); -module_exit(skypopen_cleanup_module); diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h deleted file mode 100644 index 3486bccdd1..0000000000 --- a/src/mod/endpoints/mod_skypopen/oss/skypopen.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * skypopen.h -- definitions for the char module - * - * Copyright (C) 2010 Giovanni Maruzzelli - * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet - * Copyright (C) 2001 O'Reilly & Associates - * - * The source code in this file can be freely used, adapted, - * and redistributed in source or binary form, so long as an - * acknowledgment appears in derived source files. The citation - * should list that the code comes from the book "Linux Device - * Drivers" by Alessandro Rubini and Jonathan Corbet, published - * by O'Reilly & Associates. No warranty is attached; - * we cannot take responsibility for errors or fitness for use. - * - * $Id: skypopen.h,v 1.15 2004/11/04 17:51:18 rubini Exp $ - */ - -#ifndef _SKYPOPEN_H_ -#define _SKYPOPEN_H_ - -#include -#include /* needed for the _IOW etc stuff used later */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -#include /* cli(), *_flags */ -#else -#include /* cli(), *_flags */ -#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) - - -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) -#define CENTOS_5 -#define WANT_HRTIMER /* undef this only if you don't want to use High Resolution Timers (why?) */ -#endif /* CentOS 5.x */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -#define WANT_HRTIMER -#endif /* HRTIMER */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) -#define WANT_DEFINE_SPINLOCK -#endif /* DEFINE_SPINLOCK */ - -#define SKYPOPEN_BLK 1920 -#define SKYPOPEN_SLEEP 20 - - -#define SKYPOPEN_MAJOR 14 /* dynamic major by default */ -#define SKYPOPEN_MINOR 3 /* dynamic major by default */ -#define SKYPOPEN_NR_DEVS 1 /* not useful, I'm too lazy to remove it */ - -#ifdef CENTOS_5 -#define HRTIMER_MODE_REL HRTIMER_REL -#endif// CENTOS_5 - -struct skypopen_dev { - struct cdev cdev; /* Char device structure */ - wait_queue_head_t inq; /* read and write queues */ - wait_queue_head_t outq; /* read and write queues */ -#ifndef WANT_HRTIMER - struct timer_list timer_inq; - struct timer_list timer_outq; -#else// WANT_HRTIMER - struct hrtimer timer_inq; - struct hrtimer timer_outq; -#endif// WANT_HRTIMER - int timer_inq_started; - int timer_outq_started; - int opened; -}; - - -/* - * The different configurable parameters - */ -extern int skypopen_major; /* main.c */ -extern int skypopen_nr_devs; - -#endif /* _SKYPOPEN_H_ */ diff --git a/src/mod/endpoints/mod_skypopen/skypopen.h b/src/mod/endpoints/mod_skypopen/skypopen.h deleted file mode 100644 index a38a42c915..0000000000 --- a/src/mod/endpoints/mod_skypopen/skypopen.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli - * - * Maintainer: Giovanni Maruzzelli - * - * mod_skypopen.c -- Skype compatible Endpoint Module - * - */ - - -#include - -#ifndef WIN32 -#include -#include -#include -#include - -// CLOUDTREE (Thomas Hazel) -#define XIO_ERROR_BY_SETJMP -//#define XIO_ERROR_BY_UCONTEXT - -// CLOUDTREE (Thomas Hazel) -#ifdef XIO_ERROR_BY_SETJMP -#include "setjmp.h" -#endif -// CLOUDTREE (Thomas Hazel) -#ifdef XIO_ERROR_BY_UCONTEXT -#include "ucontext.h" -#endif - -#endif //WIN32 - -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -#include -#include - -#ifndef WIN32 -#include -#endif - -#ifdef _MSC_VER -//Windows macro for FD_SET includes a warning C4127: conditional expression is constant -#pragma warning(push) -#pragma warning(disable:4127) -#endif - -#define MY_EVENT_INCOMING_CHATMESSAGE "skypopen::incoming_chatmessage" -#define MY_EVENT_INCOMING_RAW "skypopen::incoming_raw" - -#define SAMPLERATE_SKYPOPEN 16000 -#define MS_SKYPOPEN 20 -#define SAMPLES_PER_FRAME (SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN)) -#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * sizeof(short)) - -#ifndef SKYPOPEN_SVN_VERSION -#define SKYPOPEN_SVN_VERSION switch_version_full() -#endif /* SKYPOPEN_SVN_VERSION */ - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_PROGRESS = (1 << 7), - TFLAG_BREAK = (1 << 8) -} TFLAGS; - -typedef enum { - GFLAG_MY_CODEC_PREFS = (1 << 0) -} GFLAGS; - -#define DEBUGA_SKYPE(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%-*s [%s ] [DEBUG_SKYPE %-5d][%-15s][%s,%s] " __VA_ARGS__ ); -#define DEBUGA_CALL(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%-*s [%s ] [DEBUG_CALL %-5d][%-15s][%s,%s] " __VA_ARGS__ ); -#define DEBUGA_PBX(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%-*s [%s ] [DEBUG_PBX %-5d][%-15s][%s,%s] " __VA_ARGS__ ); -#define ERRORA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%-*s [%s ] [ERRORA %-5d][%-15s][%s,%s] " __VA_ARGS__ ); -#define WARNINGA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%-*s[%s ] [WARNINGA %-5d][%-15s][%s,%s] " __VA_ARGS__ ); -#define NOTICA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%-*s [%s ] [NOTICA %-5d][%-15s][%s,%s] " __VA_ARGS__ ); - -#define SKYPOPEN_P_LOG (int)((20 - (strlen(__FILE__))) + ((__LINE__ - 1000) < 0) + ((__LINE__ - 100) < 0)), " ", SKYPOPEN_SVN_VERSION, __LINE__, tech_pvt ? tech_pvt->name ? tech_pvt->name : "none" : "none", tech_pvt ? interface_status[tech_pvt->interface_state] : "N/A", tech_pvt ? skype_callflow[tech_pvt->skype_callflow] : "N/A" - -/*********************************/ -#define SKYPOPEN_CAUSE_NORMAL 1 -/*********************************/ -#define SKYPOPEN_FRAME_DTMF 1 -/*********************************/ -#define SKYPOPEN_CONTROL_RINGING 1 -#define SKYPOPEN_CONTROL_ANSWER 2 - -/*********************************/ -// CLOUDTREE (Thomas Hazel) -#define SKYPOPEN_RINGING_INIT 0 -#define SKYPOPEN_RINGING_PRE 1 - -/*********************************/ -#define SKYPOPEN_STATE_IDLE 0 -#define SKYPOPEN_STATE_DOWN 1 -#define SKYPOPEN_STATE_RING 2 -#define SKYPOPEN_STATE_DIALING 3 -#define SKYPOPEN_STATE_BUSY 4 -#define SKYPOPEN_STATE_UP 5 -#define SKYPOPEN_STATE_RINGING 6 -#define SKYPOPEN_STATE_PRERING 7 -#define SKYPOPEN_STATE_ERROR_DOUBLE_CALL 8 -#define SKYPOPEN_STATE_SELECTED 9 -#define SKYPOPEN_STATE_HANGUP_REQUESTED 10 -#define SKYPOPEN_STATE_PREANSWER 11 -#define SKYPOPEN_STATE_DEAD 12 -/*********************************/ -/* call flow from the device */ -#define CALLFLOW_CALL_IDLE 0 -#define CALLFLOW_CALL_DOWN 1 -#define CALLFLOW_INCOMING_RING 2 -#define CALLFLOW_CALL_DIALING 3 -#define CALLFLOW_CALL_LINEBUSY 4 -#define CALLFLOW_CALL_ACTIVE 5 -#define CALLFLOW_INCOMING_HANGUP 6 -#define CALLFLOW_CALL_RELEASED 7 -#define CALLFLOW_CALL_NOCARRIER 8 -#define CALLFLOW_CALL_INFLUX 9 -#define CALLFLOW_CALL_INCOMING 10 -#define CALLFLOW_CALL_FAILED 11 -#define CALLFLOW_CALL_NOSERVICE 12 -#define CALLFLOW_CALL_OUTGOINGRESTRICTED 13 -#define CALLFLOW_CALL_SECURITYFAIL 14 -#define CALLFLOW_CALL_NOANSWER 15 -#define CALLFLOW_STATUS_FINISHED 16 -#define CALLFLOW_STATUS_CANCELLED 17 -#define CALLFLOW_STATUS_FAILED 18 -#define CALLFLOW_STATUS_REFUSED 19 -#define CALLFLOW_STATUS_RINGING 20 -#define CALLFLOW_STATUS_INPROGRESS 21 -#define CALLFLOW_STATUS_UNPLACED 22 -#define CALLFLOW_STATUS_ROUTING 23 -#define CALLFLOW_STATUS_EARLYMEDIA 24 -#define CALLFLOW_INCOMING_CALLID 25 -#define CALLFLOW_STATUS_REMOTEHOLD 26 - -/*********************************/ - -#define SKYPOPEN_MAX_INTERFACES 64 - -#ifndef WIN32 -struct SkypopenHandles { - Window skype_win; - Display *disp; - Window win; - int currentuserhandle; - int api_connected; - int fdesc[2]; - - // CLOUDTREE (Thomas Hazel) -#ifdef XIO_ERROR_BY_SETJMP - jmp_buf ioerror_context; -#endif -#ifdef XIO_ERROR_BY_UCONTEXT - ucontext_t ioerror_context; -#endif - - // CLOUDTREE (Thomas Hazel) - is there a capable freeswitch list? - switch_bool_t managed; - void *prev; - void *next; -}; - -// CLOUDTREE (Thomas Hazel) - is there a capable freeswitch list? -struct SkypopenList { - int entries; - void *head; - void *tail; -}; - -// CLOUDTREE (Thomas Hazel) - is there a capable freeswitch list? -struct SkypopenHandles *skypopen_list_add(struct SkypopenList *list, struct SkypopenHandles *x); -struct SkypopenHandles *skypopen_list_find(struct SkypopenList *list, struct SkypopenHandles *x); -struct SkypopenHandles *skypopen_list_remove_by_value(struct SkypopenList *list, Display * display); -struct SkypopenHandles *skypopen_list_remove_by_reference(struct SkypopenList *list, struct SkypopenHandles *x); -int skypopen_list_size(struct SkypopenList *list); - -#else //WIN32 - -struct SkypopenHandles { - HWND win32_hInit_MainWindowHandle; - HWND win32_hGlobal_SkypeAPIWindowHandle; - HINSTANCE win32_hInit_ProcessHandle; - char win32_acInit_WindowClassName[128]; - UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach; - UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover; - int currentuserhandle; - int api_connected; - switch_file_t *fdesc[2]; -}; -#endif //WIN32 - -#define MAX_CHATS 10 - -struct chat { - char chatname[256]; - char dialog_partner[256]; -}; -typedef struct chat chat_t; - -#define MAX_CHATMESSAGES 10 - -struct chatmessage { - char id[256]; - char type[256]; - char chatname[256]; - char from_handle[256]; - char from_dispname[256]; - char body[512]; -}; -typedef struct chatmessage chatmessage_t; -struct private_object { - unsigned int flags; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_frame_t read_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - char session_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_caller_profile_t *caller_profile; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - - char interface_id[80]; - char name[80]; - char dialplan[80]; - char context[80]; - char dial_regex[256]; - char fail_dial_regex[256]; - char hold_music[256]; - char type[256]; - char X11_display[256]; -#ifdef WIN32 - unsigned short tcp_cli_port; - unsigned short tcp_srv_port; -#else - int tcp_cli_port; - int tcp_srv_port; -#endif - struct SkypopenHandles SkypopenHandles; - - // CLOUDTREE (Thomas Hazel) - char ringing_state; - - int interface_state; - char language[80]; - char exten[80]; - int skypopen_sound_rate; - char callid_name[50]; - char callid_number[50]; - double playback_boost; - double capture_boost; - int stripmsd; - char skype_call_id[512]; - int skype_call_ongoing; - char skype_friends[4096]; - char skype_fullname[512]; - char skype_displayname[512]; - int skype_callflow; - int skype; - int control_to_send; -#ifdef WIN32 - switch_file_t *audiopipe_srv[2]; - switch_file_t *audiopipe_cli[2]; - switch_file_t *skypopen_sound_capt_fd; -#else /* WIN32 */ - int audiopipe_srv[2]; - int audiopipe_cli[2]; - int skypopen_sound_capt_fd; -#endif /* WIN32 */ - switch_thread_t *tcp_srv_thread; - switch_thread_t *tcp_cli_thread; - switch_thread_t *skypopen_signaling_thread; - switch_thread_t *skypopen_api_thread; - short audiobuf[SAMPLES_PER_FRAME]; - int audiobuf_is_loaded; - short audiobuf_cli[SAMPLES_PER_FRAME]; - switch_mutex_t *mutex_audio_cli; - int flag_audio_cli; - short audiobuf_srv[SAMPLES_PER_FRAME]; - switch_mutex_t *mutex_audio_srv; - int flag_audio_srv; - switch_mutex_t *mutex_thread_audio_cli; - switch_mutex_t *mutex_thread_audio_srv; - - FILE *phonebook_writing_fp; - int skypopen_dir_entry_extension_prefix; - char skype_user[256]; - char initial_skype_user[256]; - char skype_password[256]; - char destination[256]; - struct timeval answer_time; - struct timeval ring_time; - - struct timeval transfer_time; - char transfer_callid_number[50]; - char skype_transfer_call_id[512]; - int running; - uint32_t ib_calls; - uint32_t ob_calls; - uint32_t ib_failed_calls; - uint32_t ob_failed_calls; - - chatmessage_t chatmessages[MAX_CHATMESSAGES]; - chat_t chats[MAX_CHATS]; - uint32_t report_incoming_chatmessages; - switch_timer_t timer_read; - switch_timer_t timer_read_srv; - switch_timer_t timer_write; - int begin_to_write; - int begin_to_read; - dtmf_rx_state_t dtmf_state; - switch_time_t old_dtmf_timestamp; - switch_buffer_t *write_buffer; - switch_buffer_t *read_buffer; - int silent_mode; - int write_silence_when_idle; - int setsockopt; - char answer_id[256]; - char answer_value[256]; - char ring_id[256]; - char ring_value[256]; - - char message[4096]; - char skype_voicemail_id[512]; - char skype_voicemail_id_greeting[512]; -}; - -typedef struct private_object private_t; - -void *SWITCH_THREAD_FUNC skypopen_api_thread_func(switch_thread_t *thread, void *obj); -int skypopen_audio_read(private_t *tech_pvt); -int skypopen_audio_init(private_t *tech_pvt); -int skypopen_signaling_write(private_t *tech_pvt, char *msg_to_skype); -int skypopen_signaling_read(private_t *tech_pvt); - -int skypopen_call(private_t *tech_pvt, char *idest, int timeout); -int skypopen_senddigit(private_t *tech_pvt, char digit); - -void *skypopen_do_tcp_srv_thread_func(void *obj); -void *SWITCH_THREAD_FUNC skypopen_do_tcp_srv_thread(switch_thread_t *thread, void *obj); - -void *skypopen_do_tcp_cli_thread_func(void *obj); -void *SWITCH_THREAD_FUNC skypopen_do_tcp_cli_thread(switch_thread_t *thread, void *obj); - -void *skypopen_do_skypeapi_thread_func(void *obj); -void *SWITCH_THREAD_FUNC skypopen_do_skypeapi_thread(switch_thread_t *thread, void *obj); -int dtmf_received(private_t *tech_pvt, char *value); -int start_audio_threads(private_t *tech_pvt); -int new_inbound_channel(private_t *tech_pvt); -int outbound_channel_answered(private_t *tech_pvt); -int skypopen_signaling_write(private_t *tech_pvt, char *msg_to_skype); -#if defined(WIN32) && !defined(__CYGWIN__) -int skypopen_pipe_read(switch_file_t *pipe, short *buf, int howmany); -int skypopen_pipe_write(switch_file_t *pipe, short *buf, int howmany); -/* Visual C do not have strsep ? */ -char *strsep(char **stringp, const char *delim); -#else -int skypopen_pipe_read(int pipe, short *buf, int howmany); -int skypopen_pipe_write(int pipe, short *buf, int howmany); -#endif /* WIN32 */ -int skypopen_close_socket(unsigned int fd); -private_t *find_available_skypopen_interface_rr(private_t *tech_pvt_calling); -int remote_party_is_ringing(private_t *tech_pvt); -int remote_party_is_early_media(private_t *tech_pvt); -int skypopen_answer(private_t *tech_pvt); -int skypopen_transfer(private_t *tech_pvt); -#ifndef WIN32 -int skypopen_socket_create_and_bind(private_t *tech_pvt, int *which_port); -#else -int skypopen_socket_create_and_bind(private_t *tech_pvt, unsigned short *which_port); -#endif //WIN32 -int incoming_chatmessage(private_t *tech_pvt, int which); -int next_port(void); -int skypopen_partner_handle_ring(private_t *tech_pvt); -int skypopen_answered(private_t *tech_pvt); -int inbound_channel_answered(private_t *tech_pvt); diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c deleted file mode 100644 index d001af16ab..0000000000 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ /dev/null @@ -1,2197 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli - * - * Maintainer: Giovanni Maruzzelli - * - * skypopen_protocol.c -- Low Level Interface for mod_skypopen - * - */ - - -#include "skypopen.h" - -#ifdef ASTERISK -#define skypopen_sleep usleep -#define skypopen_strncpy strncpy -#define tech_pvt p -extern int skypopen_debug; -extern char *skypopen_console_active; -#else /* FREESWITCH */ -#define skypopen_sleep switch_sleep -#define skypopen_strncpy switch_copy_string -extern switch_memory_pool_t *skypopen_module_pool; -extern switch_endpoint_interface_t *skypopen_endpoint_interface; -#endif /* ASTERISK */ -int samplerate_skypopen = SAMPLERATE_SKYPOPEN; - -extern int running; -extern char *interface_status[]; -extern char *skype_callflow[]; - -/*************************************/ -/* suspicious globals FIXME */ -#ifdef WIN32 -DWORD win32_dwThreadId; -#else - -// CLOUDTREE (Thomas Hazel) -static int global_x_error = Success; -extern struct SkypopenList global_handles_list; -extern switch_status_t remove_interface(char *the_interface, switch_bool_t force); - -#endif /* WIN32 */ -/*************************************/ -#ifndef WIN32 -int skypopen_socket_create_and_bind(private_t *tech_pvt, int *which_port) -#else -int skypopen_socket_create_and_bind(private_t *tech_pvt, unsigned short *which_port) -#endif //WIN32 -{ - int s = -1; - struct sockaddr_in my_addr; -#ifndef WIN32 - int start_port = 6001; - unsigned int size = sizeof(int); -#else - unsigned short start_port = 6001; - int size = sizeof(int); -#endif //WIN32 - int sockbufsize = 0; - int flag = 0; - - - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sin_family = AF_INET; - my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ - - if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ERRORA("socket Error\n", SKYPOPEN_P_LOG); - return -1; - } - - if (*which_port != 0) - start_port = *which_port; -#ifdef WIN32 - start_port = (unsigned short) next_port(); -#else - start_port = (unsigned short) next_port(); -#endif - my_addr.sin_port = htons(start_port); - *which_port = start_port; - while (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { - DEBUGA_SKYPE("*which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPOPEN_P_LOG, *which_port, tech_pvt->tcp_cli_port, - tech_pvt->tcp_srv_port); - DEBUGA_SKYPE("bind errno=%d, error: %s\n", SKYPOPEN_P_LOG, errno, strerror(errno)); - start_port++; - my_addr.sin_port = htons(start_port); - *which_port = start_port; - DEBUGA_SKYPE("*which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPOPEN_P_LOG, *which_port, tech_pvt->tcp_cli_port, - tech_pvt->tcp_srv_port); - - if (start_port > 65000) { - ERRORA("NO MORE PORTS! *which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPOPEN_P_LOG, *which_port, - tech_pvt->tcp_cli_port, tech_pvt->tcp_srv_port); - return -1; - } - } - - DEBUGA_SKYPE("Binded! *which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPOPEN_P_LOG, *which_port, tech_pvt->tcp_cli_port, - tech_pvt->tcp_srv_port); - - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("1 SO_RCVBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("1 SO_SNDBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - - - -#ifdef WIN32 - sockbufsize = SAMPLES_PER_FRAME * 8; -#else - sockbufsize = SAMPLES_PER_FRAME * 8; -#endif //WIN32 - size = sizeof(int); - if (tech_pvt->setsockopt) { - setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, size); - } - - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("2 SO_RCVBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - -#ifdef WIN32 - sockbufsize = SAMPLES_PER_FRAME * 8; -#else - sockbufsize = SAMPLES_PER_FRAME * 8; -#endif //WIN32 - size = sizeof(int); - if (tech_pvt->setsockopt) { - setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, size); - } - - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("2 SO_SNDBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - - flag = 0; - getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, &size); - DEBUGA_SKYPE("TCP_NODELAY is %d\n", SKYPOPEN_P_LOG, flag); - flag = 1; - if (tech_pvt->setsockopt) { - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, size); - } - flag = 0; - getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, &size); - DEBUGA_SKYPE("TCP_NODELAY is %d\n", SKYPOPEN_P_LOG, flag); - - - - - return s; -} - -int skypopen_signaling_read(private_t *tech_pvt) -{ - char read_from_pipe[4096]; - char message[4096]; - char message_2[4096]; - char *buf, obj[512] = "", id[512] = "", prop[512] = "", value[512] = "", *where; - char **stringp = NULL; - int a; - unsigned int howmany; - unsigned int i; - - memset(read_from_pipe, 0, 4096); - memset(message, 0, 4096); - memset(message_2, 0, 4096); - - howmany = skypopen_pipe_read(tech_pvt->SkypopenHandles.fdesc[0], (short *) read_from_pipe, sizeof(read_from_pipe)); - - a = 0; - for (i = 0; i < howmany; i++) { - message[a] = read_from_pipe[i]; - a++; - - if (read_from_pipe[i] == '\0') { - //if (!strstr(message, "DURATION")) { - DEBUGA_SKYPE("READING: |||%s||| \n", SKYPOPEN_P_LOG, message); - strncpy(tech_pvt->message, message, sizeof(tech_pvt->message)); - //} - if (!strcasecmp(message, "SILENT_MODE OFF")) { - if (tech_pvt->silent_mode) { - DEBUGA_SKYPE("Resetting SILENT_MODE on skype_call: %s.\n", SKYPOPEN_P_LOG, id); - skypopen_signaling_write(tech_pvt, "SET SILENT_MODE ON"); - //switch_sleep(1000); - } - } - if (!strcasecmp(message, "ERROR 68")) { - DEBUGA_SKYPE - ("If I don't connect immediately, please give the Skype client authorization to be connected by Skypopen (and to not ask you again)\n", - SKYPOPEN_P_LOG); - skypopen_sleep(1000000); - skypopen_signaling_write(tech_pvt, "PROTOCOL 999"); - skypopen_sleep(20000); - return 0; - } - if (!strncasecmp(message, "ERROR 92 CALL", 12)) { - ERRORA("Skype got ERROR: |||%s|||, the (skypeout) number we called was not recognized as valid\n", SKYPOPEN_P_LOG, message); - tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; - DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPOPEN_P_LOG); - tech_pvt->skype_call_id[0] = '\0'; - - if (tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - } - - if (!strncasecmp(message, "ERROR", 4)) { - if (!strncasecmp(message, "ERROR 96 CALL", 12)) { - DEBUGA_SKYPE - ("Skype got ERROR: |||%s|||, we are trying to use this interface to make or receive a call, but another call is half-active on this interface. Let's the previous one to continue.\n", - SKYPOPEN_P_LOG, message); - } else if (!strncasecmp(message, "ERROR 99 CALL", 12)) { - DEBUGA_SKYPE("Skype got ERROR: |||%s|||, another call is active on this interface\n\n\n", SKYPOPEN_P_LOG, message); - tech_pvt->interface_state = SKYPOPEN_STATE_ERROR_DOUBLE_CALL; - } else if (!strncasecmp(message, "ERROR 531 VOICEMAIL", 18)) { - NOTICA("Skype got ERROR about VOICEMAIL, no problem: |||%s|||\n", SKYPOPEN_P_LOG, message); - } else if (!strncasecmp(message, "ERROR 529 VOICEMAIL", 18)) { - NOTICA("Skype got ERROR about VOICEMAIL, no problem: |||%s|||\n", SKYPOPEN_P_LOG, message); - } else if (!strncasecmp(message, "ERROR 592 ALTER CALL", 19)) { - NOTICA("Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n", SKYPOPEN_P_LOG, message); - } else if (!strncasecmp(message, "ERROR 559 CALL", 13) | !strncasecmp(message, "ERROR 556 CALL", 13)) { - if (tech_pvt->interface_state == SKYPOPEN_STATE_PREANSWER) { - DEBUGA_SKYPE("Skype got ERROR about a failed action (probably TRYING to ANSWER A CALL), let's go down: |||%s|||\n", SKYPOPEN_P_LOG, - message); - tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; - DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPOPEN_P_LOG); - tech_pvt->skype_call_id[0] = '\0'; - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - - } else { - DEBUGA_SKYPE("Skype got ERROR about a failed action (probably TRYING to HANGUP A CALL), no problem: |||%s|||\n", SKYPOPEN_P_LOG, - message); - } - } else if (!strncasecmp(message, "ERROR 36 Not online", 18)) { - char msg_to_skype[256]; - ERRORA("Skype client is not online, eg: not connected to Skype network, probably got a temporary net outage: |||%s|||\n", - SKYPOPEN_P_LOG, message); - if (strlen(tech_pvt->skype_call_id)) { - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", tech_pvt->skype_call_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - if (strlen(tech_pvt->ring_id)) { - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", tech_pvt->ring_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else if (!strncasecmp(message, "ERROR 589 ALTER CALL", 19)) { - char msg_to_skype[256]; - DEBUGA_SKYPE("Skype client was not able to correctly manage tcp audio sockets, probably got a local or remote hangup: |||%s|||\n", - SKYPOPEN_P_LOG, message); - if (strlen(tech_pvt->skype_call_id)) { - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", tech_pvt->skype_call_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - if (strlen(tech_pvt->ring_id)) { - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", tech_pvt->ring_id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - ERRORA("Skype got ERROR: |||%s|||\n", SKYPOPEN_P_LOG, message); - tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; - ERRORA("skype_call now is DOWN\n", SKYPOPEN_P_LOG); - tech_pvt->skype_call_id[0] = '\0'; - - if (tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - } - } - - skypopen_strncpy(message_2, message, sizeof(message) - 1); - buf = message; - stringp = &buf; - where = strsep(stringp, " "); - if (!where) { - WARNINGA("Skype MSG without spaces: %s\n", SKYPOPEN_P_LOG, message); - } - - if (!strcasecmp(message, "CURRENTUSERHANDLE")) { - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - if (!strcasecmp(id, tech_pvt->skype_user)) { - tech_pvt->SkypopenHandles.currentuserhandle = 1; - DEBUGA_SKYPE - ("Skype MSG: message: %s, currentuserhandle: %s, cuh: %s, skype_user: %s!\n", - SKYPOPEN_P_LOG, message, obj, id, tech_pvt->skype_user); - } - } - if (!strcasecmp(message, "USER")) { - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(prop, where, sizeof(prop) - 1); - if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) { - char msg_to_skype[256]; - DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n", SKYPOPEN_P_LOG, message, obj, id, prop); - sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } - if (!strcasecmp(message, "MESSAGE")) { - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(prop, where, sizeof(prop) - 1); - if (!strcasecmp(prop, "STATUS")) { - where = strsep(stringp, " "); - skypopen_strncpy(value, where, sizeof(value) - 1); - if (!strcasecmp(value, "RECEIVED")) { - char msg_to_skype[256]; - DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s value: %s!\n", SKYPOPEN_P_LOG, message, obj, id, prop, value); - //TODO: authomatically flag messages as read based on config param - sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } else if (!strcasecmp(prop, "BODY")) { - char msg_to_skype[256]; - DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n", SKYPOPEN_P_LOG, message, obj, id, prop); - //TODO: authomatically flag messages as read based on config param - sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } - if (!strcasecmp(message, "CHAT")) { - char msg_to_skype[256]; - int i; - int found; - - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(prop, where, sizeof(prop) - 1); - skypopen_strncpy(value, *stringp, sizeof(value) - 1); - - if (!strcasecmp(prop, "STATUS") && !strcasecmp(value, "DIALOG")) { - DEBUGA_SKYPE("CHAT %s is DIALOG\n", SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "GET CHAT %s DIALOG_PARTNER", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - - if (!strcasecmp(prop, "DIALOG_PARTNER")) { - DEBUGA_SKYPE("CHAT %s has DIALOG_PARTNER %s\n", SKYPOPEN_P_LOG, id, value); - found = 0; - for (i = 0; i < MAX_CHATS; i++) { - if (strlen(tech_pvt->chats[i].chatname) == 0 || !strcmp(tech_pvt->chats[i].chatname, id)) { - strncpy(tech_pvt->chats[i].chatname, id, sizeof(tech_pvt->chats[i].chatname)); - strncpy(tech_pvt->chats[i].dialog_partner, value, sizeof(tech_pvt->chats[i].dialog_partner)); - found = 1; - break; - } - } - if (!found) { - ERRORA("why we do not have a chats slot free? we have more than %d chats in parallel?\n", SKYPOPEN_P_LOG, MAX_CHATS); - } - - DEBUGA_SKYPE("CHAT %s is in position %d in the chats array, chatname=%s, dialog_partner=%s\n", SKYPOPEN_P_LOG, id, i, - tech_pvt->chats[i].chatname, tech_pvt->chats[i].dialog_partner); - } - - } - - - if (!strcasecmp(message, "CHATMESSAGE")) { - char msg_to_skype[256]; - int i; - int found; - - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(prop, where, sizeof(prop) - 1); - skypopen_strncpy(value, *stringp, sizeof(value) - 1); - - if (!tech_pvt->report_incoming_chatmessages) { - if (!strcasecmp(prop, "STATUS") && !strcasecmp(value, "RECEIVED")) { - sprintf(msg_to_skype, "SET CHATMESSAGE %s SEEN", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } else { - if (!strcasecmp(prop, "STATUS") && !strcasecmp(value, "RECEIVED")) { - DEBUGA_SKYPE("RECEIVED CHATMESSAGE %s, let's see which type it is\n", SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "GET CHATMESSAGE %s TYPE", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - - if (!strcasecmp(prop, "TYPE") && !strcasecmp(value, "SAID")) { - DEBUGA_SKYPE("CHATMESSAGE %s is of type SAID, let's get the other infos\n", SKYPOPEN_P_LOG, id); - found = 0; - for (i = 0; i < MAX_CHATMESSAGES; i++) { - if (strlen(tech_pvt->chatmessages[i].id) == 0) { - strncpy(tech_pvt->chatmessages[i].id, id, sizeof(tech_pvt->chatmessages[i].id)); - strncpy(tech_pvt->chatmessages[i].type, value, sizeof(tech_pvt->chatmessages[i].type)); - found = 1; - break; - } - } - if (!found) { - ERRORA("why we do not have a chatmessages slot free? we have more than %d chatmessages in parallel?\n", SKYPOPEN_P_LOG, - MAX_CHATMESSAGES); - } else { - DEBUGA_SKYPE("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s\n", SKYPOPEN_P_LOG, id, i, - tech_pvt->chatmessages[i].type, tech_pvt->chatmessages[i].id); - sprintf(msg_to_skype, "GET CHATMESSAGE %s CHATNAME", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(1000); - sprintf(msg_to_skype, "GET CHATMESSAGE %s FROM_HANDLE", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(1000); - sprintf(msg_to_skype, "GET CHATMESSAGE %s FROM_DISPNAME", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(1000); - sprintf(msg_to_skype, "GET CHATMESSAGE %s BODY", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } - - if (!strcasecmp(prop, "CHATNAME")) { - DEBUGA_SKYPE("CHATMESSAGE %s belongs to the CHAT %s\n", SKYPOPEN_P_LOG, id, value); - found = 0; - for (i = 0; i < MAX_CHATMESSAGES; i++) { - if (!strcmp(tech_pvt->chatmessages[i].id, id)) { - strncpy(tech_pvt->chatmessages[i].chatname, value, sizeof(tech_pvt->chatmessages[i].chatname)); - found = 1; - break; - } - } - if (!found) { - DEBUGA_SKYPE("why chatmessage %s was not found in the chatmessages array??\n", SKYPOPEN_P_LOG, id); - } - } - if (!strcasecmp(prop, "FROM_HANDLE")) { - DEBUGA_SKYPE("CHATMESSAGE %s was sent by FROM_HANDLE %s\n", SKYPOPEN_P_LOG, id, value); - found = 0; - for (i = 0; i < MAX_CHATMESSAGES; i++) { - if (!strcmp(tech_pvt->chatmessages[i].id, id)) { - strncpy(tech_pvt->chatmessages[i].from_handle, value, sizeof(tech_pvt->chatmessages[i].from_handle)); - found = 1; - break; - } - } - if (!found) { - DEBUGA_SKYPE("why chatmessage %s was not found in the chatmessages array??\n", SKYPOPEN_P_LOG, id); - } - - } - if (!strcasecmp(prop, "FROM_DISPNAME")) { - DEBUGA_SKYPE("CHATMESSAGE %s was sent by FROM_DISPNAME %s\n", SKYPOPEN_P_LOG, id, value); - found = 0; - for (i = 0; i < MAX_CHATMESSAGES; i++) { - if (!strcmp(tech_pvt->chatmessages[i].id, id)) { - strncpy(tech_pvt->chatmessages[i].from_dispname, value, sizeof(tech_pvt->chatmessages[i].from_dispname)); - found = 1; - break; - } - } - if (!found) { - DEBUGA_SKYPE("why chatmessage %s was not found in the chatmessages array??\n", SKYPOPEN_P_LOG, id); - } - - } - if (!strcasecmp(prop, "BODY")) { - DEBUGA_SKYPE("CHATMESSAGE %s has BODY %s\n", SKYPOPEN_P_LOG, id, value); - found = 0; - for (i = 0; i < MAX_CHATMESSAGES; i++) { - if (!strcmp(tech_pvt->chatmessages[i].id, id)) { - strncpy(tech_pvt->chatmessages[i].body, value, sizeof(tech_pvt->chatmessages[i].body)); - found = 1; - break; - } - } - if (!found) { - DEBUGA_SKYPE("why chatmessage %s was not found in the chatmessages array??\n", SKYPOPEN_P_LOG, id); - } else { - DEBUGA_SKYPE - ("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s\n", - SKYPOPEN_P_LOG, id, i, tech_pvt->chatmessages[i].type, tech_pvt->chatmessages[i].id, tech_pvt->chatmessages[i].chatname, - tech_pvt->chatmessages[i].from_handle, tech_pvt->chatmessages[i].from_dispname, tech_pvt->chatmessages[i].body); - if (strcmp(tech_pvt->chatmessages[i].from_handle, tech_pvt->skype_user)) { //if the message was not sent by myself - incoming_chatmessage(tech_pvt, i); - memset(&tech_pvt->chatmessages[i], '\0', sizeof(tech_pvt->chatmessages[i])); - - sprintf(msg_to_skype, "SET CHATMESSAGE %s SEEN", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } else { - DEBUGA_SKYPE - ("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s NOT DELETED\n", - SKYPOPEN_P_LOG, id, i, tech_pvt->chatmessages[i].type, tech_pvt->chatmessages[i].id, tech_pvt->chatmessages[i].chatname, - tech_pvt->chatmessages[i].from_handle, tech_pvt->chatmessages[i].from_dispname, tech_pvt->chatmessages[i].body); - memset(&tech_pvt->chatmessages[i], '\0', sizeof(tech_pvt->chatmessages[i])); - DEBUGA_SKYPE("chatmessage %s HAS BEEN DELETED\n", SKYPOPEN_P_LOG, id); - } - - } - - } - } - - } - - - if (!strcasecmp(message, "VOICEMAIL")) { - char msg_to_skype[1024]; - - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(prop, where, sizeof(prop) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(value, where, sizeof(value) - 1); - where = strsep(stringp, " "); - - //DEBUGA_SKYPE - //("Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n", - //SKYPOPEN_P_LOG, message, obj, id, prop, value, where ? where : "NULL"); - - if (!strcasecmp(prop, "STATUS") && !strcasecmp(value, "RECORDING") ) { - DEBUGA_SKYPE("VOICEMAIL %s INPUT\n", SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "ALTER VOICEMAIL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } else if (!strcasecmp(prop, "STATUS") && !strcasecmp(value, "PLAYING") ) { - DEBUGA_SKYPE("VOICEMAIL %s OUTPUT\n", SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "ALTER VOICEMAIL %s SET_OUTPUT PORT=\"%d\"", id, tech_pvt->tcp_srv_port); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(tech_pvt->skype_voicemail_id_greeting, "%s", id); - - } else if (!strcasecmp(prop, "TYPE") && !strcasecmp(value, "OUTGOING") ) { - DEBUGA_SKYPE("VOICEMAIL OUTGOING id is %s\n", SKYPOPEN_P_LOG, id); - sprintf(tech_pvt->skype_voicemail_id, "%s", id); - } else if (!strcasecmp(prop, "STATUS") && !strcasecmp(value, "PLAYED") ) { - //switch_ivr_broadcast( tech_pvt->session_uuid_str, "gentones::%(500,0,800)",SMF_ECHO_ALEG|SMF_ECHO_BLEG); - switch_ivr_broadcast( tech_pvt->session_uuid_str, "gentones::%(500,0,800)",SMF_ECHO_BLEG); - memset(tech_pvt->skype_voicemail_id_greeting, '\0', sizeof(tech_pvt->skype_voicemail_id_greeting)); - - } - } - - if (!strcasecmp(message, "CALL")) { - skypopen_strncpy(obj, where, sizeof(obj) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(id, where, sizeof(id) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(prop, where, sizeof(prop) - 1); - where = strsep(stringp, " "); - skypopen_strncpy(value, where, sizeof(value) - 1); - where = strsep(stringp, " "); - - //DEBUGA_SKYPE - //("Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n", - //SKYPOPEN_P_LOG, message, obj, id, prop, value, where ? where : "NULL"); - - if (!strcasecmp(prop, "PARTNER_HANDLE")) { - if (tech_pvt->interface_state == SKYPOPEN_STATE_IDLE) { - /* we are NOT inside an active call */ - DEBUGA_SKYPE("Call %s go to skypopen_partner_handle_ring\n", SKYPOPEN_P_LOG, id); - skypopen_strncpy(tech_pvt->ring_id, id, sizeof(tech_pvt->ring_id)); - skypopen_strncpy(tech_pvt->ring_value, value, sizeof(tech_pvt->ring_value)); - skypopen_strncpy(tech_pvt->answer_id, id, sizeof(tech_pvt->answer_id)); - skypopen_strncpy(tech_pvt->answer_value, value, sizeof(tech_pvt->answer_value)); - skypopen_partner_handle_ring(tech_pvt); - } else { - /* we are inside an active call */ - if (!strcasecmp(tech_pvt->skype_call_id, id)) { - /* this is the call in which we are calling out */ - DEBUGA_SKYPE("Call %s DO NOTHING\n", SKYPOPEN_P_LOG, id); - } else { - DEBUGA_SKYPE("Call %s TRY TRANSFER\n", SKYPOPEN_P_LOG, id); - skypopen_strncpy(tech_pvt->ring_id, id, sizeof(tech_pvt->ring_id)); - skypopen_strncpy(tech_pvt->ring_value, value, sizeof(tech_pvt->ring_value)); - skypopen_strncpy(tech_pvt->answer_id, id, sizeof(tech_pvt->answer_id)); - skypopen_strncpy(tech_pvt->answer_value, value, sizeof(tech_pvt->answer_value)); - skypopen_transfer(tech_pvt); - } - } - } - if (!strcasecmp(prop, "PARTNER_DISPNAME")) { - snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s", value, where ? " " : "", where ? where : ""); - } - if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) { - } - if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) { - DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPOPEN_P_LOG, id); - } - if (!strcasecmp(prop, "DTMF")) { - DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPOPEN_P_LOG, id, value); - dtmf_received(tech_pvt, value); - } - if (!strcasecmp(prop, "FAILUREREASON")) { - DEBUGA_SKYPE("Skype FAILED on skype_call %s. Let's wait for the FAILED message.\n", SKYPOPEN_P_LOG, id); - } -#if 0 -#ifndef WIN32 - if (!strcasecmp(prop, "DURATION")) { /* each 20 seconds, we zero the buffers and sync the timers */ - if (!((atoi(value) % 20))) { - if (tech_pvt->read_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_srv); - switch_buffer_zero(tech_pvt->read_buffer); - if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read); - } - if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_read_srv); - } - switch_mutex_unlock(tech_pvt->mutex_audio_srv); - } - - if (tech_pvt->write_buffer) { - switch_mutex_lock(tech_pvt->mutex_audio_cli); - switch_buffer_zero(tech_pvt->write_buffer); - if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { - switch_core_timer_sync(&tech_pvt->timer_write); - } - switch_mutex_unlock(tech_pvt->mutex_audio_cli); - } - DEBUGA_SKYPE("Synching audio on skype_call: %s.\n", SKYPOPEN_P_LOG, id); - } - } -#endif //WIN32 -#endif //0 - if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) { - if (strcasecmp(id, tech_pvt->skype_call_id)) { - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("We called a Skype contact and he answered us on skype_call: %s.\n", SKYPOPEN_P_LOG, id); - } - } - - if (!strcasecmp(prop, "DURATION") && (tech_pvt->interface_state == SKYPOPEN_STATE_ERROR_DOUBLE_CALL)) { - char msg_to_skype[1024]; - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - WARNINGA("We are in a double call situation, trying to get out hanging up call id: %s.\n", SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(10000); - } - - - if (!strcasecmp(prop, "VM_DURATION") && (!strcasecmp(value, "0"))) { - char msg_to_skype[1024]; - - NOTICA("We called a Skype contact and he started Skype voicemail on our skype_call: %s.\n", SKYPOPEN_P_LOG, id); - - if (!strlen(tech_pvt->session_uuid_str)) { - DEBUGA_SKYPE("no tech_pvt->session_uuid_str\n", SKYPOPEN_P_LOG); - } - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id) - || !strcasecmp(tech_pvt->skype_call_id, id)) { - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPOPEN_P_LOG, id); - - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - tech_pvt->interface_state = SKYPOPEN_STATE_UP; - - if (tech_pvt->tcp_cli_thread == NULL) { - DEBUGA_SKYPE("START start_audio_threads\n", SKYPOPEN_P_LOG); - if (start_audio_threads(tech_pvt)) { - WARNINGA("start_audio_threads FAILED\n", SKYPOPEN_P_LOG); - return CALLFLOW_INCOMING_HANGUP; - } - } - } - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - if (skypopen_answered(tech_pvt) != SWITCH_STATUS_SUCCESS) { - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } else { - DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id); - } - } else { - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - DEBUGA_SKYPE("Back from REMOTEHOLD!\n", SKYPOPEN_P_LOG); - } - } - - if (!strcasecmp(prop, "STATUS")) { - - if (!strcasecmp(value, "RINGING")) { - char msg_to_skype[1024]; - if (tech_pvt->interface_state == SKYPOPEN_STATE_IDLE) { - // CLOUDTREE (Thomas Hazel) - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - - /* we are NOT inside an active call */ - DEBUGA_SKYPE("NO ACTIVE calls in this moment, skype_call %s is RINGING, to ask PARTNER_DISPNAME and PARTNER_HANDLE\n", - SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(100); - sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(10000); - } else { - /* we are inside an active call */ - if (!strcasecmp(tech_pvt->skype_call_id, id)) { - // CLOUDTREE (Thomas Hazel) - tech_pvt->ringing_state = SKYPOPEN_RINGING_PRE; - - /* this is the call in which we are calling out */ - tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; - tech_pvt->interface_state = SKYPOPEN_STATE_RINGING; - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n", SKYPOPEN_P_LOG, id); - if (remote_party_is_ringing(tech_pvt) != SWITCH_STATUS_SUCCESS) { - DEBUGA_SKYPE - ("We are getting the RINGING from a call we probably canceled, trying to get out hanging up call id: %s.\n", - SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - tech_pvt->skype_call_id[0] = '\0'; - // CLOUDTREE (Thomas Hazel) - tech_pvt->ringing_state = SKYPOPEN_RINGING_INIT; - tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE; - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - DEBUGA_SKYPE("we're now DOWN\n", SKYPOPEN_P_LOG); - return CALLFLOW_INCOMING_HANGUP; - - } - } else { - DEBUGA_SKYPE - ("We are in another call, but skype_call %s is RINGING on us, let's ask PARTNER_HANDLE, so maybe we'll TRANSFER\n", - SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(10000); - } - } - } else if (!strcasecmp(value, "EARLYMEDIA")) { - char msg_to_skype[1024]; - tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA; - tech_pvt->interface_state = SKYPOPEN_STATE_DIALING; - DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n", SKYPOPEN_P_LOG, id); - if (tech_pvt->tcp_cli_thread == NULL) { - DEBUGA_SKYPE("START start_audio_threads\n", SKYPOPEN_P_LOG); - if (start_audio_threads(tech_pvt)) { - ERRORA("start_audio_threads FAILED\n", SKYPOPEN_P_LOG); - return CALLFLOW_INCOMING_HANGUP; - } - } - //skypopen_sleep(1000); - sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(1000); - sprintf(msg_to_skype, "#output ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, tech_pvt->tcp_srv_port); - skypopen_signaling_write(tech_pvt, msg_to_skype); - - remote_party_is_early_media(tech_pvt); - } else if (!strcasecmp(value, "MISSED") || !strcasecmp(value, "FINISHED")) { - if (!strcasecmp(tech_pvt->skype_call_id, id)) { - DEBUGA_SKYPE("skype_call %s is MY call, now I'm going DOWN\n", SKYPOPEN_P_LOG, id); - if (tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED) { - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - } else { - DEBUGA_SKYPE("skype_call %s is NOT MY call, ignoring\n", SKYPOPEN_P_LOG, id); - } - - } else if (!strcasecmp(value, "CANCELLED")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED; - DEBUGA_SKYPE("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n", SKYPOPEN_P_LOG, id); - tech_pvt->skype_call_id[0] = '\0'; - if (tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED) { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - } - } else if (!strcasecmp(value, "FAILED")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED; - DEBUGA_SKYPE("we tried to call Skype on skype_call %s and Skype has now FAILED\n", SKYPOPEN_P_LOG, id); - tech_pvt->skype_call_id[0] = '\0'; - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else if (!strcasecmp(value, "REFUSED")) { - if (!strcasecmp(id, tech_pvt->skype_call_id)) { - /* this is the id of the call we are in, probably we generated it */ - tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED; - DEBUGA_SKYPE("we tried to call Skype on skype_call %s and Skype has now REFUSED\n", SKYPOPEN_P_LOG, id); - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - tech_pvt->skype_call_id[0] = '\0'; - return CALLFLOW_INCOMING_HANGUP; - } else { - /* we're here because were us that refused an incoming call */ - DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPOPEN_P_LOG, id); - } - } else if (!strcasecmp(value, "TRANSFERRING")) { - DEBUGA_SKYPE("skype_call %s is transferring\n", SKYPOPEN_P_LOG, id); - } else if (!strcasecmp(value, "TRANSFERRED")) { - DEBUGA_SKYPE("skype_call %s has been transferred\n", SKYPOPEN_P_LOG, id); - } else if (!strcasecmp(value, "ROUTING")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING; - tech_pvt->interface_state = SKYPOPEN_STATE_DIALING; - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPOPEN_P_LOG, id); - } else if (!strcasecmp(value, "UNPLACED")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED; - tech_pvt->interface_state = SKYPOPEN_STATE_DIALING; - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPOPEN_P_LOG, id); - } else if (!strcasecmp(value, "INPROGRESS")) { - char msg_to_skype[1024]; - - if (!strlen(tech_pvt->session_uuid_str)) { - DEBUGA_SKYPE("no tech_pvt->session_uuid_str\n", SKYPOPEN_P_LOG); - } - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id) - || !strcasecmp(tech_pvt->skype_call_id, id)) { - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPOPEN_P_LOG, id); - - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - tech_pvt->interface_state = SKYPOPEN_STATE_UP; - - if (tech_pvt->tcp_cli_thread == NULL) { - DEBUGA_SKYPE("START start_audio_threads\n", SKYPOPEN_P_LOG); - if (start_audio_threads(tech_pvt)) { - WARNINGA("start_audio_threads FAILED\n", SKYPOPEN_P_LOG); - return CALLFLOW_INCOMING_HANGUP; - } - } - //skypopen_sleep(1000); - sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port); - skypopen_signaling_write(tech_pvt, msg_to_skype); - //skypopen_sleep(1000); - sprintf(msg_to_skype, "#output ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, tech_pvt->tcp_srv_port); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - if (skypopen_answered(tech_pvt) != SWITCH_STATUS_SUCCESS) { - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } - } else { - DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id); - } - } else { - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - DEBUGA_SKYPE("Back from REMOTEHOLD!\n", SKYPOPEN_P_LOG); - } - - } else if (!strcasecmp(value, "LOCALHOLD")) { - char msg_to_skype[256]; - DEBUGA_SKYPE("skype_call: %s is now LOCALHOLD, let's hangup\n", SKYPOPEN_P_LOG, id); - sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } else if (!strcasecmp(value, "REMOTEHOLD")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_REMOTEHOLD; - DEBUGA_SKYPE("skype_call: %s is now REMOTEHOLD\n", SKYPOPEN_P_LOG, id); - - } else if (!strcasecmp(value, "BUSY")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED; - DEBUGA_SKYPE - ("we tried to call Skype on skype_call %s and remote party (destination) was BUSY. Our outbound call has failed\n", - SKYPOPEN_P_LOG, id); - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - tech_pvt->skype_call_id[0] = '\0'; - //skypopen_sleep(1000); - return CALLFLOW_INCOMING_HANGUP; - } else if (!strcasecmp(value, "WAITING_REDIAL_COMMAND")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED; - DEBUGA_SKYPE - ("we tried to call Skype on skype_call %s and remote party (destination) has rejected us (WAITING_REDIAL_COMMAND). Our outbound call has failed\n", - SKYPOPEN_P_LOG, id); - skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPOPEN_STATE_DOWN; - tech_pvt->skype_call_id[0] = '\0'; - //skypopen_sleep(1000); - return CALLFLOW_INCOMING_HANGUP; - } else if (!strncmp(value, "VM_", 2)) { - DEBUGA_SKYPE ("Our skype_call %s is in Skype voicemail: %s\n", SKYPOPEN_P_LOG, id, value); - } else { - WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPOPEN_P_LOG, id, value); - } - } //STATUS - } //CALL - /* the "numbered" messages that follows are used by the directory application, not yet ported */ - if (!strcasecmp(message, "#333")) { - memset(tech_pvt->skype_friends, 0, 4096); - skypopen_strncpy(tech_pvt->skype_friends, &message_2[11], 4095); - } - if (!strcasecmp(message, "#222")) { - memset(tech_pvt->skype_fullname, 0, 512); - skypopen_strncpy(tech_pvt->skype_fullname, &message_2[10], 511); - } - if (!strcasecmp(message, "#765")) { - memset(tech_pvt->skype_displayname, 0, 512); - skypopen_strncpy(tech_pvt->skype_displayname, &message_2[10], 511); - } - a = 0; - } //message end - } //read_from_pipe - return 0; -} - -void *skypopen_do_tcp_srv_thread_func(void *obj) -{ - private_t *tech_pvt = obj; - int s; - unsigned int len; -#if defined(WIN32) && !defined(__CYGWIN__) - int sin_size; - int size = sizeof(int); -#else /* WIN32 */ - unsigned int sin_size; - unsigned int size = sizeof(int); -#endif /* WIN32 */ - unsigned int fd; - short srv_in[SAMPLES_PER_FRAME * 10]; - struct sockaddr_in remote_addr; - int sockbufsize = 0; - - s = skypopen_socket_create_and_bind(tech_pvt, &tech_pvt->tcp_srv_port); - if (s < 0) { - ERRORA("skypopen_socket_create_and_bind error!\n", SKYPOPEN_P_LOG); - return NULL; - } - DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPOPEN_P_LOG); - - listen(s, 6); - - sin_size = sizeof(remote_addr); - - while (tech_pvt && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN - && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA - || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { - - unsigned int fdselectgio; - int rtgio; - fd_set fsgio; - struct timeval togio; - - if (!(running && tech_pvt->running)) - break; - FD_ZERO(&fsgio); - togio.tv_usec = MS_SKYPOPEN * 1000; - togio.tv_sec = 0; - fdselectgio = s; - FD_SET(fdselectgio, &fsgio); - - rtgio = select(fdselectgio + 1, &fsgio, NULL, NULL, &togio); - - if (rtgio) { - - while (s > 0 && (fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) { - DEBUGA_SKYPE("ACCEPTED here I send you %d\n", SKYPOPEN_P_LOG, tech_pvt->tcp_srv_port); - - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("3 SO_RCVBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("3 SO_SNDBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - - - if (!(running && tech_pvt->running)) - break; - while (tech_pvt && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN - && tech_pvt->interface_state != SKYPOPEN_STATE_IDLE - && tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED - && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA - || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { - - unsigned int fdselect; - int rt = 1; - fd_set fs; - struct timeval to; - int nospace; - - if (!(running && tech_pvt->running)) - break; -#if 1 - fdselect = fd; - FD_ZERO(&fs); - FD_SET(fdselect, &fs); - to.tv_usec = MS_SKYPOPEN * 1000 * 3; - to.tv_sec = 0; -#endif //0 - - if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { - switch_core_timer_next(&tech_pvt->timer_read_srv); - } else { - skypopen_sleep(20000); - - } - rt = select(fdselect + 1, &fs, NULL, NULL, &to); - if (rt > 0) { - - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - len = recv(fd, (char *) srv_in, BYTES_PER_FRAME * 2, 0); - } else { - //skypopen_sleep(10000); - continue; - } - if (tech_pvt->begin_to_read == 0) { - DEBUGA_SKYPE("len=%d\n", SKYPOPEN_P_LOG, len); - //skypopen_sleep(10000); - continue; - } - - if (len == -1) { - DEBUGA_SKYPE("len=%d, error: %s\n", SKYPOPEN_P_LOG, len, strerror(errno)); - break; - } - nospace = 0; - if (len > 0) { - switch_mutex_lock(tech_pvt->mutex_audio_srv); - if (tech_pvt->read_buffer) { - if (switch_buffer_freespace(tech_pvt->read_buffer) < len) { - switch_buffer_zero(tech_pvt->read_buffer); - switch_buffer_write(tech_pvt->read_buffer, srv_in, len); - nospace = 1; - } else { - switch_buffer_write(tech_pvt->read_buffer, srv_in, len); - } - } - switch_mutex_unlock(tech_pvt->mutex_audio_srv); - if (nospace) { - DEBUGA_SKYPE("NO SPACE in READ BUFFER: there was no space for: %d\n", SKYPOPEN_P_LOG, len); - } - } else if (len == 0) { - DEBUGA_SKYPE("CLOSED\n", SKYPOPEN_P_LOG); - break; - } else { - DEBUGA_SKYPE("len=%d\n", SKYPOPEN_P_LOG, len); - } - - } else if (rt == 0) { - continue; - } else { - DEBUGA_SKYPE("SRV rt=%d\n", SKYPOPEN_P_LOG, rt); - break; - } - - } - - DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPOPEN_P_LOG); - tech_pvt->skype_callflow = CALLFLOW_INCOMING_HANGUP; - skypopen_close_socket(fd); - break; - } - break; - } - } - - DEBUGA_SKYPE("incoming audio (read) server (I am it) EXITING\n", SKYPOPEN_P_LOG); - skypopen_close_socket(s); - s = -1; - //DEBUGA_SKYPE("debugging_hangup PRE srv lock\n", SKYPOPEN_P_LOG); - switch_mutex_lock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv lock\n", SKYPOPEN_P_LOG); - tech_pvt->tcp_srv_thread = NULL; - switch_mutex_unlock(tech_pvt->mutex_thread_audio_srv); - //DEBUGA_SKYPE("debugging_hangup srv unlock\n", SKYPOPEN_P_LOG); - return NULL; -} - -void *skypopen_do_tcp_cli_thread_func(void *obj) -{ - private_t *tech_pvt = obj; - int s; - struct sockaddr_in remote_addr; - unsigned int len; - unsigned int fd; - short cli_out[SAMPLES_PER_FRAME * 2 * 10]; -#ifdef WIN32 - int sin_size; - int size = sizeof(int); -#else - unsigned int sin_size; - unsigned int size = sizeof(int); -#endif /* WIN32 */ - int sockbufsize = 0; - - s = skypopen_socket_create_and_bind(tech_pvt, &tech_pvt->tcp_cli_port); - if (s < 0) { - ERRORA("skypopen_socket_create_and_bind error!\n", SKYPOPEN_P_LOG); - return NULL; - } - - - - DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPOPEN_P_LOG); - - listen(s, 6); - - sin_size = sizeof(remote_addr); - - while (tech_pvt && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN - && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA - || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { - - unsigned int fdselectgio; - int rtgio; - fd_set fsgio; - struct timeval togio; - - if (!(running && tech_pvt->running)) - break; - FD_ZERO(&fsgio); - togio.tv_usec = MS_SKYPOPEN * 1000 * 3; - togio.tv_sec = 0; - fdselectgio = s; - FD_SET(fdselectgio, &fsgio); - - rtgio = select(fdselectgio + 1, &fsgio, NULL, NULL, &togio); - - if (rtgio) { - - while (s > 0 && (fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) { - DEBUGA_SKYPE("ACCEPTED here you send me %d\n", SKYPOPEN_P_LOG, tech_pvt->tcp_cli_port); - - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("4 SO_RCVBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - sockbufsize = 0; - size = sizeof(int); - getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, &size); - DEBUGA_SKYPE("4 SO_SNDBUF is %d, size is %d\n", SKYPOPEN_P_LOG, sockbufsize, size); - - - - if (!(running && tech_pvt->running)) - break; - while (tech_pvt && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN - && tech_pvt->interface_state != SKYPOPEN_STATE_IDLE - && tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED - && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA - || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { - size_t bytes_to_write; - - if (!(running && tech_pvt->running)) - break; - - if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next - && tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED) { - switch_core_timer_next(&tech_pvt->timer_write); - } else { - skypopen_sleep(20000); - } - - if (tech_pvt->begin_to_write == 0) { - memset(cli_out, 255, sizeof(cli_out)); - bytes_to_write = BYTES_PER_FRAME; - len = send(fd, (char *) cli_out, bytes_to_write, 0); - if (len == -1) { - DEBUGA_SKYPE("len=%d, error: %s\n", SKYPOPEN_P_LOG, len, strerror(errno)); - break; - } - //skypopen_sleep(10000); - continue; - } else { - - bytes_to_write = 0; - - if (tech_pvt->skype_callflow == CALLFLOW_INCOMING_HANGUP) { - break; - } - switch_mutex_lock(tech_pvt->mutex_audio_cli); - if (tech_pvt->write_buffer && switch_buffer_inuse(tech_pvt->write_buffer)) { - bytes_to_write = switch_buffer_read(tech_pvt->write_buffer, cli_out, BYTES_PER_FRAME); - } - switch_mutex_unlock(tech_pvt->mutex_audio_cli); - - if (!bytes_to_write) { - if (tech_pvt->write_silence_when_idle) { - memset(cli_out, 255, sizeof(cli_out)); - bytes_to_write = BYTES_PER_FRAME; - //DEBUGA_SKYPE("WRITE Silence!\n", SKYPOPEN_P_LOG); - } else { - continue; - } - } - /* send the 16khz frame to the Skype client waiting for incoming audio to be sent to the remote party */ - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - len = send(fd, (char *) cli_out, bytes_to_write, 0); - if (len == -1) { - DEBUGA_SKYPE("len=%d, error: %s\n", SKYPOPEN_P_LOG, len, strerror(errno)); - break; - } - if (len != bytes_to_write) { - DEBUGA_SKYPE("len=%d\n", SKYPOPEN_P_LOG, len); - } - } - } - - } - DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPOPEN_P_LOG); - tech_pvt->skype_callflow = CALLFLOW_INCOMING_HANGUP; - skypopen_close_socket(fd); - break; - } - break; - } - } - - DEBUGA_SKYPE("outbound audio server (I am it) EXITING\n", SKYPOPEN_P_LOG); - skypopen_close_socket(s); - s = -1; - //DEBUGA_SKYPE("debugging_hangup PRE cli lock\n", SKYPOPEN_P_LOG); - switch_mutex_lock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli lock\n", SKYPOPEN_P_LOG); - tech_pvt->tcp_cli_thread = NULL; - switch_mutex_unlock(tech_pvt->mutex_thread_audio_cli); - //DEBUGA_SKYPE("debugging_hangup cli unlock\n", SKYPOPEN_P_LOG); - return NULL; -} - -int skypopen_senddigit(private_t *tech_pvt, char digit) -{ - char msg_to_skype[1024]; - - DEBUGA_SKYPE("DIGIT received: %c\n", SKYPOPEN_P_LOG, digit); - if (digit != 'a' && digit != 'A' && digit != 'b' && digit != 'B' && digit != 'c' && digit != 'C' && digit != 'd' && digit != 'D') { - sprintf(msg_to_skype, "SET CALL %s DTMF %c", tech_pvt->skype_call_id, digit); - skypopen_signaling_write(tech_pvt, msg_to_skype); - } else { - WARNINGA("Received DTMF DIGIT \"%c\", but not relayed to Skype client because Skype client accepts only 0-9*#\n", SKYPOPEN_P_LOG, digit); - } - - return 0; -} - -int skypopen_call(private_t *tech_pvt, char *rdest, int timeout) -{ - char msg_to_skype[1024]; - - DEBUGA_SKYPE("Calling Skype, rdest is: %s\n", SKYPOPEN_P_LOG, rdest); - - sprintf(msg_to_skype, "CALL %s", rdest); - if (skypopen_signaling_write(tech_pvt, msg_to_skype) < 0) { - ERRORA("failed to communicate with Skype client, now exit\n", SKYPOPEN_P_LOG); - return -1; - } - return 0; -} - -/***************************/ -/* PLATFORM SPECIFIC */ -/***************************/ -#if defined(WIN32) && !defined(__CYGWIN__) -int skypopen_pipe_read(switch_file_t *pipe, short *buf, int howmany) -{ - switch_size_t quantity; - - quantity = howmany; - - switch_file_read(pipe, buf, &quantity); - - howmany = (int)quantity; - - return howmany; -} - -int skypopen_pipe_write(switch_file_t *pipe, short *buf, int howmany) -{ - switch_size_t quantity; - - quantity = howmany; - - switch_file_write(pipe, buf, &quantity); - - howmany = (int)quantity; - - return howmany; -} - -int skypopen_close_socket(unsigned int fd) -{ - int res; - - res = closesocket(fd); - - return res; -} - -int skypopen_audio_init(private_t *tech_pvt) -{ - switch_status_t rv; - rv = switch_file_pipe_create(&tech_pvt->audiopipe_srv[0], &tech_pvt->audiopipe_srv[1], skypopen_module_pool); - rv = switch_file_pipe_create(&tech_pvt->audiopipe_cli[0], &tech_pvt->audiopipe_cli[1], skypopen_module_pool); - return 0; -} -#else /* WIN32 */ -int skypopen_pipe_read(int pipe, short *buf, int howmany) -{ - howmany = read(pipe, buf, howmany); - return howmany; -} - -int skypopen_pipe_write(int pipe, short *buf, int howmany) -{ - if (buf) { - howmany = write(pipe, buf, howmany); - return howmany; - } else { - return 0; - } -} - -int skypopen_close_socket(unsigned int fd) -{ - int res; - - res = close(fd); - - return res; -} - -int skypopen_audio_init(private_t *tech_pvt) -{ - if (pipe(tech_pvt->audiopipe_srv)) { - fcntl(tech_pvt->audiopipe_srv[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->audiopipe_srv[1], F_SETFL, O_NONBLOCK); - } - if (pipe(tech_pvt->audiopipe_cli)) { - fcntl(tech_pvt->audiopipe_cli[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->audiopipe_cli[1], F_SETFL, O_NONBLOCK); - } - -/* this pipe is the audio fd for asterisk to poll on during a call. FS do not use it */ - tech_pvt->skypopen_sound_capt_fd = tech_pvt->audiopipe_srv[0]; - - return 0; -} -#endif /* WIN32 */ - -#ifdef WIN32 - -enum { - SKYPECONTROLAPI_ATTACH_SUCCESS = 0, /* Client is successfully - attached and API window handle can be found - in wParam parameter */ - SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1, /* Skype has acknowledged - connection request and is waiting - for confirmation from the user. */ - /* The client is not yet attached - * and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message */ - SKYPECONTROLAPI_ATTACH_REFUSED = 2, /* User has explicitly - denied access to client */ - SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE = 3, /* API is not available - at the moment. - For example, this happens when no user - is currently logged in. */ - /* Client should wait for - * SKYPECONTROLAPI_ATTACH_API_AVAILABLE - * broadcast before making any further */ - /* connection attempts. */ - SKYPECONTROLAPI_ATTACH_API_AVAILABLE = 0x8001 -}; - -/* Visual C do not have strsep? */ -char - *strsep(char **stringp, const char *delim) -{ - char *res; - - if (!stringp || !*stringp || !**stringp) - return (char *) 0; - - res = *stringp; - while (**stringp && !strchr(delim, **stringp)) - ++(*stringp); - - if (**stringp) { - **stringp = '\0'; - ++(*stringp); - } - - return res; -} - -int skypopen_signaling_write(private_t *tech_pvt, char *msg_to_skype) -{ - static char acInputRow[1024]; - COPYDATASTRUCT oCopyData; - - DEBUGA_SKYPE("SENDING: |||%s||||\n", SKYPOPEN_P_LOG, msg_to_skype); - - sprintf(acInputRow, "%s", msg_to_skype); - /* send command to skype */ - oCopyData.dwData = 0; - oCopyData.lpData = acInputRow; - oCopyData.cbData = strlen(acInputRow) + 1; - if (oCopyData.cbData != 1) { - if (SendMessage - (tech_pvt->SkypopenHandles.win32_hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, - (WPARAM) tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle, (LPARAM) & oCopyData) == FALSE) { - ERRORA("Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypopen, then launch Skypopen and try again.\n", SKYPOPEN_P_LOG); - return -1; - } - } - - return 0; - -} - -LRESULT APIENTRY skypopen_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, LPARAM ulParam) -{ - LRESULT lReturnCode; - int fIssueDefProc; - private_t *tech_pvt = NULL; - - lReturnCode = 0; - fIssueDefProc = 0; - tech_pvt = (private_t *)(intptr_t) GetWindowLong(hWindow, GWLP_USERDATA); - - if (!running) { - DEBUGA_SKYPE("let's DIE!\n", SKYPOPEN_P_LOG); - tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle = NULL; - PostQuitMessage(0); - return lReturnCode; - } - switch (uiMessage) { - case WM_CREATE: - tech_pvt = (private_t *) ((LPCREATESTRUCT) ulParam)->lpCreateParams; - SetWindowLong(hWindow, GWLP_USERDATA, (LONG) (intptr_t)tech_pvt); - DEBUGA_SKYPE("got CREATE\n", SKYPOPEN_P_LOG); - break; - case WM_DESTROY: - DEBUGA_SKYPE("got DESTROY\n", SKYPOPEN_P_LOG); - tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle = NULL; - PostQuitMessage(0); - break; - case WM_COPYDATA: - if (tech_pvt->SkypopenHandles.win32_hGlobal_SkypeAPIWindowHandle == (HWND) uiParam) { - unsigned int howmany; - char msg_from_skype[2048]; - - PCOPYDATASTRUCT poCopyData = (PCOPYDATASTRUCT) ulParam; - - memset(msg_from_skype, '\0', sizeof(msg_from_skype)); - skypopen_strncpy(msg_from_skype, (const char *) poCopyData->lpData, sizeof(msg_from_skype) - 2); - - howmany = strlen(msg_from_skype) + 1; - howmany = skypopen_pipe_write(tech_pvt->SkypopenHandles.fdesc[1], (short *) msg_from_skype, howmany); - lReturnCode = 1; - } - break; - default: - if (tech_pvt && tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) { - if (uiMessage == tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) { - switch (ulParam) { - case SKYPECONTROLAPI_ATTACH_SUCCESS: - if (!tech_pvt->SkypopenHandles.currentuserhandle) { - //DEBUGA_SKYPE("\n\n\tConnected to Skype API!\n", SKYPOPEN_P_LOG); - tech_pvt->SkypopenHandles.api_connected = 1; - tech_pvt->SkypopenHandles.win32_hGlobal_SkypeAPIWindowHandle = (HWND) uiParam; - tech_pvt->SkypopenHandles.win32_hGlobal_SkypeAPIWindowHandle = tech_pvt->SkypopenHandles.win32_hGlobal_SkypeAPIWindowHandle; - } - break; - case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: - skypopen_sleep(20000); - break; - case SKYPECONTROLAPI_ATTACH_REFUSED: - ERRORA("Skype client refused to be connected by Skypopen!\n", SKYPOPEN_P_LOG); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - ERRORA("Skype API not (yet?) available\n", SKYPOPEN_P_LOG); - break; - case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: - DEBUGA_SKYPE("Skype API available\n", SKYPOPEN_P_LOG); - skypopen_sleep(20000); - break; - default: - WARNINGA("GOT AN UNKNOWN SKYPE WINDOWS MSG\n", SKYPOPEN_P_LOG); - } - lReturnCode = 1; - break; - } - } - fIssueDefProc = 1; - break; - } - if (fIssueDefProc) - lReturnCode = DefWindowProc(hWindow, uiMessage, uiParam, ulParam); - return (lReturnCode); -} - -int win32_Initialize_CreateWindowClass(private_t *tech_pvt) -{ - unsigned char *paucUUIDString; - RPC_STATUS lUUIDResult; - int fReturnStatus; - UUID oUUID; - - fReturnStatus = 0; - lUUIDResult = UuidCreate(&oUUID); - tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle = (HINSTANCE) OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId()); - if (tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle != NULL && (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) { - if (UuidToString(&oUUID, &paucUUIDString) == RPC_S_OK) { - WNDCLASS oWindowClass; - - strcpy(tech_pvt->SkypopenHandles.win32_acInit_WindowClassName, "Skype-API-Skypopen-"); - strcat(tech_pvt->SkypopenHandles.win32_acInit_WindowClassName, (char *) paucUUIDString); - - oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - oWindowClass.lpfnWndProc = (WNDPROC) & skypopen_present; - oWindowClass.cbClsExtra = 0; - oWindowClass.cbWndExtra = 0; - oWindowClass.hInstance = tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle; - oWindowClass.hIcon = NULL; - oWindowClass.hCursor = NULL; - oWindowClass.hbrBackground = NULL; - oWindowClass.lpszMenuName = NULL; - oWindowClass.lpszClassName = tech_pvt->SkypopenHandles.win32_acInit_WindowClassName; - - if (RegisterClass(&oWindowClass) != 0) - fReturnStatus = 1; - - RpcStringFree(&paucUUIDString); - } - } - if (fReturnStatus == 0) - CloseHandle(tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle); - tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle = NULL; - return (fReturnStatus); -} - -void win32_DeInitialize_DestroyWindowClass(private_t *tech_pvt) -{ - UnregisterClass(tech_pvt->SkypopenHandles.win32_acInit_WindowClassName, tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle); - CloseHandle(tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle); - tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle = NULL; -} - -int win32_Initialize_CreateMainWindow(private_t *tech_pvt) -{ - tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle = - CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, - tech_pvt->SkypopenHandles.win32_acInit_WindowClassName, "", - WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, - 128, 128, NULL, 0, tech_pvt->SkypopenHandles.win32_hInit_ProcessHandle, tech_pvt); - return (tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle != NULL ? 1 : 0); -} - -void win32_DeInitialize_DestroyMainWindow(private_t *tech_pvt) -{ - if (tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle != NULL) - DestroyWindow(tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle), tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle = NULL; -} - -void *skypopen_do_skypeapi_thread_func(void *obj) -{ - private_t *tech_pvt = obj; -#if defined(WIN32) && !defined(__CYGWIN__) - switch_status_t rv; - - switch_file_pipe_create(&tech_pvt->SkypopenHandles.fdesc[0], &tech_pvt->SkypopenHandles.fdesc[1], skypopen_module_pool); - rv = switch_file_pipe_create(&tech_pvt->SkypopenHandles.fdesc[0], &tech_pvt->SkypopenHandles.fdesc[1], skypopen_module_pool); -#else /* WIN32 */ - if (pipe(tech_pvt->SkypopenHandles.fdesc)) { - fcntl(tech_pvt->SkypopenHandles.fdesc[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->SkypopenHandles.fdesc[1], F_SETFL, O_NONBLOCK); - } -#endif /* WIN32 */ - - tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach = RegisterWindowMessage("SkypeControlAPIAttach"); - tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover = RegisterWindowMessage("SkypeControlAPIDiscover"); - - skypopen_sleep(200000); //0,2 sec - - if (tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0 - && tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { - if (win32_Initialize_CreateWindowClass(tech_pvt)) { - if (win32_Initialize_CreateMainWindow(tech_pvt)) { - if (SendMessage - (HWND_BROADCAST, - tech_pvt->SkypopenHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover, - (WPARAM) tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle, 0) != 0) { - tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle = tech_pvt->SkypopenHandles.win32_hInit_MainWindowHandle; - while (running && tech_pvt->running) { - MSG oMessage; - if (!(running && tech_pvt->running)) - break; - while (GetMessage(&oMessage, 0, 0, 0)) { - TranslateMessage(&oMessage); - DispatchMessage(&oMessage); - } - } - } - win32_DeInitialize_DestroyMainWindow(tech_pvt); - } - win32_DeInitialize_DestroyWindowClass(tech_pvt); - } - } - tech_pvt->skypopen_api_thread = NULL; - DEBUGA_SKYPE("EXITING\n", SKYPOPEN_P_LOG); - return NULL; -} - -#else /* NOT WIN32 */ - -// CLOUDTREE (Thomas Hazel) -int xio_error_handler(Display * dpy) -{ - private_t *tech_pvt = NULL; - struct SkypopenHandles *handle; - - ERRORA("Fatal display error for %d, %s\n", SKYPOPEN_P_LOG, skypopen_list_size(&global_handles_list), dpy->display_name); - - handle = skypopen_list_remove_by_value(&global_handles_list, dpy); - if (handle != NULL) { -#ifdef XIO_ERROR_BY_SETJMP - siglongjmp(handle->ioerror_context, 1); -#endif -#ifdef XIO_ERROR_BY_UCONTEXT - setcontext(&handle->ioerror_context); -#endif - } - - ERRORA("Fatal display error for %p, %s - failed to siglongjmp\n", SKYPOPEN_P_LOG, (void *) handle, dpy->display_name); - - return 0; -} - -int xio_error_handler2(Display * dpy, XErrorEvent * err) -{ - private_t *tech_pvt = NULL; - struct SkypopenHandles *handle; - global_x_error = err->error_code; - - ERRORA("Received error code %d from X Server\n\n", SKYPOPEN_P_LOG, global_x_error); - ERRORA("Display error for %d, %s\n", SKYPOPEN_P_LOG, skypopen_list_size(&global_handles_list), dpy->display_name); - - handle = skypopen_list_remove_by_value(&global_handles_list, dpy); - if (handle != NULL) { -#ifdef XIO_ERROR_BY_SETJMP - siglongjmp(handle->ioerror_context, 1); -#endif -#ifdef XIO_ERROR_BY_UCONTEXT - setcontext(&handle->ioerror_context); -#endif - } - - ERRORA("Fatal display error for %p, %s - failed to siglongjmp\n", SKYPOPEN_P_LOG, (void *) handle, dpy->display_name); - - return 0; -} - - -int X11_errors_handler(Display * dpy, XErrorEvent * err) -{ - private_t *tech_pvt = NULL; - (void) dpy; - - global_x_error = err->error_code; - ERRORA("Received error code %d from X Server\n\n", SKYPOPEN_P_LOG, global_x_error); - return 0; /* ignore the error */ -} - -int skypopen_send_message(private_t *tech_pvt, const char *message_P) -{ - struct SkypopenHandles *SkypopenHandles = &tech_pvt->SkypopenHandles; - Window w_P = SkypopenHandles->skype_win; - Display *disp = SkypopenHandles->disp; - Window handle_P = SkypopenHandles->win; - - - Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False); - Atom atom2 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False); - unsigned int pos = 0; - unsigned int len = strlen(message_P); - XEvent e; - - //skypopen_sleep(1000); - //XFlush(disp); - - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.message_type = atom1; /* leading message */ - e.xclient.display = disp; - e.xclient.window = handle_P; - e.xclient.format = 8; - - // CLOUDTREE (Thomas Hazel) - global_x_error = Success; - - do { - unsigned int i; - for (i = 0; i < 20 && i + pos <= len; ++i) - e.xclient.data.b[i] = message_P[i + pos]; - XSendEvent(disp, w_P, False, 0, &e); - - e.xclient.message_type = atom2; /* following messages */ - pos += i; - } while (pos <= len); - - XFlush(disp); - - // CLOUDTREE (Thomas Hazel) - if (global_x_error != Success) { - ERRORA("Sending message failed with status %d\n", SKYPOPEN_P_LOG, global_x_error); - tech_pvt->running = 0; - return 0; - } - - return 1; -} - -int skypopen_signaling_write(private_t *tech_pvt, char *msg_to_skype) -{ - - DEBUGA_SKYPE("SENDING: |||%s||||\n", SKYPOPEN_P_LOG, msg_to_skype); - - - if (!skypopen_send_message(tech_pvt, msg_to_skype)) { - ERRORA - ("Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypopen, then restart Skype, then launch Skypopen and try again.\n", - SKYPOPEN_P_LOG); - return -1; - } - - return 0; - -} - -int skypopen_present(struct SkypopenHandles *SkypopenHandles) -{ - Atom skype_inst = XInternAtom(SkypopenHandles->disp, "_SKYPE_INSTANCE", True); - - Atom type_ret; - int format_ret; - unsigned long nitems_ret; - unsigned long bytes_after_ret; - unsigned char *prop; - int status; - private_t *tech_pvt = NULL; - - status = - XGetWindowProperty(SkypopenHandles->disp, DefaultRootWindow(SkypopenHandles->disp), - skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, &prop); - - /* sanity check */ - if (status != Success || format_ret != 32 || nitems_ret != 1) { - SkypopenHandles->skype_win = (Window) - 1; - DEBUGA_SKYPE("Skype instance not found\n", SKYPOPEN_P_LOG); - running = 0; - SkypopenHandles->api_connected = 0; - return 0; - } - - SkypopenHandles->skype_win = *(const unsigned long *) prop & 0xffffffff; - DEBUGA_SKYPE("Skype instance found with id #%d\n", SKYPOPEN_P_LOG, (unsigned int) SkypopenHandles->skype_win); - SkypopenHandles->api_connected = 1; - return 1; -} - -void skypopen_clean_disp(void *data) -{ - - int *dispptr; - int disp; - private_t *tech_pvt = NULL; - - dispptr = data; - disp = *dispptr; - - if (disp) { - DEBUGA_SKYPE("to be destroyed disp %d\n", SKYPOPEN_P_LOG, disp); - close(disp); - DEBUGA_SKYPE("destroyed disp\n", SKYPOPEN_P_LOG); - } else { - DEBUGA_SKYPE("NOT destroyed disp\n", SKYPOPEN_P_LOG); - } - DEBUGA_SKYPE("OUT destroyed disp\n", SKYPOPEN_P_LOG); - skypopen_sleep(20000); -} - -void *skypopen_do_skypeapi_thread_func(void *obj) -{ - - private_t *tech_pvt = obj; - struct SkypopenHandles *SkypopenHandles; - char buf[512]; - Display *disp = NULL; - Window root = -1; - Window win = -1; - int xfd; - fd_set xfds; - - if (!strlen(tech_pvt->X11_display)) - strcpy(tech_pvt->X11_display, getenv("DISPLAY")); - - if (!tech_pvt->tcp_srv_port) - tech_pvt->tcp_srv_port = 10160; - - if (!tech_pvt->tcp_cli_port) - tech_pvt->tcp_cli_port = 10161; - - if (pipe(tech_pvt->SkypopenHandles.fdesc)) { - fcntl(tech_pvt->SkypopenHandles.fdesc[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->SkypopenHandles.fdesc[1], F_SETFL, O_NONBLOCK); - } - SkypopenHandles = &tech_pvt->SkypopenHandles; - disp = XOpenDisplay(tech_pvt->X11_display); - if (!disp) { - ERRORA("Cannot open X Display '%s', exiting skype thread\n", SKYPOPEN_P_LOG, tech_pvt->X11_display); - running = 0; - - // CLOUDTREE (Thomas Hazel) - tech_pvt->skypopen_api_thread = NULL; - remove_interface(tech_pvt->skype_user, FALSE); - return NULL; - } else { - DEBUGA_SKYPE("X Display '%s' opened\n", SKYPOPEN_P_LOG, tech_pvt->X11_display); - } - - // CLOUDTREE (Thomas Hazel) -#ifndef WIN32 - { - char interfacename[256]; - - skypopen_list_add(&global_handles_list, SkypopenHandles); - sprintf(interfacename, "#%s", tech_pvt->name); - -#ifdef XIO_ERROR_BY_SETJMP - if (sigsetjmp(SkypopenHandles->ioerror_context, 1) != 0) { - switch_core_session_t *session = NULL; - tech_pvt->interface_state = SKYPOPEN_STATE_DEAD; - ERRORA("Fatal display error for %s - successed to jump\n", SKYPOPEN_P_LOG, tech_pvt->X11_display); - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (channel) { - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - } - switch_mutex_unlock(tech_pvt->flag_mutex); - - - switch_core_session_rwunlock(session); - WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename); - switch_channel_hangup(channel, SWITCH_CAUSE_CRASH); - } else { - WARNINGA("NO CHANNEL ?\n", SKYPOPEN_P_LOG); - switch_core_session_rwunlock(session); - } - } - - WARNINGA("Removing skype interface %s\n", SKYPOPEN_P_LOG, interfacename); - remove_interface(interfacename, TRUE); - return NULL; - } -#endif -#ifdef XIO_ERROR_BY_UCONTEXT - getcontext(&SkypopenHandles->ioerror_context); - - if (skypopen_list_find(&global_handles_list, SkypopenHandles) == NULL) { - switch_core_session_t *session = NULL; - tech_pvt->interface_state = SKYPOPEN_STATE_DEAD; - ERRORA("Fatal display error for %s - successed to jump\n", SKYPOPEN_P_LOG, tech_pvt->X11_display); - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - - - if (channel) { - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); - } - switch_mutex_unlock(tech_pvt->flag_mutex); - - - switch_core_session_rwunlock(session); - WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename); - switch_channel_hangup(channel, SWITCH_CAUSE_CRASH); - - } else { - WARNINGA("NO CHANNEL ?\n", SKYPOPEN_P_LOG); - } - //skypopen_sleep(500000); - } - - WARNINGA("Removing skype interface %s\n", SKYPOPEN_P_LOG, interfacename); - //tech_pvt->skypopen_api_thread = NULL; - remove_interface(interfacename, TRUE); - //XCloseDisplay(disp); - return NULL; - } -#endif - } -#endif /* NOT WIN32 */ - - xfd = XConnectionNumber(disp); - fcntl(xfd, F_SETFD, FD_CLOEXEC); - - SkypopenHandles->disp = disp; - - if (skypopen_present(SkypopenHandles)) { - root = DefaultRootWindow(disp); - win = XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, DefaultScreen(disp))); - - SkypopenHandles->win = win; - - snprintf(buf, 512, "NAME skypopen"); - - if (!skypopen_send_message(tech_pvt, buf)) { - ERRORA("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypopen again\n", SKYPOPEN_P_LOG); - - // CLOUDTREE (Thomas Hazel) -#ifndef WIN32 - skypopen_list_remove_by_reference(&global_handles_list, SkypopenHandles); -#endif - - XCloseDisplay(disp); - running = 0; - return NULL; - } - - snprintf(buf, 512, "PROTOCOL 999"); - if (!skypopen_send_message(tech_pvt, buf)) { - ERRORA("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypopen again\n", SKYPOPEN_P_LOG); - - // CLOUDTREE (Thomas Hazel) -#ifndef WIN32 - skypopen_list_remove_by_reference(&global_handles_list, SkypopenHandles); -#endif - - XCloseDisplay(disp); - running = 0; - return NULL; - } - - { - /* perform an events loop */ - XEvent an_event; - char buf[21]; /* can't be longer */ - char buffer[17000]; - char continuebuffer[17000]; - char *b; - int i; - int continue_is_broken = 0; - int there_were_continues = 0; - struct timeval tv; - Atom atom_begin = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False); - Atom atom_continue = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False); - - memset(buffer, '\0', 17000); - memset(continuebuffer, '\0', 17000); - b = buffer; - - while (running && tech_pvt->running) { - - - FD_ZERO(&xfds); - FD_SET(xfd, &xfds); - - tv.tv_usec = 100000; - tv.tv_sec = 0; - - - - if (select(xfd + 1, &xfds, 0, 0, &tv)) { - - while (XPending(disp)) { - - - - XNextEvent(disp, &an_event); - if (!(running && tech_pvt->running)) - break; - switch (an_event.type) { - case ClientMessage: - - if (an_event.xclient.format != 8) { - //skypopen_sleep(1000); //0.1 msec - break; - } - - for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i) - buf[i] = an_event.xclient.data.b[i]; - - buf[i] = '\0'; - - if (an_event.xclient.message_type == atom_begin) { - if (strlen(buffer)) { - unsigned int howmany; - howmany = strlen(b) + 1; - howmany = write(SkypopenHandles->fdesc[1], b, howmany); - WARNINGA - ("A begin atom while the previous message is not closed???? value of previous message (between vertical bars) is=|||%s|||, will be lost\n", - SKYPOPEN_P_LOG, buffer); - memset(buffer, '\0', 17000); - } - if (continue_is_broken) { - continue_is_broken = 0; - there_were_continues = 1; - } - } - if (an_event.xclient.message_type == atom_continue) { - if (!strlen(buffer)) { - WARNINGA - ("Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||, let's store it and hope next 'begin' will be the good one\n", - SKYPOPEN_P_LOG, buf); - strcat(continuebuffer, buf); - continue_is_broken = 1; - if (!strncmp(buf, "ognised identity", 15)) { - WARNINGA - ("Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||. Let's introduce a 1 second delay.\n", - SKYPOPEN_P_LOG, buf); - skypopen_sleep(1000000); //1 sec - } - skypopen_sleep(20000); //20 msec - break; - } - } - if (continue_is_broken) { - XFlush(disp); - skypopen_sleep(20000); //20 msec - WARNINGA("continue_is_broken\n", SKYPOPEN_P_LOG); - continue; - } - strcat(buffer, buf); - strcat(buffer, continuebuffer); - memset(continuebuffer, '\0', 17000); - - if (i < 20 || there_were_continues) { /* last fragment */ - unsigned int howmany; - - howmany = strlen(b) + 1; - howmany = write(SkypopenHandles->fdesc[1], b, howmany); - memset(buffer, '\0', 17000); - //XFlush(disp); - there_were_continues = 0; - } - //skypopen_sleep(1000); //0.1 msec - break; - default: - //skypopen_sleep(1000); //0.1 msec - break; - } //switch event.type - } //while XPending - XFlush(disp); - - } // if select - } //while running - - - - - - } - } else { - ERRORA("Skype is not running, maybe crashed. Please run/restart Skype and relaunch Skypopen\n", SKYPOPEN_P_LOG); - running = 0; - } - - DEBUGA_SKYPE("EXITING\n", SKYPOPEN_P_LOG); - - // CLOUDTREE (Thomas Hazel) -#ifndef WIN32 - skypopen_list_remove_by_reference(&global_handles_list, SkypopenHandles); -#endif - - tech_pvt->skypopen_api_thread = NULL; - return NULL; - -} -#endif // WIN32 - -int inbound_channel_answered(private_t *tech_pvt) -{ - int res = 0; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - - if (channel) { - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_IO); - switch_mutex_unlock(tech_pvt->flag_mutex); - } else { - ERRORA("no channel\n", SKYPOPEN_P_LOG); - } - switch_core_session_rwunlock(session); - } else { - ERRORA("no session\n", SKYPOPEN_P_LOG); - - } - return res; -} - - -int skypopen_answered(private_t *tech_pvt) -{ - - int res = SWITCH_STATUS_SUCCESS; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (strlen(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - - if (channel) { - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - tech_pvt->interface_state = SKYPOPEN_STATE_UP; - DEBUGA_SKYPE("Outbound Channel Answered! session_uuid_str=%s\n", SKYPOPEN_P_LOG, tech_pvt->session_uuid_str); - outbound_channel_answered(tech_pvt); - } else { - DEBUGA_SKYPE("answered Inbound Channel!\n\n\n\n", SKYPOPEN_P_LOG); - inbound_channel_answered(tech_pvt); - } - - } else { - ERRORA("no channel after INPROGRESS?\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - switch_core_session_rwunlock(session); - } else { - WARNINGA("no session after INPROGRESS, let's hangup\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - } else { - WARNINGA("no tech_pvt->session_uuid_str after INPROGRESS, let's hangup\n", SKYPOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - return res; -} From 9ab4d17ccecb5a91eb244320da676e20ad17e767 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 24 Aug 2024 14:00:14 +0300 Subject: [PATCH 180/205] [mod_gsmopen] Remove from tree. --- .gitignore | 1 - Freeswitch.2017.sln | 42 - LICENSE | 19 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 1 - debian/bootstrap.sh | 1 - debian/control-modules | 5 - debian/copyright | 19 - freeswitch.spec | 15 +- libs/win32/libcbt/libcbt.2017.vcxproj | 168 - src/mod/Makefile.am | 1 - src/mod/endpoints/mod_gsmopen/.gitignore | 2 - .../endpoints/mod_gsmopen/FREEBSD_README.txt | 9 - .../endpoints/mod_gsmopen/FREEBSD_patch.diff | 171 - src/mod/endpoints/mod_gsmopen/Makefile.am | 9 - src/mod/endpoints/mod_gsmopen/README | 14 - .../mod_gsmopen/Makefile | 7 - .../mod_gsmopen/configs/asound.conf | 6 - .../mod_gsmopen/configs/gsmopen.conf.xml | 23 - .../configs/gsmopen.conf.xml.motorola | 110 - .../mod_gsmopen/configs/setmixers | 13 - .../mod_gsmopen/gsmopen.h | 665 - .../mod_gsmopen/gsmopen_protocol.c | 4009 -- .../mod_gsmopen/mod_gsmopen.c | 3474 -- .../mod_gsmopen/usb-cm-108-2.txt | 62 - .../endpoints/mod_gsmopen/asterisk/Makefile | 81 - src/mod/endpoints/mod_gsmopen/asterisk/README | 96 - .../mod_gsmopen/asterisk/asound.conf | 2 - .../mod_gsmopen/asterisk/celliax.conf | 205 - .../endpoints/mod_gsmopen/asterisk/celliax.h | 909 - .../mod_gsmopen/asterisk/celliax_additional.c | 7027 ---- .../mod_gsmopen/asterisk/celliax_libcsv.c | 356 - .../mod_gsmopen/asterisk/celliax_libcsv.h | 48 - .../mod_gsmopen/asterisk/celliax_spandsp.c | 1059 - .../mod_gsmopen/asterisk/celliax_spandsp.h | 1028 - .../mod_gsmopen/asterisk/chan_celliax.c | 3094 -- .../endpoints/mod_gsmopen/asterisk/ciapalo | 8 - .../mod_gsmopen/configs/gsmopen.conf.xml | 27 - .../mod_gsmopen/driver_usb_dongle/Makefile | 43 - .../mod_gsmopen/driver_usb_dongle/README | 9 - .../mod_gsmopen/driver_usb_dongle/main.c | 1817 - src/mod/endpoints/mod_gsmopen/gsmlib/README | 8 - .../gsmlib-1.10-patched-13ubuntu/ABOUT-NLS | 226 - .../gsmlib-1.10-patched-13ubuntu/AUTHORS | 0 .../gsmlib-1.10-patched-13ubuntu/COPYING | 482 - .../gsmlib-1.10-patched-13ubuntu/ChangeLog | 386 - .../gsmlib-1.10-patched-13ubuntu/INSTALL | 198 - .../gsmlib-1.10-patched-13ubuntu/Makefile.am | 24 - .../gsmlib-1.10-patched-13ubuntu/Makefile.in | 423 - .../gsmlib/gsmlib-1.10-patched-13ubuntu/NEWS | 11 - .../gsmlib-1.10-patched-13ubuntu/README | 166 - .../gsmlib/gsmlib-1.10-patched-13ubuntu/TODO | 289 - .../gsmlib-1.10-patched-13ubuntu/acconfig.h | 33 - .../gsmlib-1.10-patched-13ubuntu/acinclude.m4 | 0 .../gsmlib-1.10-patched-13ubuntu/aclocal.m4 | 9704 ----- .../apps/Makefile.am | 36 - .../apps/Makefile.in | 442 - .../apps/gsmctl.cc | 635 - .../apps/gsmpb.cc | 507 - .../apps/gsmsendsms.cc | 257 - .../apps/gsmsmsd.cc | 723 - .../apps/gsmsmsstore.cc | 434 - .../gsmlib-1.10-patched-13ubuntu/configure | 30623 ---------------- .../gsmlib-1.10-patched-13ubuntu/configure.in | 131 - .../contrib/gsm-utils.cron.d | 3 - .../contrib/gsm-utils.default | 13 - .../contrib/gsm-utils.init | 81 - .../contrib/gsmsmsrequeue | 48 - .../contrib/gsmsmsspool | 34 - .../debian/changelog | 284 - .../debian/compat | 1 - .../debian/control | 45 - .../debian/copyright | 34 - .../gsmlib-1.10-patched-13ubuntu/debian/dirs | 1 - .../debian/gsm-utils.cron.d | 3 - .../debian/gsm-utils.default | 18 - .../debian/gsm-utils.dirs | 11 - .../debian/gsm-utils.docs | 4 - .../debian/gsm-utils.examples | 2 - .../debian/gsm-utils.init | 87 - .../debian/gsm-utils.postinst | 28 - .../debian/gsm-utils.postrm | 43 - .../debian/gsmsiexfer.1 | 29 - .../debian/libgsmme-dev.docs | 2 - .../gsmlib-1.10-patched-13ubuntu/debian/rules | 129 - .../gsmlib-1.10-patched-13ubuntu/debian/watch | 2 - .../gsmlib-1.10-patched-13ubuntu/doc/FAQ | 101 - .../doc/Makefile.am | 33 - .../doc/Makefile.in | 412 - .../doc/README.NLS | 72 - .../doc/README.developers | 138 - .../doc/gsmctl.man | 683 - .../doc/gsminfo.man | 56 - .../doc/gsmlib.lsm | 20 - .../doc/gsmpb.man | 245 - .../doc/gsmsendsms.man | 154 - .../doc/gsmsmsd.man | 269 - .../doc/gsmsmsstore.man | 185 - .../ext/Makefile.am | 40 - .../ext/Makefile.in | 480 - .../ext/README.sieme | 75 - .../ext/gsm_sie_me.cc | 258 - .../ext/gsm_sie_me.h | 99 - .../ext/gsmsiectl.cc | 698 - .../ext/gsmsiexfer.cc | 292 - .../gsmlib-1.10-patched-13ubuntu/g41.patch | 29 - .../gsm_config.h.in | 344 - .../gsmlib-1.10.debmg/debian/gsm-utils.dirs | 11 - .../debian/gsm-utils.postinst | 28 - .../gsmlib-1.10.debmg/debian/gsm-utils.prerm | 7 - .../debian/gsm-utils.undocumented | 2 - .../gsmlib-1.10-patched-13ubuntu/gsmlib.spec | 92 - .../gsmlib/Makefile.am | 38 - .../gsmlib/Makefile.in | 461 - .../gsmlib/gsm_at.cc | 444 - .../gsmlib/gsm_at.h | 104 - .../gsmlib/gsm_cb.cc | 176 - .../gsmlib/gsm_cb.h | 106 - .../gsmlib/gsm_error.cc | 424 - .../gsmlib/gsm_error.h | 209 - .../gsmlib/gsm_event.cc | 174 - .../gsmlib/gsm_event.h | 68 - .../gsmlib/gsm_map_key.h | 128 - .../gsmlib/gsm_me_ta.cc | 1254 - .../gsmlib/gsm_me_ta.h | 402 - .../gsmlib/gsm_nls.cc | 32 - .../gsmlib/gsm_nls.h | 71 - .../gsmlib/gsm_parser.cc | 381 - .../gsmlib/gsm_parser.h | 125 - .../gsmlib/gsm_phonebook.cc | 585 - .../gsmlib/gsm_phonebook.h | 195 - .../gsmlib/gsm_port.h | 58 - .../gsmlib/gsm_sms.cc | 863 - .../gsmlib/gsm_sms.h | 480 - .../gsmlib/gsm_sms_codec.cc | 702 - .../gsmlib/gsm_sms_codec.h | 329 - .../gsmlib/gsm_sms_store.cc | 489 - .../gsmlib/gsm_sms_store.h | 295 - .../gsmlib/gsm_sorted_phonebook.cc | 503 - .../gsmlib/gsm_sorted_phonebook.h | 159 - .../gsmlib/gsm_sorted_phonebook_base.cc | 115 - .../gsmlib/gsm_sorted_phonebook_base.h | 220 - .../gsmlib/gsm_sorted_sms_store.cc | 499 - .../gsmlib/gsm_sorted_sms_store.h | 217 - .../gsmlib/gsm_sysdep.h | 83 - .../gsmlib/gsm_unix_serial.cc | 456 - .../gsmlib/gsm_unix_serial.h | 62 - .../gsmlib/gsm_util.cc | 381 - .../gsmlib/gsm_util.h | 233 - .../gsmlib/gsm_win32_serial.cc | 507 - .../gsmlib/gsm_win32_serial.h | 60 - .../intl/ChangeLog | 1086 - .../intl/Makefile | 214 - .../intl/Makefile.in | 214 - .../gsmlib-1.10-patched-13ubuntu/intl/VERSION | 1 - .../intl/bindtextdom.c | 203 - .../intl/cat-compat.c | 262 - .../intl/dcgettext.c | 624 - .../intl/dgettext.c | 59 - .../intl/explodename.c | 188 - .../intl/finddomain.c | 216 - .../intl/gettext.c | 70 - .../intl/gettext.h | 105 - .../intl/gettextP.h | 89 - .../intl/hash-string.h | 59 - .../intl/intl-compat.c | 76 - .../intl/l10nflist.c | 411 - .../intl/libgettext.h | 182 - .../intl/linux-msg.sed | 100 - .../intl/loadinfo.h | 76 - .../intl/loadmsgcat.c | 222 - .../intl/localealias.c | 424 - .../intl/po2tbl.sed.in | 102 - .../intl/textdomain.c | 108 - .../intl/xopen-msg.sed | 104 - .../po/Makefile.in.in | 250 - .../po/POTFILES.in | 19 - .../po/cat-id-tbl.c | 0 .../gsmlib-1.10-patched-13ubuntu/po/de.gmo | Bin 34591 -> 0 bytes .../gsmlib-1.10-patched-13ubuntu/po/de.po | 1758 - .../po/gsmlib.pot | 1689 - .../po/stamp-cat-id | 1 - .../scripts/Makefile.am | 15 - .../scripts/Makefile.in | 259 - .../scripts/config.guess | 1420 - .../scripts/config.rpath | 513 - .../scripts/config.sub | 1799 - .../scripts/debugconfig.sh | 3 - .../scripts/depcomp | 423 - .../scripts/install-sh | 250 - .../scripts/ltconfig | 3115 -- .../scripts/ltmain.sh | 6538 ---- .../scripts/missing | 336 - .../scripts/mkinstalldirs | 40 - .../gsmlib-1.10-patched-13ubuntu/stamp-h.in | 1 - .../tests/Makefile.am | 65 - .../tests/Makefile.in | 544 - .../tests/runparser.sh | 12 - .../tests/runsms.sh | 18 - .../tests/runspb.sh | 17 - .../tests/runspb2.sh | 17 - .../tests/runspbi.sh | 18 - .../tests/runssms.sh | 21 - .../gsmlib-1.10-patched-13ubuntu/tests/spb.pb | 11 - .../tests/spb2.pb | 11 - .../tests/spbi1.pb | 3 - .../tests/spbi2-orig.pb | 4 - .../tests/testcb.cc | 40 - .../tests/testgsmlib.cc | 179 - .../tests/testparser-output.txt | 22 - .../tests/testparser.cc | 200 - .../tests/testpb.cc | 52 - .../tests/testpb2.cc | 75 - .../tests/testsms-output.txt | 167 - .../tests/testsms.cc | 80 - .../tests/testsms2.cc | 89 - .../tests/testspb-output.txt | 47 - .../tests/testspb.cc | 81 - .../tests/testspb2-output.txt | 47 - .../tests/testspbi-output.txt | 8 - .../tests/testssms-output.txt | 157 - .../tests/testssms.cc | 68 - .../win32/COPYING | 5 - .../win32/Makefile.am | 17 - .../win32/Makefile.in | 259 - .../win32/README.win | 41 - .../win32/getopt.c | 185 - .../win32/getopt.h | 49 - .../win32/gsm_config.h | 171 - .../win32/gsmctl.dsp | 118 - .../win32/gsmlib.2017.vcxproj | 250 - .../win32/gsmlib.dsp | 232 - .../win32/gsmlib.dsw | 149 - .../win32/gsmlib.sln | 92 - .../win32/gsmpb.dsp | 118 - .../win32/gsmsendsms.dsp | 118 - .../win32/gsmsmsd.dsp | 118 - .../win32/gsmsmsstore.dsp | 119 - .../win32/testgsmlib.dsp | 101 - .../win32/testsms.dsp | 100 - .../win32/testsms2.dsp | 100 - src/mod/endpoints/mod_gsmopen/gsmopen.h | 584 - .../mod_gsmopen/gsmopen_protocol.cpp | 3306 -- .../mod_gsmopen/libctb-0.16/build/COPYRIGHT | 18 - .../mod_gsmopen/libctb-0.16/build/GNUmakefile | 293 - .../mod_gsmopen/libctb-0.16/build/README | 169 - .../mod_gsmopen/libctb-0.16/build/libctb.bkl | 281 - .../libctb-0.16/build/makefile.bcc | 269 - .../libctb-0.16/build/makefile.gcc | 238 - .../mod_gsmopen/libctb-0.16/build/makefile.vc | 260 - .../libctb-0.16/build/makefile.wat | 283 - .../libctb-0.16/include/ctb-0.16/ctb.h | 139 - .../libctb-0.16/include/ctb-0.16/fifo.h | 96 - .../libctb-0.16/include/ctb-0.16/getopt.h | 19 - .../libctb-0.16/include/ctb-0.16/gpib.h | 378 - .../libctb-0.16/include/ctb-0.16/iobase.h | 294 - .../libctb-0.16/include/ctb-0.16/kbhit.h | 10 - .../include/ctb-0.16/linux/serport.h | 94 - .../include/ctb-0.16/linux/timer.h | 139 - .../libctb-0.16/include/ctb-0.16/portscan.h | 25 - .../libctb-0.16/include/ctb-0.16/serport.h | 20 - .../libctb-0.16/include/ctb-0.16/serportx.h | 451 - .../libctb-0.16/include/ctb-0.16/timer.h | 19 - .../include/ctb-0.16/win32/getopt.h | 17 - .../include/ctb-0.16/win32/gpib-32.h | 414 - .../include/ctb-0.16/win32/serport.h | 74 - .../include/ctb-0.16/win32/timer.h | 140 - .../mod_gsmopen/libctb-0.16/lib/EMPTY | 1 - .../mod_gsmopen/libctb-0.16/manual/refman.pdf | Bin 727923 -> 0 bytes .../libctb-0.16/python/module/linux/ctb.py | 455 - .../libctb-0.16/python/module/linux/wxctb.py | 264 - .../libctb-0.16/python/samples/parity.py | 70 - .../libctb-0.16/python/samples/protocol.py | 88 - .../libctb-0.16/python/samples/rtsdtr.py | 53 - .../libctb-0.16/python/src/ctb.html | 353 - .../mod_gsmopen/libctb-0.16/python/src/ctb.py | 455 - .../mod_gsmopen/libctb-0.16/python/src/gpib.i | 96 - .../libctb-0.16/python/src/iobase.i | 59 - .../libctb-0.16/python/src/kbhit.i | 9 - .../libctb-0.16/python/src/linux/makepy.sh | 63 - .../libctb-0.16/python/src/linux/serport.i | 50 - .../libctb-0.16/python/src/linux/timer.i | 37 - .../libctb-0.16/python/src/linux/wxctb.i | 6 - .../libctb-0.16/python/src/linux/wxctb.py | 264 - .../python/src/linux/wxctb_wrap.cxx | 6469 ---- .../libctb-0.16/python/src/serportx.i | 84 - .../libctb-0.16/python/src/win32/makepy.bat | 65 - .../libctb-0.16/python/src/win32/serport.i | 57 - .../libctb-0.16/python/src/win32/timer.i | 39 - .../libctb-0.16/python/src/win32/wxctb.i | 6 - .../libctb-0.16/samples/ctbtest.cpp | 181 - .../mod_gsmopen/libctb-0.16/src/fifo.cpp | 130 - .../mod_gsmopen/libctb-0.16/src/getopt.cpp | 14 - .../mod_gsmopen/libctb-0.16/src/gpib.cpp | 340 - .../mod_gsmopen/libctb-0.16/src/iobase.cpp | 211 - .../mod_gsmopen/libctb-0.16/src/kbhit.cpp | 37 - .../libctb-0.16/src/linux/serport.cpp | 443 - .../libctb-0.16/src/linux/timer.cpp | 97 - .../mod_gsmopen/libctb-0.16/src/portscan.cpp | 109 - .../mod_gsmopen/libctb-0.16/src/serportx.cpp | 104 - .../libctb-0.16/src/win32/getopt.cpp | 66 - .../libctb-0.16/src/win32/serport.cpp | 452 - .../libctb-0.16/src/win32/timer.cpp | 85 - .../mod_gsmopen/mod_gsmopen.2017.vcxproj | 172 - src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp | 3299 -- src/mod/endpoints/mod_gsmopen/win_iconv.c | 1986 - .../endpoints/mod_gsmopen/win_iconv/Makefile | 72 - .../endpoints/mod_gsmopen/win_iconv/iconv.def | 24 - .../endpoints/mod_gsmopen/win_iconv/iconv.h | 5 - .../endpoints/mod_gsmopen/win_iconv/mlang.def | 11 - .../endpoints/mod_gsmopen/win_iconv/mlang.h | 54 - .../mod_gsmopen/win_iconv/readme.txt | 3 - .../mod_gsmopen/win_iconv/win_iconv.c | 1986 - .../mod_gsmopen/win_iconv/win_iconv_test.c | 261 - w32/Setup/Setup.2017.wixproj | 8 - 316 files changed, 1 insertion(+), 143449 deletions(-) delete mode 100644 libs/win32/libcbt/libcbt.2017.vcxproj delete mode 100644 src/mod/endpoints/mod_gsmopen/.gitignore delete mode 100644 src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff delete mode 100644 src/mod/endpoints/mod_gsmopen/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/README delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/Makefile delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/asound.conf delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml.motorola delete mode 100755 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/setmixers delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen.h delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c delete mode 100644 src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/usb-cm-108-2.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/Makefile delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/README delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/asound.conf delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax.conf delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax.h delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.c delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.h delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.c delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.h delete mode 100644 src/mod/endpoints/mod_gsmopen/asterisk/chan_celliax.c delete mode 100755 src/mod/endpoints/mod_gsmopen/asterisk/ciapalo delete mode 100644 src/mod/endpoints/mod_gsmopen/configs/gsmopen.conf.xml delete mode 100644 src/mod/endpoints/mod_gsmopen/driver_usb_dongle/Makefile delete mode 100644 src/mod/endpoints/mod_gsmopen/driver_usb_dongle/README delete mode 100644 src/mod/endpoints/mod_gsmopen/driver_usb_dongle/main.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/README delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ABOUT-NLS delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/AUTHORS delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/COPYING delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ChangeLog delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/INSTALL delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/NEWS delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/README delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/TODO delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acconfig.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acinclude.m4 delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/aclocal.m4 delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmctl.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmpb.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsendsms.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsd.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsstore.cc delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.cron.d delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.default delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.init delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsrequeue delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsspool delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/changelog delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/compat delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/control delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/copyright delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/dirs delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.cron.d delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.default delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.dirs delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.docs delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.examples delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.init delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postinst delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postrm delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsmsiexfer.1 delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/libgsmme-dev.docs delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/rules delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/watch delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/FAQ delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.NLS delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.developers delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmctl.man delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsminfo.man delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmlib.lsm delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmpb.man delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsendsms.man delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsd.man delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsstore.man delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/README.sieme delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiectl.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiexfer.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/g41.patch delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsm_config.h.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.dirs delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.postinst delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.prerm delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.undocumented delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib.spec delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_map_key.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_port.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sysdep.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.h delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/ChangeLog delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/VERSION delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/bindtextdom.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/cat-compat.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dcgettext.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dgettext.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/explodename.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/finddomain.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettextP.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/hash-string.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/intl-compat.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/l10nflist.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/libgettext.h delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/linux-msg.sed delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadinfo.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadmsgcat.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/localealias.c delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/po2tbl.sed.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/textdomain.c delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/xopen-msg.sed delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/Makefile.in.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/POTFILES.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/cat-id-tbl.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/de.gmo delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/de.po delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/gsmlib.pot delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/stamp-cat-id delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.in delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.guess delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.rpath delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.sub delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/debugconfig.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/depcomp delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/install-sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltconfig delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltmain.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/missing delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/mkinstalldirs delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/stamp-h.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.in delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runparser.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runsms.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb2.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspbi.sh delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runssms.sh delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb.pb delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb2.pb delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi1.pb delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi2-orig.pb delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testcb.cc delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testgsmlib.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser-output.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb2.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms-output.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms2.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb-output.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb2-output.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspbi-output.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms-output.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms.cc delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/COPYING delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.am delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.in delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/README.win delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.c delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.h delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsm_config.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmctl.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.2017.vcxproj delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsw delete mode 100755 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.sln delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmpb.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsendsms.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsd.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsstore.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testgsmlib.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms2.dsp delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmopen.h delete mode 100644 src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/COPYRIGHT delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/GNUmakefile delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/README delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/libctb.bkl delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.bcc delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.gcc delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.vc delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.wat delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/ctb.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/fifo.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/getopt.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/gpib.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/iobase.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/kbhit.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/timer.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/portscan.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serport.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/timer.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/getopt.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/gpib-32.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/serport.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/timer.h delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/lib/EMPTY delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/manual/refman.pdf delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/ctb.py delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/wxctb.py delete mode 100755 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/parity.py delete mode 100755 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/protocol.py delete mode 100755 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/rtsdtr.py delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.html delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.py delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/gpib.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/iobase.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/kbhit.i delete mode 100755 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/makepy.sh delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/serport.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/timer.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.py delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb_wrap.cxx delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/serportx.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/makepy.bat delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/serport.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/timer.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/wxctb.i delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/samples/ctbtest.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/fifo.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/getopt.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/gpib.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/iobase.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/kbhit.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/timer.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/portscan.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/serportx.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/serport.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/timer.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/mod_gsmopen.2017.vcxproj delete mode 100644 src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv.c delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/Makefile delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/iconv.def delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/iconv.h delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/mlang.def delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/mlang.h delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/readme.txt delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv.c delete mode 100644 src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv_test.c diff --git a/.gitignore b/.gitignore index 7859b4db2a..6a47caf4ae 100644 --- a/.gitignore +++ b/.gitignore @@ -175,7 +175,6 @@ BuildLog.htm !/libs/win32/ !/libs/speex/win32/ -!/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/ *.suo *.sdf x64/ diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index c27b1ee6fe..459419ff44 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -411,10 +411,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_sms", "src\mod\applicat EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "xmlrpc-c", "xmlrpc-c", "{9DE35039-A8F6-4FBF-B1B6-EB527F802411}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmlib", "src\mod\endpoints\mod_gsmopen\gsmlib\gsmlib-1.10-patched-13ubuntu\win32\gsmlib.2017.vcxproj", "{26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_gsmopen", "src\mod\endpoints\mod_gsmopen\mod_gsmopen.2017.vcxproj", "{74B120FF-6935-4DFE-A142-CDB6BEA99C90}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_redis", "src\mod\applications\mod_redis\mod_redis.2017.vcxproj", "{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libs\win32\libjpeg\libjpeg.2017.vcxproj", "{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}" @@ -448,8 +444,6 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup.2017", "w32\Setup\Set EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_math_fixed_tables", "libs\win32\spandsp\make_math_fixed_tables.2017.vcxproj", "{2386B892-35F5-46CF-A0F0-10394D2FBF9B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcbt", "libs\win32\libcbt\libcbt.2017.vcxproj", "{77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_cielab_luts", "libs\win32\spandsp\make_cielab_luts.2017.vcxproj", "{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opus", "opus", "{ED2CA8B5-8E91-4296-A120-02BB0B674652}" @@ -1834,28 +1828,6 @@ Global {2469B306-B027-4FF2-8815-C9C1EA2CAE79}.Release|Win32.Build.0 = Release|Win32 {2469B306-B027-4FF2-8815-C9C1EA2CAE79}.Release|x64.ActiveCfg = Release|x64 {2469B306-B027-4FF2-8815-C9C1EA2CAE79}.Release|x64.Build.0 = Release|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.All|Win32.ActiveCfg = Release|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.All|x64.ActiveCfg = Release|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.All|x64.Build.0 = Release|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Debug|Win32.ActiveCfg = Debug|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Debug|Win32.Build.0 = Debug|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Debug|x64.ActiveCfg = Debug|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Debug|x64.Build.0 = Debug|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Release|Win32.ActiveCfg = Release|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Release|Win32.Build.0 = Release|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Release|x64.ActiveCfg = Release|x64 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Release|x64.Build.0 = Release|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.All|Win32.ActiveCfg = Release|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.All|x64.ActiveCfg = Release|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.All|x64.Build.0 = Release|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Debug|Win32.ActiveCfg = Debug|Win32 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Debug|Win32.Build.0 = Debug|Win32 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Debug|x64.ActiveCfg = Debug|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Debug|x64.Build.0 = Debug|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|Win32.ActiveCfg = Release|Win32 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|Win32.Build.0 = Release|Win32 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|x64.ActiveCfg = Release|x64 - {74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|x64.Build.0 = Release|x64 {886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|Win32.ActiveCfg = Release|x64 {886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|x64.ActiveCfg = Release|x64 {886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|x64.Build.0 = Release|x64 @@ -1956,17 +1928,6 @@ Global {2386B892-35F5-46CF-A0F0-10394D2FBF9B}.Release|Win32.Build.0 = All|Win32 {2386B892-35F5-46CF-A0F0-10394D2FBF9B}.Release|x64.ActiveCfg = All|Win32 {2386B892-35F5-46CF-A0F0-10394D2FBF9B}.Release|x64.Build.0 = All|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.All|Win32.ActiveCfg = Release|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.All|Win32.Build.0 = Release|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.All|x64.ActiveCfg = Release|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Debug|Win32.ActiveCfg = Debug|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Debug|Win32.Build.0 = Debug|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Debug|x64.ActiveCfg = Debug|x64 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Debug|x64.Build.0 = Debug|x64 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Release|Win32.ActiveCfg = Release|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Release|Win32.Build.0 = Release|Win32 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Release|x64.ActiveCfg = Release|x64 - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9}.Release|x64.Build.0 = Release|x64 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.All|Win32.ActiveCfg = All|Win32 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.All|Win32.Build.0 = All|Win32 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.All|x64.ActiveCfg = All|Win32 @@ -2683,8 +2644,6 @@ Global {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {2469B306-B027-4FF2-8815-C9C1EA2CAE79} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {9DE35039-A8F6-4FBF-B1B6-EB527F802411} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} - {74B120FF-6935-4DFE-A142-CDB6BEA99C90} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {D2396DD7-7D38-473A-ABB7-6F96D65AE1B9} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} @@ -2693,7 +2652,6 @@ Global {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} {B535402E-38D2-4D54-8360-423ACBD17192} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} {2386B892-35F5-46CF-A0F0-10394D2FBF9B} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {ED2CA8B5-8E91-4296-A120-02BB0B674652} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} diff --git a/LICENSE b/LICENSE index d37d77ce56..7d64386fb2 100644 --- a/LICENSE +++ b/LICENSE @@ -1513,21 +1513,6 @@ Files: src/mod/languages/mod_managed/* Copyright: 2008, Michael Giagnocavo License: MPL-1.1 -Files: src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/* - src/mod/languages/mod_lua/lua-mode.el -Copyright: 1995-2007 Free Software Foundation, Inc. -License: GPL-2+ - -Files: src/mod/endpoints/mod_gsmopen/libctb-0.16/* -Copyright: 2001-2010 Joachim Buermann -License: wxWindows - -Files: src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp -Copyright: 2001 ? -License: clueless and unacceptable - FIXME -- this cannot go in Debian -- the license is stated as: - (I think Open Source) - Files: src/mod/endpoints/mod_rtmp/libamf/src/types.[ch] Copyright: 2007, 2008 Marc Noirot License: GPL-2+ @@ -1539,10 +1524,6 @@ Files: src/mod/endpoints/mod_rtmp/rtmp.c Copyright: 2011-2012, Barracuda Networks Inc. License: MPL-1.1 -Files: src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.[ch] -Copyright: 2001-2006 Steve Underwood -License: GPL-2 - Files: src/mod/endpoints/mod_skinny/* src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c Copyright: 2009-2010, Mathieu Parent diff --git a/build/modules.conf.in b/build/modules.conf.in index 445ee5ade1..d114df88f5 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -86,7 +86,6 @@ dialplans/mod_dialplan_asterisk dialplans/mod_dialplan_xml #directories/mod_ldap #endpoints/mod_alsa -#endpoints/mod_gsmopen #endpoints/mod_h323 #endpoints/mod_khomp endpoints/mod_loopback diff --git a/build/modules.conf.most b/build/modules.conf.most index a8ee0d179a..43a5290057 100644 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -83,7 +83,6 @@ dialplans/mod_dialplan_directory dialplans/mod_dialplan_xml directories/mod_ldap #endpoints/mod_alsa -#endpoints/mod_gsmopen #endpoints/mod_h323 #endpoints/mod_khomp endpoints/mod_loopback diff --git a/configure.ac b/configure.ac index 0d9c2efc1a..ed3eb4f32b 100644 --- a/configure.ac +++ b/configure.ac @@ -2183,7 +2183,6 @@ AC_CONFIG_FILES([Makefile src/mod/dialplans/mod_dialplan_xml/Makefile src/mod/directories/mod_ldap/Makefile src/mod/endpoints/mod_alsa/Makefile - src/mod/endpoints/mod_gsmopen/Makefile src/mod/endpoints/mod_h323/Makefile src/mod/endpoints/mod_khomp/Makefile src/mod/endpoints/mod_loopback/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index da2f303d49..484ba54555 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -48,7 +48,6 @@ avoid_mods=( codecs/mod_siren codecs/mod_sangoma_codec codecs/mod_skel_codec - endpoints/mod_gsmopen endpoints/mod_h323 endpoints/mod_khomp endpoints/mod_opal diff --git a/debian/control-modules b/debian/control-modules index 7d6182d790..291ffc1940 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -428,11 +428,6 @@ Description: mod_alsa Adds mod_alsa. Build-Depends: libasound2-dev -Module: endpoints/mod_gsmopen -Description: mod_gsmopen - Adds mod_gsmopen. -Build-Depends: libx11-dev - Module: endpoints/mod_h323 Description: mod_h323 Adds mod_h323. diff --git a/debian/copyright b/debian/copyright index 2270e4a9d5..a2860ea7b9 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1513,21 +1513,6 @@ Files: src/mod/languages/mod_managed/* Copyright: 2008, Michael Giagnocavo License: MPL-1.1 -Files: src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/* - src/mod/languages/mod_lua/lua-mode.el -Copyright: 1995-2007 Free Software Foundation, Inc. -License: GPL-2+ - -Files: src/mod/endpoints/mod_gsmopen/libctb-0.16/* -Copyright: 2001-2010 Joachim Buermann -License: wxWindows - -Files: src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp -Copyright: 2001 ? -License: clueless and unacceptable - FIXME -- this cannot go in Debian -- the license is stated as: - (I think Open Source) - Files: src/mod/endpoints/mod_rtmp/libamf/src/types.[ch] Copyright: 2007, 2008 Marc Noirot License: GPL-2+ @@ -1539,10 +1524,6 @@ Files: src/mod/endpoints/mod_rtmp/rtmp.c Copyright: 2011-2012, Barracuda Networks Inc. License: MPL-1.1 -Files: src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.[ch] -Copyright: 2001-2006 Steve Underwood -License: GPL-2 - Files: src/mod/endpoints/mod_skinny/* src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c Copyright: 2009-2010, Mathieu Parent diff --git a/freeswitch.spec b/freeswitch.spec index 6d7ad663d4..9a28d21324 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -830,16 +830,6 @@ PostgreSQL native support for FreeSWITCH. # FreeSWITCH Endpoint Modules ###################################################################################################################### -#%package endpoint-gsmopen -#Summary: Generic GSM endpoint support for FreeSWITCH open source telephony platform -#Group: System/Libraries -#Requires: %{name} = %{version}-%{release} -# -#%description endpoint-gsmopen -#GSMopen is an endpoint (channel driver) that allows an SMS to be sent or -#received from FreeSWITCH as well as incoming and outgoing GSM voice calls. -#SMS is handled via the standard CHAT API in FreeSWITCH. - #%package endpoint-h323 #Summary: H.323 endpoint support for FreeSWITCH open source telephony platform #Group: System/Libraries @@ -1438,7 +1428,7 @@ ENDPOINTS_MODULES=" \ endpoints/mod_loopback endpoints/mod_portaudio endpoints/mod_rtmp \ endpoints/mod_skinny endpoints/mod_verto endpoints/mod_rtc endpoints/mod_sofia" -## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_gsmopen endpoints/mod_h323 endpoints/mod_khomp +## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_h323 endpoints/mod_khomp ###################################################################################################################### # @@ -2191,9 +2181,6 @@ fi # ###################################################################################################################### -#%files endpoint-gsmopen -#%{MODINSTDIR}/mod_gsmopen.so* - #%files endpoint-h323 #%{MODINSTDIR}/mod_h323.so* diff --git a/libs/win32/libcbt/libcbt.2017.vcxproj b/libs/win32/libcbt/libcbt.2017.vcxproj deleted file mode 100644 index 9df8a3d599..0000000000 --- a/libs/win32/libcbt/libcbt.2017.vcxproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9} - libcbt - - - - StaticLibrary - true - $(DefaultPlatformToolset) - MultiByte - - - StaticLibrary - false - $(DefaultPlatformToolset) - true - MultiByte - - - StaticLibrary - false - MultiByte - $(DefaultPlatformToolset) - - - StaticLibrary - false - MultiByte - $(DefaultPlatformToolset) - - - - - - - - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - .lib - - - - NotUsing - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions) - true - $(SolutionDir)src\mod\endpoints\mod_gsmopen\libctb-0.16\include - 4311;4302;4800;4101;4267;%(DisableSpecificWarnings) - ProgramDatabase - - - Windows - true - - - /ignore:4042 %(AdditionalOptions) - - - - - NotUsing - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions) - true - $(SolutionDir)src\mod\endpoints\mod_gsmopen\libctb-0.16\include - 4311;4302;4800;4101;4267;%(DisableSpecificWarnings) - - - Windows - true - - - /ignore:4042 %(AdditionalOptions) - - - - - Level3 - NotUsing - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - $(SolutionDir)src\mod\endpoints\mod_gsmopen\libctb-0.16\include - 4311;4302;4800;4101;4267;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - /ignore:4042 %(AdditionalOptions) - - - - - Level3 - NotUsing - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - $(SolutionDir)src\mod\endpoints\mod_gsmopen\libctb-0.16\include - 4311;4302;4800;4101;4267;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - /ignore:4042 %(AdditionalOptions) - - - - - - \ No newline at end of file diff --git a/src/mod/Makefile.am b/src/mod/Makefile.am index 54064d49f3..e1cc13fb6d 100644 --- a/src/mod/Makefile.am +++ b/src/mod/Makefile.am @@ -7,7 +7,6 @@ uninstall: $(OUR_UNINSTALL_MODULES) $(OUR_DISABLED_UNINSTALL_MODULES) print_tests: $(OUR_TEST_MODULES) check: $(OUR_CHECK_MODULES) -mod_gsmopen-all: mod_spandsp-all $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODULES) $(OUR_DISABLED_MODULES) $(OUR_DISABLED_CLEAN_MODULES) $(OUR_DISABLED_INSTALL_MODULES) $(OUR_DISABLED_UNINSTALL_MODULES) $(OUR_TEST_MODULES) $(OUR_CHECK_MODULES): @set fnord $$MAKEFLAGS; amf=$$2; \ diff --git a/src/mod/endpoints/mod_gsmopen/.gitignore b/src/mod/endpoints/mod_gsmopen/.gitignore deleted file mode 100644 index 9fdeeb1412..0000000000 --- a/src/mod/endpoints/mod_gsmopen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -!/gsmlib/gsmlib-*/aclocal.m4 -!/gsmlib/gsmlib-*/configure diff --git a/src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt b/src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt deleted file mode 100644 index 4cbedeae63..0000000000 --- a/src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt +++ /dev/null @@ -1,9 +0,0 @@ -This patch (updated to be applied today) was sent via Jira by royj@yandex.ru, with Jira issue FS-4338. - -Apply in this way: -# patch -p6 < FREEBSD_patch.diff - -I have not tested it, but it works for him. -Please open another Jira issue if anything wrong. - --giovanni diff --git a/src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff b/src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff deleted file mode 100644 index cd5613a2d7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff +++ /dev/null @@ -1,171 +0,0 @@ -diff --git a/src/mod/endpoints/mod_gsmopen/Makefile b/src/mod/endpoints/mod_gsmopen/Makefile -index 18943c8..5324c52 100644 ---- a/src/mod/endpoints/mod_gsmopen/Makefile -+++ b/src/mod/endpoints/mod_gsmopen/Makefile -@@ -1,5 +1,5 @@ - MODNAME=mod_gsmopen --LOCAL_CFLAGS += -I../../../../libs/spandsp/src -I../../../..//libs/tiff-4.0.2/libtiff -DGSMOPEN_C_VER=\"`git log -1 --format="%h" gsmopen_protocol.cpp`\" -DMODGSMOPEN_C_VER=\"`git log -1 --format="%h" mod_gsmopen.cpp`\" -+LOCAL_CFLAGS += -I/usr/local/include -I../../../../libs/spandsp/src -I../../../..//libs/tiff-4.0.2/libtiff -DGSMOPEN_C_VER=\"`git log -1 --format="%h" gsmopen_protocol.cpp`\" -DMODGSMOPEN_C_VER=\"`git log -1 --format="%h" mod_gsmopen.cpp`\" - LOCAL_LDFLAGS=-L../../../../libs/spandsp/src -lspandsp -lctb-0.16 -lgsmme - LOCAL_OBJS=gsmopen_protocol.o - include ../../../../build/modmake.rules -diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp -index 5bdda08..73ef93d 100644 ---- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp -+++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp -@@ -2356,7 +2356,7 @@ int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outb - iconv_t iconv_format; - int iconv_res; - char *outbuf; -- char *inbuf; -+ //char *inbuf; - size_t inbytesleft; - int c; - char stringa[5]; -@@ -2376,9 +2376,10 @@ int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outb - } - - outbuf = utf8_out; -- inbuf = converted; -+ const char *inbuf = converted; - -- iconv_format = iconv_open("UTF8", "UCS-2BE"); -+ //iconv_format = iconv_open("UTF8", "UCS-2BE"); -+ iconv_format = iconv_open("UTF-8", "UCS-2BE"); - //iconv_format = iconv_open("UTF8", "UCS2"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); -@@ -2417,12 +2418,12 @@ int utf8_to_iso_8859_1(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, c - iconv_t iconv_format; - int iconv_res; - char *outbuf; -- char *inbuf; -+ //char *inbuf; - - outbuf = iso_8859_1_out; -- inbuf = utf8_in; -+ const char *inbuf = utf8_in; - -- iconv_format = iconv_open("ISO_8859-1", "UTF8"); -+ iconv_format = iconv_open("ISO_8859-1", "UTF-8"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; -@@ -2467,7 +2468,7 @@ int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, - iconv_t iconv_format; - int iconv_res; - char *outbuf; -- char *inbuf; -+ //char *inbuf; - size_t inbytesleft; - //int c; - //char stringa[5]; -@@ -2477,9 +2478,9 @@ int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, - DEBUGA_GSMOPEN("iso_8859_1_in=%s\n", GSMOPEN_P_LOG, iso_8859_1_in); - - outbuf = utf8_out; -- inbuf = iso_8859_1_in; -+ const char *inbuf = iso_8859_1_in; - -- iconv_format = iconv_open("UTF8", "ISO_8859-1"); -+ iconv_format = iconv_open("UTF-8", "ISO_8859-1"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; -@@ -2514,7 +2515,7 @@ int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *u - iconv_t iconv_format; - int iconv_res; - char *outbuf; -- char *inbuf; -+ //char *inbuf; - char converted[16000]; - int i; - char stringa[16]; -@@ -2523,9 +2524,9 @@ int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *u - memset(converted, '\0', sizeof(converted)); - - outbuf = converted; -- inbuf = utf8_in; -+ const char *inbuf = utf8_in; - -- iconv_format = iconv_open("UCS-2BE", "UTF8"); -+ iconv_format = iconv_open("UCS-2BE", "UTF-8"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; -diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h -index d88528b..f8851cc 100644 ---- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h -+++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h -@@ -10,7 +10,7 @@ - ///////////////////////////////////////////////////////////////////////////// - - #include "ctb-0.16/serportx.h" --#include -+//#include - #include - - namespace ctb { -@@ -40,7 +40,7 @@ namespace ctb { - need the errors during a active connection, we must save the actual - error numbers in this separate structurs. - */ -- struct serial_icounter_struct save_info, last_info; -+ //struct serial_icounter_struct save_info, last_info; - - /*! - \brief adaptor member function, to convert the plattform independent -diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp -index a369abc..d190567 100644 ---- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp -+++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp -@@ -136,7 +136,7 @@ namespace ctb { - // - int SerialPort::Ioctl(int cmd, void* args) - { -- int count = 0; -+ /* int count = 0; - int err = 0; - struct serial_icounter_struct info; - SerialPort_EINFO einfo; -@@ -184,7 +184,8 @@ namespace ctb { - return -1; - } - last_info = info; -- return 0; -+ return 0;*/ -+ return -1; - }; - - int SerialPort::IsOpen() -@@ -292,9 +293,9 @@ namespace ctb { - // request the actual numbers of breaks, framing, overrun - // and parity errors (because Linux summing all of them during - // system lifetime, not only while serial port is open. -- ioctl(fd,TIOCGICOUNT,&save_info); -+ //ioctl(fd,TIOCGICOUNT,&save_info); - // it's also careless, but we assume, that there was no error -- last_info = save_info; -+ //last_info = save_info; - - // in case of a non-standard rate, the termios struct have to set - // with the B38400 rate, see above! -@@ -359,7 +360,7 @@ namespace ctb { - - int SerialPort::SetBaudrateAny( int baudrate ) - { -- struct serial_struct ser_info; -+ /* struct serial_struct ser_info; - - int result = ioctl( fd, TIOCGSERIAL, &ser_info ); - -@@ -369,7 +370,8 @@ namespace ctb { - - result = ioctl( fd, TIOCSSERIAL, &ser_info ); - -- return result; -+ return result;*/ -+ return -1; - } - - int SerialPort::SetBaudrateStandard( int baudrate ) diff --git a/src/mod/endpoints/mod_gsmopen/Makefile.am b/src/mod/endpoints/mod_gsmopen/Makefile.am deleted file mode 100644 index e7c20f257c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_gsmopen - -mod_LTLIBRARIES = mod_gsmopen.la -mod_gsmopen_la_SOURCES = mod_gsmopen.cpp gsmopen_protocol.cpp -mod_gsmopen_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) -mod_gsmopen_la_CPPFLAGS = $(SPANDSP_CFLAGS) -I. -mod_gsmopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LIBS) -mod_gsmopen_la_LDFLAGS = -avoid-version -module -no-undefined -lctb-0.16 -lgsmme diff --git a/src/mod/endpoints/mod_gsmopen/README b/src/mod/endpoints/mod_gsmopen/README deleted file mode 100644 index 30955a2157..0000000000 --- a/src/mod/endpoints/mod_gsmopen/README +++ /dev/null @@ -1,14 +0,0 @@ -GSMopen, GSM Endpoint and Trunk - -All documentation on compiling, using, configuring, -tricks and tweaks, possible problems at: - -http://wiki.freeswitch.org/wiki/Gsmopen - -Enjoy - --giovanni - - -< gmaruzz at gmail dot com > - diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/Makefile b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/Makefile deleted file mode 100644 index 15e3388bd2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -MODNAME=mod_gsmopen -SVNDEF := -D'GSMOPEN_SVN_VERSION="$(shell svnversion -n .)"' -#LOCAL_CFLAGS += $(SVNDEF) -Wno-error=address -DNO_GSMLIB -I../../../../../../libs/spandsp/src -I../../../../../..//libs/tiff-4.0.2/libtiff -LOCAL_CFLAGS += $(SVNDEF) -DNO_GSMLIB -I../../../../../../libs/spandsp/src -I../../../../../..//libs/tiff-4.0.2/libtiff -LOCAL_LDFLAGS=-lasound -L../../../../../../libs/spandsp/src -lspandsp -LOCAL_OBJS=gsmopen_protocol.o -include ../../../../../../build/modmake.rules diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/asound.conf b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/asound.conf deleted file mode 100644 index c3a8068e9c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/asound.conf +++ /dev/null @@ -1,6 +0,0 @@ -defaults.pcm.rate_converter "linear" -#defaults.pcm.rate_converter "speexrate" -#defaults.pcm.dmix.rate 16000 -#defaults.pcm.dsnoop.rate 16000 - - diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml deleted file mode 100644 index d21a4c1969..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml.motorola b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml.motorola deleted file mode 100644 index a38257ef1c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/gsmopen.conf.xml.motorola +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/setmixers b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/setmixers deleted file mode 100755 index 063904b9cf..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/configs/setmixers +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# ALSA can manage a max of 8 cards -CARD_LIST="0 1 2 3 4 5 6 7" - -for i in $CARD_LIST; do - -#amixer -c ${i} -q set Mic 0% mute -amixer -c ${i} -q set Speaker 70% unmute >/dev/null 2>&1 -amixer -c ${i} -q set Mic cap mute 70% >/dev/null 2>&1 -amixer -c ${i} -q set "Auto Gain Control" off >/dev/null 2>&1 - -done diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen.h b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen.h deleted file mode 100644 index cf8561a683..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen.h +++ /dev/null @@ -1,665 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli (gmaruzz@gmail.com) - * - * - * Further Contributors: - * - * - * - * mod_gsmopen.c -- GSM compatible Endpoint Module - * - */ - -#define __STDC_LIMIT_MACROS - -#ifdef WIN32 -#define HAVE_VSNPRINTF -#pragma warning(disable: 4290) -#endif //WIN32 - -#define MY_EVENT_INCOMING_SMS "gsmopen::incoming_sms" -#define MY_EVENT_DUMP "gsmopen::dump_event" -#define MY_EVENT_ALARM "gsmopen::alarm" - -#define ALARM_FAILED_INTERFACE 0 -#define ALARM_NO_NETWORK_REGISTRATION 1 -#define ALARM_ROAMING_NETWORK_REGISTRATION 2 -#define ALARM_NETWORK_NO_SERVICE 3 -#define ALARM_NETWORK_NO_SIGNAL 4 -#define ALARM_NETWORK_LOW_SIGNAL 5 - - - - - -#undef GIOVA48 - -#ifndef GIOVA48 -#define SAMPLES_PER_FRAME 160 -#else // GIOVA48 -#define SAMPLES_PER_FRAME 960 -#endif // GIOVA48 - - -#ifndef GIOVA48 -#define GSMOPEN_FRAME_SIZE 160 -#else //GIOVA48 -#define GSMOPEN_FRAME_SIZE 960 -#endif //GIOVA48 -#define SAMPLERATE_GSMOPEN 8000 - -#ifndef NO_ALSA -#define GSMOPEN_ALSA -#endif // NO_ALSA -#include -#ifndef WIN32 -#include -#include -#include -#endif //WIN32 -//#include - -#ifdef GSMOPEN_ALSA -#define ALSA_PCM_NEW_HW_PARAMS_API -#define ALSA_PCM_NEW_SW_PARAMS_API -#include -#endif /* GSMOPEN_ALSA */ - -#ifdef GSMOPEN_PORTAUDIO -#include "pablio.h" -#undef WANT_SPEEX -#ifdef WANT_SPEEX -#include "speex/speex_preprocess.h" -#include "speex/speex_echo.h" -#endif /* WANT_SPEEX */ -#endif// GSMOPEN_PORTAUDIO - -//#include "celliax_spandsp.h" -#ifndef WIN32 -#include -//#include -//#include -//#include -#endif //WIN32 - -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -#include -#include - -#ifdef _MSC_VER -//Windows macro for FD_SET includes a warning C4127: conditional expression is constant -#pragma warning(push) -#pragma warning(disable:4127) -#endif - -#define PROTOCOL_ALSA_VOICEMODEM 4 -#define PROTOCOL_AT 2 -#define PROTOCOL_FBUS2 1 -#define PROTOCOL_NO_SERIAL 3 - -#define AT_BUFSIZ 8192 -//FIXME FIXME FIXME #define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */ -#define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */ -//FIXME FIXME FIXME #define AT_MESG_MAX_LINES 256 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */ -#define AT_MESG_MAX_LINES 20 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */ - -//#define SAMPLERATE_GSMOPEN 16000 -//#define SAMPLES_PER_FRAME SAMPLERATE_GSMOPEN/50 - -#ifndef GSMOPEN_SVN_VERSION -#define GSMOPEN_SVN_VERSION switch_version_full() -#endif /* GSMOPEN_SVN_VERSION */ - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_CODEC = (1 << 7), - TFLAG_BREAK = (1 << 8) -} TFLAGS; - -typedef enum { - GFLAG_MY_CODEC_PREFS = (1 << 0) -} GFLAGS; - -#define DEBUGA_GSMOPEN(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][DEBUG_GSMOPEN %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_CALL(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_PBX(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define ERRORA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][ERRORA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define WARNINGA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][WARNINGA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define NOTICA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][NOTICA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); - -#define GSMOPEN_P_LOG (void *)NULL, (unsigned long)55, __LINE__, tech_pvt ? tech_pvt->name ? tech_pvt->name : "none" : "none", -1, tech_pvt ? tech_pvt->interface_state : -1, tech_pvt ? tech_pvt->phone_callflow : -1 - -/*********************************/ -#define GSMOPEN_CAUSE_NORMAL 1 -#define GSMOPEN_CAUSE_FAILURE 2 -#define GSMOPEN_CAUSE_NO_ANSWER 3 -/*********************************/ -#define GSMOPEN_FRAME_DTMF 1 -/*********************************/ -#define GSMOPEN_CONTROL_RINGING 1 -#define GSMOPEN_CONTROL_ANSWER 2 -#define GSMOPEN_CONTROL_HANGUP 3 -#define GSMOPEN_CONTROL_BUSY 4 - -/*********************************/ -#define GSMOPEN_STATE_IDLE 0 -#define GSMOPEN_STATE_DOWN 1 -#define GSMOPEN_STATE_RING 2 -#define GSMOPEN_STATE_DIALING 3 -#define GSMOPEN_STATE_BUSY 4 -#define GSMOPEN_STATE_UP 5 -#define GSMOPEN_STATE_RINGING 6 -#define GSMOPEN_STATE_PRERING 7 -#define GSMOPEN_STATE_ERROR_DOUBLE_CALL 8 -#define GSMOPEN_STATE_SELECTED 9 -#define GSMOPEN_STATE_HANGUP_REQUESTED 10 -#define GSMOPEN_STATE_PREANSWER 11 -/*********************************/ -/* call flow from the device */ -#define CALLFLOW_CALL_IDLE 0 -#define CALLFLOW_CALL_DOWN 1 -#define CALLFLOW_INCOMING_RING 2 -#define CALLFLOW_CALL_DIALING 3 -#define CALLFLOW_CALL_LINEBUSY 4 -#define CALLFLOW_CALL_ACTIVE 5 -#define CALLFLOW_INCOMING_HANGUP 6 -#define CALLFLOW_CALL_RELEASED 7 -#define CALLFLOW_CALL_NOCARRIER 8 -#define CALLFLOW_CALL_INFLUX 9 -#define CALLFLOW_CALL_INCOMING 10 -#define CALLFLOW_CALL_FAILED 11 -#define CALLFLOW_CALL_NOSERVICE 12 -#define CALLFLOW_CALL_OUTGOINGRESTRICTED 13 -#define CALLFLOW_CALL_SECURITYFAIL 14 -#define CALLFLOW_CALL_NOANSWER 15 -#define CALLFLOW_STATUS_FINISHED 16 -#define CALLFLOW_STATUS_CANCELLED 17 -#define CALLFLOW_STATUS_FAILED 18 -#define CALLFLOW_STATUS_REFUSED 19 -#define CALLFLOW_STATUS_RINGING 20 -#define CALLFLOW_STATUS_INPROGRESS 21 -#define CALLFLOW_STATUS_UNPLACED 22 -#define CALLFLOW_STATUS_ROUTING 23 -#define CALLFLOW_STATUS_EARLYMEDIA 24 -#define CALLFLOW_INCOMING_CALLID 25 -#define CALLFLOW_STATUS_REMOTEHOLD 26 -#define CALLFLOW_CALL_REMOTEANSWER 27 -#define CALLFLOW_CALL_HANGUP_REQUESTED 28 - -/*********************************/ - -#define AT_OK 0 -#define AT_ERROR 1 - -#define GSMOPEN_MAX_INTERFACES 64 - -#ifndef WIN32 -struct GSMopenHandles { - //Window gsmopen_win; - //Display *disp; - //Window win; - int currentuserhandle; - int api_connected; - int fdesc[2]; -}; -#else //WIN32 - -struct GSMopenHandles { - HWND win32_hInit_MainWindowHandle; - HWND win32_hGlobal_GSMAPIWindowHandle; - HINSTANCE win32_hInit_ProcessHandle; - char win32_acInit_WindowClassName[128]; - UINT win32_uiGlobal_MsgID_GSMControlAPIAttach; - UINT win32_uiGlobal_MsgID_GSMControlAPIDiscover; - int currentuserhandle; - int api_connected; - switch_file_t *fdesc[2]; -}; - -#endif //WIN32 - -/*! - * \brief structure for storing the results of AT commands, in an array of AT_MESG_MAX_LINES * AT_MESG_MAX_LENGTH chars - */ -struct s_result { - int elemcount; - char result[AT_MESG_MAX_LINES][AT_MESG_MAX_LENGTH]; -}; - -struct ciapa_struct { - int state; - int hangupcause; -}; -typedef struct ciapa_struct ciapa_t; - -struct private_object { - unsigned int flags; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_frame_t read_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - char session_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_caller_profile_t *caller_profile; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - - char id[80]; - char name[80]; - char dialplan[80]; - char context[80]; - char dial_regex[256]; - char fail_dial_regex[256]; - char hold_music[256]; - char type[256]; - char X11_display[256]; -#ifdef WIN32 - unsigned short tcp_cli_port; - unsigned short tcp_srv_port; -#else - int tcp_cli_port; - int tcp_srv_port; -#endif - struct GSMopenHandles GSMopenHandles; - - int interface_state; /*!< \brief 'state' of the interface (channel) */ - char language[80]; /*!< \brief default Asterisk dialplan language for this interface */ - char exten[80]; /*!< \brief default Asterisk dialplan extension for this interface */ - int gsmopen_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */ - char callid_name[50]; - char callid_number[50]; - double playback_boost; - double capture_boost; - int stripmsd; - char gsmopen_call_id[512]; - int gsmopen_call_ongoing; - char gsmopen_friends[4096]; - char gsmopen_fullname[512]; - char gsmopen_displayname[512]; - int phone_callflow; /*!< \brief 'callflow' of the gsmopen interface (as opposed to phone interface) */ - int gsmopen; /*!< \brief config flag, bool, GSM support on this interface (0 if false, -1 if true) */ - int control_to_send; -#ifdef WIN32 - switch_file_t *audiopipe[2]; - switch_file_t *audiogsmopenpipe[2]; - switch_file_t *gsmopen_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ -#else /* WIN32 */ - int audiopipe[2]; - int audiogsmopenpipe[2]; - int gsmopen_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ -#endif /* WIN32 */ - switch_thread_t *tcp_srv_thread; - switch_thread_t *tcp_cli_thread; - switch_thread_t *gsmopen_signaling_thread; - switch_thread_t *gsmopen_api_thread; - //short audiobuf[SAMPLES_PER_FRAME]; - //int audiobuf_is_loaded; - - //int phonebook_listing; - //int phonebook_querying; - //int phonebook_listing_received_calls; - - //int phonebook_first_entry; - //int phonebook_last_entry; - //int phonebook_number_lenght; - //int phonebook_text_lenght; - int gsmopen_dir_entry_extension_prefix; - char gsmopen_user[256]; - char gsmopen_password[256]; - char destination[256]; - struct timeval answer_time; - - struct timeval transfer_time; - char transfer_callid_number[50]; - char gsmopen_transfer_call_id[512]; - int running; - unsigned long ib_calls; - unsigned long ob_calls; - unsigned long ib_failed_calls; - unsigned long ob_failed_calls; - - - char controldevice_name[50]; /*!< \brief name of the serial device controlling the interface, possibly none */ - int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */ - char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */ - int controldevfd; /*!< \brief serial controlling file descriptor for this interface */ - //pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */ -#ifdef WIN32 - int controldevice_speed; -#else - speed_t controldevice_speed; -#endif// WIN32 - int controldev_dead; - - char at_dial_pre_number[64]; - char at_dial_post_number[64]; - char at_dial_expect[64]; - unsigned int at_early_audio; - char at_hangup[64]; - char at_hangup_expect[64]; - char at_answer[64]; - char at_answer_expect[64]; - unsigned int at_initial_pause; - char at_preinit_1[64]; - char at_preinit_1_expect[64]; - char at_preinit_2[64]; - char at_preinit_2_expect[64]; - char at_preinit_3[64]; - char at_preinit_3_expect[64]; - char at_preinit_4[64]; - char at_preinit_4_expect[64]; - char at_preinit_5[64]; - char at_preinit_5_expect[64]; - unsigned int at_after_preinit_pause; - - char at_postinit_1[64]; - char at_postinit_1_expect[64]; - char at_postinit_2[64]; - char at_postinit_2_expect[64]; - char at_postinit_3[64]; - char at_postinit_3_expect[64]; - char at_postinit_4[64]; - char at_postinit_4_expect[64]; - char at_postinit_5[64]; - char at_postinit_5_expect[64]; - - char at_send_dtmf[64]; - - char at_query_battchg[64]; - char at_query_battchg_expect[64]; - char at_query_signal[64]; - char at_query_signal_expect[64]; - char at_call_idle[64]; - char at_call_incoming[64]; - char at_call_active[64]; - char at_call_failed[64]; - char at_call_calling[64]; - -#define CIEV_STRING_SIZE 64 - char at_indicator_noservice_string[64]; - char at_indicator_nosignal_string[64]; - char at_indicator_lowsignal_string[64]; - char at_indicator_lowbattchg_string[64]; - char at_indicator_nobattchg_string[64]; - char at_indicator_callactive_string[64]; - char at_indicator_nocallactive_string[64]; - char at_indicator_nocallsetup_string[64]; - char at_indicator_callsetupincoming_string[64]; - char at_indicator_callsetupoutgoing_string[64]; - char at_indicator_callsetupremoteringing_string[64]; - - int at_indicator_callp; - int at_indicator_callsetupp; - int at_indicator_roamp; - int at_indicator_battchgp; - int at_indicator_servicep; - int at_indicator_signalp; - - int at_has_clcc; - int at_has_ecam; - - char at_cmgw[16]; - int no_ucs2; - time_t gsmopen_serial_sync_period; - - time_t gsmopen_serial_synced_timestamp; - struct s_result line_array; - - - int unread_sms_msg_id; - int reading_sms_msg; - char sms_message[4800]; - char sms_sender[256]; - char sms_date[256]; - char sms_userdataheader[256]; - char sms_body[4800]; - char sms_datacodingscheme[256]; - char sms_servicecentreaddress[256]; - int sms_messagetype; - int sms_cnmi_not_supported; - int sms_pdu_not_supported; - //char sms_receiving_program[256]; - - - struct timeval call_incoming_time; - switch_mutex_t *controldev_lock; - - int phonebook_listing; - int phonebook_querying; - int phonebook_listing_received_calls; - - int phonebook_first_entry; - int phonebook_last_entry; - int phonebook_number_lenght; - int phonebook_text_lenght; - FILE *phonebook_writing_fp; - - struct timeval ringtime; - ciapa_t *owner; -#ifdef GSMOPEN_ALSA - snd_pcm_t *alsac; /*!< \brief handle of the ALSA capture audio device */ - snd_pcm_t *alsap; /*!< \brief handle of the ALSA playback audio device */ - char alsacname[50]; /*!< \brief name of the ALSA capture audio device */ - char alsapname[50]; /*!< \brief name of the ALSA playback audio device */ - int alsa_period_size; /*!< \brief ALSA period_size, in byte */ - int alsa_periods_in_buffer; /*!< \brief how many periods in ALSA buffer, to calculate buffer_size */ - unsigned long int alsa_buffer_size; /*!< \brief ALSA buffer_size, in byte */ - int alsawrite_filled; - int alsa_capture_is_mono; - int alsa_play_is_mono; - struct pollfd pfd; -#endif // GSMOPEN_ALSA - - time_t audio_play_reset_timestamp; - int audio_play_reset_period; - - switch_timer_t timer_read; - switch_timer_t timer_write; - teletone_dtmf_detect_state_t dtmf_detect; - switch_time_t old_dtmf_timestamp; - - int no_sound; - -#ifdef GSMOPEN_PORTAUDIO - int speexecho; - int speexpreprocess; - int portaudiocindex; /*!< \brief Index of the Portaudio capture audio device */ - int portaudiopindex; /*!< \brief Index of the Portaudio playback audio device */ - PABLIO_Stream *stream; - -#ifdef WANT_SPEEX - SpeexPreprocessState *preprocess; - SpeexEchoState *echo_state; -#endif// WANT_SPEEX -#endif// GSMOPEN_PORTAUDIO - dtmf_rx_state_t dtmf_state; - int active; - int home_network_registered; - int roaming_registered; - int not_registered; - int got_signal; - char imei[128]; - int requesting_imei; - char imsi[128]; - int requesting_imsi; - int network_creg_not_supported; - char creg[128]; - -}; - -typedef struct private_object private_t; - -void *SWITCH_THREAD_FUNC gsmopen_api_thread_func(switch_thread_t * thread, void *obj); -int gsmopen_audio_read(private_t * tech_pvt); -int gsmopen_audio_init(private_t * tech_pvt); -int gsmopen_signaling_read(private_t * tech_pvt); - -int gsmopen_call(private_t * tech_pvt, char *idest, int timeout); -int gsmopen_senddigit(private_t * tech_pvt, char digit); - -void *gsmopen_do_tcp_srv_thread_func(void *obj); -void *SWITCH_THREAD_FUNC gsmopen_do_tcp_srv_thread(switch_thread_t * thread, void *obj); - -void *gsmopen_do_tcp_cli_thread_func(void *obj); -void *SWITCH_THREAD_FUNC gsmopen_do_tcp_cli_thread(switch_thread_t * thread, void *obj); - -void *gsmopen_do_gsmopenapi_thread_func(void *obj); -void *SWITCH_THREAD_FUNC gsmopen_do_gsmopenapi_thread(switch_thread_t * thread, void *obj); -int dtmf_received(private_t * tech_pvt, char *value); -int start_audio_threads(private_t * tech_pvt); -int new_inbound_channel(private_t * tech_pvt); -int outbound_channel_answered(private_t * tech_pvt); -//int gsmopen_signaling_write(private_t * tech_pvt, char *msg_to_gsmopen); -#if defined(WIN32) && !defined(__CYGWIN__) -int gsmopen_pipe_read(switch_file_t * pipe, short *buf, int howmany); -int gsmopen_pipe_write(switch_file_t * pipe, short *buf, int howmany); -/* Visual C do not have strsep ? */ -char *strsep(char **stringp, const char *delim); -#else -int gsmopen_pipe_read(int pipe, short *buf, int howmany); -int gsmopen_pipe_write(int pipe, short *buf, int howmany); -#endif /* WIN32 */ -int gsmopen_close_socket(unsigned int fd); -private_t *find_available_gsmopen_interface_rr(private_t * tech_pvt_calling); -int remote_party_is_ringing(private_t * tech_pvt); -int remote_party_is_early_media(private_t * tech_pvt); -//int gsmopen_answer(private_t * tech_pvt, char *id, char *value); -#if 0 -int gsmopen_transfer(private_t * tech_pvt, char *id, char *value); -#endif //0 -int gsmopen_socket_create_and_bind(private_t * tech_pvt, int *which_port); - - - - - -void *gsmopen_do_controldev_thread(void *data); -#ifdef WIN32 -int gsmopen_serial_init(private_t * tech_pvt, int controldevice_speed); -#else -int gsmopen_serial_init(private_t * tech_pvt, speed_t controldevice_speed); -#endif //WIN32 -int gsmopen_serial_monitor(private_t * tech_pvt); -int gsmopen_serial_sync(private_t * tech_pvt); -int gsmopen_serial_sync_AT(private_t * tech_pvt); -int gsmopen_serial_config(private_t * tech_pvt); -int gsmopen_serial_config_AT(private_t * tech_pvt); - -#define gsmopen_serial_write_AT_expect(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 1, 2) -#define gsmopen_serial_write_AT_expect_noexpcr(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 0, 2) -#define gsmopen_serial_write_AT_expect_noexpcr_tout(P, D, S, T) gsmopen_serial_write_AT_expect1(P, D, S, 0, T) -// 20.5 sec timeout, used for querying the SIM and sending SMSs -#define gsmopen_serial_write_AT_expect_longtime(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 1, 20) -#define gsmopen_serial_write_AT_expect_longtime_noexpcr(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 0, 20) -int gsmopen_serial_write_AT(private_t * tech_pvt, const char *data); -int gsmopen_serial_write_AT_nocr(private_t * tech_pvt, const char *data); -int gsmopen_serial_write_AT_ack(private_t * tech_pvt, const char *data); -int gsmopen_serial_write_AT_ack_nocr_longtime(private_t * tech_pvt, const char *data); -int gsmopen_serial_write_AT_noack(private_t * tech_pvt, const char *data); -int gsmopen_serial_write_AT_expect1(private_t * tech_pvt, const char *data, const char *expected_string, int expect_crlf, int seconds); -int gsmopen_serial_AT_expect(private_t * tech_pvt, const char *expected_string, int expect_crlf, int seconds); -int gsmopen_serial_read_AT(private_t * tech_pvt, int look_for_ack, int timeout_usec, int timeout_sec, const char *expected_string, int expect_crlf); -int gsmopen_serial_read(private_t * tech_pvt); -#ifdef NOTDEF -int gsmopen_serial_getstatus(private_t * tech_pvt); -int gsmopen_serial_hangup(private_t * tech_pvt); -int gsmopen_serial_answer(private_t * tech_pvt); -int gsmopen_serial_answer_AT(private_t * tech_pvt); -int gsmopen_serial_hangup_AT(private_t * tech_pvt); -int gsmopen_serial_call_AT(private_t * tech_pvt, char *dstr); -int gsmopen_serial_getstatus_AT(private_t * tech_pvt); -#endif // NOTDEF -#define RESULT_FAILURE 0 -#define RESULT_SUCCESS 1 -int utf_to_ucs2(private_t * tech_pvt, char *utf_in, size_t inbytesleft, char *ucs2_out, size_t outbytesleft); -int ucs2_to_utf8(private_t * tech_pvt, char *ucs2_in, char *utf8_out, size_t outbytesleft); -//#define PUSHA_UNLOCKA(x) pthread_cleanup_push(gsmopen_unlocka_log, (void *) x); -//#define POPPA_UNLOCKA(x) pthread_cleanup_pop(0); - -#define PUSHA_UNLOCKA(x) if(option_debug > 100) ERRORA("PUSHA_UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); -#define POPPA_UNLOCKA(x) if(option_debug > 100) ERRORA("POPPA_UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); -//#define LOKKA(x) if(option_debug > 100) ERRORA("LOKKA: %p\n", GSMOPEN_P_LOG, (void *)x); -#define LOKKA(x) switch_mutex_lock(x); -#define UNLOCKA(x) switch_mutex_unlock(x); -//#define UNLOCKA(x) if(option_debug > 100) ERRORA("UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); - -#define gsmopen_queue_control(x, y) ERRORA("gsmopen_queue_control: %p, %d\n", GSMOPEN_P_LOG, (void *)x, y); - -#define ast_setstate(x, y) ERRORA("ast_setstate: %p, %d\n", GSMOPEN_P_LOG, (void *)x, y); - -int gsmopen_serial_read(private_t * tech_pvt); -int gsmopen_answer(private_t * tech_pvt); -int gsmopen_serial_answer(private_t * tech_pvt); -int gsmopen_serial_answer_AT(private_t * tech_pvt); -int gsmopen_serial_hangup(private_t * tech_pvt); -int gsmopen_serial_hangup_AT(private_t * tech_pvt); -int gsmopen_hangup(private_t * tech_pvt); -int gsmopen_serial_call(private_t * tech_pvt, char *dstr); -int gsmopen_serial_call_AT(private_t * tech_pvt, char *dstr); -int gsmopen_sendsms(private_t * tech_pvt, char *dest, char *text); - -#ifdef GSMOPEN_ALSA -int alsa_init(private_t * tech_pvt); -int alsa_shutdown(private_t * tech_pvt); -snd_pcm_t *alsa_open_dev(private_t * tech_pvt, snd_pcm_stream_t stream); -int alsa_write(private_t * tech_pvt, short *data, int datalen); -int alsa_read(private_t * tech_pvt, short *data, int datalen); - -#endif /* GSMOPEN_ALSA */ - - -void gsmopen_store_boost(char *s, double *boost); -int gsmopen_sound_boost(void *data, int samples_num, double boost); -int sms_incoming(private_t * tech_pvt); -int gsmopen_ring(private_t * tech_pvt); - -int iso_8859_1_to_utf8(private_t * tech_pvt, char *iso_8859_1_in, char *utf8_out, size_t outbytesleft); -int gsmopen_serial_getstatus_AT(private_t * tech_pvt); - - -#ifdef GSMOPEN_PORTAUDIO - -int gsmopen_portaudio_devlist(private_t *tech_pvt); - -int gsmopen_portaudio_init(private_t *tech_pvt); - -int gsmopen_portaudio_write(private_t * tech_pvt, short *data, int datalen); - -int gsmopen_portaudio_read(private_t * tech_pvt, short *data, int datalen); - - -int gsmopen_portaudio_shutdown(private_t *tech_pvt); - -#endif // GSMOPEN_PORTAUDIO -int dump_event(private_t *tech_pvt); -int alarm_event(private_t * tech_pvt, int alarm_code, const char *alarm_message); -int dump_event_full(private_t * tech_pvt, int is_alarm, int alarm_code, const char *alarm_message); diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c deleted file mode 100644 index 5a97ffa873..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c +++ /dev/null @@ -1,4009 +0,0 @@ -#include "gsmopen.h" -//#include - -#ifndef NO_GSMLIB -#include -#ifdef WIN32 -#include -#else -#include -#endif -#include -#include - - -using namespace std; -using namespace gsmlib; -#endif// NO_GSMLIB - -#ifdef ASTERISK -#define gsmopen_sleep usleep -#define gsmopen_strncpy strncpy -#define tech_pvt p -extern int gsmopen_debug; -extern char *gsmopen_console_active; -#else /* FREESWITCH */ -#define gsmopen_sleep switch_sleep -#define gsmopen_strncpy switch_copy_string -extern switch_memory_pool_t *gsmopen_module_pool; -extern switch_endpoint_interface_t *gsmopen_endpoint_interface; -#endif /* ASTERISK */ -//int samplerate_gsmopen = SAMPLERATE_GSMOPEN; - -extern int running; -int gsmopen_dir_entry_extension = 1; - -int option_debug = 100; - - -#ifdef WIN32 -#define GSMLIBGIO -#else //WIN32 -#undef GSMLIBGIO -#endif //WIN32 - -#ifdef WIN32 -/***************/ -// from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/ - -#include - -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else /* */ -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif /* */ -struct sk_timezone { - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; -int gettimeofday(struct timeval *tv, struct sk_timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - if (NULL != tv) { - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch */ - tmpres /= 10; /*convert into microseconds */ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long) (tmpres / 1000000UL); - tv->tv_usec = (long) (tmpres % 1000000UL); - } - if (NULL != tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - return 0; -} - -/***************/ -#endif /* WIN32 */ - -#ifdef GSMOPEN_PORTAUDIO -#include "pablio.h" - -#ifndef GIOVA48 -#define SAMPLES_PER_FRAME 160 -#else // GIOVA48 -#define SAMPLES_PER_FRAME 960 -#endif // GIOVA48 - -int gsmopen_portaudio_devlist(private_t *tech_pvt) -{ - int i, numDevices; - const PaDeviceInfo *deviceInfo; - - numDevices = Pa_GetDeviceCount(); - if (numDevices < 0) { - return 0; - } - for (i = 0; i < numDevices; i++) { - deviceInfo = Pa_GetDeviceInfo(i); - NOTICA - ("Found PORTAUDIO device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - GSMOPEN_P_LOG, i, deviceInfo->name, deviceInfo->maxInputChannels, - deviceInfo->maxOutputChannels); - } - - return numDevices; -} - -int gsmopen_portaudio_init(private_t *tech_pvt) -{ - PaError err; - int c; - PaStreamParameters inputParameters, outputParameters; - int numdevices; - const PaDeviceInfo *deviceInfo; - -#ifndef GIOVA48 - setenv("PA_ALSA_PLUGHW", "1", 1); -#endif // GIOVA48 - - err = Pa_Initialize(); - if (err != paNoError) - return err; - - numdevices = gsmopen_portaudio_devlist(tech_pvt); - - if (tech_pvt->portaudiocindex > (numdevices - 1)) { - ERRORA("Portaudio Capture id=%d is out of range: valid id are from 0 to %d\n", - GSMOPEN_P_LOG, tech_pvt->portaudiocindex, (numdevices - 1)); - return -1; - } - - if (tech_pvt->portaudiopindex > (numdevices - 1)) { - ERRORA("Portaudio Playback id=%d is out of range: valid id are from 0 to %d\n", - GSMOPEN_P_LOG, tech_pvt->portaudiopindex, (numdevices - 1)); - return -1; - } - //inputParameters.device = 0; - if (tech_pvt->portaudiocindex != -1) { - inputParameters.device = tech_pvt->portaudiocindex; - } else { - inputParameters.device = Pa_GetDefaultInputDevice(); - } - deviceInfo = Pa_GetDeviceInfo(inputParameters.device); - NOTICA - ("Using INPUT PORTAUDIO device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - GSMOPEN_P_LOG, inputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - if (deviceInfo->maxInputChannels == 0) { - ERRORA - ("No INPUT channels on device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - GSMOPEN_P_LOG, inputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - return -1; - } - inputParameters.channelCount = 1; - inputParameters.sampleFormat = paInt16; - //inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultHighInputLatency; - inputParameters.suggestedLatency = 0.1; - inputParameters.hostApiSpecificStreamInfo = NULL; - - //outputParameters.device = 3; - if (tech_pvt->portaudiopindex != -1) { - outputParameters.device = tech_pvt->portaudiopindex; - } else { - outputParameters.device = Pa_GetDefaultOutputDevice(); - } - deviceInfo = Pa_GetDeviceInfo(outputParameters.device); - NOTICA - ("Using OUTPUT PORTAUDIO device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - GSMOPEN_P_LOG, outputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - if (deviceInfo->maxOutputChannels == 0) { - ERRORA - ("No OUTPUT channels on device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - GSMOPEN_P_LOG, inputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - return -1; - } -#ifndef GIOVA48 - outputParameters.channelCount = 1; -#else // GIOVA48 - outputParameters.channelCount = 2; -#endif // GIOVA48 - outputParameters.sampleFormat = paInt16; - //outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultHighOutputLatency; - outputParameters.suggestedLatency = 0.1; - outputParameters.hostApiSpecificStreamInfo = NULL; - -/* build the pipe that will be polled on by pbx */ - c = pipe(tech_pvt->audiopipe); - if (c) { - ERRORA("Unable to create audio pipe\n", GSMOPEN_P_LOG); - return -1; - } - fcntl(tech_pvt->audiopipe[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->audiopipe[1], F_SETFL, O_NONBLOCK); - - err = -#ifndef GIOVA48 - OpenAudioStream(&tech_pvt->stream, &inputParameters, &outputParameters, 8000, - paClipOff|paDitherOff, SAMPLES_PER_FRAME, 0); - //&tech_pvt->speexecho, &tech_pvt->speexpreprocess, &tech_pvt->owner); - -#else // GIOVA48 - OpenAudioStream(&tech_pvt->stream, &inputParameters, &outputParameters, 48000, - paDitherOff | paClipOff, SAMPLES_PER_FRAME, tech_pvt->audiopipe[1], - &tech_pvt->speexecho, &tech_pvt->speexpreprocess, &tech_pvt->owner); - - -#endif// GIOVA48 - if (err != paNoError) { - ERRORA("Unable to open audio stream: %s\n", GSMOPEN_P_LOG, Pa_GetErrorText(err)); - return -1; - } - -/* the pipe is our audio fd for pbx to poll on */ - tech_pvt->gsmopen_sound_capt_fd = tech_pvt->audiopipe[0]; - - return 0; -} -//int gsmopen_portaudio_write(private_t *tech_pvt, struct ast_frame *f) -int gsmopen_portaudio_write(private_t * tech_pvt, short *data, int datalen) -{ - int samples; -#ifdef GIOVA48 - //short buf[GSMOPEN_FRAME_SIZE * 2]; - short buf[3840]; - short *buf2; - - //ERRORA("1 f->datalen=: %d\n", GSMOPEN_P_LOG, f->datalen); - - - - - memset(buf, '\0', GSMOPEN_FRAME_SIZE *2); - - buf2 = f->data; - - int i=0, a=0; - - for(i=0; i< f->datalen / sizeof(short); i++){ -//stereo, 2 chan 48 -> mono 8 - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - /* - */ - } - f->data = &buf; - f->datalen = f->datalen * 6; - //ERRORA("2 f->datalen=: %d\n", GSMOPEN_P_LOG, f->datalen); - //f->datalen = f->datalen; -#endif // GIOVA48 - - - samples = - WriteAudioStream(tech_pvt->stream, (short *) data, (int) (datalen / sizeof(short)), &tech_pvt->timer_write); - - if (samples != (int) (datalen / sizeof(short))) - ERRORA("WriteAudioStream wrote: %d of %d\n", GSMOPEN_P_LOG, samples, - (int) (datalen / sizeof(short))); - - return samples; -} -//struct ast_frame *gsmopen_portaudio_read(private_t *tech_pvt) -#define AST_FRIENDLY_OFFSET 0 -int gsmopen_portaudio_read(private_t * tech_pvt, short *data, int datalen) -{ -#if 0 - //static struct ast_frame f; - static short __buf[GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - short *buf; - static short __buf2[GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - short *buf2; - int samples; - //char c; - - memset(__buf, '\0', (GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2)); - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - - memset(__buf2, '\0', (GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2)); - - buf2 = __buf2 + AST_FRIENDLY_OFFSET / 2; - -#if 0 - f.frametype = AST_FRAME_NULL; - f.subclass = 0; - f.samples = 0; - f.datalen = 0; - -#ifdef ASTERISK_VERSION_1_6_1 - f.data.ptr = NULL; -#else - f.data = NULL; -#endif /* ASTERISK_VERSION_1_6_1 */ - f.offset = 0; - f.src = gsmopen_type; - f.mallocd = 0; - f.delivery.tv_sec = 0; - f.delivery.tv_usec = 0; -#endif //0 - - //if ((samples = ReadAudioStream(tech_pvt->stream, buf, SAMPLES_PER_FRAME)) == 0) - //if ((samples = ReadAudioStream(tech_pvt->stream, data, datalen/sizeof(short))) == 0) - if (samples = ReadAudioStream(tech_pvt->stream, (short *)data, datalen, &tech_pvt->timer_read) == 0) { - //do nothing - } else { -#ifdef GIOVA48 - int i=0, a=0; - - samples = samples / 6; - for(i=0; i< samples; i++){ - buf2[i] = buf[a]; - a = a + 6; //mono, 1 chan 48 -> 8 - } - buf = buf2; - -#if 0 - /* A real frame */ - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = GSMOPEN_FRAME_SIZE/6; - f.datalen = GSMOPEN_FRAME_SIZE * 2/6; -#endif //0 -#else// GIOVA48 -#if 0 - /* A real frame */ - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = GSMOPEN_FRAME_SIZE; - f.datalen = GSMOPEN_FRAME_SIZE * 2; -#endif //0 -#endif// GIOVA48 - -#if 0 -#ifdef ASTERISK_VERSION_1_6_1 - f.data.ptr = buf; -#else - f.data = buf; -#endif /* ASTERISK_VERSION_1_6_1 */ - f.offset = AST_FRIENDLY_OFFSET; - f.src = gsmopen_type; - f.mallocd = 0; -#endif //0 - } - -#if 0 - read(tech_pvt->audiopipe[0], &c, 1); - - return &f; -#endif //0 -#endif //0 - - int samples; - samples = ReadAudioStream(tech_pvt->stream, (short *)data, datalen, &tech_pvt->timer_read); - //WARNINGA("samples=%d\n", GSMOPEN_P_LOG, samples); - - return samples; -} -int gsmopen_portaudio_shutdown(private_t *tech_pvt) -{ - PaError err; - - err = CloseAudioStream(tech_pvt->stream); - - if (err != paNoError) - ERRORA("not able to CloseAudioStream\n", GSMOPEN_P_LOG); - - Pa_Terminate(); - return 0; -} - - - - -#endif // GSMOPEN_PORTAUDIO -#ifndef GSMLIBGIO -int gsmopen_serial_init(private_t * tech_pvt, speed_t controldevice_speed) -{ - int fd; - int rt; - struct termios tp; - unsigned int status = 0; - unsigned int flags = TIOCM_DTR; - -/* if there is a file descriptor, close it. But it is probably just an old value, so don't check for close success*/ - fd = tech_pvt->controldevfd; - if (fd) { - close(fd); - } -/* open the serial port */ -//#ifdef __CYGWIN__ - fd = open(tech_pvt->controldevice_name, O_RDWR | O_NOCTTY | O_NONBLOCK); - sleep(1); - close(fd); -//#endif /* __CYGWIN__ */ - fd = open(tech_pvt->controldevice_name, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (fd == -1) { - perror("open error "); - DEBUGA_GSMOPEN("serial error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - tech_pvt->controldevfd = fd; - return -1; - } -/* flush it */ - rt = tcflush(fd, TCIFLUSH); - if (rt == -1) { - ERRORA("serial error: %s", GSMOPEN_P_LOG, strerror(errno)); - } -/* attributes */ - tp.c_cflag = B0 | CS8 | CLOCAL | CREAD | HUPCL; - tp.c_iflag = IGNPAR; - tp.c_cflag &= ~CRTSCTS; - tp.c_oflag = 0; - tp.c_lflag = 0; - tp.c_cc[VMIN] = 1; - tp.c_cc[VTIME] = 0; -/* set controldevice_speed */ - rt = cfsetispeed(&tp, tech_pvt->controldevice_speed); - if (rt == -1) { - ERRORA("serial error: %s, speed was: %d", GSMOPEN_P_LOG, strerror(errno), tech_pvt->controldevice_speed); - } - rt = cfsetospeed(&tp, tech_pvt->controldevice_speed); - if (rt == -1) { - ERRORA("serial error: %s", GSMOPEN_P_LOG, strerror(errno)); - } -/* set port attributes */ - if (tcsetattr(fd, TCSADRAIN, &tp) == -1) { - ERRORA("serial error: %s", GSMOPEN_P_LOG, strerror(errno)); - } - rt = tcsetattr(fd, TCSANOW, &tp); - if (rt == -1) { - ERRORA("serial error: %s", GSMOPEN_P_LOG, strerror(errno)); - } -#ifndef __CYGWIN__ - ioctl(fd, TIOCMGET, &status); - status |= TIOCM_DTR; /* Set DTR high */ - status &= ~TIOCM_RTS; /* Set RTS low */ - ioctl(fd, TIOCMSET, &status); - ioctl(fd, TIOCMGET, &status); - ioctl(fd, TIOCMBIS, &flags); - flags = TIOCM_RTS; - ioctl(fd, TIOCMBIC, &flags); - ioctl(fd, TIOCMGET, &status); -#else /* __CYGWIN__ */ - ioctl(fd, TIOCMGET, &status); - status |= TIOCM_DTR; /* Set DTR high */ - status &= ~TIOCM_RTS; /* Set RTS low */ - ioctl(fd, TIOCMSET, &status); -#endif /* __CYGWIN__ */ - tech_pvt->controldevfd = fd; - DEBUGA_GSMOPEN("Syncing Serial, fd=%d, protocol=%d\n", GSMOPEN_P_LOG, fd, tech_pvt->controldevprotocol); - rt = gsmopen_serial_sync(tech_pvt); - if (rt == -1) { - ERRORA("Serial init error\n", GSMOPEN_P_LOG); - return -1; - } - return (fd); -} -#else //GSMLIBGIO -#ifdef WIN32 -int gsmopen_serial_init(private_t * tech_pvt, int controldevice_speed) -#else -int gsmopen_serial_init(private_t * tech_pvt, speed_t controldevice_speed) -#endif //WIN32 -{ - int i; - string ciapa; - SMSMessageRef sms; - char content2[1000]; - int size; - -#ifdef WIN32 - Ref port = new Win32SerialPort((string) tech_pvt->controldevice_name, 38400); -#else - //Ref port = new UnixSerialPort((string)argv[1], B38400); - Ref < Port > port = new UnixSerialPort((string) tech_pvt->controldevice_name, B115200); -#endif - MeTa m(port); - - //cout << "Creating GsmAt object" << endl; - Ref gsmat = new GsmAt(m); - - //cout << "Using GsmAt object" << endl; - //cout << gsmat->chat("AT", "OK", false, false) << endl; - //cout << gsmat->chat("D3472665618;") << endl; - gsmat->putLine("AT+cgmm", true); - for (i = 0; i < 4; i++) { - ciapa = gsmat->getLine(); - //cout << "PRESO: |||" << ciapa << "|||" << endl; - NOTICA("PRESO %d |||%s|||\n", GSMOPEN_P_LOG, i, ciapa.c_str()); - //gsmopen_sleep(5000); - } - - sms = SMSMessage::decode("079194710167120004038571F1390099406180904480A0D41631067296EF7390383D07CD622E58CD95CB81D6EF39BDEC66BFE7207A794E2FBB4320AFB82C07E56020A8FC7D9687DBED32285C9F83A06F769A9E5EB340D7B49C3E1FA3C3663A0B24E4CBE76516680A7FCBE920725A5E5ED341F0B21C346D4E41E1BA790E4286DDE4BC0BD42CA3E5207258EE1797E5A0BA9B5E9683C86539685997EBEF61341B249BC966"); // dataCodingScheme = 0 - NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - sms = SMSMessage::decode("0791934329002000040C9193432766658100009001211133318004D4F29C0E"); // dataCodingScheme = 0 - NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - sms = SMSMessage::decode("0791934329002000040C919343276665810008900121612521801600CC00E800E900F900F200E00020006300690061006F"); // dataCodingScheme = 8 - NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - sms = SMSMessage::decode("0791934329002000040C919343276665810008900172002293404C006300690061006F0020003100320033002000620065006C00E80020043D043E0432043E044104420438002005DC05E7002005E805D005EA0020FE8EFEE0FEA0FEE4FECBFE9300204EBA5927"); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大 - NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - sms = SMSMessage::decode("07911497941902F00414D0E474989D769F5DE4320839001040122151820000"); // dataCodingScheme = 0 - NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - -#if 0 - size = MultiByteToWideChar(CP_OEMCP, 0, username, strlen(username)+1, UserName, 0); - UserName=(wchar_t*)GlobalAlloc(GME­ M_ZEROINIT, size); - ret = MultiByteToWideChar(CP_OEMCP, 0, username, strlen(username)+1, UserName, size); - if(ret == 0) - getError(GetLastError()); -#endif //0 - return (-1); -} - -#endif //GSMLIBGIO - - -int gsmopen_serial_read(private_t * tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_read_AT(tech_pvt, 0, 100000, 0, NULL, 1); // a 10th of a second timeout -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_read_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_read_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - return -1; -} - - -int gsmopen_serial_sync(private_t * tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_sync_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_sync_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_sync_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - - return -1; -} - -int gsmopen_serial_config(private_t * tech_pvt) -{ -#ifndef NO_GSMLIB - SMSMessageRef sms; - char content2[1000]; - //sms = SMSMessage::decode("079194710167120004038571F1390099406180904480A0D41631067296EF7390383D07CD622E58CD95CB81D6EF39BDEC66BFE7207A794E2FBB4320AFB82C07E56020A8FC7D9687DBED32285C9F83A06F769A9E5EB340D7B49C3E1FA3C3663A0B24E4CBE76516680A7FCBE920725A5E5ED341F0B21C346D4E41E1BA790E4286DDE4BC0BD42CA3E5207258EE1797E5A0BA9B5E9683C86539685997EBEF61341B249BC966"); // dataCodingScheme = 0 - //sms = SMSMessage::decode("0791934329002000040C9193432766658100009001211133318004D4F29C0E"); // dataCodingScheme = 0 - //sms = SMSMessage::decode("0791934329002000040C919343276665810008900121612521801600CC00E800E900F900F200E00020006300690061006F"); // dataCodingScheme = 8 - sms = SMSMessage::decode("0791934329002000040C919343276665810008900172002293404C006300690061006F0020003100320033002000620065006C00E80020043D043E0432043E044104420438002005DC05E7002005E805D005EA0020FE8EFEE0FEA0FEE4FECBFE9300204EBA5927"); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大 - //sms = SMSMessage::decode("07911497941902F00414D0E474989D769F5DE4320839001040122151820000"); // dataCodingScheme = 0 - //NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - - memset(content2, '\0', sizeof(content2)); - if (sms->dataCodingScheme().getAlphabet() == DCS_DEFAULT_ALPHABET) { - iso_8859_1_to_utf8(tech_pvt, (char *) sms->userData().c_str(), content2, sizeof(content2)); - } else if (sms->dataCodingScheme().getAlphabet() == DCS_SIXTEEN_BIT_ALPHABET) { - ucs2_to_utf8(tech_pvt, (char *) bufToHex((unsigned char *) sms->userData().data(), sms->userData().length()).c_str(), content2, - sizeof(content2)); - } else { - ERRORA("dataCodingScheme not supported=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - - } - //NOTICA("dataCodingScheme=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - //NOTICA("userData= |||%s|||\n", GSMOPEN_P_LOG, content2); -#endif// NO_GSMLIB - - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_config_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_config_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_config_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - - return -1; -} - -int gsmopen_serial_config_AT(private_t * tech_pvt) -{ - int res; - char at_command[5]; - int i; - -/* initial_pause? */ - if (tech_pvt->at_initial_pause) { - DEBUGA_GSMOPEN("sleeping for %d usec\n", GSMOPEN_P_LOG, tech_pvt->at_initial_pause); - gsmopen_sleep(tech_pvt->at_initial_pause); - } - -/* go until first empty preinit string, or last preinit string */ - while (1) { - - if (strlen(tech_pvt->at_preinit_1)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_1, tech_pvt->at_preinit_1_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_1, tech_pvt->at_preinit_1_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_2)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_2, tech_pvt->at_preinit_2_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_2, tech_pvt->at_preinit_2_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_3)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_3, tech_pvt->at_preinit_3_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_3, tech_pvt->at_preinit_3_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_4)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_4, tech_pvt->at_preinit_4_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_4, tech_pvt->at_preinit_4_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_5)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_5, tech_pvt->at_preinit_5_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_5, tech_pvt->at_preinit_5_expect); - } - } else { - break; - } - - break; - } - -/* after_preinit_pause? */ - if (tech_pvt->at_after_preinit_pause) { - DEBUGA_GSMOPEN("sleeping for %d usec\n", GSMOPEN_P_LOG, tech_pvt->at_after_preinit_pause); - gsmopen_sleep(tech_pvt->at_after_preinit_pause); - } - - /* phone, brother, art you alive? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT"); - if (res) { - ERRORA("no response to AT\n", GSMOPEN_P_LOG); - return -1; - } - /* for motorola, bring it back to "normal" mode if it happens to be in another mode */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+mode=0"); - if (res) { - DEBUGA_GSMOPEN("AT+mode=0 does not get OK from the phone. If it is NOT Motorola," " no problem.\n", GSMOPEN_P_LOG); - } - gsmopen_sleep(50000); - /* for motorola end */ - - /* reset AT configuration to phone default */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "ATZ"); - if (res) { - DEBUGA_GSMOPEN("ATZ failed\n", GSMOPEN_P_LOG); - } - - /* disable AT command echo */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "ATE0"); - if (res) { - DEBUGA_GSMOPEN("ATE0 failed\n", GSMOPEN_P_LOG); - } - - /* disable extended error reporting */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMEE=0"); - if (res) { - DEBUGA_GSMOPEN("AT+CMEE failed\n", GSMOPEN_P_LOG); - } - - /* various phone manufacturer identifier */ - for (i = 0; i < 10; i++) { - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "ATI%d", i); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res) { - DEBUGA_GSMOPEN("ATI%d command failed, continue\n", GSMOPEN_P_LOG, i); - } - } - - /* phone manufacturer */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMI"); - if (res) { - DEBUGA_GSMOPEN("AT+CGMI failed\n", GSMOPEN_P_LOG); - } - - /* phone model */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMM"); - if (res) { - DEBUGA_GSMOPEN("AT+CGMM failed\n", GSMOPEN_P_LOG); - } - - /* signal network registration with a +CREG unsolicited msg */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG=1"); - if (res) { - DEBUGA_GSMOPEN("AT+CREG=1 failed\n", GSMOPEN_P_LOG); - tech_pvt->network_creg_not_supported = 1; - } - if(!tech_pvt->network_creg_not_supported){ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG?"); - if (res) { - DEBUGA_GSMOPEN("AT+CREG? failed\n", GSMOPEN_P_LOG); - } - } - /* query signal strength */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSQ"); - if (res) { - DEBUGA_GSMOPEN("AT+CSQ failed\n", GSMOPEN_P_LOG); - } - /* IMEI */ - tech_pvt->requesting_imei = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+GSN"); - tech_pvt->requesting_imei = 0; - if (res) { - DEBUGA_GSMOPEN("AT+GSN failed\n", GSMOPEN_P_LOG); - tech_pvt->requesting_imei = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGSN"); - tech_pvt->requesting_imei = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CGSN failed\n", GSMOPEN_P_LOG); - } - } - /* IMSI */ - tech_pvt->requesting_imsi = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CIMI"); - tech_pvt->requesting_imsi = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CIMI failed\n", GSMOPEN_P_LOG); - } - - /* signal incoming SMS with a +CMTI unsolicited msg */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=3,1,0,0,0"); - if (res) { - DEBUGA_GSMOPEN("AT+CNMI=3,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->sms_cnmi_not_supported = 1; - tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config - } - /* what is the Message Center address (number) to which the SMS has to be sent? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCA?"); - if (res) { - DEBUGA_GSMOPEN("AT+CSCA? failed, continue\n", GSMOPEN_P_LOG); - } - /* what is the Message Format of SMSs? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF?"); - if (res) { - DEBUGA_GSMOPEN("AT+CMGF? failed, continue\n", GSMOPEN_P_LOG); - } -#ifdef NO_GSMLIB - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1"); - if (res) { - ERRORA("Error setting SMS sending mode to TEXT on the cellphone, let's hope is TEXT by default. Continuing\n", GSMOPEN_P_LOG); - } - tech_pvt->sms_pdu_not_supported = 1; -#else // NO_GSMLIB - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0"); - if (res) { - WARNINGA("Error setting SMS sending mode to PDU on the cellphone, falling back to TEXT mode. Continuing\n", GSMOPEN_P_LOG); - tech_pvt->sms_pdu_not_supported = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1"); - if (res) { - ERRORA("Error setting SMS sending mode to TEXT on the cellphone, let's hope is TEXT by default. Continuing\n", GSMOPEN_P_LOG); - } - } -#endif // NO_GSMLIB - /* what is the Charset of SMSs? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS?"); - if (res) { - DEBUGA_GSMOPEN("AT+CSCS? failed, continue\n", GSMOPEN_P_LOG); - } - - tech_pvt->no_ucs2 = 0; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\""); - if (res) { - WARNINGA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone, let's try with 'GSM'\n", GSMOPEN_P_LOG); - tech_pvt->no_ucs2 = 1; - } - - if (tech_pvt->no_ucs2) { - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"GSM\""); - if (res) { - WARNINGA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - //res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,16"); //"flash", class 0 sms 7 bit - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,0"); //normal, 7 bit message - if (res) { - WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", GSMOPEN_P_LOG); - } - } else { - //res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,20"); //"flash", class 0 sms 16 bit unicode - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,8"); //unicode, 16 bit message - if (res) { - WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", GSMOPEN_P_LOG); - } - } - - /* is the unsolicited reporting of mobile equipment event supported? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMER=?"); - if (res) { - DEBUGA_GSMOPEN("AT+CMER=? failed, continue\n", GSMOPEN_P_LOG); - } - /* request unsolicited reporting of mobile equipment indicators' events, to be screened by categories reported by +CIND=? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMER=3,0,0,1"); - if (res) { - DEBUGA_GSMOPEN("AT+CMER=? failed, continue\n", GSMOPEN_P_LOG); - } - - /* is the solicited reporting of mobile equipment indications supported? */ - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CIND=?"); - if (res) { - DEBUGA_GSMOPEN("AT+CIND=? failed, continue\n", GSMOPEN_P_LOG); - } - - /* is the unsolicited reporting of call monitoring supported? sony-ericsson specific */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT*ECAM=?"); - if (res) { - DEBUGA_GSMOPEN("AT*ECAM=? failed, continue\n", GSMOPEN_P_LOG); - } - /* enable the unsolicited reporting of call monitoring. sony-ericsson specific */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT*ECAM=1"); - if (res) { - DEBUGA_GSMOPEN("AT*ECAM=1 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->at_has_ecam = 0; - } else { - tech_pvt->at_has_ecam = 1; - } - - /* disable unsolicited signaling of call list */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CLCC=0"); - if (res) { - DEBUGA_GSMOPEN("AT+CLCC=0 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->at_has_clcc = 0; - } else { - tech_pvt->at_has_clcc = 1; - } - - /* give unsolicited caller id when incoming call */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CLIP=1"); - if (res) { - DEBUGA_GSMOPEN("AT+CLIP failed, continue\n", GSMOPEN_P_LOG); - } - /* for motorola */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+MCST=1"); /* motorola call control codes - (to know when call is disconnected (they - don't give you "no carrier") */ - if (res) { - DEBUGA_GSMOPEN("AT+MCST=1 does not get OK from the phone. If it is NOT Motorola," " no problem.\n", GSMOPEN_P_LOG); - } - /* for motorola end */ - -/* go until first empty postinit string, or last postinit string */ - while (1) { - - if (strlen(tech_pvt->at_postinit_1)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_1, tech_pvt->at_postinit_1_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_1, tech_pvt->at_postinit_1_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_2)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_2, tech_pvt->at_postinit_2_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_2, tech_pvt->at_postinit_2_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_3)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_3, tech_pvt->at_postinit_3_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_3, tech_pvt->at_postinit_3_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_4)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_4, tech_pvt->at_postinit_4_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_4, tech_pvt->at_postinit_4_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_5)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_5, tech_pvt->at_postinit_5_expect); - if (res) { - DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_5, tech_pvt->at_postinit_5_expect); - } - } else { - break; - } - - break; - } - - return 0; -} - - -int gsmopen_serial_sync_AT(private_t * tech_pvt) -{ - gsmopen_sleep(10000); /* 10msec */ - time(&tech_pvt->gsmopen_serial_synced_timestamp); - return 0; -} -int gsmopen_serial_read_AT(private_t * tech_pvt, int look_for_ack, int timeout_usec, int timeout_sec, const char *expected_string, int expect_crlf) -{ - int select_err = 1; - int res; - fd_set read_fds; - struct timeval timeout; - char tmp_answer[AT_BUFSIZ]; - char tmp_answer2[AT_BUFSIZ]; - char *tmp_answer_ptr; - char *last_line_ptr; - int i = 0; - int read_count = 0; - int la_counter = 0; - int at_ack = -1; - int la_read = 0; - - if(!running || !tech_pvt->running){ - return -1; - } - - FD_ZERO(&read_fds); - FD_SET(tech_pvt->controldevfd, &read_fds); - - //NOTICA (" INSIDE this gsmopen_serial_device %s \n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tmp_answer_ptr = tmp_answer; - memset(tmp_answer, 0, sizeof(char) * AT_BUFSIZ); - - timeout.tv_sec = timeout_sec; - timeout.tv_usec = timeout_usec; - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - - while ((!tech_pvt->controldev_dead) && ((select_err = select(tech_pvt->controldevfd + 1, &read_fds, NULL, NULL, &timeout)) > 0)) { - char *token_ptr; - timeout.tv_sec = timeout_sec; //reset the timeout, linux modify it - timeout.tv_usec = timeout_usec; //reset the timeout, linux modify it - read_count = read(tech_pvt->controldevfd, tmp_answer_ptr, AT_BUFSIZ - (tmp_answer_ptr - tmp_answer)); - - if (read_count == 0) { - ERRORA - ("read 0 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - close(tech_pvt->controldevfd); - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running=0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active=0; - tech_pvt->name[0]='\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - return -1; - } - - if (option_debug > 90) { - //DEBUGA_GSMOPEN("1 read %d bytes, --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer_ptr); - //DEBUGA_GSMOPEN("2 read %d bytes, --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer); - } - tmp_answer_ptr = tmp_answer_ptr + read_count; - - - la_counter = 0; - memset(tmp_answer2, 0, sizeof(char) * AT_BUFSIZ); - strcpy(tmp_answer2, tmp_answer); - if ((token_ptr = strtok(tmp_answer2, "\n\r"))) { - last_line_ptr = token_ptr; - strncpy(tech_pvt->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH); - if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) { - WARNINGA - ("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n", - GSMOPEN_P_LOG, token_ptr, tech_pvt->line_array.result[la_counter]); - } - la_counter++; - while ((token_ptr = strtok(NULL, "\n\r"))) { - last_line_ptr = token_ptr; - strncpy(tech_pvt->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH); - if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) { - WARNINGA - ("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n", - GSMOPEN_P_LOG, token_ptr, tech_pvt->line_array.result[la_counter]); - } - la_counter++; - } - } else { - last_line_ptr = tmp_answer; - } - - if (expected_string && !expect_crlf) { - DEBUGA_GSMOPEN - ("last_line_ptr=|%s|, expected_string=|%s|, expect_crlf=%d, memcmp(last_line_ptr, expected_string, strlen(expected_string)) = %d\n", - GSMOPEN_P_LOG, last_line_ptr, expected_string, expect_crlf, memcmp(last_line_ptr, expected_string, strlen(expected_string))); - } - - if (expected_string && !expect_crlf && !memcmp(last_line_ptr, expected_string, strlen(expected_string)) - ) { - strncpy(tech_pvt->line_array.result[la_counter], last_line_ptr, AT_MESG_MAX_LENGTH); - // match expected string -> accept it withtout CRLF - la_counter++; - - } - /* if the last line read was not a complete line, we'll read the rest in the future */ - else if (tmp_answer[strlen(tmp_answer) - 1] != '\r' && tmp_answer[strlen(tmp_answer) - 1] != '\n') - la_counter--; - - /* let's list the complete lines read so far, without re-listing the lines that has yet been listed */ - if (option_debug > 1) { - for (i = la_read; i < la_counter; i++) - DEBUGA_GSMOPEN("Read line %d: |%s|\n", GSMOPEN_P_LOG, i, tech_pvt->line_array.result[i]); - } - - /* let's interpret the complete lines read so far (WITHOUT looking for OK, ERROR, and EXPECTED_STRING), without re-interpreting the lines that has been yet interpreted, so we're sure we don't miss anything */ - for (i = la_read; i < la_counter; i++) { - - if ((strcmp(tech_pvt->line_array.result[i], "RING") == 0)) { - /* with first RING we wait for callid */ - gettimeofday(&(tech_pvt->ringtime), NULL); - /* give CALLID (+CLIP) a chance, wait for the next RING before answering */ - if (tech_pvt->phone_callflow == CALLFLOW_INCOMING_RING) { - /* we're at the second ring, set the interface state, will be answered by gsmopen_do_monitor */ - DEBUGA_GSMOPEN("|%s| got second RING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->interface_state = GSMOPEN_STATE_RING; - } else { - /* we're at the first ring, so there is no CALLID yet thus clean the previous one - just in case we don't receive the caller identification in this new call */ - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - /* only send AT+CLCC? if the device previously reported its support */ - if (tech_pvt->at_has_clcc != 0) { - /* we're at the first ring, try to get CALLID (with +CLCC) */ - DEBUGA_GSMOPEN("|%s| got first RING, sending AT+CLCC?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - res = gsmopen_serial_write_AT_noack(tech_pvt, "AT+CLCC?"); - if (res) { - ERRORA("AT+CLCC? (call list) was not correctly sent to the phone\n", GSMOPEN_P_LOG); - } - } else { - DEBUGA_GSMOPEN("|%s| got first RING, but not sending AT+CLCC? as this device " - "seems not to support\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - } - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CLCC", 5) == 0)) { - int commacount = 0; - int a = 0; - int b = 0; - int c = 0; - /* with clcc we wait for clip */ - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - - for (a = 0; a < strlen(tech_pvt->line_array.result[i]); a++) { - - if (tech_pvt->line_array.result[i][a] == ',') { - commacount++; - } - if (commacount == 5) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_number[b] = tech_pvt->line_array.result[i][a]; - b++; - } - } - if (commacount == 7) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_name[c] = tech_pvt->line_array.result[i][a]; - c++; - } - } - } - - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - DEBUGA_GSMOPEN("|%s| CLCC CALLID: name is %s, number is %s\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], - tech_pvt->callid_name[0] ? tech_pvt->callid_name : "not available", - tech_pvt->callid_number[0] ? tech_pvt->callid_number : "not available"); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CLIP", 5) == 0)) { - int commacount = 0; - int a = 0; - int b = 0; - int c = 0; - /* with CLIP, we want to answer right away */ - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - - - for (a = 7; a < strlen(tech_pvt->line_array.result[i]); a++) { - if (tech_pvt->line_array.result[i][a] == ',') { - commacount++; - } - if (commacount == 0) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_number[b] = tech_pvt->line_array.result[i][a]; - b++; - } - } - if (commacount == 4) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_name[c] = tech_pvt->line_array.result[i][a]; - c++; - } - } - } - - if (tech_pvt->interface_state != GSMOPEN_STATE_RING) { - gettimeofday(&(tech_pvt->call_incoming_time), NULL); - DEBUGA_GSMOPEN("GSMOPEN_STATE_RING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec); - - } - - tech_pvt->interface_state = GSMOPEN_STATE_RING; - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - DEBUGA_GSMOPEN("|%s| CLIP INCOMING CALLID: name is %s, number is %s\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], - (strlen(tech_pvt->callid_name) && tech_pvt->callid_name[0] != 1) ? tech_pvt->callid_name : "not available", - strlen(tech_pvt->callid_number) ? tech_pvt->callid_number : "not available"); - - if (!strlen(tech_pvt->callid_number)) { - strcpy(tech_pvt->callid_number, "not available"); - } - - if (!strlen(tech_pvt->callid_name) && tech_pvt->callid_name[0] != 1) { - strncpy(tech_pvt->callid_name, tech_pvt->callid_number, sizeof(tech_pvt->callid_name)); - //strncpy(tech_pvt->callid_name, tech_pvt->callid_number, sizeof(tech_pvt->callid_name)) ; - snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name), "GSMopen: %s", tech_pvt->callid_number); - } - - DEBUGA_GSMOPEN("|%s| CLIP INCOMING CALLID: NOW name is %s, number is %s\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], tech_pvt->callid_name, tech_pvt->callid_number); - } - - if ((strcmp(tech_pvt->line_array.result[i], "BUSY") == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_LINEBUSY; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_LINEBUSY\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - //if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner && tech_pvt->phone_callflow != CALLFLOW_CALL_DOWN) { - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->phone_callflow != CALLFLOW_CALL_DOWN) { - //ast_setstate(tech_pvt->owner, GSMOPEN_STATE_BUSY); - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_BUSY); - //cicopet - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - //gsmopen_hangup(tech_pvt); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - // - //tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - - } else { - ERRORA("Why BUSY now?\n", GSMOPEN_P_LOG); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "NO ANSWER") == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_NOANSWER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOANSWER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NO_ANSWER; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } else { - ERRORA("Why NO ANSWER now?\n", GSMOPEN_P_LOG); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "NO CARRIER") == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - //cicopet - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - //gsmopen_hangup(tech_pvt); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - // - //tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } else { - ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CBC:", 5) == 0)) { - int power_supply, battery_strenght, err; - - power_supply = battery_strenght = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &power_supply, &battery_strenght); - if (err < 2) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+CBC: xx,yy| now trying |+CBC:xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][5], "%d,%d", &power_supply, &battery_strenght); - DEBUGA_GSMOPEN("|%s| +CBC: Powered by %s, battery strenght=%d\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], power_supply ? "power supply" : "battery", battery_strenght); - - } - - if (err < 2) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+CBC:xx,yy| giving up\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - else { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CBC: Powered by %s, battery strenght=%d\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], power_supply ? "power supply" : "battery", battery_strenght); - if (!power_supply) { - if (battery_strenght < 10) { - ERRORA("|%s| BATTERY ALMOST EXHAUSTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if (battery_strenght < 20) { - WARNINGA("|%s| BATTERY LOW\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - } - - } - } - - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CSQ:", 5) == 0)) { - int signal_quality, ber, err; - - signal_quality = ber = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &signal_quality, &ber); - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CSQ: Signal Quality: %d, Error Rate=%d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], signal_quality, ber); - if (err < 2) { - ERRORA("|%s| is not formatted as: |+CSQ: xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - if (signal_quality < 11 || signal_quality == 99) { - ERRORA - ("|%s| CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or additional antenna\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->got_signal=0; - alarm_event(tech_pvt, ALARM_NETWORK_NO_SIGNAL, "CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or additional antenna"); - } else if (signal_quality < 15) { - WARNINGA("|%s| CELLPHONE GETS SIGNAL LOW\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->got_signal=1; - alarm_event(tech_pvt, ALARM_NETWORK_LOW_SIGNAL, "CELLPHONE GETS SIGNAL LOW"); - } else { - tech_pvt->got_signal=2; - } - - } - - } - if ((strncmp(tech_pvt->line_array.result[i], "+CREG:", 6) == 0)) { - int n, stat, err; - - n = stat = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &n, &stat); - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CREG: Display: %d, Registration=%d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], n, stat); - if (err < 2) { - WARNINGA("|%s| is not formatted as: |+CREG: xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - if (stat==0) { - ERRORA - ("|%s| CELLPHONE is not registered to network, consider to move it or additional antenna\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->not_registered=1; - tech_pvt->home_network_registered=0; - tech_pvt->roaming_registered=0; - alarm_event(tech_pvt, ALARM_NO_NETWORK_REGISTRATION, "CELLPHONE is not registered to network, consider to move it or additional antenna"); - } else if (stat==1) { - DEBUGA_GSMOPEN("|%s| CELLPHONE is registered to the HOME network\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->not_registered=0; - tech_pvt->home_network_registered=1; - tech_pvt->roaming_registered=0; - }else { - ERRORA("|%s| CELLPHONE is registered to a ROAMING network\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->not_registered=0; - tech_pvt->home_network_registered=0; - tech_pvt->roaming_registered=1; - alarm_event(tech_pvt, ALARM_ROAMING_NETWORK_REGISTRATION, "CELLPHONE is registered to a ROAMING network"); - } - - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CMGW:", 6) == 0)) { - int err; - - err = sscanf(&tech_pvt->line_array.result[i][7], "%s", tech_pvt->at_cmgw); - DEBUGA_GSMOPEN("|%s| +CMGW: %s\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], tech_pvt->at_cmgw); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+CMGW: xxxx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - } - - /* at_call_* are unsolicited messages sent by the modem to signal us about call processing activity and events */ - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_idle) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - DEBUGA_GSMOPEN("just received a remote HANGUP\n", GSMOPEN_P_LOG); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - DEBUGA_GSMOPEN("just sent GSMOPEN_CONTROL_HANGUP\n", GSMOPEN_P_LOG); - } - - tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - //cicopet - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - //gsmopen_hangup(tech_pvt); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - // - //tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } else { - ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG); - } - - - - - - - - - - - - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_incoming) == 0)) { - - //char list_command[64]; - - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_INCOMING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - if (tech_pvt->phone_callflow != CALLFLOW_CALL_INCOMING && tech_pvt->phone_callflow != CALLFLOW_INCOMING_RING) { - //mark the time of CALLFLOW_CALL_INCOMING - gettimeofday(&(tech_pvt->call_incoming_time), NULL); - tech_pvt->phone_callflow = CALLFLOW_CALL_INCOMING; - DEBUGA_GSMOPEN("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec); - - } - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_active) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_ACTIVE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - if (tech_pvt->interface_state == CALLFLOW_CALL_DIALING || tech_pvt->interface_state == CALLFLOW_STATUS_EARLYMEDIA) { - DEBUGA_PBX("just received a remote ANSWER\n", GSMOPEN_P_LOG); - if (tech_pvt->phone_callflow == GSMOPEN_STATE_UP) { - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_RINGING); - DEBUGA_PBX("just sent GSMOPEN_CONTROL_RINGING\n", GSMOPEN_P_LOG); - DEBUGA_PBX("going to send GSMOPEN_CONTROL_ANSWER\n", GSMOPEN_P_LOG); - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER); - tech_pvt->interface_state = CALLFLOW_CALL_REMOTEANSWER; - DEBUGA_PBX("just sent GSMOPEN_CONTROL_ANSWER\n", GSMOPEN_P_LOG); - } - } else { - } - //tech_pvt->interface_state = GSMOPEN_STATE_UP; - //DEBUGA_PBX("just interface_state UP\n", GSMOPEN_P_LOG); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_calling) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_DIALING; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_DIALING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_failed) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_FAILED; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_FAILED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CSCA:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CSCA: Message Center Address!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CMGF:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CMGF: Message Format!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CMTI:", 6) == 0)) { //TODO SMS FIXME in config! - int err; - int pos; - - //FIXME all the following commands in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMTI: Incoming SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][12], "%d", &pos); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+CMTI: \"MT\",xx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - DEBUGA_GSMOPEN("|%s| +CMTI: Incoming SMS in position: %d!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], pos); - tech_pvt->unread_sms_msg_id = pos; - gsmopen_sleep(1000); - - if (tech_pvt->unread_sms_msg_id) { - char at_command[256]; - - if (tech_pvt->no_ucs2 == 0) { - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\""); - if (res) { - ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone, continuing\n", GSMOPEN_P_LOG); - //memset(tech_pvt->sms_message, 0, sizeof(tech_pvt->sms_message)); - } - } - - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGR=%d", tech_pvt->unread_sms_msg_id); - //memset(tech_pvt->sms_message, 0, sizeof(tech_pvt->sms_message)); - - tech_pvt->reading_sms_msg = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - tech_pvt->reading_sms_msg = 0; - if (res) { - ERRORA("AT+CMGR (read SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"GSM\""); - if (res) { - ERRORA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGD=%d", tech_pvt->unread_sms_msg_id); /* delete the message */ - tech_pvt->unread_sms_msg_id = 0; - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res) { - ERRORA("AT+CMGD (Delete SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - - res = sms_incoming(tech_pvt); - -#if 0 - if (strlen(tech_pvt->sms_message)) { - //FIXME manager_event(EVENT_FLAG_SYSTEM, "GSMOPENincomingsms", - //FIXME "Interface: %s\r\nSMS_Message: %s\r\n", tech_pvt->name, - //FIXME tech_pvt->sms_message); - - res = sms_incoming(tech_pvt, tech_pvt->sms_message); - - if (strlen(tech_pvt->sms_receiving_program)) { - int fd1[2]; - pid_t pid1; - char *arg1[] = { tech_pvt->sms_receiving_program, (char *) NULL }; - int i; - - DEBUGA_GSMOPEN("incoming SMS message:>>>%s<<<\n", GSMOPEN_P_LOG, tech_pvt->sms_message); - res = pipe(fd1); - pid1 = fork(); - - if (pid1 == 0) { //child - int err; - - dup2(fd1[0], 0); // Connect stdin to pipe output - close(fd1[1]); // close input pipe side - close(tech_pvt->controldevfd); - setsid(); //session id - err = execvp(arg1[0], arg1); //exec our program, with stdin connected to pipe output - if (err) { - ERRORA - ("'sms_receiving_program' is set in config file to '%s', and it gave us back this error: %d, (%s). SMS received was:---%s---\n", - GSMOPEN_P_LOG, tech_pvt->sms_receiving_program, err, strerror(errno), tech_pvt->sms_message); - } - close(fd1[0]); // close output pipe side - } -//starting here continue the parent - close(fd1[0]); // close output pipe side - // write the msg on the pipe input - for (i = 0; i < strlen(tech_pvt->sms_message); i++) { - res = write(fd1[1], &tech_pvt->sms_message[i], 1); - } - close(fd1[1]); // close pipe input, let our program know we've finished - } else { - ERRORA - ("got SMS incoming message, but 'sms_receiving_program' is not set in config file. SMS received was:---%s---\n", - GSMOPEN_P_LOG, tech_pvt->sms_message); - } - } -#endif //0 -#if 1 //is this one needed? maybe it can interrupt an incoming call that is just to announce itself - if (tech_pvt->phone_callflow == CALLFLOW_CALL_IDLE && tech_pvt->interface_state == GSMOPEN_STATE_DOWN && tech_pvt->owner == NULL) { - /* we're not in a call, neither calling */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA("AT+CKPD=\"EEE\" (cellphone screen back to user) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - } -#endif - } //unread_msg_id - - } //CMTI well formatted - - } //CMTI - - if ((strncmp(tech_pvt->line_array.result[i], "+MMGL:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config! - int err = 0; - //int unread_msg_id=0; - - if (option_debug) - DEBUGA_GSMOPEN("|%s| +MMGL: Listing Motorola SMSs!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][7], "%d", &tech_pvt->unread_sms_msg_id); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+MMGL: xx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - } - if ((strncmp(tech_pvt->line_array.result[i], "+CMGL:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGL: Listing SMSs!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - if ((strncmp(tech_pvt->line_array.result[i], "+MMGR:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +MMGR: Reading Motorola SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->reading_sms_msg) - tech_pvt->reading_sms_msg++; - } - if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"STO U", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading stored UNSENT SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"STO S", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading stored SENT SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"REC R", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading received READ SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"REC U", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading received UNREAD SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->reading_sms_msg) - tech_pvt->reading_sms_msg++; - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: ", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->reading_sms_msg) - tech_pvt->reading_sms_msg++; - } - - - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 17") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_INFLUX; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_INFLUX\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 68") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_NOSERVICE; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOSERVICE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 70") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_OUTGOINGRESTRICTED; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_OUTGOINGRESTRICTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 72") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_SECURITYFAIL; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_SECURITYFAIL\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CPBR", 5) == 0)) { /* phonebook stuff begins */ - - if (tech_pvt->phonebook_querying) { /* probably phonebook struct begins */ - int err, first_entry, last_entry, number_lenght, text_lenght; - - if (option_debug) - DEBUGA_GSMOPEN("phonebook struct: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][8], "%d-%d),%d,%d", &first_entry, &last_entry, &number_lenght, &text_lenght); - if (err < 4) { - - err = sscanf(&tech_pvt->line_array.result[i][7], "%d-%d,%d,%d", &first_entry, &last_entry, &number_lenght, &text_lenght); - } - - if (err < 4) { - ERRORA - ("phonebook struct: |%s| is nor formatted as: |+CPBR: (1-750),40,14| neither as: |+CPBR: 1-750,40,14|\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - - if (option_debug) - DEBUGA_GSMOPEN - ("First entry: %d, last entry: %d, phone number max lenght: %d, text max lenght: %d\n", - GSMOPEN_P_LOG, first_entry, last_entry, number_lenght, text_lenght); - tech_pvt->phonebook_first_entry = first_entry; - tech_pvt->phonebook_last_entry = last_entry; - tech_pvt->phonebook_number_lenght = number_lenght; - tech_pvt->phonebook_text_lenght = text_lenght; - } - - } else { /* probably phonebook entry begins */ - - if (tech_pvt->phonebook_listing) { - int err, entry_id, entry_type; - - char entry_number[256]; - char entry_text[256]; - - if (option_debug) - DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = - sscanf(&tech_pvt->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", &entry_id, entry_number, &entry_type, - entry_text); - if (err < 4) { - ERRORA - ("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n", - GSMOPEN_P_LOG, err, tech_pvt->line_array.result[i]); - } else { - //TODO: sanitize entry_text - if (option_debug) - DEBUGA_GSMOPEN("Number: %s, Text: %s, Type: %d\n", GSMOPEN_P_LOG, entry_number, entry_text, entry_type); - /* write entry in phonebook file */ - if (tech_pvt->phonebook_writing_fp) { - gsmopen_dir_entry_extension++; - - fprintf(tech_pvt->phonebook_writing_fp, - "%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n", - entry_number, entry_text, "no", - tech_pvt->gsmopen_dir_entry_extension_prefix, "2", gsmopen_dir_entry_extension, "yes", "not_specified"); - fprintf(tech_pvt->phonebook_writing_fp, - "%s => ,%sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n", - entry_number, entry_text, "no", - tech_pvt->gsmopen_dir_entry_extension_prefix, "3", gsmopen_dir_entry_extension, "yes", "not_specified"); - } - } - - } - - if (tech_pvt->phonebook_listing_received_calls) { - int err, entry_id, entry_type; - - char entry_number[256] = ""; - char entry_text[256] = ""; - - if (option_debug) - DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = - sscanf(&tech_pvt->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", &entry_id, entry_number, &entry_type, - entry_text); - if (err < 1) { //we match only on the progressive id, maybe the remote party has not sent its number, and/or there is no corresponding text entry in the phone directory - ERRORA - ("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n", - GSMOPEN_P_LOG, err, tech_pvt->line_array.result[i]); - } else { - //TODO: sanitize entry_text - - if (option_debug) - DEBUGA_GSMOPEN("Number: %s, Text: %s, Type: %d\n", GSMOPEN_P_LOG, entry_number, entry_text, entry_type); - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - strncpy(tech_pvt->callid_name, entry_text, sizeof(tech_pvt->callid_name)); - strncpy(tech_pvt->callid_number, entry_number, sizeof(tech_pvt->callid_number)); - if (option_debug) - DEBUGA_GSMOPEN("incoming callid: Text: %s, Number: %s\n", GSMOPEN_P_LOG, tech_pvt->callid_name, tech_pvt->callid_number); - - DEBUGA_GSMOPEN("|%s| CPBR INCOMING CALLID: name is %s, number is %s\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i], - tech_pvt->callid_name[0] != 1 ? tech_pvt->callid_name : "not available", - tech_pvt->callid_number[0] ? tech_pvt->callid_number : "not available"); - - /* mark the time of RING */ - gettimeofday(&(tech_pvt->ringtime), NULL); - tech_pvt->interface_state = GSMOPEN_STATE_RING; - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - - } - - } - - else { - DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - } - } - - } - - if ((strncmp(tech_pvt->line_array.result[i], "*ECAV", 5) == 0) || (strncmp(tech_pvt->line_array.result[i], "*ECAM", 5) == 0)) { /* sony-ericsson call processing unsolicited messages */ - int res, ccid, ccstatus, calltype, processid, exitcause, number, type; - res = ccid = ccstatus = calltype = processid = exitcause = number = type = 0; - res = - sscanf(&tech_pvt->line_array.result[i][6], "%d,%d,%d,%d,%d,%d,%d", &ccid, &ccstatus, &calltype, &processid, &exitcause, &number, - &type); - /* only changes the phone_callflow if enought parameters were parsed */ - if (res >= 3) { - switch (ccstatus) { - case 0: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_DOWN); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 1: - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: CALLING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 2: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_DIALING); - } - tech_pvt->interface_state = CALLFLOW_CALL_DIALING; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: CONNECTING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 3: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_UP); - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - tech_pvt->interface_state = GSMOPEN_STATE_UP; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: ACTIVE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 4: - if (option_debug > 1) - DEBUGA_GSMOPEN - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle HOLD event\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 5: - if (option_debug > 1) - DEBUGA_GSMOPEN - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle WAITING event\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i]); - break; - case 6: - if (option_debug > 1) - DEBUGA_GSMOPEN - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle ALERTING event\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i]); - break; - case 7: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_BUSY); - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_BUSY); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_LINEBUSY; - tech_pvt->interface_state = GSMOPEN_STATE_BUSY; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: BUSY\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - } - } else { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: could not parse parameters\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - } - - /* at_indicator_* are unsolicited messages sent by the phone to signal us that some of its visual indicators on its screen has changed, based on CIND CMER ETSI docs */ - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_noservice_string) == 0)) { - ERRORA("|%s| at_indicator_noservice_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - alarm_event(tech_pvt, ALARM_NETWORK_NO_SERVICE, "at_indicator_noservice_string"); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nosignal_string) == 0)) { - ERRORA("|%s| at_indicator_nosignal_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - alarm_event(tech_pvt, ALARM_NETWORK_NO_SIGNAL, "at_indicator_nosignal_string"); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_lowsignal_string) == 0)) { - WARNINGA("|%s| at_indicator_lowsignal_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - alarm_event(tech_pvt, ALARM_NETWORK_LOW_SIGNAL, "at_indicator_lowsignal_string"); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_lowbattchg_string) == 0)) { - WARNINGA("|%s| at_indicator_lowbattchg_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nobattchg_string) == 0)) { - ERRORA("|%s| at_indicator_nobattchg_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callactive_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callactive_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nocallactive_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_nocallactive_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nocallsetup_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_nocallsetup_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupincoming_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callsetupincoming_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupoutgoing_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callsetupoutgoing_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupremoteringing_string) - == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callsetupremoteringing_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - } - - /* let's look for OK, ERROR and EXPECTED_STRING in the complete lines read so far, without re-looking at the lines that has been yet looked at */ - for (i = la_read; i < la_counter; i++) { - if (expected_string) { - if ((strncmp(tech_pvt->line_array.result[i], expected_string, strlen(expected_string)) - == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| got what EXPECTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - at_ack = AT_OK; - } - } else { - if ((strcmp(tech_pvt->line_array.result[i], "OK") == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("got OK\n", GSMOPEN_P_LOG); - at_ack = AT_OK; - } - } - if ((strcmp(tech_pvt->line_array.result[i], "ERROR") == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("got ERROR\n", GSMOPEN_P_LOG); - at_ack = AT_ERROR; - } - - /* if we are requesting IMEI, put the line into the imei buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->requesting_imei && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMEI */ - strncpy(tech_pvt->imei, tech_pvt->line_array.result[i], sizeof(tech_pvt->imei)); - } - } - - /* if we are requesting IMSI, put the line into the imei buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->requesting_imsi && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMSI */ - strncpy(tech_pvt->imsi, tech_pvt->line_array.result[i], sizeof(tech_pvt->imsi)); - } - } - /* if we are reading an sms message from memory, put the line into the sms buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->reading_sms_msg > 1 && at_ack == -1) { - int c; - char sms_body[16000]; - //int err = 0; - memset(sms_body, '\0', sizeof(sms_body)); - - if (strncmp(tech_pvt->line_array.result[i], "+CMGR", 5) == 0) { /* we are reading the "header" of an SMS */ -#if 1 - char content[512]; - char content2[512]; - int inside_comma = 0; - int inside_quote = 0; - int which_field = 0; - int d = 0; - - DEBUGA_GSMOPEN("HERE\n", GSMOPEN_P_LOG); - - memset(content, '\0', sizeof(content)); - - - for (c = 0; c < strlen(tech_pvt->line_array.result[i]); c++) { - if (tech_pvt->line_array.result[i][c] == ',' && tech_pvt->line_array.result[i][c - 1] != '\\' && inside_quote == 0) { - if (inside_comma) { - inside_comma = 0; - DEBUGA_GSMOPEN("inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - } else { - inside_comma = 1; - DEBUGA_GSMOPEN("inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - } - } - if (tech_pvt->line_array.result[i][c] == '"' && tech_pvt->line_array.result[i][c - 1] != '\\') { - if (inside_quote) { - inside_quote = 0; - DEBUGA_GSMOPEN("END_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content); - - //strncat(tech_pvt->sms_message, "---", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //strncat(tech_pvt->sms_message, content, ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //strncat(tech_pvt->sms_message, "|||", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - - memset(content2, '\0', sizeof(content2)); - if (which_field == 1) { - //FIXME why this? err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2)); - //err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2)); - //err = 0; - strncpy(content2, content, sizeof(content2)); - } else { - //err = 0; - strncpy(content2, content, sizeof(content2)); - } - DEBUGA_GSMOPEN("%d content2=%s\n", GSMOPEN_P_LOG, which_field, content2); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2); - - //strncat(tech_pvt->sms_message, "---", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //if (!err) - //strncat(tech_pvt->sms_message, content2, ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //strncat(tech_pvt->sms_message, "|||", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - memset(content, '\0', sizeof(content)); - d = 0; - if (which_field == 1) { - strncpy(tech_pvt->sms_sender, content2, sizeof(tech_pvt->sms_sender)); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2); - - } else if (which_field == 2) { - strncpy(tech_pvt->sms_date, content2, sizeof(tech_pvt->sms_date)); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2); - } else if (which_field > 2) { - WARNINGA("WHY which_field is > 2 ? (which_field is %d)\n", GSMOPEN_P_LOG, which_field); - } - which_field++; - } else { - inside_quote = 1; - DEBUGA_GSMOPEN("START_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - } - } - if (inside_quote && tech_pvt->line_array.result[i][c] != '"') { - - content[d] = tech_pvt->line_array.result[i][c]; - d++; - - } - - } -#endif //0 - } //it was the +CMGR answer from the cellphone - else { - DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body); - DEBUGA_GSMOPEN("tech_pvt->line_array.result[i]=%s\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->sms_pdu_not_supported) { - char content3[1000]; - strncpy(tech_pvt->sms_message, tech_pvt->line_array.result[i], sizeof(tech_pvt->sms_message)); - - //int howmanyleft; - - - DEBUGA_GSMOPEN("sms_message=%s\n", GSMOPEN_P_LOG, tech_pvt->sms_message); - ucs2_to_utf8(tech_pvt, tech_pvt->sms_message, content3, sizeof(content3)); - DEBUGA_GSMOPEN("content3=%s\n", GSMOPEN_P_LOG, content3); - strncpy(tech_pvt->sms_body, content3, sizeof(tech_pvt->sms_body)); - //sleep(10); - //cicopet - if (tech_pvt->sms_cnmi_not_supported) { - sms_incoming(tech_pvt); - DEBUGA_GSMOPEN("2 content3=%s\n", GSMOPEN_P_LOG, content3); - } - } else { -#ifndef NO_GSMLIB - char content2[1000]; - SMSMessageRef sms; -//MessageType messagetype; -//Address servicecentreaddress; -//Timestamp servicecentretimestamp; -//Address sender_recipient_address; - - sms = SMSMessage::decode(tech_pvt->line_array.result[i]); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大 - - DEBUGA_GSMOPEN("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - - memset(content2, '\0', sizeof(content2)); - if (sms->dataCodingScheme().getAlphabet() == DCS_DEFAULT_ALPHABET) { - iso_8859_1_to_utf8(tech_pvt, (char *) sms->userData().c_str(), content2, sizeof(content2)); - } else if (sms->dataCodingScheme().getAlphabet() == DCS_SIXTEEN_BIT_ALPHABET) { - ucs2_to_utf8(tech_pvt, (char *) bufToHex((unsigned char *) sms->userData().data(), sms->userData().length()).c_str(), content2, - sizeof(content2)); - } else { - ERRORA("dataCodingScheme not supported=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - - } - DEBUGA_GSMOPEN("dataCodingScheme=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - DEBUGA_GSMOPEN("dataCodingScheme=%s\n", GSMOPEN_P_LOG, sms->dataCodingScheme().toString().c_str()); - DEBUGA_GSMOPEN("address=%s\n", GSMOPEN_P_LOG, sms->address().toString().c_str()); - DEBUGA_GSMOPEN("serviceCentreAddress=%s\n", GSMOPEN_P_LOG, sms->serviceCentreAddress().toString().c_str()); - DEBUGA_GSMOPEN("serviceCentreTimestamp=%s\n", GSMOPEN_P_LOG, sms->serviceCentreTimestamp().toString().c_str()); - DEBUGA_GSMOPEN("UserDataHeader=%s\n", GSMOPEN_P_LOG, (char *)bufToHex((unsigned char *) - ((string) sms->userDataHeader()).data(), sms->userDataHeader().length()).c_str()); - DEBUGA_GSMOPEN("messageType=%d\n", GSMOPEN_P_LOG, sms->messageType()); - DEBUGA_GSMOPEN("userData= |||%s|||\n", GSMOPEN_P_LOG, content2); - - - memset(sms_body, '\0', sizeof(sms_body)); - strncpy(sms_body, content2, sizeof(sms_body)); - DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body); - strncpy(tech_pvt->sms_body, sms_body, sizeof(tech_pvt->sms_body)); - strncpy(tech_pvt->sms_sender, sms->address().toString().c_str(), sizeof(tech_pvt->sms_sender)); - strncpy(tech_pvt->sms_date, sms->serviceCentreTimestamp().toString().c_str(), sizeof(tech_pvt->sms_date)); - strncpy(tech_pvt->sms_userdataheader, (char *) - bufToHex((unsigned char *)((string) sms->userDataHeader()).data(), sms->userDataHeader().length()).c_str(), - sizeof(tech_pvt->sms_userdataheader)); - strncpy(tech_pvt->sms_datacodingscheme, sms->dataCodingScheme().toString().c_str(), sizeof(tech_pvt->sms_datacodingscheme)); - strncpy(tech_pvt->sms_servicecentreaddress, sms->serviceCentreAddress().toString().c_str(), - sizeof(tech_pvt->sms_servicecentreaddress)); - tech_pvt->sms_messagetype = sms->messageType(); -//messagetype = sms->messageType(); -//servicecentreaddress = sms->serviceCentreAddress(); -//servicecentretimestamp = sms->serviceCentreTimestamp(); -//sender_recipient_address = sms->address(); - -#endif// NO_GSMLIB - } - -#if 0 - //strncat(tech_pvt->sms_message, "---", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //strncat(tech_pvt->sms_message, tech_pvt->line_array.result[i], ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //strncat(tech_pvt->sms_message, "|||", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - - memset(sms_body, '\0', sizeof(sms_body)); - err = ucs2_to_utf8(tech_pvt, tech_pvt->line_array.result[i], sms_body, sizeof(sms_body)); - DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body); - strncpy(tech_pvt->sms_body, sms_body, sizeof(tech_pvt->sms_body)); - - //strncat(tech_pvt->sms_message, "---", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //if (!err) - //strncat(tech_pvt->sms_message, sms_body, ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - //strncat(tech_pvt->sms_message, "|||", ((sizeof(tech_pvt->sms_message) - strlen(tech_pvt->sms_message)) - 1)); - - //DEBUGA_GSMOPEN("sms_message=%s\n", GSMOPEN_P_LOG, tech_pvt->sms_message); -#endif //0 - } //it was the UCS2 from cellphone - - } //we were reading the SMS - - } - - la_read = la_counter; - - if (look_for_ack && at_ack > -1) - break; - - if (la_counter > AT_MESG_MAX_LINES) { - ERRORA("Too many lines in result (>%d). Stopping reader.\n", GSMOPEN_P_LOG, AT_MESG_MAX_LINES); - at_ack = AT_ERROR; - break; - } - } - - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - if (select_err == -1) { - ERRORA("select returned -1 on %s, setting controldev_dead, error was: %s\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name, strerror(errno)); - tech_pvt->controldev_dead = 1; - close(tech_pvt->controldevfd); - - tech_pvt->running=0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "select returned -1 on interface, setting controldev_dead"); - tech_pvt->active=0; - tech_pvt->name[0]='\0'; - if (tech_pvt->owner) - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - switch_sleep(1000000); - return -1; - } - - if (tech_pvt->phone_callflow == CALLFLOW_CALL_INCOMING && tech_pvt->call_incoming_time.tv_sec) { //after three sec of CALLFLOW_CALL_INCOMING, we assume the phone is incapable of notifying RING (eg: motorola c350), so we try to answer - char list_command[64]; - struct timeval call_incoming_timeout; - gettimeofday(&call_incoming_timeout, NULL); - call_incoming_timeout.tv_sec -= 3; - DEBUGA_GSMOPEN - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (call_incoming_timeout.tv_sec > tech_pvt->call_incoming_time.tv_sec) { - - tech_pvt->call_incoming_time.tv_sec = 0; - tech_pvt->call_incoming_time.tv_usec = 0; - DEBUGA_GSMOPEN - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBS=RC"); - if (res) { - ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG); - } - tech_pvt->phonebook_querying = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBR=?"); - if (res) { - ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG); - } - tech_pvt->phonebook_querying = 0; - sprintf(list_command, "AT+CPBR=%d,%d", tech_pvt->phonebook_first_entry, tech_pvt->phonebook_last_entry); - tech_pvt->phonebook_listing_received_calls = 1; - res = gsmopen_serial_write_AT_expect_longtime(tech_pvt, list_command, "OK"); - if (res) { - WARNINGA("AT+CPBR=%d,%d failed, continue\n", GSMOPEN_P_LOG, tech_pvt->phonebook_first_entry, tech_pvt->phonebook_last_entry); - } - tech_pvt->phonebook_listing_received_calls = 0; - } - } - - if (tech_pvt->phone_callflow == CALLFLOW_INCOMING_RING) { - struct timeval call_incoming_timeout; - gettimeofday(&call_incoming_timeout, NULL); - call_incoming_timeout.tv_sec -= 10; - // DEBUGA_GSMOPEN ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (call_incoming_timeout.tv_sec > tech_pvt->ringtime.tv_sec) { - ERRORA("Ringing stopped and I have not answered. Why?\n", GSMOPEN_P_LOG); - DEBUGA_GSMOPEN - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (tech_pvt->owner) { - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - } - } - } - tech_pvt->line_array.elemcount = la_counter; - //NOTICA (" OUTSIDE this gsmopen_serial_device %s \n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - if (look_for_ack) - return at_ack; - else - return 0; -} - -int gsmopen_serial_write_AT(private_t * tech_pvt, const char *data) -{ - int howmany; - int i; - int res; - int count; - - howmany = strlen(data); - - for (i = 0; i < howmany; i++) { - res = write(tech_pvt->controldevfd, &data[i], 1); - - if (res != 1) { - DEBUGA_GSMOPEN("Error sending (%.1s): %d (%s)\n", GSMOPEN_P_LOG, &data[i], res, strerror(errno)); - gsmopen_sleep(100000); - for (count = 0; count < 10; count++) { - res = write(tech_pvt->controldevfd, &data[i], 1); - if (res == 1) { - DEBUGA_GSMOPEN("Successfully RE-sent (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &data[i], count, res, strerror(errno)); - break; - } else - DEBUGA_GSMOPEN("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &data[i], count, res, strerror(errno)); - gsmopen_sleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &data[i], count, res, strerror(errno)); - return -1; - } - } - if (option_debug > 1) - DEBUGA_GSMOPEN("sent data... (%.1s)\n", GSMOPEN_P_LOG, &data[i]); - gsmopen_sleep(1000); /* release the cpu */ - } - - res = write(tech_pvt->controldevfd, "\r", 1); - - if (res != 1) { - DEBUGA_GSMOPEN("Error sending (carriage return): %d (%s)\n", GSMOPEN_P_LOG, res, strerror(errno)); - gsmopen_sleep(100000); - for (count = 0; count < 10; count++) { - res = write(tech_pvt->controldevfd, "\r", 1); - - if (res == 1) { - DEBUGA_GSMOPEN("Successfully RE-sent carriage return: %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno)); - break; - } else - DEBUGA_GSMOPEN("Error RE-sending (carriage return): %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno)); - gsmopen_sleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (carriage return): %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno)); - return -1; - } - } - if (option_debug > 1) - DEBUGA_GSMOPEN("sent (carriage return)\n", GSMOPEN_P_LOG); - gsmopen_sleep(1000); /* release the cpu */ - - return howmany; -} - -int gsmopen_serial_write_AT_nocr(private_t * tech_pvt, const char *data) -{ - int howmany; - int i; - int res; - int count; - - howmany = strlen(data); - - for (i = 0; i < howmany; i++) { - res = write(tech_pvt->controldevfd, &data[i], 1); - - if (res != 1) { - DEBUGA_GSMOPEN("Error sending (%.1s): %d (%s)\n", GSMOPEN_P_LOG, &data[i], res, strerror(errno)); - gsmopen_sleep(100000); - for (count = 0; count < 10; count++) { - res = write(tech_pvt->controldevfd, &data[i], 1); - if (res == 1) - break; - else - DEBUGA_GSMOPEN("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &data[i], count, res, strerror(errno)); - gsmopen_sleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &data[i], count, res, strerror(errno)); - return -1; - } - } - if (option_debug > 1) - DEBUGA_GSMOPEN("sent data... (%.1s)\n", GSMOPEN_P_LOG, &data[i]); - gsmopen_sleep(1000); /* release the cpu */ - } - - gsmopen_sleep(1000); /* release the cpu */ - - return howmany; -} - -int gsmopen_serial_write_AT_noack(private_t * tech_pvt, const char *data) -{ - - if (option_debug > 1) - DEBUGA_GSMOPEN("gsmopen_serial_write_AT_noack: %s\n", GSMOPEN_P_LOG, data); - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (gsmopen_serial_write_AT(tech_pvt, data) != strlen(data)) { - - ERRORA("Error sending data... (%s)\n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - return -1; - } - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return 0; -} - -int gsmopen_serial_write_AT_ack(private_t * tech_pvt, const char *data) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("sending: %s\n", GSMOPEN_P_LOG, data); - if (gsmopen_serial_write_AT(tech_pvt, data) != strlen(data)) { - ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - return -1; - } - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, 2, NULL, 1); // 2.5 sec timeout - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_write_AT_ack_nocr_longtime(private_t * tech_pvt, const char *data) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("sending: %s\n", GSMOPEN_P_LOG, data); - if (gsmopen_serial_write_AT_nocr(tech_pvt, data) != strlen(data)) { - ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - return -1; - } - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, 20, NULL, 1); // 20.5 sec timeout - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_write_AT_expect1(private_t * tech_pvt, const char *data, const char *expected_string, int expect_crlf, int seconds) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("sending: %s, expecting: %s\n", GSMOPEN_P_LOG, data, expected_string); - if (gsmopen_serial_write_AT(tech_pvt, data) != strlen(data)) { - ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - return -1; - } - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, seconds, expected_string, expect_crlf); // 20.5 sec timeout, used for querying the SIM and sending SMSs - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_AT_expect(private_t * tech_pvt, const char *expected_string, int expect_crlf, int seconds) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("expecting: %s\n", GSMOPEN_P_LOG, expected_string); - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, seconds, expected_string, expect_crlf); // 20.5 sec timeout, used for querying the SIM and sending SMSs - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_answer(private_t * tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_answer_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_answer_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_answer_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - return -1; -} - - -int gsmopen_serial_answer_AT(private_t * tech_pvt) -{ - int res; - - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_answer, tech_pvt->at_answer_expect); - if (res) { - DEBUGA_GSMOPEN - ("at_answer command failed, command used: %s, expecting: %s, trying with AT+CKPD=\"S\"\n", - GSMOPEN_P_LOG, tech_pvt->at_answer, tech_pvt->at_answer_expect); - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"S\""); - if (res) { - ERRORA("at_answer command failed, command used: 'AT+CKPD=\"S\"', giving up\n", GSMOPEN_P_LOG); - return -1; - } - } - //tech_pvt->interface_state = GSMOPEN_STATE_UP; - //tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - DEBUGA_GSMOPEN("AT: call answered\n", GSMOPEN_P_LOG); - return 0; -} - -int gsmopen_serial_hangup(private_t * tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_hangup_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_hangup_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_hangup_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - return -1; -} - - -int gsmopen_serial_hangup_AT(private_t * tech_pvt) -{ - int res; - - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_hangup, tech_pvt->at_hangup_expect); - if (res) { - DEBUGA_GSMOPEN("at_hangup command failed, command used: %s, trying to use AT+CKPD=\"EEE\"\n", GSMOPEN_P_LOG, tech_pvt->at_hangup); - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA("at_hangup command failed, command used: 'AT+CKPD=\"EEE\"'\n", GSMOPEN_P_LOG); - return -1; - } - } - } - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - return 0; -} - - -int gsmopen_serial_call(private_t * tech_pvt, char *dstr) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_call_AT(tech_pvt, dstr); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_call_FBUS2(tech_pvt, dstr); -#endif /* GSMOPEN_FBUS2 */ - if (tech_pvt->controldevprotocol == PROTOCOL_NO_SERIAL) - return 0; -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_call_CVM_BUSMAIL(tech_pvt, dstr); -#endif /* GSMOPEN_CVM */ - return -1; -} - -int gsmopen_serial_call_AT(private_t * tech_pvt, char *dstr) -{ - int res; - char at_command[256]; - - if (option_debug) - DEBUGA_PBX("Dialing %s\n", GSMOPEN_P_LOG, dstr); - memset(at_command, 0, sizeof(at_command)); - tech_pvt->phone_callflow = CALLFLOW_CALL_DIALING; - tech_pvt->interface_state = GSMOPEN_STATE_DIALING; - //ast_uri_decode(dstr); -/* - size_t fixdstr = strspn(dstr, AST_DIGIT_ANYDIG); - if (fixdstr == 0) { - ERRORA("dial command failed because of invalid dial number. dial string was: %s\n", - GSMOPEN_P_LOG, dstr); - return -1; - } -*/ - //dstr[fixdstr] = '\0'; - sprintf(at_command, "%s%s%s", tech_pvt->at_dial_pre_number, dstr, tech_pvt->at_dial_post_number); - DEBUGA_PBX("Dialstring %s\n", GSMOPEN_P_LOG, at_command); - res = gsmopen_serial_write_AT_expect(tech_pvt, at_command, tech_pvt->at_dial_expect); - if (res) { - ERRORA("dial command failed, dial string was: %s\n", GSMOPEN_P_LOG, at_command); - return -1; - } - // jet - early audio - //if (tech_pvt->at_early_audio) { - //ast_queue_control(tech_pvt->owner, AST_CONTROL_ANSWER); - //} - - return 0; -} - -int ucs2_to_utf8(private_t * tech_pvt, char *ucs2_in, char *utf8_out, size_t outbytesleft) -{ - char converted[16000]; -#ifndef WIN32 - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - size_t inbytesleft; - int c; - char stringa[5]; - double hexnum; - int i = 0; - - memset(converted, '\0', sizeof(converted)); - - DEBUGA_GSMOPEN("ucs2_in=%s\n", GSMOPEN_P_LOG, ucs2_in); - /* cicopet */ - for (c = 0; c < strlen(ucs2_in); c++) { - sprintf(stringa, "0x%c%c", ucs2_in[c], ucs2_in[c + 1]); - c++; - hexnum = strtod(stringa, NULL); - converted[i] = (char) hexnum; - i++; - } - - outbuf = utf8_out; - inbuf = converted; - - iconv_format = iconv_open("UTF8", "UCS-2BE"); - if (iconv_format == (iconv_t) - 1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - - inbytesleft = i; - DEBUGA_GSMOPEN("1 ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out); - - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (iconv_res == (size_t) -1) { - DEBUGA_GSMOPEN("2 ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out); - DEBUGA_GSMOPEN("3 error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno); - iconv_close(iconv_format); - return -1; - } - DEBUGA_GSMOPEN - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out); - iconv_close(iconv_format); - -#endif //WIN32 - return 0; -} - -int iso_8859_1_to_utf8(private_t * tech_pvt, char *iso_8859_1_in, char *utf8_out, size_t outbytesleft) -{ - char converted[16000]; -#ifndef WIN32 - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - size_t inbytesleft; - //int c; - //char stringa[5]; - //double hexnum; - //int i = 0; - - memset(converted, '\0', sizeof(converted)); - - DEBUGA_GSMOPEN("iso_8859_1_in=%s\n", GSMOPEN_P_LOG, iso_8859_1_in); - - outbuf = utf8_out; - inbuf = iso_8859_1_in; - - iconv_format = iconv_open("UTF8", "ISO_8859-1"); - if (iconv_format == (iconv_t) - 1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - - - inbytesleft = strlen(iso_8859_1_in) * 2; - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (iconv_res == (size_t) -1) { - DEBUGA_GSMOPEN("ciao in=%s, inleft=%d, out=%s, outleft=%d, utf8_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_out); - DEBUGA_GSMOPEN("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_GSMOPEN - (" strlen(iso_8859_1_in)=%d, iconv_res=%d, inbuf=%s, inleft=%d, out=%s, outleft=%d, utf8_out=%s\n", - GSMOPEN_P_LOG, (int) strlen(iso_8859_1_in), iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_out); - - - - iconv_close(iconv_format); - -#endif //WIN32 - return 0; -} - - -int utf_to_ucs2(private_t * tech_pvt, char *utf_in, size_t inbytesleft, char *ucs2_out, size_t outbytesleft) -{ - /* cicopet */ -#ifndef WIN32 - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - char converted[16000]; - int i; - char stringa[16]; - char stringa2[16]; - - memset(converted, '\0', sizeof(converted)); - - outbuf = converted; - inbuf = utf_in; - - iconv_format = iconv_open("UCS-2BE", "UTF8"); - if (iconv_format == (iconv_t) - 1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - outbytesleft = 16000; - - DEBUGA_GSMOPEN("in=%s, inleft=%d, out=%s, outleft=%d, utf_in=%s, converted=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf_in, converted); - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (iconv_res == (size_t) -1) { - ERRORA("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_GSMOPEN - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, utf_in=%s, converted=%s\n", - GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf_in, converted); - iconv_close(iconv_format); - - for (i = 0; i < 16000 - outbytesleft; i++) { - memset(stringa, '\0', sizeof(stringa)); - memset(stringa2, '\0', sizeof(stringa2)); - sprintf(stringa, "%02X", converted[i]); - DEBUGA_GSMOPEN("character is |%02X|\n", GSMOPEN_P_LOG, converted[i]); - stringa2[0] = stringa[strlen(stringa) - 2]; - stringa2[1] = stringa[strlen(stringa) - 1]; - strncat(ucs2_out, stringa2, ((outbytesleft - strlen(ucs2_out)) - 1)); //add the received line to the buffer - DEBUGA_GSMOPEN("stringa=%s, stringa2=%s, ucs2_out=%s\n", GSMOPEN_P_LOG, stringa, stringa2, ucs2_out); - } -#endif //WIN32 - return 0; -} - - -/*! \brief Answer incoming call, - * Part of PBX interface */ -int gsmopen_answer(private_t * tech_pvt) -{ - int res; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", GSMOPEN_P_LOG); - } - /* do something to actually answer the call, if needed (eg. pick up the phone) */ - if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) { - if (gsmopen_serial_answer(tech_pvt)) { - ERRORA("gsmopen_answer FAILED\n", GSMOPEN_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return -1; - } - } - tech_pvt->interface_state = GSMOPEN_STATE_UP; - tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - - while (tech_pvt->interface_state == GSMOPEN_STATE_RING) { - gsmopen_sleep(10000); //10msec - } - if (tech_pvt->interface_state != GSMOPEN_STATE_UP) { - ERRORA("call answering failed\n", GSMOPEN_P_LOG); - res = -1; - } else { - if (option_debug) - DEBUGA_PBX("call answered\n", GSMOPEN_P_LOG); - res = 0; -#ifdef GSMOPEN_PORTAUDIO - //speex_echo_state_reset(tech_pvt->stream->echo_state); -#endif // GSMOPEN_PORTAUDIO - - new_inbound_channel(tech_pvt); - if (tech_pvt->owner) { - DEBUGA_PBX("going to send GSMOPEN_STATE_UP\n", GSMOPEN_P_LOG); - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_UP); - //ast_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER); - //gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER); - DEBUGA_PBX("just sent GSMOPEN_STATE_UP\n", GSMOPEN_P_LOG); - } - } - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return res; -} - -int gsmopen_ring(private_t * tech_pvt) -{ - int res = 0; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (option_debug) { - //DEBUGA_PBX("ENTERING FUNC\n", GSMOPEN_P_LOG); - } - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - switch_core_session_rwunlock(session); - return 0; - } - - new_inbound_channel(tech_pvt); - - gsmopen_sleep(10000); - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - - switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING); - if (channel) { - switch_channel_mark_ring_ready(channel); - } else { - ERRORA("no session\n", GSMOPEN_P_LOG); - } - switch_core_session_rwunlock(session); - } else { - ERRORA("no session\n", GSMOPEN_P_LOG); - - } - - - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return res; -} - - -/*! \brief Hangup gsmopen call - * Part of PBX interface, called from ast_hangup */ - -int gsmopen_hangup(private_t * tech_pvt) -{ - - /* if there is not gsmopen pvt why we are here ? */ - if (!tech_pvt) { - ERRORA("Asked to hangup channel not connected\n", GSMOPEN_P_LOG); - return 0; - } - - DEBUGA_GSMOPEN("ENTERING FUNC\n", GSMOPEN_P_LOG); - - - if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) { - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - /* actually hangup through the serial port */ - if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) { - int res; - res = gsmopen_serial_hangup(tech_pvt); - if (res) { - ERRORA("gsmopen_serial_hangup error: %d\n", GSMOPEN_P_LOG, res); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return -1; - } - } - - while (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - gsmopen_sleep(10000); //10msec - } - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - ERRORA("call hangup failed\n", GSMOPEN_P_LOG); - return -1; - } else { - DEBUGA_GSMOPEN("call hungup\n", GSMOPEN_P_LOG); - } - } - } else { - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - } - - switch_set_flag(tech_pvt, TFLAG_HANGUP); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return 0; -} - - - -#ifdef GSMOPEN_ALSA -/*! \brief ALSA pcm format, according to endianess */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -snd_pcm_format_t gsmopen_format = SND_PCM_FORMAT_S16_LE; -#else -snd_pcm_format_t gsmopen_format = SND_PCM_FORMAT_S16_BE; -#endif - -/*! - * \brief Initialize the ALSA soundcard channels (capture AND playback) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the gsmopen_pvt of the interface - * - * This function call alsa_open_dev to initialize the ALSA soundcard for each channel (capture AND playback) used by one interface (a multichannel soundcard can be used by multiple interfaces). Called by sound_init - * - * \return zero on success, -1 on error. - */ -int alsa_init(private_t * tech_pvt) -{ - tech_pvt->alsac = alsa_open_dev(tech_pvt, SND_PCM_STREAM_CAPTURE); - if (!tech_pvt->alsac) { - ERRORA("Failed opening ALSA capture device: %s\n", GSMOPEN_P_LOG, tech_pvt->alsacname); - if (alsa_shutdown(tech_pvt)) { - ERRORA("alsa_shutdown failed\n", GSMOPEN_P_LOG); - return -1; - } - return -1; - } - tech_pvt->alsap = alsa_open_dev(tech_pvt, SND_PCM_STREAM_PLAYBACK); - if (!tech_pvt->alsap) { - ERRORA("Failed opening ALSA playback device: %s\n", GSMOPEN_P_LOG, tech_pvt->alsapname); - if (alsa_shutdown(tech_pvt)) { - ERRORA("alsa_shutdown failed\n", GSMOPEN_P_LOG); - return -1; - } - return -1; - } - - /* make valgrind very happy */ - snd_config_update_free_global(); - return 0; -} - -/*! - * \brief Shutdown the ALSA soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the gsmopen_pvt of the interface - * - * This function shutdown the ALSA soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces). Called by sound_init - * - * \return zero on success, -1 on error. - */ - -int alsa_shutdown(private_t * tech_pvt) -{ - - int err; - - if (tech_pvt->alsap) { - err = snd_pcm_drop(tech_pvt->alsap); - if (err < 0) { - ERRORA("device [%s], snd_pcm_drop failed with error '%s'\n", GSMOPEN_P_LOG, tech_pvt->alsapname, snd_strerror(err)); - return -1; - } - err = snd_pcm_close(tech_pvt->alsap); - if (err < 0) { - ERRORA("device [%s], snd_pcm_close failed with error '%s'\n", GSMOPEN_P_LOG, tech_pvt->alsapname, snd_strerror(err)); - return -1; - } - tech_pvt->alsap = NULL; - } - if (tech_pvt->alsac) { - err = snd_pcm_drop(tech_pvt->alsac); - if (err < 0) { - ERRORA("device [%s], snd_pcm_drop failed with error '%s'\n", GSMOPEN_P_LOG, tech_pvt->alsacname, snd_strerror(err)); - return -1; - } - err = snd_pcm_close(tech_pvt->alsac); - if (err < 0) { - ERRORA("device [%s], snd_pcm_close failed with error '%s'\n", GSMOPEN_P_LOG, tech_pvt->alsacname, snd_strerror(err)); - return -1; - } - tech_pvt->alsac = NULL; - } - - return 0; -} - -/*! - * \brief Setup and open the ALSA device (capture OR playback) - * \param p the gsmopen_pvt of the interface - * \param stream the ALSA capture/playback definition - * - * This function setup and open the ALSA device (capture OR playback). Called by alsa_init - * - * \return zero on success, -1 on error. - */ -snd_pcm_t *alsa_open_dev(private_t * tech_pvt, snd_pcm_stream_t stream) -{ - - snd_pcm_t *handle = NULL; - snd_pcm_hw_params_t *params; - snd_pcm_sw_params_t *swparams; - snd_pcm_uframes_t buffer_size; - int err; - size_t n; - //snd_pcm_uframes_t xfer_align; - unsigned int rate; - snd_pcm_uframes_t start_threshold, stop_threshold; - snd_pcm_uframes_t period_size = 0; - snd_pcm_uframes_t chunk_size = 0; - int start_delay = 0; - int stop_delay = 0; - snd_pcm_state_t state; - snd_pcm_info_t *info; - unsigned int chan_num; - - period_size = tech_pvt->alsa_period_size; - - snd_pcm_hw_params_alloca(¶ms); - snd_pcm_sw_params_alloca(&swparams); - - if (stream == SND_PCM_STREAM_CAPTURE) { - err = snd_pcm_open(&handle, tech_pvt->alsacname, stream, 0 | SND_PCM_NONBLOCK); - } else { - err = snd_pcm_open(&handle, tech_pvt->alsapname, stream, 0 | SND_PCM_NONBLOCK); - } - if (err < 0) { - ERRORA - ("snd_pcm_open failed with error '%s' on device '%s', if you are using a plughw:n device please change it to be a default:n device (so to allow it to be shared with other concurrent programs), or maybe you are using an ALSA voicemodem and slmodemd" - " is running?\n", GSMOPEN_P_LOG, snd_strerror(err), stream == SND_PCM_STREAM_CAPTURE ? tech_pvt->alsacname : tech_pvt->alsapname); - return NULL; - } - - snd_pcm_info_alloca(&info); - - if ((err = snd_pcm_info(handle, info)) < 0) { - ERRORA("info error: %s", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - - err = snd_pcm_nonblock(handle, 1); - if (err < 0) { - ERRORA("nonblock setting error: %s", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - ERRORA("Broken configuration for this PCM, no configurations available: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - - err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); - if (err < 0) { - ERRORA("Access type not available: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - err = snd_pcm_hw_params_set_format(handle, params, gsmopen_format); - if (err < 0) { - ERRORA("Sample format non available: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - err = snd_pcm_hw_params_set_channels(handle, params, 1); - if (err < 0) { - DEBUGA_GSMOPEN("Channels count set failed: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } -#if 1 - err = snd_pcm_hw_params_get_channels(params, &chan_num); - if (err < 0) { - ERRORA("Channels count non available: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - if (chan_num < 1 || chan_num > 2) { - ERRORA("Channels count MUST BE 1 or 2, it is: %d\n", GSMOPEN_P_LOG, chan_num); - ERRORA("Channels count MUST BE 1 or 2, it is: %d on %s %s\n", GSMOPEN_P_LOG, chan_num, tech_pvt->alsapname, tech_pvt->alsacname); - return NULL; - } else { - if (chan_num == 1) { - if (stream == SND_PCM_STREAM_CAPTURE) - tech_pvt->alsa_capture_is_mono = 1; - else - tech_pvt->alsa_play_is_mono = 1; - } else { - if (stream == SND_PCM_STREAM_CAPTURE) - tech_pvt->alsa_capture_is_mono = 0; - else - tech_pvt->alsa_play_is_mono = 0; - } - } -#else - tech_pvt->alsa_capture_is_mono = 1; - tech_pvt->alsa_play_is_mono = 1; -#endif - -#if 1 - rate = tech_pvt->gsmopen_sound_rate; - err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0); - if ((float) tech_pvt->gsmopen_sound_rate * 1.05 < rate || (float) tech_pvt->gsmopen_sound_rate * 0.95 > rate) { - WARNINGA("Rate is not accurate (requested = %iHz, got = %iHz)\n", GSMOPEN_P_LOG, tech_pvt->gsmopen_sound_rate, rate); - } - - if (err < 0) { - ERRORA("Error setting rate: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - tech_pvt->gsmopen_sound_rate = rate; - - err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, 0); - - if (err < 0) { - ERRORA("Error setting period_size: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - - tech_pvt->alsa_period_size = period_size; - - tech_pvt->alsa_buffer_size = tech_pvt->alsa_period_size * tech_pvt->alsa_periods_in_buffer; - - err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &tech_pvt->alsa_buffer_size); - - if (err < 0) { - ERRORA("Error setting buffer_size: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } -#endif - - err = snd_pcm_hw_params(handle, params); - if (err < 0) { - ERRORA("Unable to install hw params: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - - snd_pcm_hw_params_get_period_size(params, &chunk_size, 0); - snd_pcm_hw_params_get_buffer_size(params, &buffer_size); - if (chunk_size == buffer_size) { - ERRORA("Can't use period equal to buffer size (%lu == %lu)\n", GSMOPEN_P_LOG, chunk_size, buffer_size); - return NULL; - } - - snd_pcm_sw_params_current(handle, swparams); - - /* - if (sleep_min) - xfer_align = 1; - err = snd_pcm_sw_params_set_sleep_min(handle, swparams, - 0); - - if (err < 0) { - ERRORA("Error setting slep_min: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } - */ - n = chunk_size; - err = snd_pcm_sw_params_set_avail_min(handle, swparams, n); - if (err < 0) { - ERRORA("Error setting avail_min: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } - if (stream == SND_PCM_STREAM_CAPTURE) { - start_delay = 1; - } - if (start_delay <= 0) { - start_threshold = n + (snd_pcm_uframes_t) rate *start_delay / 1000000; - } else { - start_threshold = (snd_pcm_uframes_t) rate *start_delay / 1000000; - } - if (start_threshold < 1) - start_threshold = 1; - if (start_threshold > n) - start_threshold = n; - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold); - if (err < 0) { - ERRORA("Error setting start_threshold: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } - - if (stop_delay <= 0) - stop_threshold = buffer_size + (snd_pcm_uframes_t) rate *stop_delay / 1000000; - else - stop_threshold = (snd_pcm_uframes_t) rate *stop_delay / 1000000; - - if (stream == SND_PCM_STREAM_CAPTURE) { - stop_threshold = -1; - } - - err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); - - if (err < 0) { - ERRORA("Error setting stop_threshold: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } - - if (snd_pcm_sw_params(handle, swparams) < 0) { - ERRORA("Error installing software parameters: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } - - err = snd_pcm_poll_descriptors_count(handle); - if (err <= 0) { - ERRORA("Unable to get a poll descriptors count, error is %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - - if (err != 1) { //number of poll descriptors - DEBUGA_GSMOPEN("Can't handle more than one device\n", GSMOPEN_P_LOG); - return NULL; - } - - err = snd_pcm_poll_descriptors(handle, &tech_pvt->pfd, err); - if (err != 1) { - ERRORA("snd_pcm_poll_descriptors failed, %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - DEBUGA_GSMOPEN("Acquired fd %d from the poll descriptor\n", GSMOPEN_P_LOG, tech_pvt->pfd.fd); - - if (stream == SND_PCM_STREAM_CAPTURE) { - tech_pvt->gsmopen_sound_capt_fd = tech_pvt->pfd.fd; - } - - state = snd_pcm_state(handle); - - if (state != SND_PCM_STATE_RUNNING) { - if (state != SND_PCM_STATE_PREPARED) { - err = snd_pcm_prepare(handle); - if (err) { - ERRORA("snd_pcm_prepare failed, %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - DEBUGA_GSMOPEN("prepared!\n", GSMOPEN_P_LOG); - } - if (stream == SND_PCM_STREAM_CAPTURE) { - err = snd_pcm_start(handle); - if (err) { - ERRORA("snd_pcm_start failed, %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - return NULL; - } - DEBUGA_GSMOPEN("started!\n", GSMOPEN_P_LOG); - } - } - if (option_debug > 1) { - snd_output_t *output = NULL; - err = snd_output_stdio_attach(&output, stdout, 0); - if (err < 0) { - ERRORA("snd_output_stdio_attach failed: %s\n", GSMOPEN_P_LOG, snd_strerror(err)); - } - snd_pcm_dump(handle, output); - -#ifndef NO_GSMLIB - SMSMessageRef sms; - char content2[1000]; - //sms = SMSMessage::decode("079194710167120004038571F1390099406180904480A0D41631067296EF7390383D07CD622E58CD95CB81D6EF39BDEC66BFE7207A794E2FBB4320AFB82C07E56020A8FC7D9687DBED32285C9F83A06F769A9E5EB340D7B49C3E1FA3C3663A0B24E4CBE76516680A7FCBE920725A5E5ED341F0B21C346D4E41E1BA790E4286DDE4BC0BD42CA3E5207258EE1797E5A0BA9B5E9683C86539685997EBEF61341B249BC966"); // dataCodingScheme = 0 - //sms = SMSMessage::decode("0791934329002000040C9193432766658100009001211133318004D4F29C0E"); // dataCodingScheme = 0 - //sms = SMSMessage::decode("0791934329002000040C919343276665810008900121612521801600CC00E800E900F900F200E00020006300690061006F"); // dataCodingScheme = 8 - sms = SMSMessage::decode("0791934329002000040C919343276665810008900172002293404C006300690061006F0020003100320033002000620065006C00E80020043D043E0432043E044104420438002005DC05E7002005E805D005EA0020FE8EFEE0FEA0FEE4FECBFE9300204EBA5927"); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大 - //sms = SMSMessage::decode("07911497941902F00414D0E474989D769F5DE4320839001040122151820000"); // dataCodingScheme = 0 - //NOTICA("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str()); - - memset(content2, '\0', sizeof(content2)); - if (sms->dataCodingScheme().getAlphabet() == DCS_DEFAULT_ALPHABET) { - iso_8859_1_to_utf8(tech_pvt, (char *) sms->userData().c_str(), content2, sizeof(content2)); - } else if (sms->dataCodingScheme().getAlphabet() == DCS_SIXTEEN_BIT_ALPHABET) { - ucs2_to_utf8(tech_pvt, (char *) bufToHex((unsigned char *) sms->userData().data(), sms->userData().length()).c_str(), content2, - sizeof(content2)); - } else { - ERRORA("dataCodingScheme not supported=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - - } - //NOTICA("dataCodingScheme=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - //NOTICA("userData= |||%s|||\n", GSMOPEN_P_LOG, content2); -#endif// NO_GSMLIB - - } - if (option_debug > 1) - DEBUGA_GSMOPEN("ALSA handle = %ld\n", GSMOPEN_P_LOG, (long int) handle); - return handle; - -} - -/*! \brief Write audio frames to interface */ -#endif /* GSMOPEN_ALSA */ - -int gsmopen_call(private_t * tech_pvt, char *rdest, int timeout) -{ - - //gsmopen_sleep(5000); - DEBUGA_GSMOPEN("Calling GSM, rdest is: %s\n", GSMOPEN_P_LOG, rdest); - //gsmopen_signaling_write(tech_pvt, "SET AGC OFF"); - //gsmopen_sleep(10000); - //gsmopen_signaling_write(tech_pvt, "SET AEC OFF"); - //gsmopen_sleep(10000); - - gsmopen_serial_call(tech_pvt, rdest); - //ERRORA("failed to communicate with GSM client, now exit\n", GSMOPEN_P_LOG); - //return -1; - //} - return 0; -} - - -int gsmopen_senddigit(private_t * tech_pvt, char digit) -{ - - DEBUGA_GSMOPEN("DIGIT received: %c\n", GSMOPEN_P_LOG, digit); - if (tech_pvt->controldevprotocol == PROTOCOL_AT && tech_pvt->at_send_dtmf[0]) { - int res = 0; - char at_command[256]; - - memset(at_command, '\0', 256); - sprintf(at_command, "%s=\"%c\"", tech_pvt->at_send_dtmf, digit); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res) { - ERRORA("senddigit command failed, command used: '%s=\"%c\"', giving up\n", GSMOPEN_P_LOG, tech_pvt->at_send_dtmf, digit); - } - } - - return 0; -} - -#ifdef GSMOPEN_ALSA -/*! \brief Write audio frames to interface */ -int alsa_write(private_t * tech_pvt, short *data, int datalen) -{ - static char sizbuf[8000]; - static char sizbuf2[16000]; - static char silencebuf[8000]; - static int sizpos = 0; - int len = sizpos; - //int pos; - int res = 0; - time_t now_timestamp; - /* size_t frames = 0; */ - snd_pcm_state_t state; - snd_pcm_sframes_t delayp1=0; - snd_pcm_sframes_t delayp2=0; - - if(tech_pvt->no_sound==1){ - return res; - } - - - memset(sizbuf, 255, sizeof(sizbuf)); - memset(sizbuf2, 255, sizeof(sizbuf)); - memset(silencebuf, 255, sizeof(sizbuf)); - - //ERRORA("data=%p, datalen=%d\n", GSMOPEN_P_LOG, (void *)data, datalen); - /* We have to digest the frame in 160-byte portions */ - if (datalen > sizeof(sizbuf) - sizpos) { - ERRORA("Frame too large\n", GSMOPEN_P_LOG); - res = -1; - } else { - memcpy(sizbuf + sizpos, data, datalen); - memset(data, 255, datalen); - len += datalen; - //pos = 0; - - -#ifdef ALSA_MONITOR - alsa_monitor_write(sizbuf, len); -#endif - state = snd_pcm_state(tech_pvt->alsap); - if (state == SND_PCM_STATE_XRUN) { - int i; - - DEBUGA_GSMOPEN - ("You've got an ALSA write XRUN in the past (gsmopen can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file\n", - GSMOPEN_P_LOG, tech_pvt->alsa_periods_in_buffer); - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } else { - res = snd_pcm_format_set_silence(gsmopen_format, silencebuf, len / 2); - if (res < 0) { - DEBUGA_GSMOPEN("Silence error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } - for (i = 0; i < (tech_pvt->alsa_periods_in_buffer - 1); i++) { - res = snd_pcm_writei(tech_pvt->alsap, silencebuf, len / 2); - if (res != len / 2) { - DEBUGA_GSMOPEN("Write returned a different quantity: %d\n", GSMOPEN_P_LOG, res); - res = -1; - } else if (res < 0) { - DEBUGA_GSMOPEN("Write error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } - } - } - - } - - res = snd_pcm_delay(tech_pvt->alsap, &delayp1); - if (res < 0) { - DEBUGA_GSMOPEN("Error %d on snd_pcm_delay: \"%s\"\n", GSMOPEN_P_LOG, res, snd_strerror(res)); - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - DEBUGA_GSMOPEN("snd_pcm_prepare failed: '%s'\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_delay(tech_pvt->alsap, &delayp1); - } - - delayp2 = snd_pcm_avail_update(tech_pvt->alsap); - if (delayp2 < 0) { - DEBUGA_GSMOPEN("Error %d on snd_pcm_avail_update: \"%s\"\n", GSMOPEN_P_LOG, (int) delayp2, snd_strerror(delayp2)); - - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - DEBUGA_GSMOPEN("snd_pcm_prepare failed: '%s'\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - delayp2 = snd_pcm_avail_update(tech_pvt->alsap); - } - - if ( /* delayp1 != 0 && delayp1 != 160 */ - delayp1 < 160 || delayp2 > tech_pvt->alsa_buffer_size) { - - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - DEBUGA_GSMOPEN - ("snd_pcm_prepare failed while trying to prevent an ALSA write XRUN: %s, delayp1=%d, delayp2=%d\n", - GSMOPEN_P_LOG, snd_strerror(res), (int) delayp1, (int) delayp2); - } else { - - int i; - for (i = 0; i < (tech_pvt->alsa_periods_in_buffer - 1); i++) { - res = snd_pcm_format_set_silence(gsmopen_format, silencebuf, len / 2); - if (res < 0) { - DEBUGA_GSMOPEN("Silence error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } - res = snd_pcm_writei(tech_pvt->alsap, silencebuf, len / 2); - if (res < 0) { - DEBUGA_GSMOPEN("Write error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } else if (res != len / 2) { - DEBUGA_GSMOPEN("Write returned a different quantity: %d\n", GSMOPEN_P_LOG, res); - res = -1; - } - } - - DEBUGA_GSMOPEN - ("PREVENTING an ALSA write XRUN (gsmopen can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file. delayp1=%d, delayp2=%d\n", - GSMOPEN_P_LOG, tech_pvt->alsa_periods_in_buffer, (int) delayp1, (int) delayp2); - } - - } - - memset(sizbuf2, 0, sizeof(sizbuf2)); - if (tech_pvt->alsa_play_is_mono) { - res = snd_pcm_writei(tech_pvt->alsap, sizbuf, len / 2); - } else { - int a = 0; - int i = 0; - for (i = 0; i < 8000;) { - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i--; - sizbuf2[a] = sizbuf[i]; // comment out this line to use only left - a++; - i++; - sizbuf2[a] = sizbuf[i]; // comment out this line to use only left - a++; - i++; - } - res = snd_pcm_writei(tech_pvt->alsap, sizbuf2, len); - } - if (res == -EPIPE) { - DEBUGA_GSMOPEN - ("ALSA write EPIPE (XRUN) (gsmopen can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file. delayp1=%d, delayp2=%d\n", - GSMOPEN_P_LOG, tech_pvt->alsa_periods_in_buffer, (int) delayp1, (int) delayp2); - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } else { - - if (tech_pvt->alsa_play_is_mono) { - res = snd_pcm_writei(tech_pvt->alsap, sizbuf, len / 2); - } else { - int a = 0; - int i = 0; - for (i = 0; i < 8000;) { - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i--; - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i++; - } - res = snd_pcm_writei(tech_pvt->alsap, sizbuf2, len); - } - - } - - } else { - if (res == -ESTRPIPE) { - ERRORA("You've got some big problems\n", GSMOPEN_P_LOG); - } else if (res == -EAGAIN) { - DEBUGA_GSMOPEN("Momentarily busy\n", GSMOPEN_P_LOG); - res = 0; - } else if (res < 0) { - ERRORA("Error %d on audio write: \"%s\"\n", GSMOPEN_P_LOG, res, snd_strerror(res)); - } - } - } - - if (tech_pvt->audio_play_reset_period) { - time(&now_timestamp); - if ((now_timestamp - tech_pvt->audio_play_reset_timestamp) > tech_pvt->audio_play_reset_period) { - if (option_debug) - DEBUGA_GSMOPEN("reset audio play\n", GSMOPEN_P_LOG); - res = snd_pcm_wait(tech_pvt->alsap, 1000); - if (res < 0) { - ERRORA("audio play wait failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_drop(tech_pvt->alsap); - if (res) { - ERRORA("audio play drop failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_wait(tech_pvt->alsap, 1000); - if (res < 0) { - ERRORA("audio play wait failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - time(&tech_pvt->audio_play_reset_timestamp); - } - } - //res = 0; - //if (res > 0) - //res = 0; - return res; -} - -#define AST_FRIENDLY_OFFSET 0 -int alsa_read(private_t * tech_pvt, short *data, int datalen) -{ - //static struct ast_frame f; - static short __buf[GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - static short __buf2[(GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2]; - short *buf; - short *buf2; - static int readpos = 0; - //static int left = GSMOPEN_FRAME_SIZE; - static int left; - snd_pcm_state_t state; - int r = 0; - int off = 0; - int error = 0; - //time_t now_timestamp; - - //DEBUGA_GSMOPEN("buf=%p, datalen=%d, left=%d\n", GSMOPEN_P_LOG, (void *)buf, datalen, left); - //memset(&f, 0, sizeof(struct ast_frame)); //giova - - - - if(tech_pvt->no_sound==1){ - return r; - } - - left = datalen; - - - state = snd_pcm_state(tech_pvt->alsac); - if (state != SND_PCM_STATE_RUNNING) { - DEBUGA_GSMOPEN("ALSA read state is not SND_PCM_STATE_RUNNING\n", GSMOPEN_P_LOG); - - if (state != SND_PCM_STATE_PREPARED) { - error = snd_pcm_prepare(tech_pvt->alsac); - if (error) { - ERRORA("snd_pcm_prepare failed, %s\n", GSMOPEN_P_LOG, snd_strerror(error)); - return r; - } - DEBUGA_GSMOPEN("prepared!\n", GSMOPEN_P_LOG); - } - gsmopen_sleep(1000); - error = snd_pcm_start(tech_pvt->alsac); - if (error) { - ERRORA("snd_pcm_start failed, %s\n", GSMOPEN_P_LOG, snd_strerror(error)); - return r; - } - DEBUGA_GSMOPEN("started!\n", GSMOPEN_P_LOG); - gsmopen_sleep(1000); - } - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - buf2 = __buf2 + ((AST_FRIENDLY_OFFSET / 2) * 2); - - if (tech_pvt->alsa_capture_is_mono) { - r = snd_pcm_readi(tech_pvt->alsac, buf + readpos, left); - //DEBUGA_GSMOPEN("r=%d, buf=%p, buf+readpos=%p, datalen=%d, left=%d\n", GSMOPEN_P_LOG, r, (void *)buf, (void *)(buf + readpos), datalen, left); - } else { - int a = 0; - int i = 0; - r = snd_pcm_readi(tech_pvt->alsac, buf2 + (readpos * 2), left); - - for (i = 0; i < (GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2;) { - __buf[a] = (__buf2[i] + __buf2[i + 1]) / 2; //comment out this line to use only left - //__buf[a] = __buf2[i]; // enable this line to use only left - a++; - i++; - i++; - } - } - - if (r == -EPIPE) { - DEBUGA_GSMOPEN("ALSA XRUN on read\n", GSMOPEN_P_LOG); - return r; - } else if (r == -ESTRPIPE) { - ERRORA("-ESTRPIPE\n", GSMOPEN_P_LOG); - return r; - - } else if (r == -EAGAIN) { - int count=0; - while (r == -EAGAIN) { - gsmopen_sleep(10000); - DEBUGA_GSMOPEN("%d ALSA read -EAGAIN, the soundcard is not ready to be read by gsmopen\n", GSMOPEN_P_LOG, count); - count++; - - if (tech_pvt->alsa_capture_is_mono) { - r = snd_pcm_readi(tech_pvt->alsac, buf + readpos, left); - } else { - int a = 0; - int i = 0; - r = snd_pcm_readi(tech_pvt->alsac, buf2 + (readpos * 2), left); - - for (i = 0; i < (GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2;) { - __buf[a] = (__buf2[i] + __buf2[i + 1]) / 2; - a++; - i++; - i++; - } - } - - } - } else if (r < 0) { - WARNINGA("ALSA Read error: %s\n", GSMOPEN_P_LOG, snd_strerror(r)); - } else if (r >= 0) { - //DEBUGA_GSMOPEN("read: r=%d, readpos=%d, left=%d, off=%d\n", GSMOPEN_P_LOG, r, readpos, left, off); - off -= r; //what is the meaning of this? a leftover, probably - } - /* Update positions */ - readpos += r; - left -= r; - - if (readpos >= GSMOPEN_FRAME_SIZE) { - int i; - /* A real frame */ - readpos = 0; - left = GSMOPEN_FRAME_SIZE; - for (i = 0; i < r; i++) - data[i] = buf[i]; - - } - return r; -} - -#endif // GSMOPEN_ALSA - - - - - -int gsmopen_sendsms(private_t * tech_pvt, char *dest, char *text) -{ - //char *idest = data; - //char rdest[256]; - //private_t *p = NULL; - //char *device; - //char *dest; - //char *text; - //char *stringp = NULL; - //int found = 0; - int failed = 0; - int err = 0; - - //strncpy(rdest, idest, sizeof(rdest) - 1); - DEBUGA_GSMOPEN("GSMopenSendsms: dest=%s text=%s\n", GSMOPEN_P_LOG, dest, text); - DEBUGA_GSMOPEN("START\n", GSMOPEN_P_LOG); - /* we can use gsmopen_request to get the channel, but gsmopen_request would look for onowned channels, and probably we can send SMSs while a call is ongoing - * - */ - - if (tech_pvt->controldevprotocol != PROTOCOL_AT) { - ERRORA(", GSMOPEN_P_LOGGSMopenSendsms supports only AT command cellphones at the moment :-( !\n", GSMOPEN_P_LOG); - return RESULT_FAILURE; - } - - if (tech_pvt->controldevprotocol == PROTOCOL_AT) { - char smscommand[16000]; - memset(smscommand, '\0', sizeof(smscommand)); - - PUSHA_UNLOCKA(&tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - - err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1"); - if (err) { - ERRORA("AT+CMGF=1 (set message sending to TEXT (as opposed to PDU) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - - - if (tech_pvt->no_ucs2) { - sprintf(smscommand, "AT+CMGS=\"%s\"", dest); //TODO: support phones that only accept pdu mode - } else { - char dest2[1048]; - - err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\""); - if (err) { - ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - - memset(dest2, '\0', sizeof(dest2)); - utf_to_ucs2(tech_pvt, dest, strlen(dest), dest2, sizeof(dest2)); - sprintf(smscommand, "AT+CMGS=\"%s\"", dest2); //TODO: support phones that only accept pdu mode - } - //TODO: support phones that only accept pdu mode - //TODO would be better to lock controldev here - //sprintf(smscommand, "AT+CMGS=\"%s\"", dest); //FIXME: nokia e63 want this - err = gsmopen_serial_write_AT_noack(tech_pvt, smscommand); - if (err) { - ERRORA("Error sending SMS\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - err = gsmopen_serial_AT_expect(tech_pvt, "> ", 0, 1); // wait 1.5s for the prompt, no crlf -#if 1 - if (err) { - DEBUGA_GSMOPEN - ("Error or timeout getting prompt '> ' for sending sms directly to the remote party. BTW, seems that we cannot do that with Motorola c350, so we'll write to cellphone memory, then send from memory\n", - GSMOPEN_P_LOG); - - err = gsmopen_serial_write_AT_ack(tech_pvt, "ATE1"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!! - if (err) { - ERRORA("Error activating echo from modem\n", GSMOPEN_P_LOG); - } - tech_pvt->at_cmgw[0] = '\0'; - sprintf(smscommand, "AT+CMGW=\"%s\"", dest); //TODO: support phones that only accept pdu mode - err = gsmopen_serial_write_AT_noack(tech_pvt, smscommand); - if (err) { - ERRORA("Error writing SMS destination to the cellphone memory\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - err = gsmopen_serial_AT_expect(tech_pvt, "> ", 0, 1); // wait 1.5s for the prompt, no crlf - if (err) { - ERRORA("Error or timeout getting prompt '> ' for writing sms text in cellphone memory\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - } -#endif - - //sprintf(text,"ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大"); //let's test the beauty of utf - memset(smscommand, '\0', sizeof(smscommand)); - if (tech_pvt->no_ucs2) { - sprintf(smscommand, "%s", text); - } else { - utf_to_ucs2(tech_pvt, text, strlen(text), smscommand, sizeof(smscommand)); - } - - smscommand[strlen(smscommand)] = 0x1A; - DEBUGA_GSMOPEN("smscommand len is: %d, text is:|||%s|||\n", GSMOPEN_P_LOG, (int) strlen(smscommand), smscommand); - - err = gsmopen_serial_write_AT_ack_nocr_longtime(tech_pvt, smscommand); - //TODO would be better to unlock controldev here - if (err) { - ERRORA("Error writing SMS text to the cellphone memory\n", GSMOPEN_P_LOG); - //return RESULT_FAILURE; - failed = 1; - goto uscita; - } - if (tech_pvt->at_cmgw[0]) { - sprintf(smscommand, "AT+CMSS=%s", tech_pvt->at_cmgw); - err = gsmopen_serial_write_AT_expect_longtime(tech_pvt, smscommand, "OK"); - if (err) { - ERRORA("Error sending SMS from the cellphone memory\n", GSMOPEN_P_LOG); - //return RESULT_FAILURE; - failed = 1; - goto uscita; - } - - err = gsmopen_serial_write_AT_ack(tech_pvt, "ATE0"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!! - if (err) { - ERRORA("Error de-activating echo from modem\n", GSMOPEN_P_LOG); - } - } - uscita: - gsmopen_sleep(1000); - - if (tech_pvt->at_cmgw[0]) { - - /* let's see what we've sent, just for check TODO: Motorola it's not reliable! Motorola c350 tells that all was sent, but is not true! It just sends how much it fits into one SMS FIXME: need an algorithm to calculate how many ucs2 chars fits into an SMS. It make difference based, probably, on the GSM alphabet translation, or so */ - sprintf(smscommand, "AT+CMGR=%s", tech_pvt->at_cmgw); - err = gsmopen_serial_write_AT_ack(tech_pvt, smscommand); - if (err) { - ERRORA("Error reading SMS back from the cellphone memory\n", GSMOPEN_P_LOG); - } - - /* let's delete from cellphone memory what we've sent */ - sprintf(smscommand, "AT+CMGD=%s", tech_pvt->at_cmgw); - err = gsmopen_serial_write_AT_ack(tech_pvt, smscommand); - if (err) { - ERRORA("Error deleting SMS from the cellphone memory\n", GSMOPEN_P_LOG); - } - - tech_pvt->at_cmgw[0] = '\0'; - } - //gsmopen_sleep(500000); //.5 secs - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(&tech_pvt->controldev_lock); - } - - err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0"); - if (err) { - DEBUGA_GSMOPEN("AT+CMGF=0 (set message sending to PDU (as opposed to TEXT) do not got OK from the phone, continuing\n", GSMOPEN_P_LOG); - } - - - DEBUGA_GSMOPEN("FINISH\n", GSMOPEN_P_LOG); - if (failed) - return -1; - else - return RESULT_SUCCESS; -} - -/************************************************/ - -/* LUIGI RIZZO's magic */ -/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must - * be representable in 16 bits to avoid overflows. - */ -#define BOOST_SCALE (1<<9) -#define BOOST_MAX 40 /* slightly less than 7 bits */ - -/* - * store the boost factor - */ -void gsmopen_store_boost(char *s, double *boost) -{ - private_t *tech_pvt = NULL; - - if (sscanf(s, "%lf", boost) != 1) { - ERRORA("invalid boost <%s>\n", GSMOPEN_P_LOG, s); - return; - } - if (*boost < -BOOST_MAX) { - WARNINGA("boost %s too small, using %d\n", GSMOPEN_P_LOG, s, -BOOST_MAX); - *boost = -BOOST_MAX; - } else if (*boost > BOOST_MAX) { - WARNINGA("boost %s too large, using %d\n", GSMOPEN_P_LOG, s, BOOST_MAX); - *boost = BOOST_MAX; - } -#ifdef WIN32 - *boost = exp(log ((double)10) * *boost / 20) * BOOST_SCALE; -#else - *boost = exp(log(10) * *boost / 20) * BOOST_SCALE; -#endif //WIN32 - if (option_debug > 1) - DEBUGA_GSMOPEN("setting boost %s to %f\n", GSMOPEN_P_LOG, s, *boost); -} - - -int gsmopen_sound_boost(void *data, int samples_num, double boost) -{ -/* LUIGI RIZZO's magic */ - if (boost != 0 && (boost < 511 || boost > 513)) { /* scale and clip values */ - int i, x; - - int16_t *ptr = (int16_t *) data; - - for (i = 0; i < samples_num; i++) { - x = (int) (ptr[i] * boost) / BOOST_SCALE; - if (x > 32767) { - x = 32767; - } else if (x < -32768) { - x = -32768; - } - ptr[i] = x; - } - } else { - //printf("BOOST=%f\n", boost); - } - - return 0; -} - - -int gsmopen_serial_getstatus_AT(private_t * tech_pvt) -{ - int res; - private_t *p = tech_pvt; - -#if 0 - if (p->owner) { - if (p->owner->_state != AST_STATE_UP && p->owner->_state != AST_STATE_DOWN) { - DEBUGA_AT("No getstatus, we're neither UP nor DOWN\n", GSMOPEN_P_LOG); - return 0; - } - } -#endif - - - PUSHA_UNLOCKA(p->controldev_lock); - LOKKA(p->controldev_lock); - res = gsmopen_serial_write_AT_ack(p, "AT"); - if (res) { - ERRORA("AT was not acknowledged, continuing but maybe there is a problem\n", GSMOPEN_P_LOG); - } - gsmopen_sleep(1000); - - if (strlen(p->at_query_battchg)) { - res = gsmopen_serial_write_AT_expect(p, p->at_query_battchg, p->at_query_battchg_expect); - if (res) { - WARNINGA("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, p->at_query_battchg, p->at_query_battchg_expect); - } - gsmopen_sleep(1000); - } - - if (strlen(p->at_query_signal)) { - res = gsmopen_serial_write_AT_expect(p, p->at_query_signal, p->at_query_signal_expect); - if (res) { - WARNINGA("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, p->at_query_signal, p->at_query_signal_expect); - } - gsmopen_sleep(1000); - } - - if (!p->network_creg_not_supported) { - res = gsmopen_serial_write_AT_ack(p, "AT+CREG?"); - if (res) { - WARNINGA("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, "AT+CREG?", "OK"); - } - gsmopen_sleep(1000); - } - - //FIXME all the following commands in config! - - if (p->sms_cnmi_not_supported) { - res = gsmopen_serial_write_AT_ack(p, "AT+MMGL=\"HEADER ONLY\""); - if (res) { - WARNINGA - ("%s does not get %s from the phone. If your phone is not Motorola, please contact the gsmopen developers. Else, if your phone IS a Motorola, probably a long msg was incoming and ther first part was read and then deleted. The second part is now orphan. If you got this warning repeatedly, and you cannot correctly receive SMSs from this interface, please manually clean all messages (and the residual parts of them) from the cellphone/SIM. Continuing.\n", - GSMOPEN_P_LOG, "AT+MMGL=\"HEADER ONLY\"", "OK"); - } else { - gsmopen_sleep(1000); - if (p->unread_sms_msg_id) { - char at_command[256]; - - res = gsmopen_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\""); - if (res) { - ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone\n", GSMOPEN_P_LOG); - memset(p->sms_message, 0, sizeof(p->sms_message)); - } - - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGR=%d", p->unread_sms_msg_id); - memset(p->sms_message, 0, sizeof(p->sms_message)); - - p->reading_sms_msg = 1; - res = gsmopen_serial_write_AT_ack(p, at_command); - p->reading_sms_msg = 0; - if (res) { - ERRORA("AT+CMGR (read SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - res = gsmopen_serial_write_AT_ack(p, "AT+CSCS=\"GSM\""); - if (res) { - ERRORA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGD=%d", p->unread_sms_msg_id); /* delete the message */ - p->unread_sms_msg_id = 0; - res = gsmopen_serial_write_AT_ack(p, at_command); - if (res) { - ERRORA("AT+CMGD (Delete SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - - if (strlen(p->sms_message)) { -#if 0 - - manager_event(EVENT_FLAG_SYSTEM, "GSMOPENincomingsms", "Interface: %s\r\nSMS_Message: %s\r\n", p->name, p->sms_message); - - if (strlen(p->sms_receiving_program)) { - int fd1[2]; - pid_t pid1; - char *arg1[] = { p->sms_receiving_program, (char *) NULL }; - int i; - - DEBUGA_AT("incoming SMS message:---%s---\n", GSMOPEN_P_LOG, p->sms_message); - pipe(fd1); - pid1 = fork(); - - if (pid1 == 0) { //child - int err; - - dup2(fd1[0], 0); // Connect stdin to pipe output - close(fd1[1]); // close input pipe side - setsid(); //session id - err = execvp(arg1[0], arg1); //exec our program, with stdin connected to pipe output - if (err) { - ERRORA - ("'sms_receiving_program' is set in config file to '%s', and it gave us back this error: %d, (%s). SMS received was:---%s---\n", - GSMOPEN_P_LOG, p->sms_receiving_program, err, strerror(errno), p->sms_message); - } - close(fd1[0]); // close output pipe side - } //starting here continue the parent - close(fd1[0]); // close output pipe side - // write the msg on the pipe input - for (i = 0; i < strlen(p->sms_message); i++) { - write(fd1[1], &p->sms_message[i], 1); - } - close(fd1[1]); // close pipe input, let our program know we've finished - } else { - ERRORA - ("got SMS incoming message, but 'sms_receiving_program' is not set in config file. SMS received was:---%s---\n", - GSMOPEN_P_LOG, p->sms_message); - } -#endif //0 - DEBUGA_GSMOPEN("got SMS incoming message. SMS received was:---%s---\n", GSMOPEN_P_LOG, p->sms_message); - } -#if 0 //is this one needed? maybe it can interrupt an incoming call that is just to announce itself - if (p->phone_callflow == CALLFLOW_CALL_IDLE && p->interface_state == AST_STATE_DOWN && p->owner == NULL) { - /* we're not in a call, neither calling */ - res = gsmopen_serial_write_AT_ack(p, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA("AT+CKPD=\"EEE\" (cellphone screen back to user) do not got OK from the phone\n", GSMOPEN_P_LOG); - } - } -#endif - } - } - } - - UNLOCKA(p->controldev_lock); - POPPA_UNLOCKA(p->controldev_lock); - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c deleted file mode 100644 index 16c83fa29c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c +++ /dev/null @@ -1,3474 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli (gmaruzz@gmail.com) - * - * - * Further Contributors: - * - * - * - * mod_gsmopen.c -- GSM compatible Endpoint Module - * - */ - -#include "gsmopen.h" - -#if 0 -#ifdef WIN32 -/***************/ -// from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/ - -#include - -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else /* */ -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif /* */ -struct sk_timezone { - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; -int gettimeofday(struct timeval *tv, struct sk_timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - if (NULL != tv) { - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch */ - tmpres /= 10; /*convert into microseconds */ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long) (tmpres / 1000000UL); - tv->tv_usec = (long) (tmpres % 1000000UL); - } - if (NULL != tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - return 0; -} - -/***************/ -#endif /* WIN32 */ -#endif //0 -SWITCH_BEGIN_EXTERN_C -SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown); -SWITCH_MODULE_DEFINITION(mod_gsmopen, mod_gsmopen_load, mod_gsmopen_shutdown, NULL); -SWITCH_END_EXTERN_C -#define GSMOPEN_CHAT_PROTO "sms" -#if 1 -SWITCH_STANDARD_API(gsm_function); -/* BEGIN: Changes here */ -#define GSM_SYNTAX "list [full] || console || AT_command || remove < interface_name | interface_id > || reload" -/* END: Changes heres */ -SWITCH_STANDARD_API(gsmopen_function); -#define GSMOPEN_SYNTAX "interface_name AT_command" -#endif //0 - -SWITCH_STANDARD_API(gsmopen_boost_audio_function); -#define GSMOPEN_BOOST_AUDIO_SYNTAX "interface_name [ ]" -SWITCH_STANDARD_API(sendsms_function); -#define SENDSMS_SYNTAX "gsmopen_sendsms interface_name destination_number SMS_text" -SWITCH_STANDARD_API(gsmopen_dump_function); -#define GSMOPEN_DUMP_SYNTAX "gsmopen_dump " -/* BEGIN: Changes here */ -#define FULL_RELOAD 0 -#define SOFT_RELOAD 1 -/* END: Changes heres */ - -const char *interface_status[] = { /* should match GSMOPEN_STATE_xxx in gsmopen.h */ - "IDLE", - "DOWN", - "RING", - "DIALING", - "BUSY", - "UP", - "RINGING", - "PRERING", - "DOUBLE", - "SELECTD", - "HANG_RQ", - "PREANSW" -}; -const char *phone_callflow[] = { /* should match CALLFLOW_XXX in gsmopen.h */ - "CALL_IDLE", - "CALL_DOWN", - "INCOMING_RNG", - "CALL_DIALING", - "CALL_LINEBUSY", - "CALL_ACTIVE", - "INCOMING_HNG", - "CALL_RLEASD", - "CALL_NOCARR", - "CALL_INFLUX", - "CALL_INCOMING", - "CALL_FAILED", - "CALL_NOSRVC", - "CALL_OUTRESTR", - "CALL_SECFAIL", - "CALL_NOANSWER", - "STATUS_FNSHED", - "STATUS_CANCLED", - "STATUS_FAILED", - "STATUS_REFUSED", - "STATUS_RINGING", - "STATUS_INPROGRS", - "STATUS_UNPLACD", - "STATUS_ROUTING", - "STATUS_EARLYMD", - "INCOMING_CLID", - "STATUS_RMTEHOLD" -}; - - -static struct { - int debug; - char *ip; - int port; - char *dialplan; - char *destination; - char *context; - char *codec_string; - char *codec_order[SWITCH_MAX_CODECS]; - int codec_order_last; - char *codec_rates_string; - char *codec_rates[SWITCH_MAX_CODECS]; - int codec_rates_last; - unsigned int flags; - int fd; - int calls; - int real_interfaces; - int next_interface; - char hold_music[256]; - private_t GSMOPEN_INTERFACES[GSMOPEN_MAX_INTERFACES]; - switch_mutex_t *mutex; - private_t *gsm_console; -} globals; - -switch_endpoint_interface_t *gsmopen_endpoint_interface; -switch_memory_pool_t *gsmopen_module_pool = NULL; -int running = 0; - -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_destination, globals.destination); -//SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string); -//SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string); - -/* BEGIN: Changes here */ -static switch_status_t interface_exists(char *the_interface); -#if 1 -static switch_status_t remove_interface(char *the_interface); -#endif //0 -/* END: Changes here */ - -static switch_status_t channel_on_init(switch_core_session_t *session); -static switch_status_t channel_on_hangup(switch_core_session_t *session); -static switch_status_t channel_on_destroy(switch_core_session_t *session); -static switch_status_t channel_on_routing(switch_core_session_t *session); -static switch_status_t channel_on_exchange_media(switch_core_session_t *session); -static switch_status_t channel_on_consume_media(switch_core_session_t *session); -static switch_status_t channel_on_soft_execute(switch_core_session_t *session); -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause); -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); -static switch_status_t gsmopen_tech_init(private_t * tech_pvt, switch_core_session_t *session); - -static switch_status_t gsmopen_codec(private_t * tech_pvt, int sample_rate, int codec_ms) -{ - switch_core_session_t *session = NULL; - - if (switch_core_codec_init - (&tech_pvt->read_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - ERRORA("Can't load codec?\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - if (switch_core_codec_init - (&tech_pvt->write_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - ERRORA("Can't load codec?\n", GSMOPEN_P_LOG); - switch_core_codec_destroy(&tech_pvt->read_codec); - return SWITCH_STATUS_FALSE; - } - - tech_pvt->read_frame.rate = sample_rate; - tech_pvt->read_frame.codec = &tech_pvt->read_codec; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - - if (session) { - switch_core_session_set_read_codec(session, &tech_pvt->read_codec); - switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - switch_core_session_rwunlock(session); - } else { - ERRORA("no session\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t gsmopen_tech_init(private_t * tech_pvt, switch_core_session_t *session) -{ - -#ifdef WANT_SPEEX - int ciapa; - long level; - int tmp; -#endif// WANT_SPEEX - switch_assert(tech_pvt != NULL); - switch_assert(session != NULL); - tech_pvt->read_frame.data = tech_pvt->databuf; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); - switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_core_session_set_private(session, tech_pvt); - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str)); - if (!strlen(tech_pvt->session_uuid_str)) { - ERRORA("no tech_pvt->session_uuid_str\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - if (gsmopen_codec(tech_pvt, SAMPLERATE_GSMOPEN, 20) != SWITCH_STATUS_SUCCESS) { - ERRORA("gsmopen_codec FAILED\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - //teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, tech_pvt->read_codec.implementation->actual_samples_per_second); - //teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, 8000); - dtmf_rx_init(&tech_pvt->dtmf_state, NULL, NULL); - dtmf_rx_parms(&tech_pvt->dtmf_state, 0, 10, 10, -99); - -#ifdef GSMOPEN_ALSA - if(tech_pvt->no_sound==0){ - if (alsa_init(tech_pvt)) { - ERRORA("alsa_init failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - - } - } -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - if(tech_pvt->no_sound==0){ - if (gsmopen_portaudio_init(tech_pvt)) { - ERRORA("gsmopen_portaudio_init failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - - } - } -#endif// GSMOPEN_PORTAUDIO - - if (switch_core_timer_init(&tech_pvt->timer_read, "soft", 20, tech_pvt->read_codec.implementation->samples_per_packet, gsmopen_module_pool) != - SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_read); - - if (switch_core_timer_init(&tech_pvt->timer_write, "soft", 20, tech_pvt->write_codec.implementation->samples_per_packet, gsmopen_module_pool) != - SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_write); - -#ifdef WANT_SPEEX - /* Echo canceller with 100 ms tail length */ -#ifndef GIOVA48 - tech_pvt->echo_state = speex_echo_state_init(160, 1024); - ciapa = 8000; -#else// GIOVA48 - tech_pvt->echo_state = speex_echo_state_init(960, 4800); - ciapa = 48000; -#endif // GIOVA48 - speex_echo_ctl(tech_pvt->echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &ciapa); - -#if 1 //NO MORE - /* Setup preprocessor and associate with echo canceller for residual echo suppression */ -#ifndef GIOVA48 - tech_pvt->preprocess = speex_preprocess_state_init(160, 8000); -#else// GIOVA48 - tech_pvt->preprocess = speex_preprocess_state_init(960, 48000); -#endif // GIOVA48 - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, - tech_pvt->echo_state); - -#if 0 - /* Setup preprocessor various other goodies */ - tmp = 0; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_AGC, &tmp); - //level=8000.1; - //speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_AGC_LEVEL, &level); - - // Let's turn off all of the 'denoisers' (eg denoise and dereverb, and vad too) because they start automatic gain on mic input on cm108 usb, also if it (the agc on usb) disbled through mixer - tmp = 0; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_DENOISE, &tmp); - tmp = 0; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_DEREVERB, &tmp); - tmp = 0; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_VAD, &tmp); -#endif - - tmp = 0; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_DENOISE, &tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC, &tmp); - fprintf(stderr, "AGC is: %d\n", tmp); - level = 1.0; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_LEVEL, &level); - fprintf(stderr, "AGC_LEVEL is: %f\n", level); - //tmp=1; - //speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_TARGET, &tmp); - //fprintf( stderr, "AGC_TARGET is: %d\n", tmp ); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_DENOISE, &tmp); - fprintf(stderr, "DENOISE is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_DEREVERB, &tmp); - fprintf(stderr, "DEREVERB is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_VAD, &tmp); - fprintf(stderr, "VAD is: %d\n", tmp); - -#if 0 - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_NOISE_SUPPRESS, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_NOISE_SUPPRESS is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_ECHO_SUPPRESS is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE, - &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_MAX_GAIN, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_AGC_MAX_GAIN is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_INCREMENT, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_AGC_INCREMENT is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_DECREMENT, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_AGC_DECREMENT is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_PROB_START, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_PROB_START is: %d\n", tmp); - tmp = 1; - speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_PROB_CONTINUE, &tmp); - fprintf(stderr, "SPEEX_PREPROCESS_GET_PROB_CONTINUE is: %d\n", tmp); -#endif //0 -#endif// 0 //NO MORE - -#endif // WANT_SPEEX - - - - switch_clear_flag(tech_pvt, TFLAG_HANGUP); - DEBUGA_GSMOPEN("gsmopen_codec SUCCESS\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; -} - -/* BEGIN: Changes here */ -static switch_status_t interface_exists(char *the_interface) -{ - int i; - int interface_id; - - if (*the_interface == '#') { /* look by interface id or interface name */ - the_interface++; - switch_assert(the_interface); - interface_id = atoi(the_interface); - - /* take a number as interface id */ - if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) { - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - return SWITCH_STATUS_SUCCESS; - } - } else { - /* interface name */ - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].name, the_interface) == 0) { - return SWITCH_STATUS_SUCCESS; - break; - } - } - } - } else { /* look by gsmopen_user */ - - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].gsmopen_user)) { - if (strcmp(globals.GSMOPEN_INTERFACES[i].gsmopen_user, the_interface) == 0) { - return SWITCH_STATUS_SUCCESS; - } - } - } - } - return SWITCH_STATUS_FALSE; -} - -#if 1 -static switch_status_t remove_interface(char *the_interface) -{ - int x = 10; - unsigned int howmany = 8; - int interface_id = -1; - private_t *tech_pvt = NULL; - switch_status_t status; - - //running = 0; - - - //XXX if (*the_interface == '#') { /* remove by interface id or interface name */ - //XXX the_interface++; - switch_assert(the_interface); - interface_id = atoi(the_interface); - - if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) { - /* take a number as interface id */ - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - } else { - - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].name, the_interface) == 0) { - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - break; - } - } - } - //XXX } //else { /* remove by gsmopen_user */ - //for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - //if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].gsmopen_user, the_interface) == 0) { - //tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - //break; - //} - //} - //} - - if (!tech_pvt) { - DEBUGA_GSMOPEN("interface '%s' does not exist\n", GSMOPEN_P_LOG, the_interface); - goto end; - } - - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].session_uuid_str)) { - DEBUGA_GSMOPEN("interface '%s' is busy\n", GSMOPEN_P_LOG, the_interface); - goto end; - } - - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { -#if 1 -#ifdef WIN32 - switch_file_write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die -#else /* WIN32 */ - howmany = write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", howmany); -#endif /* WIN32 */ -#endif //0 - DEBUGA_GSMOPEN("HERE will shutdown gsmopen_signaling_thread of '%s'\n", GSMOPEN_P_LOG, the_interface); - } - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) { -#if 0 -#ifdef WIN32 - if (SendMessage(tech_pvt->GSMopenHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) { // let's the gsmopen_api_thread_func die - DEBUGA_GSMOPEN("got FALSE here, thread probably was already dead. GetLastError returned: %d\n", GSMOPEN_P_LOG, GetLastError()); - globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread = NULL; - } -#else - XEvent e; - Atom atom1 = XInternAtom(tech_pvt->GSMopenHandles.disp, "GSMOPENCONTROLAPI_MESSAGE_BEGIN", False); - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.message_type = atom1; /* leading message */ - e.xclient.display = tech_pvt->GSMopenHandles.disp; - e.xclient.window = tech_pvt->GSMopenHandles.gsmopen_win; - e.xclient.format = 8; - - XSendEvent(tech_pvt->GSMopenHandles.disp, tech_pvt->GSMopenHandles.win, False, 0, &e); - XSync(tech_pvt->GSMopenHandles.disp, False); -#endif //WIN32 -#endif //0 - - DEBUGA_GSMOPEN("HERE will shutdown gsmopen_api_thread of '%s'\n", GSMOPEN_P_LOG, the_interface); - } - - while (x) { - x--; - switch_yield(50000); - } - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread); - } - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread); - } - - switch_mutex_lock(globals.mutex); - if (globals.gsm_console == &globals.GSMOPEN_INTERFACES[interface_id]) { - DEBUGA_GSMOPEN("interface '%s' no more console\n", GSMOPEN_P_LOG, the_interface); - globals.gsm_console = NULL; - } else { - DEBUGA_GSMOPEN("interface '%s' STILL console\n", GSMOPEN_P_LOG, the_interface); - } - memset(&globals.GSMOPEN_INTERFACES[interface_id], '\0', sizeof(private_t)); - globals.real_interfaces--; - switch_mutex_unlock(globals.mutex); - - DEBUGA_GSMOPEN("interface '%s' deleted successfully\n", GSMOPEN_P_LOG, the_interface); - globals.GSMOPEN_INTERFACES[interface_id].running = 1; - end: - //running = 1; - return SWITCH_STATUS_SUCCESS; -} -#endif //0 - -/* END: Changes here */ - -/* - State methods they get called when the state changes to the specific state - returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next - so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. -*/ -static switch_status_t channel_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - //ERRORA("%s CHANNEL INIT\n", GSMOPEN_P_LOG, tech_pvt->name); - switch_set_flag(tech_pvt, TFLAG_IO); - - switch_mutex_lock(globals.mutex); - globals.calls++; - - switch_mutex_unlock(globals.mutex); - DEBUGA_GSMOPEN("%s CHANNEL INIT %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_destroy(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - - - if (tech_pvt) { - DEBUGA_GSMOPEN("%s CHANNEL DESTROY %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - switch_core_timer_destroy(&tech_pvt->timer_read); - switch_core_timer_destroy(&tech_pvt->timer_write); - -#ifdef GSMOPEN_ALSA - if(tech_pvt->no_sound==0){ - alsa_shutdown(tech_pvt); - } -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - if(tech_pvt->no_sound==0){ - if (gsmopen_portaudio_shutdown(tech_pvt)) { - ERRORA("gsmopen_portaudio_shutdown failed\n", GSMOPEN_P_LOG); - - } - } -#endif// GSMOPEN_PORTAUDIO - - - *tech_pvt->session_uuid_str = '\0'; - tech_pvt->interface_state = GSMOPEN_STATE_IDLE; - if (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED) { - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - } - switch_core_session_set_private(session, NULL); - } else { - DEBUGA_GSMOPEN("!!!!!!NO tech_pvt!!!! CHANNEL DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(session)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - tech_pvt->phone_callflow = CALLFLOW_CALL_HANGUP_REQUESTED; - - if (!switch_channel_test_flag(channel, CF_ANSWERED)) { - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - tech_pvt->ob_failed_calls++; - } else { - tech_pvt->ib_failed_calls++; - } - } - - - DEBUGA_GSMOPEN("%s CHANNEL HANGUP\n", GSMOPEN_P_LOG, tech_pvt->name); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_HANGUP); - - gsmopen_hangup(tech_pvt); - - //memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str)); - //*tech_pvt->session_uuid_str = '\0'; - DEBUGA_GSMOPEN("%s CHANNEL HANGUP\n", GSMOPEN_P_LOG, tech_pvt->name); - switch_mutex_lock(globals.mutex); - globals.calls--; - if (globals.calls < 0) { - globals.calls = 0; - } - - tech_pvt->interface_state = GSMOPEN_STATE_IDLE; - //FIXME if (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED) { - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - //FIXME } - switch_mutex_unlock(globals.mutex); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_routing(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL ROUTING\n", GSMOPEN_P_LOG, tech_pvt->name); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_execute(switch_core_session_t *session) -{ - - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL EXECUTE\n", GSMOPEN_P_LOG, tech_pvt->name); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL KILL_CHANNEL\n", GSMOPEN_P_LOG, tech_pvt->name); - switch (sig) { - case SWITCH_SIG_KILL: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_SIG_KILL\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - //switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_HANGUP); - //switch_mutex_unlock(tech_pvt->flag_mutex); - break; - case SWITCH_SIG_BREAK: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_SIG_BREAK\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - //switch_set_flag(tech_pvt, TFLAG_BREAK); - //switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_BREAK); - //switch_mutex_unlock(tech_pvt->flag_mutex); - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} -static switch_status_t channel_on_consume_media(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - - DEBUGA_GSMOPEN("%s CHANNEL CONSUME_MEDIA\n", GSMOPEN_P_LOG, tech_pvt->name); - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t channel_on_exchange_media(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - tech_pvt = (private_t *) switch_core_session_get_private(session); - DEBUGA_GSMOPEN("%s CHANNEL EXCHANGE_MEDIA\n", GSMOPEN_P_LOG, tech_pvt->name); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_soft_execute(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - tech_pvt = (private_t *) switch_core_session_get_private(session); - DEBUGA_GSMOPEN("%s CHANNEL SOFT_EXECUTE\n", GSMOPEN_P_LOG, tech_pvt->name); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - private_t *tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL SEND_DTMF\n", GSMOPEN_P_LOG, tech_pvt->name); - DEBUGA_GSMOPEN("DTMF: %c\n", GSMOPEN_P_LOG, dtmf->digit); - - gsmopen_senddigit(tech_pvt, dtmf->digit); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - switch_byte_t *data; -#if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - int samples; - char digit_str[256]; -#endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) -#ifdef GSMOPEN_PORTAUDIO -#ifdef WANT_SPEEX - spx_int16_t *speexptr; - spx_int16_t pcm2[160]; - int i; -#endif// GSMOPEN_ALSA -#endif// WANT_SPEEX - - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) { - ERRORA("channel not ready \n", GSMOPEN_P_LOG); - //TODO: kill the bastard - return SWITCH_STATUS_FALSE; - } - - - tech_pvt->read_frame.flags = SFF_NONE; - *frame = NULL; - - if (switch_test_flag(tech_pvt, TFLAG_HANGUP)) { - return SWITCH_STATUS_FALSE; - } - -#ifndef GSMOPEN_PORTAUDIO - switch_core_timer_next(&tech_pvt->timer_read); -#endif// GSMOPEN_PORTAUDIO - - if(tech_pvt->no_sound==1){ - goto cng; - } -#if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) -#ifdef GSMOPEN_ALSA - //if ((samples = snd_pcm_readi(tech_pvt->alsac, tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0) - if ((samples = alsa_read(tech_pvt, (short *) tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0) -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - if ((samples = gsmopen_portaudio_read(tech_pvt, (short *) tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0) -#endif// GSMOPEN_PORTAUDIO - { - -#ifdef GSMOPEN_PORTAUDIO -#ifdef WANT_SPEEX - - if (tech_pvt->speexecho) { - speexptr = ((spx_int16_t *) tech_pvt->read_frame.data); - /* Perform echo cancellation */ - speex_echo_capture(tech_pvt->echo_state, speexptr, pcm2); -#ifndef GIOVA48 - for (i = 0; i < 160; i++) -#else //GIOVA48 - for (i = 0; i < 960; i++) -#endif //GIOVA48 - speexptr[i] = pcm2[i]; - } - /* Apply noise/echo residual suppression */ - if (tech_pvt->speexpreprocess) { - speex_preprocess_run(tech_pvt->preprocess, speexptr); - } - - DEBUGA_GSMOPEN("read\n", GSMOPEN_P_LOG); -#endif //WANT_SPEEX -#endif // GSMOPEN_PORTAUDIO - - - - - - tech_pvt->read_frame.datalen = samples * 2; - tech_pvt->read_frame.samples = samples; - -#ifndef GSMOPEN_PORTAUDIO - tech_pvt->read_frame.timestamp = tech_pvt->timer_read.samplecount; -#endif// GSMOPEN_PORTAUDIO - - *frame = &tech_pvt->read_frame; - - //status = SWITCH_STATUS_SUCCESS; - switch_set_flag(tech_pvt, TFLAG_VOICE); - } - - //WARNINGA("samples=%d\n", GSMOPEN_P_LOG, samples); - if (samples != 160) { - ERRORA("samples=%d\n", GSMOPEN_P_LOG, samples); - goto cng; - } -//DEBUGA_GSMOPEN("samples=%d tech_pvt->read_frame.timestamp=%d\n", GSMOPEN_P_LOG, samples, tech_pvt->read_frame.timestamp); - -//usleep(17000); -//usleep(17000); - - - - - - memset(digit_str, 0, sizeof(digit_str)); - //teletone_dtmf_detect(&tech_pvt->dtmf_detect, (int16_t *) tech_pvt->read_frame.data, tech_pvt->read_frame.samples); - //teletone_dtmf_get(&tech_pvt->dtmf_detect, digit_str, sizeof(digit_str)); - dtmf_rx(&tech_pvt->dtmf_state, (int16_t *) tech_pvt->read_frame.data, tech_pvt->read_frame.samples); - dtmf_rx_get(&tech_pvt->dtmf_state, digit_str, sizeof(digit_str)); - - gsmopen_sound_boost(tech_pvt->read_frame.data, tech_pvt->read_frame.samples, tech_pvt->capture_boost); - - if (digit_str[0]) { - switch_time_t new_dtmf_timestamp = switch_time_now(); - if ((new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp) > 350000) { //FIXME: make it configurable - char *p = digit_str; - switch_channel_t *channel = switch_core_session_get_channel(session); - - while (p && *p) { - switch_dtmf_t dtmf = {0}; - dtmf.digit = *p; - dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION; - switch_channel_queue_dtmf(channel, &dtmf); - p++; - } - NOTICA("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", GSMOPEN_P_LOG, digit_str, (unsigned int) new_dtmf_timestamp, - (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp)); - tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp; - } - } - while (switch_test_flag(tech_pvt, TFLAG_IO)) { - if (switch_test_flag(tech_pvt, TFLAG_BREAK)) { - switch_clear_flag(tech_pvt, TFLAG_BREAK); - DEBUGA_GSMOPEN("CHANNEL READ FRAME goto CNG\n", GSMOPEN_P_LOG); - goto cng; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - DEBUGA_GSMOPEN("CHANNEL READ FRAME not IO\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (!tech_pvt->read_frame.datalen) { - DEBUGA_GSMOPEN("CHANNEL READ CONTINUE\n", GSMOPEN_P_LOG); - continue; - } - *frame = &tech_pvt->read_frame; -#ifdef BIGENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { - switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2); - } -#endif - //WARNINGA("HERE\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - WARNINGA("HERE\n", GSMOPEN_P_LOG); - DEBUGA_GSMOPEN("CHANNEL READ no TFLAG_VOICE\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - - } - - DEBUGA_GSMOPEN("CHANNEL READ FALSE\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; -#endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - cng: - data = (switch_byte_t *) tech_pvt->read_frame.data; - data[0] = 65; - data[1] = 0; - tech_pvt->read_frame.datalen = 2; - tech_pvt->read_frame.flags = SFF_CNG; - *frame = &tech_pvt->read_frame; -#ifdef GSMOPEN_PORTAUDIO - //speex_echo_state_reset(tech_pvt->stream->echo_state); -#endif // GSMOPEN_PORTAUDIO - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; -#if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - unsigned int sent; -#endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) -#ifdef GSMOPEN_PORTAUDIO -#ifdef WANT_SPEEX - spx_int16_t *speexptr; -#endif// GSMOPEN_ALSA -#endif// WANT_SPEEX - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) { - ERRORA("channel not ready \n", GSMOPEN_P_LOG); - //TODO: kill the bastard - return SWITCH_STATUS_FALSE; - } -#ifdef BIGENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { -#ifdef WIN32 - switch_swap_linear((int16_t *)frame->data, (int) frame->datalen / 2); -#else - switch_swap_linear(frame->data, (int) frame->datalen / 2); -#endif //WIN32 - } -#endif - - //switch_core_timer_next(&tech_pvt->timer_write); - //sent = frame->datalen; - - //ERRORA("PLAY \n", GSMOPEN_P_LOG); - //snd_pcm_writei(tech_pvt->alsap, (short *) frame->data, (int) (frame->datalen / 2)); - - gsmopen_sound_boost(frame->data, frame->samples, tech_pvt->playback_boost); -#ifdef GSMOPEN_ALSA - - switch_core_timer_next(&tech_pvt->timer_write); - sent = alsa_write(tech_pvt, (short *) frame->data, (int) (frame->datalen)); -//DEBUGA_GSMOPEN("sent=%d \n", GSMOPEN_P_LOG, sent); - - if (sent && sent != frame->datalen / 2 && sent != -1) { - DEBUGA_GSMOPEN("sent %d\n", GSMOPEN_P_LOG, sent); - } -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - sent = gsmopen_portaudio_write(tech_pvt, (short *) frame->data, (int) (frame->datalen)); -//DEBUGA_GSMOPEN("sent=%d \n", GSMOPEN_P_LOG, sent); - - if (sent && sent != frame->datalen / 2 && sent != -1) { - DEBUGA_GSMOPEN("sent %d\n", GSMOPEN_P_LOG, sent); - } - -#ifdef WANT_SPEEX - if (tech_pvt->speexecho) { - speexptr = (spx_int16_t *) frame->data; - /* Put frame into playback buffer */ - speex_echo_playback(tech_pvt->echo_state, speexptr); - DEBUGA_GSMOPEN("write\n", GSMOPEN_P_LOG); - } -#endif //WANT_SPEEX -#endif // GSMOPEN_PORTAUDIO - //NOTICA("sent=%d\n", GSMOPEN_P_LOG, sent); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_answer_channel(switch_core_session_t *session) -{ - private_t *tech_pvt; - switch_channel_t *channel = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - //ERRORA("%s CHANNEL INIT\n", GSMOPEN_P_LOG, tech_pvt->name); - switch_set_flag(tech_pvt, TFLAG_IO); - gsmopen_serial_answer(tech_pvt); - - /* Move channel's state machine to ROUTING. This means the call is trying - to get from the initial start where the call because, to the point - where a destination has been identified. If the channel is simply - left in the initial state, nothing will happen. */ - switch_channel_set_state(channel, CS_ROUTING); - switch_mutex_lock(globals.mutex); - globals.calls++; - - switch_mutex_unlock(globals.mutex); - DEBUGA_GSMOPEN("%s CHANNEL ANSWER %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - - - - - - - - - - - - - - - - DEBUGA_GSMOPEN("ANSWERED! \n", GSMOPEN_P_LOG); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; -#if defined(GSMOPEN_ALSA) - int samples; - short tmp_buffer[1280]; -#endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_ANSWER: - { - DEBUGA_GSMOPEN("MSG_ID=%d, TO BE ANSWERED!\n", GSMOPEN_P_LOG, msg->message_id); - channel_answer_channel(session); - } - break; - case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: - - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_AUDIO_SYNC\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - switch_core_timer_sync(&tech_pvt->timer_read); - switch_core_timer_sync(&tech_pvt->timer_write); - -#ifdef GSMOPEN_ALSA - while ((samples = alsa_read(tech_pvt, tmp_buffer, tech_pvt->read_codec.implementation->samples_per_packet * 4)) > 160) { - //WARNINGA("read %d samples\n", GSMOPEN_P_LOG, samples); - } -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - //while ((samples = gsmopen_portaudio_read(tech_pvt, tmp_buffer, tech_pvt->read_codec.implementation->samples_per_packet * 2)) > 160) { - //WARNINGA("read %d samples\n", GSMOPEN_P_LOG, samples); - //} -#ifdef WANT_SPEEX - speex_echo_state_reset(tech_pvt->echo_state); -#endif// WANT_SPEEX -#endif// GSMOPEN_PORTAUDIO - break; - - - default: - { - DEBUGA_GSMOPEN("MSG_ID=%d\n", GSMOPEN_P_LOG, msg->message_id); - } - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event) -{ - struct private_object *tech_pvt = (struct private_object *) switch_core_session_get_private(session); - char *body = switch_event_get_body(event); - switch_assert(tech_pvt != NULL); - - if (!body) { - body = (char *) ""; - } - - WARNINGA("event: |||%s|||\n", GSMOPEN_P_LOG, body); - - return SWITCH_STATUS_SUCCESS; -} - -switch_state_handler_table_t gsmopen_state_handlers = { - /*.on_init */ channel_on_init, - /*.on_routing */ channel_on_routing, - /*.on_execute */ channel_on_execute, - /*.on_hangup */ channel_on_hangup, - /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute, - /*.on_consume_media */ channel_on_consume_media, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ channel_on_destroy -}; - -switch_io_routines_t gsmopen_io_routines = { - /*.outgoing_channel */ channel_outgoing_channel, - /*.read_frame */ channel_read_frame, - /*.write_frame */ channel_write_frame, - /*.kill_channel */ channel_kill_channel, - /*.send_dtmf */ channel_send_dtmf, - /*.receive_message */ channel_receive_message, - /*.receive_event */ channel_receive_event -}; - -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause) -{ - private_t *tech_pvt = NULL; - if ((*new_session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { - switch_channel_t *channel = NULL; - switch_caller_profile_t *caller_profile; - char *rdest; - int found = 0; - char interface_name[256]; - - DEBUGA_GSMOPEN("1 SESSION_REQUEST %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_add_stream(*new_session, NULL); - - - if (!zstr(outbound_profile->destination_number)) { - int i; - char *slash; - - switch_copy_string(interface_name, outbound_profile->destination_number, 255); - slash = strrchr(interface_name, '/'); - *slash = '\0'; - - switch_mutex_lock(globals.mutex); - if (strncmp("ANY", interface_name, strlen(interface_name)) == 0 || strncmp("RR", interface_name, strlen(interface_name)) == 0) { - /* we've been asked for the "ANY" interface, let's find the first idle interface */ - //DEBUGA_GSMOPEN("Finding one available gsmopen interface\n", GSMOPEN_P_LOG); - //tech_pvt = find_available_gsmopen_interface(NULL); - //if (tech_pvt) - //found = 1; - //} else if (strncmp("RR", interface_name, strlen(interface_name)) == 0) { - /* Find the first idle interface using Round Robin */ - DEBUGA_GSMOPEN("Finding one available gsmopen interface RR\n", GSMOPEN_P_LOG); - tech_pvt = find_available_gsmopen_interface_rr(NULL); - if (tech_pvt) { - found = 1; - DEBUGA_GSMOPEN("FOUND one available gsmopen interface RR\n", GSMOPEN_P_LOG); - } - } - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, interface_name, strlen(interface_name)) == 0)) { - if (strlen(globals.GSMOPEN_INTERFACES[i].session_uuid_str)) { - DEBUGA_GSMOPEN - ("globals.GSMOPEN_INTERFACES[%d].name=|||%s||| session_uuid_str=|||%s||| is BUSY\n", - GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].session_uuid_str); - DEBUGA_GSMOPEN("1 SESSION_DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - DEBUGA_GSMOPEN("globals.GSMOPEN_INTERFACES[%d].name=|||%s|||?\n", GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name); - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - found = 1; - break; - } - - } - - } else { - ERRORA("Doh! no destination number?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (!found) { - DEBUGA_GSMOPEN("Doh! no available interface for |||%s|||?\n", GSMOPEN_P_LOG, interface_name); - DEBUGA_GSMOPEN("2 SESSION_DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - //return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - channel = switch_core_session_get_channel(*new_session); - if (!channel) { - ERRORA("Doh! no channel?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - if (gsmopen_tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Doh! no tech_init?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - - if (outbound_profile) { - char name[128]; - - snprintf(name, sizeof(name), "gsmopen/%s", outbound_profile->destination_number); - //snprintf(name, sizeof(name), "gsmopen/%s", tech_pvt->name); - switch_channel_set_name(channel, name); - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - } else { - ERRORA("Doh! no caller profile\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - tech_pvt->ob_calls++; - - rdest = strchr(caller_profile->destination_number, '/'); - *rdest++ = '\0'; - - //gsmopen_call(tech_pvt, rdest, 30); - - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt->session_uuid_str)); - caller_profile = tech_pvt->caller_profile; - caller_profile->destination_number = rdest; - - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); - switch_channel_set_state(channel, CS_INIT); - gsmopen_call(tech_pvt, rdest, 30); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_SUCCESS; - } - - ERRORA("Doh! no new_session\n", GSMOPEN_P_LOG); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; -} - -/*! - * \brief This thread runs during a call, and monitor the interface for signaling, like hangup, caller id, etc most of signaling is handled inside the gsmopen_signaling_read function - * - */ - -static switch_status_t load_config(int reload_type) -{ - const char *cf = "gsmopen.conf"; - switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface; - private_t *tech_pvt = NULL; - - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, gsmopen_module_pool); - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - ERRORA("open of %s failed\n", GSMOPEN_P_LOG, cf); - running = 0; - switch_xml_free(xml); - return SWITCH_STATUS_TERM; - } - - switch_mutex_lock(globals.mutex); - if ((global_settings = switch_xml_child(cfg, "global_settings"))) { - for (param = switch_xml_child(global_settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "debug")) { - DEBUGA_GSMOPEN("globals.debug=%d\n", GSMOPEN_P_LOG, globals.debug); - globals.debug = atoi(val); - DEBUGA_GSMOPEN("globals.debug=%d\n", GSMOPEN_P_LOG, globals.debug); - } else if (!strcasecmp(var, "hold-music")) { - switch_set_string(globals.hold_music, val); - DEBUGA_GSMOPEN("globals.hold_music=%s\n", GSMOPEN_P_LOG, globals.hold_music); - } else if (!strcmp(var, "dialplan")) { - set_global_dialplan(val); - DEBUGA_GSMOPEN("globals.dialplan=%s\n", GSMOPEN_P_LOG, globals.dialplan); - } else if (!strcmp(var, "destination")) { - set_global_destination(val); - DEBUGA_GSMOPEN("globals.destination=%s\n", GSMOPEN_P_LOG, globals.destination); - } else if (!strcmp(var, "context")) { - set_global_context(val); - DEBUGA_GSMOPEN("globals.context=%s\n", GSMOPEN_P_LOG, globals.context); - - } - - } - } - - if ((interfaces = switch_xml_child(cfg, "per_interface_settings"))) { - int i = 0; - - for (myinterface = switch_xml_child(interfaces, "interface"); myinterface; myinterface = myinterface->next) { - char *id = (char *) switch_xml_attr(myinterface, "id"); - char *name = (char *) switch_xml_attr(myinterface, "name"); - const char *context = "default"; - const char *dialplan = "XML"; - const char *destination = "5000"; - const char *controldevice_name = "/dev/ttyACM0"; - //char *digit_timeout; - //char *max_digits; - //char *hotline; - char *dial_regex = NULL; - char *hold_music = NULL; - char *fail_dial_regex = NULL; - //const char *enable_callerid ; - - - const char *at_dial_pre_number = "ATD"; - const char *at_dial_post_number = ";"; - const char *at_dial_expect = "OK"; - const char *at_hangup = "ATH"; - const char *at_hangup_expect = "OK"; - const char *at_answer = "ATA"; - const char *at_answer_expect = "OK"; - const char *at_send_dtmf = "AT+VTS"; - const char *at_preinit_1 = ""; - const char *at_preinit_1_expect = ""; - const char *at_preinit_2 = ""; - const char *at_preinit_2_expect = ""; - const char *at_preinit_3 = ""; - const char *at_preinit_3_expect = ""; - const char *at_preinit_4 = ""; - const char *at_preinit_4_expect = ""; - const char *at_preinit_5 = ""; - const char *at_preinit_5_expect = ""; - const char *at_postinit_1 = "at+cmic=0,9"; - const char *at_postinit_1_expect = "OK"; - const char *at_postinit_2 = "AT+CKPD=\"EEE\""; - const char *at_postinit_2_expect = "OK"; - const char *at_postinit_3 = "AT+CSSN=1,0"; - const char *at_postinit_3_expect = "OK"; - const char *at_postinit_4 = "at+sidet=0"; - const char *at_postinit_4_expect = "OK"; - const char *at_postinit_5 = "at+clvl=99"; - const char *at_postinit_5_expect = "OK"; - const char *at_query_battchg = "AT+CBC"; - const char *at_query_battchg_expect = "OK"; - const char *at_query_signal = "AT+CSQ"; - const char *at_query_signal_expect = "OK"; - const char *at_call_idle = "+MCST: 1"; - const char *at_call_incoming = "+MCST: 2"; - const char *at_call_active = "+CSSI: 7"; - const char *at_call_failed = "+MCST: 65"; - const char *at_call_calling = "+CSSI: 1"; - const char *at_indicator_noservice_string = "CIEV: 2;0"; - const char *at_indicator_nosignal_string = "CIEV: 5;0"; - const char *at_indicator_lowsignal_string = "CIEV: 5;1"; - const char *at_indicator_lowbattchg_string = "CIEV: 0;1"; - const char *at_indicator_nobattchg_string = "CIEV: 0;0"; - const char *at_indicator_callactive_string = "CIEV: 3;1"; - const char *at_indicator_nocallactive_string = "CIEV: 3;0"; - const char *at_indicator_nocallsetup_string = "CIEV: 6;0"; - const char *at_indicator_callsetupincoming_string = "CIEV: 6;1"; - const char *at_indicator_callsetupoutgoing_string = "CIEV: 6;2"; - const char *at_indicator_callsetupremoteringing_string = "CIEV: 6;3"; - //const char *sms_receiving_program = "/usr/local/bin/ciapalo"; - const char *alsacname = "plughw:1"; - const char *alsapname = "plughw:1"; - const char *at_early_audio = "0"; - const char *at_after_preinit_pause = "500000"; - const char *at_initial_pause = "500000"; - const char *at_has_clcc = "0"; - const char *at_has_ecam = "0"; - const char *alsa_period_size = "160"; - const char *alsa_periods_in_buffer = "4"; - const char *gsmopen_sound_rate = "8000"; - const char *alsa_play_is_mono = "1"; - const char *alsa_capture_is_mono = "1"; - const char *capture_boost = "5"; - const char *playback_boost = "10"; -#if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - const char *no_sound = "0"; -#else - const char *no_sound = "1"; -#endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) -#ifdef GSMOPEN_PORTAUDIO - const char *portaudiocindex; - const char *portaudiopindex; - const char *speexecho; - const char *speexpreprocess; -#endif// GSMOPEN_PORTAUDIO - - uint32_t interface_id = 0; -#ifdef WIN32 - int controldevice_speed = 115200; //FIXME TODO -#else - uint32_t controldevice_speed = B115200; //FIXME TODO -#endif //WIN32 - uint32_t controldevprotocol = PROTOCOL_AT; //FIXME TODO - uint32_t running = 1; //FIXME TODO - const char *gsmopen_serial_sync_period = "300"; //FIXME TODO - - - - tech_pvt = NULL; - - for (param = switch_xml_child(myinterface, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "id")) { - id = val; - } else if (!strcasecmp(var, "name")) { - name = val; - } else if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "destination")) { - destination = val; - } else if (!strcasecmp(var, "controldevice_name")) { - controldevice_name = val; - //} else if (!strcasecmp(var, "digit_timeout")) { - //digit_timeout = val; - //} else if (!strcasecmp(var, "max_digits")) { - //max_digits = val; - //} else if (!strcasecmp(var, "hotline")) { - //hotline = val; - } else if (!strcasecmp(var, "dial_regex")) { - dial_regex = val; - } else if (!strcasecmp(var, SWITCH_HOLD_MUSIC_VARIABLE)) { - hold_music = val; - } else if (!strcasecmp(var, "fail_dial_regex")) { - fail_dial_regex = val; - //} else if (!strcasecmp(var, "enable_callerid")) { - //enable_callerid = val; - } else if (!strcasecmp(var, "at_dial_pre_number")) { - at_dial_pre_number = val; - } else if (!strcasecmp(var, "at_dial_post_number")) { - at_dial_post_number = val; - } else if (!strcasecmp(var, "at_dial_expect")) { - at_dial_expect = val; - } else if (!strcasecmp(var, "at_hangup")) { - at_hangup = val; - } else if (!strcasecmp(var, "at_hangup_expect")) { - at_hangup_expect = val; - } else if (!strcasecmp(var, "at_answer")) { - at_answer = val; - } else if (!strcasecmp(var, "at_answer_expect")) { - at_answer_expect = val; - } else if (!strcasecmp(var, "at_send_dtmf")) { - at_send_dtmf = val; - } else if (!strcasecmp(var, "at_preinit_1")) { - at_preinit_1 = val; - } else if (!strcasecmp(var, "at_preinit_1_expect")) { - at_preinit_1_expect = val; - } else if (!strcasecmp(var, "at_preinit_2")) { - at_preinit_2 = val; - } else if (!strcasecmp(var, "at_preinit_2_expect")) { - at_preinit_2_expect = val; - } else if (!strcasecmp(var, "at_preinit_3")) { - at_preinit_3 = val; - } else if (!strcasecmp(var, "at_preinit_3_expect")) { - at_preinit_3_expect = val; - } else if (!strcasecmp(var, "at_preinit_4")) { - at_preinit_4 = val; - } else if (!strcasecmp(var, "at_preinit_4_expect")) { - at_preinit_4_expect = val; - } else if (!strcasecmp(var, "at_preinit_5")) { - at_preinit_5 = val; - } else if (!strcasecmp(var, "at_preinit_5_expect")) { - at_preinit_5_expect = val; - } else if (!strcasecmp(var, "at_postinit_1")) { - at_postinit_1 = val; - } else if (!strcasecmp(var, "at_postinit_1_expect")) { - at_postinit_1_expect = val; - } else if (!strcasecmp(var, "at_postinit_2")) { - at_postinit_2 = val; - } else if (!strcasecmp(var, "at_postinit_2_expect")) { - at_postinit_2_expect = val; - } else if (!strcasecmp(var, "at_postinit_3")) { - at_postinit_3 = val; - } else if (!strcasecmp(var, "at_postinit_3_expect")) { - at_postinit_3_expect = val; - } else if (!strcasecmp(var, "at_postinit_4")) { - at_postinit_4 = val; - } else if (!strcasecmp(var, "at_postinit_4_expect")) { - at_postinit_4_expect = val; - } else if (!strcasecmp(var, "at_postinit_5")) { - at_postinit_5 = val; - } else if (!strcasecmp(var, "at_postinit_5_expect")) { - at_postinit_5_expect = val; - } else if (!strcasecmp(var, "at_query_battchg")) { - at_query_battchg = val; - } else if (!strcasecmp(var, "at_query_battchg_expect")) { - at_query_battchg_expect = val; - } else if (!strcasecmp(var, "at_query_signal")) { - at_query_signal = val; - } else if (!strcasecmp(var, "at_query_signal_expect")) { - at_query_signal_expect = val; - } else if (!strcasecmp(var, "at_call_idle")) { - at_call_idle = val; - } else if (!strcasecmp(var, "at_call_incoming")) { - at_call_incoming = val; - } else if (!strcasecmp(var, "at_call_active")) { - at_call_active = val; - } else if (!strcasecmp(var, "at_call_failed")) { - at_call_failed = val; - } else if (!strcasecmp(var, "at_call_calling")) { - at_call_calling = val; - } else if (!strcasecmp(var, "at_indicator_noservice_string")) { - at_indicator_noservice_string = val; - } else if (!strcasecmp(var, "at_indicator_nosignal_string")) { - at_indicator_nosignal_string = val; - } else if (!strcasecmp(var, "at_indicator_lowsignal_string")) { - at_indicator_lowsignal_string = val; - } else if (!strcasecmp(var, "at_indicator_lowbattchg_string")) { - at_indicator_lowbattchg_string = val; - } else if (!strcasecmp(var, "at_indicator_nobattchg_string")) { - at_indicator_nobattchg_string = val; - } else if (!strcasecmp(var, "at_indicator_callactive_string")) { - at_indicator_callactive_string = val; - } else if (!strcasecmp(var, "at_indicator_nocallactive_string")) { - at_indicator_nocallactive_string = val; - } else if (!strcasecmp(var, "at_indicator_nocallsetup_string")) { - at_indicator_nocallsetup_string = val; - } else if (!strcasecmp(var, "at_indicator_callsetupincoming_string")) { - at_indicator_callsetupincoming_string = val; - } else if (!strcasecmp(var, "at_indicator_callsetupoutgoing_string")) { - at_indicator_callsetupoutgoing_string = val; - } else if (!strcasecmp(var, "at_indicator_callsetupremoteringing_string")) { - at_indicator_callsetupremoteringing_string = val; - //} else if (!strcasecmp(var, "sms_receiving_program")) { - //sms_receiving_program = val; - } else if (!strcasecmp(var, "alsacname")) { - alsacname = val; - } else if (!strcasecmp(var, "alsapname")) { - alsapname = val; -#ifdef GSMOPEN_PORTAUDIO - } else if (!strcasecmp(var, "portaudiocindex")) { - portaudiocindex = val; - } else if (!strcasecmp(var, "portaudiopindex")) { - portaudiopindex = val; - } else if (!strcasecmp(var, "speexecho")) { - speexecho = val; - } else if (!strcasecmp(var, "speexpreprocess")) { - speexpreprocess = val; -#endif// GSMOPEN_PORTAUDIO - } else if (!strcasecmp(var, "at_early_audio")) { - at_early_audio = val; - } else if (!strcasecmp(var, "at_after_preinit_pause")) { - at_after_preinit_pause = val; - } else if (!strcasecmp(var, "at_initial_pause")) { - at_initial_pause = val; - } else if (!strcasecmp(var, "at_has_clcc")) { - at_has_clcc = val; - } else if (!strcasecmp(var, "at_has_ecam")) { - at_has_ecam = val; - } else if (!strcasecmp(var, "alsa_period_size")) { - alsa_period_size = val; - } else if (!strcasecmp(var, "alsa_periods_in_buffer")) { - alsa_periods_in_buffer = val; - } else if (!strcasecmp(var, "gsmopen_sound_rate")) { - gsmopen_sound_rate = val; - } else if (!strcasecmp(var, "alsa_play_is_mono")) { - alsa_play_is_mono = val; - } else if (!strcasecmp(var, "alsa_capture_is_mono")) { - alsa_capture_is_mono = val; - } else if (!strcasecmp(var, "capture_boost")) { - capture_boost = val; - } else if (!strcasecmp(var, "playback_boost")) { - playback_boost = val; - } else if (!strcasecmp(var, "no_sound")) { - no_sound = val; - } else if (!strcasecmp(var, "gsmopen_serial_sync_period")) { - gsmopen_serial_sync_period = val; - } - - - } - - /* BEGIN: Changes here */ - if (reload_type == SOFT_RELOAD) { - char the_interface[256]; - sprintf(the_interface, "#%s", name); - - if (interface_exists(the_interface) == SWITCH_STATUS_SUCCESS) { - continue; - } - } - /* END: Changes here */ - - if (!id) { - ERRORA("interface missing REQUIRED param 'id'\n", GSMOPEN_P_LOG); - continue; - } - - if (switch_is_number(id)) { - interface_id = atoi(id); - } else { - ERRORA("interface param 'id' MUST be a number, now id='%s'\n", GSMOPEN_P_LOG, id); - continue; - } - - if (!switch_is_number(at_early_audio)) { - ERRORA("interface param 'at_early_audio' MUST be a number, now at_early_audio='%s'\n", GSMOPEN_P_LOG, at_early_audio); - continue; - } - if (!switch_is_number(at_after_preinit_pause)) { - ERRORA("interface param 'at_after_preinit_pause' MUST be a number, now at_after_preinit_pause='%s'\n", GSMOPEN_P_LOG, - at_after_preinit_pause); - continue; - } - if (!switch_is_number(at_initial_pause)) { - ERRORA("interface param 'at_initial_pause' MUST be a number, now at_initial_pause='%s'\n", GSMOPEN_P_LOG, at_initial_pause); - continue; - } - if (!switch_is_number(at_has_clcc)) { - ERRORA("interface param 'at_has_clcc' MUST be a number, now at_has_clcc='%s'\n", GSMOPEN_P_LOG, at_has_clcc); - continue; - } - if (!switch_is_number(at_has_ecam)) { - ERRORA("interface param 'at_has_ecam' MUST be a number, now at_has_ecam='%s'\n", GSMOPEN_P_LOG, at_has_ecam); - continue; - } - if (!switch_is_number(alsa_period_size)) { - ERRORA("interface param 'alsa_period_size' MUST be a number, now alsa_period_size='%s'\n", GSMOPEN_P_LOG, alsa_period_size); - continue; - } - if (!switch_is_number(alsa_periods_in_buffer)) { - ERRORA("interface param 'alsa_periods_in_buffer' MUST be a number, now alsa_periods_in_buffer='%s'\n", GSMOPEN_P_LOG, - alsa_periods_in_buffer); - continue; - } - if (!switch_is_number(gsmopen_sound_rate)) { - ERRORA("interface param 'gsmopen_sound_rate' MUST be a number, now gsmopen_sound_rate='%s'\n", GSMOPEN_P_LOG, gsmopen_sound_rate); - continue; - } - if (!switch_is_number(alsa_play_is_mono)) { - ERRORA("interface param 'alsa_play_is_mono' MUST be a number, now alsa_play_is_mono='%s'\n", GSMOPEN_P_LOG, alsa_play_is_mono); - continue; - } - if (!switch_is_number(alsa_capture_is_mono)) { - ERRORA("interface param 'alsa_capture_is_mono' MUST be a number, now alsa_capture_is_mono='%s'\n", GSMOPEN_P_LOG, alsa_capture_is_mono); - continue; - } - if (!switch_is_number(capture_boost)) { - ERRORA("interface param 'capture_boost' MUST be a number, now capture_boost='%s'\n", GSMOPEN_P_LOG, capture_boost); - continue; - } - if (!switch_is_number(playback_boost)) { - ERRORA("interface param 'playback_boost' MUST be a number, now playback_boost='%s'\n", GSMOPEN_P_LOG, playback_boost); - continue; - } - if (!switch_is_number(no_sound)) { - ERRORA("interface param 'no_sound' MUST be a number, now no_sound='%s'\n", GSMOPEN_P_LOG, no_sound); - continue; - } - if (!switch_is_number(gsmopen_serial_sync_period)) { - ERRORA("interface param 'gsmopen_serial_sync_period' MUST be a number, now gsmopen_serial_sync_period='%s'\n", GSMOPEN_P_LOG, gsmopen_serial_sync_period); - continue; - } - - - if (interface_id && interface_id < GSMOPEN_MAX_INTERFACES) { - private_t newconf; - switch_threadattr_t *gsmopen_api_thread_attr = NULL; - int res = 0; - - memset(&newconf, '\0', sizeof(newconf)); - globals.GSMOPEN_INTERFACES[interface_id] = newconf; - - - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - - switch_mutex_init(&globals.GSMOPEN_INTERFACES[interface_id].controldev_lock, SWITCH_MUTEX_NESTED, gsmopen_module_pool); - - - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].id, id); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].name, name); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].context, context); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].dialplan, dialplan); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].destination, destination); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].controldevice_name, controldevice_name); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].dial_regex, dial_regex); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].hold_music, hold_music); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].fail_dial_regex, fail_dial_regex); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_pre_number, at_dial_pre_number); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_post_number, at_dial_post_number); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_expect, at_dial_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_hangup, at_hangup); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_hangup_expect, at_hangup_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_answer, at_answer); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_answer_expect, at_answer_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_send_dtmf, at_send_dtmf); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_1, at_preinit_1); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_1_expect, at_preinit_1_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_2, at_preinit_2); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_2_expect, at_preinit_2_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_3, at_preinit_3); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_3_expect, at_preinit_3_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_4, at_preinit_4); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_4_expect, at_preinit_4_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_5, at_preinit_5); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_5_expect, at_preinit_5_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_1, at_postinit_1); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_1_expect, at_postinit_1_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_2, at_postinit_2); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_2_expect, at_postinit_2_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_3, at_postinit_3); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_3_expect, at_postinit_3_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_4, at_postinit_4); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_4_expect, at_postinit_4_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_5, at_postinit_5); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_5_expect, at_postinit_5_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_battchg, at_query_battchg); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_battchg_expect, at_query_battchg_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_signal, at_query_signal); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_signal_expect, at_query_signal_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_idle, at_call_idle); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_incoming, at_call_incoming); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_active, at_call_active); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_failed, at_call_failed); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_calling, at_call_calling); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_noservice_string, at_indicator_noservice_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nosignal_string, at_indicator_nosignal_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_lowsignal_string, at_indicator_lowsignal_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_lowbattchg_string, at_indicator_lowbattchg_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nobattchg_string, at_indicator_nobattchg_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callactive_string, at_indicator_callactive_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nocallactive_string, at_indicator_nocallactive_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nocallsetup_string, at_indicator_nocallsetup_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupincoming_string, at_indicator_callsetupincoming_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupoutgoing_string, at_indicator_callsetupoutgoing_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupremoteringing_string, - at_indicator_callsetupremoteringing_string); - //switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].sms_receiving_program, sms_receiving_program); -#ifdef GSMOPEN_ALSA - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].alsacname, alsacname); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].alsapname, alsapname); -#endif// GSMOPEN_ALSA - -#ifdef GSMOPEN_PORTAUDIO - globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex = atoi(portaudiocindex); - globals.GSMOPEN_INTERFACES[interface_id].portaudiopindex = atoi(portaudiopindex); - globals.GSMOPEN_INTERFACES[interface_id].speexecho = atoi(speexecho); - globals.GSMOPEN_INTERFACES[interface_id].speexpreprocess = atoi(speexpreprocess); -#endif// GSMOPEN_PORTAUDIO - globals.GSMOPEN_INTERFACES[interface_id].at_early_audio = atoi(at_early_audio); - globals.GSMOPEN_INTERFACES[interface_id].at_after_preinit_pause = atoi(at_after_preinit_pause); - globals.GSMOPEN_INTERFACES[interface_id].at_initial_pause = atoi(at_initial_pause); - globals.GSMOPEN_INTERFACES[interface_id].at_has_clcc = atoi(at_has_clcc); - globals.GSMOPEN_INTERFACES[interface_id].at_has_ecam = atoi(at_has_ecam); -#ifdef GSMOPEN_ALSA - globals.GSMOPEN_INTERFACES[interface_id].alsa_period_size = atoi(alsa_period_size); - globals.GSMOPEN_INTERFACES[interface_id].alsa_periods_in_buffer = atoi(alsa_periods_in_buffer); - globals.GSMOPEN_INTERFACES[interface_id].gsmopen_sound_rate = atoi(gsmopen_sound_rate); - globals.GSMOPEN_INTERFACES[interface_id].alsa_play_is_mono = atoi(alsa_play_is_mono); - globals.GSMOPEN_INTERFACES[interface_id].alsa_capture_is_mono = atoi(alsa_capture_is_mono); -#endif// GSMOPEN_ALSA - globals.GSMOPEN_INTERFACES[interface_id].capture_boost = atoi(capture_boost); - globals.GSMOPEN_INTERFACES[interface_id].playback_boost = atoi(playback_boost); -#if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - globals.GSMOPEN_INTERFACES[interface_id].no_sound = atoi(no_sound); -#else - globals.GSMOPEN_INTERFACES[interface_id].no_sound = 1; -#endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - globals.GSMOPEN_INTERFACES[interface_id].gsmopen_serial_sync_period = atoi(gsmopen_serial_sync_period); - - - - globals.GSMOPEN_INTERFACES[interface_id].controldevice_speed = controldevice_speed; //FIXME - globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol = controldevprotocol; //FIXME - globals.GSMOPEN_INTERFACES[interface_id].running = running; //FIXME - - - - WARNINGA("STARTING interface_id=%d\n", GSMOPEN_P_LOG, interface_id); - DEBUGA_GSMOPEN("id=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].id); - DEBUGA_GSMOPEN("name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].name); - DEBUGA_GSMOPEN("hold-music=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].hold_music); - DEBUGA_GSMOPEN("context=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].context); - DEBUGA_GSMOPEN("dialplan=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].dialplan); - DEBUGA_GSMOPEN("destination=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].destination); - DEBUGA_GSMOPEN("controldevice_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].controldevice_name); -#ifdef GSMOPEN_ALSA - DEBUGA_GSMOPEN("alsacname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].alsacname); - DEBUGA_GSMOPEN("alsapname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].alsapname); -#endif// GSMOPEN_ALSA - - -#ifdef GSMOPEN_PORTAUDIO - //FIXME - //globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex = 1; - //globals.GSMOPEN_INTERFACES[interface_id].portaudiopindex = 1; - //globals.GSMOPEN_INTERFACES[interface_id].speexecho = 1; - //globals.GSMOPEN_INTERFACES[interface_id].speexpreprocess = 1; - DEBUGA_GSMOPEN("portaudiocindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex); - DEBUGA_GSMOPEN("portaudiocindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex); - DEBUGA_GSMOPEN("speexecho=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].speexecho); - DEBUGA_GSMOPEN("speexpreprocess=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].speexpreprocess); -#endif// GSMOPEN_PORTAUDIO - DEBUGA_GSMOPEN("gsmopen_serial_sync_period=%d\n", GSMOPEN_P_LOG, (int)globals.GSMOPEN_INTERFACES[interface_id].gsmopen_serial_sync_period); - /* init the serial port */ - if (globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol != PROTOCOL_NO_SERIAL) { - globals.GSMOPEN_INTERFACES[interface_id].controldevfd = - gsmopen_serial_init(&globals.GSMOPEN_INTERFACES[interface_id], globals.GSMOPEN_INTERFACES[interface_id].controldevice_speed); - if (globals.GSMOPEN_INTERFACES[interface_id].controldevfd == -1) { - ERRORA("gsmopen_serial_init failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id); - //return SWITCH_STATUS_FALSE; - globals.GSMOPEN_INTERFACES[interface_id].running=0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_serial_init failed"); - globals.GSMOPEN_INTERFACES[interface_id].active=0; - globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0'; - continue; - } - } - - /* config the phone/modem on the serial port */ - if (globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol != PROTOCOL_NO_SERIAL) { - res = gsmopen_serial_config(&globals.GSMOPEN_INTERFACES[interface_id]); - if (res) { - int count = 0; - ERRORA("gsmopen_serial_config failed, let's try again\n", GSMOPEN_P_LOG); - while(res && count < 5){ - switch_sleep(100000); //0.1 seconds - res = gsmopen_serial_config(&globals.GSMOPEN_INTERFACES[interface_id]); - count++; - if (res) { - ERRORA("%d: gsmopen_serial_config failed, let's try again\n", GSMOPEN_P_LOG, count); - } - } - if (res) { - ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id); - //return SWITCH_STATUS_FALSE; - globals.GSMOPEN_INTERFACES[interface_id].running=0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_serial_config failed"); - globals.GSMOPEN_INTERFACES[interface_id].active=0; - globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0'; - continue; - } - } - } - - if(globals.GSMOPEN_INTERFACES[interface_id].no_sound==0){ -#ifdef GSMOPEN_ALSA - if (alsa_init(&globals.GSMOPEN_INTERFACES[interface_id])) { - ERRORA("alsa_init failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id); - //return SWITCH_STATUS_FALSE; - globals.GSMOPEN_INTERFACES[interface_id].running=0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "alsa_init failed"); - globals.GSMOPEN_INTERFACES[interface_id].active=0; - globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0'; - continue; - - } - - if (alsa_shutdown(&globals.GSMOPEN_INTERFACES[interface_id])) { - ERRORA("alsa_shutdown failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id); - //return SWITCH_STATUS_FALSE; - globals.GSMOPEN_INTERFACES[interface_id].running=0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "alsa_shutdown failed"); - globals.GSMOPEN_INTERFACES[interface_id].active=0; - globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0'; - continue; - - } -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - if (gsmopen_portaudio_init(&globals.GSMOPEN_INTERFACES[interface_id])) { - ERRORA("gsmopen_portaudio_init failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id); - //return SWITCH_STATUS_FALSE; - globals.GSMOPEN_INTERFACES[interface_id].running=0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_portaudio_init failed"); - globals.GSMOPEN_INTERFACES[interface_id].active=0; - globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0'; - continue; - - } - - if (gsmopen_portaudio_shutdown(&globals.GSMOPEN_INTERFACES[interface_id])) { - ERRORA("gsmopen_portaudio_shutdown failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id); - //return SWITCH_STATUS_FALSE; - globals.GSMOPEN_INTERFACES[interface_id].running=0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_portaudio_shutdown failed"); - globals.GSMOPEN_INTERFACES[interface_id].active=0; - globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0'; - continue; - - } -#endif// GSMOPEN_PORTAUDIO - } - - globals.GSMOPEN_INTERFACES[interface_id].active=1; - - //gsmopen_store_boost((char *)"5", &globals.GSMOPEN_INTERFACES[interface_id].capture_boost); //FIXME - //gsmopen_store_boost((char *)"10", &globals.GSMOPEN_INTERFACES[interface_id].playback_boost); //FIXME - gsmopen_store_boost((char *) capture_boost, &globals.GSMOPEN_INTERFACES[interface_id].capture_boost); //FIXME - gsmopen_store_boost((char *) playback_boost, &globals.GSMOPEN_INTERFACES[interface_id].playback_boost); //FIXME - - switch_sleep(100000); - switch_threadattr_create(&gsmopen_api_thread_attr, gsmopen_module_pool); - switch_threadattr_stacksize_set(gsmopen_api_thread_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread, gsmopen_api_thread_attr, gsmopen_do_gsmopenapi_thread, - &globals.GSMOPEN_INTERFACES[interface_id], gsmopen_module_pool); - - switch_sleep(100000); - WARNINGA("STARTED interface_id=%d\n", GSMOPEN_P_LOG, interface_id); - - } else { - ERRORA("interface id %d is higher than GSMOPEN_MAX_INTERFACES (%d)\n", GSMOPEN_P_LOG, interface_id, GSMOPEN_MAX_INTERFACES); - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "interface id is higher than GSMOPEN_MAX_INTERFACES"); - continue; - } - - } - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - /* How many real intterfaces */ - globals.real_interfaces = i + 1; - - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - - DEBUGA_GSMOPEN("id=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].id); - DEBUGA_GSMOPEN("name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].name); - DEBUGA_GSMOPEN("context=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].context); - DEBUGA_GSMOPEN("hold-music=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].hold_music); - DEBUGA_GSMOPEN("dialplan=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].dialplan); - DEBUGA_GSMOPEN("destination=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].destination); - DEBUGA_GSMOPEN("controldevice_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].controldevice_name); -#ifdef GSMOPEN_ALSA - DEBUGA_GSMOPEN("alsacname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].alsacname); - DEBUGA_GSMOPEN("alsapname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].alsapname); -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - DEBUGA_GSMOPEN("portaudiocindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].portaudiocindex); - DEBUGA_GSMOPEN("portaudiopindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].portaudiopindex); - DEBUGA_GSMOPEN("speexecho=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].speexecho); - DEBUGA_GSMOPEN("speexpreprocess=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].speexpreprocess); -#endif// GSMOPEN_PORTAUDIO - DEBUGA_GSMOPEN("gsmopen_serial_sync_period=%d\n", GSMOPEN_P_LOG, (int)globals.GSMOPEN_INTERFACES[i].gsmopen_serial_sync_period); - - } - } - } - - switch_mutex_unlock(globals.mutex); - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -//static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint) -static switch_status_t chat_send(switch_event_t *message_event) -{ - char *user, *host, *f_user = NULL, *f_host = NULL, *f_resource = NULL; - private_t *tech_pvt = NULL; - int i = 0, found = 0; - - const char *proto; - const char *from; - const char *to; - const char *subject; - const char *body; - //const char *type; - const char *hint; - - proto = switch_event_get_header(message_event, "proto"); - from = switch_event_get_header(message_event, "from"); - to = switch_event_get_header(message_event, "to"); - subject = switch_event_get_header(message_event, "subject"); - body = switch_event_get_body(message_event); - //type = switch_event_get_header(message_event, "type"); - hint = switch_event_get_header(message_event, "hint"); - - switch_assert(proto != NULL); - - DEBUGA_GSMOPEN("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", GSMOPEN_P_LOG, proto, from, to, subject, body, - hint ? hint : "NULL"); - - if (!to || !strlen(to)) { - ERRORA("Missing To: header.\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if ((!from && !hint) || (!strlen(from) && !strlen(hint))) { - ERRORA("Missing From: AND Hint: headers.\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if (from && (f_user = strdup(from))) { - if ((f_host = strchr(f_user, '@'))) { - *f_host++ = '\0'; - if ((f_resource = strchr(f_host, '/'))) { - *f_resource++ = '\0'; - } - } - } - - if (!strlen(hint)) { //FIXME FIXME FIXME - hint = from; - } - if (to && (user = strdup(to))) { - if ((host = strchr(user, '@'))) { - *host++ = '\0'; - } - - DEBUGA_GSMOPEN("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", GSMOPEN_P_LOG, proto, from, to, subject, body, - hint ? hint : "NULL"); - if (hint && strlen(hint)) { - //in hint we receive the interface name to use - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, hint, strlen(hint)) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - DEBUGA_GSMOPEN("Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", GSMOPEN_P_LOG, i, - globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - } - } /* FIXME add a tech_pvt member for the SIM telephone number //else { - //we have no a predefined interface name to use (hint is NULL), so let's choose an interface from the username (from) - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].skype_user, from, strlen(from)) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - DEBUGA_GSMOPEN("Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - } - } - */ - if (!found) { - ERRORA("ERROR: A GSMopen interface with name='%s' or one with SIM_number='%s' was not found\n", GSMOPEN_P_LOG, hint ? hint : "NULL", - from ? from : "NULL"); - goto end; - } else { - gsmopen_sendsms(tech_pvt, (char *) to, (char *) body); - } - } - end: - switch_safe_free(user); - switch_safe_free(f_user); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t compat_chat_send(const char *proto, const char *from, const char *to, - const char *subject, const char *body, const char *type, const char *hint) -{ - switch_event_t *message_event; - switch_status_t status; - - if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint); - - if (body) { - switch_event_add_body(message_event, "%s", body); - } - } else { - abort(); - } - - status = chat_send(message_event); - switch_event_destroy(&message_event); - - return status; - -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load) -{ - switch_api_interface_t *commands_api_interface; - switch_chat_interface_t *chat_interface; - - gsmopen_module_pool = pool; - memset(&globals, '\0', sizeof(globals)); - - running = 1; - - if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) { - running = 0; - return SWITCH_STATUS_FALSE; - } - - if (switch_event_reserve_subclass(MY_EVENT_INCOMING_SMS) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - gsmopen_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - gsmopen_endpoint_interface->interface_name = "gsmopen"; - gsmopen_endpoint_interface->io_routines = &gsmopen_io_routines; - gsmopen_endpoint_interface->state_handler = &gsmopen_state_handlers; - - if (running) { - -#if 1 - SWITCH_ADD_API(commands_api_interface, "gsm", "gsm console AT_command", gsm_function, GSM_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen", "gsmopen interface AT_command", gsmopen_function, GSMOPEN_SYNTAX); -#endif //0 - SWITCH_ADD_API(commands_api_interface, "gsmopen_boost_audio", "gsmopen_boost_audio interface AT_command", gsmopen_boost_audio_function, GSMOPEN_BOOST_AUDIO_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen_dump", "gsmopen_dump interface", gsmopen_dump_function, GSMOPEN_DUMP_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen_sendsms", "gsmopen_sendsms interface destination_number SMS_text", sendsms_function, - SENDSMS_SYNTAX); - SWITCH_ADD_CHAT(chat_interface, GSMOPEN_CHAT_PROTO, chat_send); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; - } else - return SWITCH_STATUS_FALSE; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown) -{ - int x; - private_t *tech_pvt = NULL; - switch_status_t status; - unsigned int howmany = 8; - int interface_id; - int fd; - - running = 0; - - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - WARNINGA("SHUTDOWN interface_id=%d\n", GSMOPEN_P_LOG, interface_id); - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { -#ifdef WIN32 - switch_file_write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die -#else /* WIN32 */ - howmany = write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", howmany); -#endif /* WIN32 */ - } - x = 10; - while (x) { //FIXME 0.5 seconds? - x--; - switch_yield(50000); - } - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread); - } - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread); - } - - x = 10; - while (x) { //FIXME 0.5 seconds? - x--; - switch_yield(50000); - } - fd = tech_pvt->controldevfd; - //DEBUGA_GSMOPEN("SHUTDOWN tech_pvt->controldevfd=%d\n", GSMOPEN_P_LOG, tech_pvt->controldevfd); - if (fd) { - //close(fd); - //tech_pvt->controldevfd = -1; - DEBUGA_GSMOPEN("SHUTDOWN tech_pvt->controldevfd=%d\n", GSMOPEN_P_LOG, tech_pvt->controldevfd); - } -#ifndef WIN32 - shutdown(tech_pvt->audiogsmopenpipe[0], 2); - close(tech_pvt->audiogsmopenpipe[0]); - shutdown(tech_pvt->audiogsmopenpipe[1], 2); - close(tech_pvt->audiogsmopenpipe[1]); - shutdown(tech_pvt->audiopipe[0], 2); - close(tech_pvt->audiopipe[0]); - shutdown(tech_pvt->audiopipe[1], 2); - close(tech_pvt->audiopipe[1]); - shutdown(tech_pvt->GSMopenHandles.fdesc[0], 2); - close(tech_pvt->GSMopenHandles.fdesc[0]); - shutdown(tech_pvt->GSMopenHandles.fdesc[1], 2); - close(tech_pvt->GSMopenHandles.fdesc[1]); -#endif /* WIN32 */ - } - - } - - switch_event_free_subclass(MY_EVENT_INCOMING_SMS); - - switch_safe_free(globals.dialplan); - switch_safe_free(globals.context); - switch_safe_free(globals.destination); - switch_safe_free(globals.codec_string); - switch_safe_free(globals.codec_rates_string); - - return SWITCH_STATUS_SUCCESS; -} - - -void *SWITCH_THREAD_FUNC gsmopen_do_gsmopenapi_thread(switch_thread_t * thread, void *obj) -{ - return gsmopen_do_gsmopenapi_thread_func(obj); -} - -int dtmf_received(private_t * tech_pvt, char *value) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - channel = switch_core_session_get_channel(session); - - if (channel) { - - if (!switch_channel_test_flag(channel, CF_BRIDGED)) { - - switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; - DEBUGA_GSMOPEN("received DTMF %c on channel %s\n", GSMOPEN_P_LOG, dtmf.digit, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - //FIXME: why sometimes DTMFs from here do not seems to be get by FS? - switch_channel_queue_dtmf(channel, &dtmf); - switch_set_flag(tech_pvt, TFLAG_DTMF); - switch_mutex_unlock(tech_pvt->flag_mutex); - } else { - DEBUGA_GSMOPEN - ("received a DTMF on channel %s, but we're BRIDGED, so let's NOT relay it out of band\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - } - } else { - WARNINGA("received %c DTMF, but no channel?\n", GSMOPEN_P_LOG, value[0]); - } - switch_core_session_rwunlock(session); - - return 0; -} - -int new_inbound_channel(private_t * tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - switch_assert(tech_pvt != NULL); - tech_pvt->ib_calls++; - if ((session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)) != 0) { - DEBUGA_GSMOPEN("2 SESSION_REQUEST %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(session)); - switch_core_session_add_stream(session, NULL); - channel = switch_core_session_get_channel(session); - if (!channel) { - ERRORA("Doh! no channel?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - if (gsmopen_tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Doh! no tech_init?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - - if ((tech_pvt->caller_profile = - switch_caller_profile_new(switch_core_session_get_pool(session), "gsmopen", - tech_pvt->dialplan, tech_pvt->callid_name, - tech_pvt->callid_number, NULL, NULL, NULL, NULL, "mod_gsmopen", tech_pvt->context, tech_pvt->destination)) != 0) { - char name[128]; - //switch_snprintf(name, sizeof(name), "gsmopen/%s/%s", tech_pvt->name, tech_pvt->caller_profile->destination_number); - switch_snprintf(name, sizeof(name), "gsmopen/%s", tech_pvt->name); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - } - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Error spawning thread\n", GSMOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - } - if (channel) { - //switch_channel_mark_answered(channel); - } - - DEBUGA_GSMOPEN("new_inbound_channel\n", GSMOPEN_P_LOG); - - return 0; -} - -int remote_party_is_ringing(private_t * tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - goto done; - } - if (channel) { - switch_channel_mark_ring_ready(channel); - DEBUGA_GSMOPEN("gsmopen_call: REMOTE PARTY RINGING\n", GSMOPEN_P_LOG); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - done: - return 0; -} - -int remote_party_is_early_media(private_t * tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n\n\n", GSMOPEN_P_LOG); - //TODO: kill the bastard - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_add_stream(session, NULL); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - //TODO: kill the bastard - goto done; - } - if (channel) { - switch_channel_mark_pre_answered(channel); - DEBUGA_GSMOPEN("gsmopen_call: REMOTE PARTY EARLY MEDIA\n", GSMOPEN_P_LOG); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - //TODO: kill the bastard - } - - switch_core_session_rwunlock(session); - - done: - return 0; -} - -int outbound_channel_answered(private_t * tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - goto done; - } - if (channel) { - switch_channel_mark_answered(channel); - tech_pvt->phone_callflow = GSMOPEN_STATE_UP; - tech_pvt->interface_state = GSMOPEN_STATE_UP; - //DEBUGA_GSMOPEN("gsmopen_call: %s, answered\n", GSMOPEN_P_LOG, id); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - done: - DEBUGA_GSMOPEN("outbound_channel_answered!\n", GSMOPEN_P_LOG); - - return 0; -} - -private_t *find_available_gsmopen_interface_rr(private_t * tech_pvt_calling) -{ - private_t *tech_pvt = NULL; - int i; - //int num_interfaces = GSMOPEN_MAX_INTERFACES; - //int num_interfaces = globals.real_interfaces; - - switch_mutex_lock(globals.mutex); - - /* Fact is the real interface start from 1 */ - //XXX no, is just a convention, but you can have it start from 0. I do not, for aestetic reasons :-) - //if (globals.next_interface == 0) globals.next_interface = 1; - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - int interface_id; - - interface_id = globals.next_interface; - //interface_id = interface_id < GSMOPEN_MAX_INTERFACES ? interface_id : interface_id - GSMOPEN_MAX_INTERFACES + 1; - globals.next_interface = interface_id + 1 < GSMOPEN_MAX_INTERFACES ? interface_id + 1 : 0; - - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - int gsmopen_state = 0; - - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - gsmopen_state = tech_pvt->interface_state; - DEBUGA_GSMOPEN("gsmopen interface: %d, name: %s, state: %d\n", GSMOPEN_P_LOG, interface_id, globals.GSMOPEN_INTERFACES[interface_id].name, - gsmopen_state); - if ((tech_pvt_calling ? strcmp(tech_pvt->gsmopen_user, tech_pvt_calling->gsmopen_user) : 1) - && (GSMOPEN_STATE_DOWN == gsmopen_state || 0 == gsmopen_state) && (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED - || 0 == tech_pvt->phone_callflow)) { - DEBUGA_GSMOPEN("returning as available gsmopen interface name: %s, state: %d callflow: %d\n", GSMOPEN_P_LOG, tech_pvt->name, gsmopen_state, - tech_pvt->phone_callflow); - /*set to Dialing state to avoid other thread fint it, don't know if it is safe */ - //XXX no, it's not safe - if (tech_pvt_calling == NULL) { - tech_pvt->interface_state = GSMOPEN_STATE_SELECTED; - } - - switch_mutex_unlock(globals.mutex); - return tech_pvt; - } - } // else { - //DEBUGA_GSMOPEN("GSM interface: %d blank!! A hole here means we cannot hunt the last interface.\n", GSMOPEN_P_LOG, interface_id); - //} - } - - switch_mutex_unlock(globals.mutex); - return NULL; -} - -#if 1 -SWITCH_STANDARD_API(gsm_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (globals.gsm_console) - stream->write_function(stream, "gsm console is: |||%s|||\n", globals.gsm_console->name); - else - stream->write_function(stream, "gsm console is NOT yet assigned\n"); - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc || !argv[0]) { - stream->write_function(stream, "%s", GSM_SYNTAX); - goto end; - } - - if (!strcasecmp(argv[0], "list")) { - int i; - char next_flag_char = ' '; - - stream->write_function(stream, "F ID\t Name \tIB (F/T) OB (F/T)\tState\tCallFlw\t\tUUID\n"); - stream->write_function(stream, "= ====\t ======== \t======= =======\t======\t============\t======\n"); - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - next_flag_char = i == globals.next_interface ? '*' : ' '; - - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - stream->write_function(stream, - "%c %d\t[%s]\t%3ld/%ld\t%6ld/%ld\t%s\t%s\t%s\n", - next_flag_char, - i, globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].ib_failed_calls, - globals.GSMOPEN_INTERFACES[i].ib_calls, - globals.GSMOPEN_INTERFACES[i].ob_failed_calls, - globals.GSMOPEN_INTERFACES[i].ob_calls, - interface_status[globals.GSMOPEN_INTERFACES[i].interface_state], - phone_callflow[globals.GSMOPEN_INTERFACES[i].phone_callflow], globals.GSMOPEN_INTERFACES[i].session_uuid_str); - } else if (argc > 1 && !strcasecmp(argv[1], "full")) { - stream->write_function(stream, "%c\t%d\n", next_flag_char, i); - } - - } - stream->write_function(stream, "\nTotal: %d\n", globals.real_interfaces - 1); - - } else if (!strcasecmp(argv[0], "console")) { - int i; - int found = 0; - - if (argc == 2) { - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[1], strlen(argv[1])) == 0)) { - globals.gsm_console = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "gsm console is now: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, - globals.GSMOPEN_INTERFACES[i].name); - stream->write_function(stream, "gsm console is: |||%s|||\n", globals.gsm_console->name); - found = 1; - break; - } - - } - if (!found) - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[1]); - } else { - - stream->write_function(stream, "-ERR Usage: gsm console interface_name\n"); - goto end; - } - - } else if (!strcasecmp(argv[0], "ciapalino")) { - -/* BEGIN: Changes heres */ - } else if (!strcasecmp(argv[0], "reload")) { - if (load_config(SOFT_RELOAD) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "gsm reload failed\n"); - } else { - stream->write_function(stream, "gsm reload success\n"); - } - } else if (!strcasecmp(argv[0], "remove")) { - if (argc == 2) { - if (remove_interface(argv[1]) == SWITCH_STATUS_SUCCESS) { - if (interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "gsm remove '%s' failed\n", argv[1]); - } else { - stream->write_function(stream, "gsm remove '%s' success\n", argv[1]); - } - } - } else { - stream->write_function(stream, "-ERR Usage: gsm remove interface_name\n"); - goto end; - } -/* END: Changes heres */ - - } else { - if (globals.gsm_console) - gsmopen_serial_write_AT_noack(globals.gsm_console, (char *) cmd); - else - stream->write_function(stream, "gsm console is NOT yet assigned\n"); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(gsmopen_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX); - goto end; - } - - if (argc < 2) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX); - goto end; - } - - if (argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; - } else { - gsmopen_serial_write_AT_noack(tech_pvt, (char *) &cmd[strlen(argv[0]) + 1]); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} -#endif //0 -SWITCH_STANDARD_API(gsmopen_dump_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - char value[512]; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_DUMP_SYNTAX); - goto end; - } - if (argc == 1) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - //stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found && (strcmp("list", argv[0]) == 0)) { - int i; - stream->write_function(stream, "gsmopen_dump LIST\n\n"); - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - stream->write_function(stream, "dumping interface '%s'\n\n", globals.GSMOPEN_INTERFACES[i].name); - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - - - stream->write_function(stream, "interface_name = %s\n", tech_pvt->name); - stream->write_function(stream, "interface_id = %s\n", tech_pvt->id); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->active); - stream->write_function(stream, "active = %s\n", value); - if(!tech_pvt->network_creg_not_supported){ - snprintf(value, sizeof(value)-1, "%d", tech_pvt->not_registered); - stream->write_function(stream, "not_registered = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->home_network_registered); - stream->write_function(stream, "home_network_registered = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->roaming_registered); - stream->write_function(stream, "roaming_registered = %s\n", value); - }else{ - stream->write_function(stream, "not_registered = %s\n", "N/A"); - stream->write_function(stream, "home_network_registered = %s\n", "N/A"); - stream->write_function(stream, "roaming_registered = %s\n", "N/A"); - } - snprintf(value, sizeof(value)-1, "%d", tech_pvt->got_signal); - stream->write_function(stream, "got_signal = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->running); - stream->write_function(stream, "running = %s\n", value); - stream->write_function(stream, "imei = %s\n", tech_pvt->imei); - stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->controldev_dead); - stream->write_function(stream, "controldev_dead = %s\n", value); - stream->write_function(stream, "controldevice_name = %s\n", tech_pvt->controldevice_name); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->no_sound); - stream->write_function(stream, "no_sound = %s\n", value); -#ifdef GSMOPEN_ALSA - stream->write_function(stream, "alsacname = %s\n", tech_pvt->alsacname); - stream->write_function(stream, "alsapname = %s\n", tech_pvt->alsapname); -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiocindex); - stream->write_function(stream, "portaudiocindex = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiopindex); - stream->write_function(stream, "portaudiopindex = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexecho); - stream->write_function(stream, "speexecho = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexpreprocess); - stream->write_function(stream, "speexpreprocess = %s\n", value); -#endif// GSMOPEN_PORTAUDIO - snprintf(value, sizeof(value)-1, "%f", tech_pvt->playback_boost); - stream->write_function(stream, "playback_boost = %s\n", value); - snprintf(value, sizeof(value)-1, "%f", tech_pvt->capture_boost); - stream->write_function(stream, "capture_boost = %s\n", value); - stream->write_function(stream, "dialplan = %s\n", tech_pvt->dialplan); - stream->write_function(stream, "context = %s\n", tech_pvt->context); - stream->write_function(stream, "destination = %s\n", tech_pvt->destination); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_calls); - stream->write_function(stream, "ib_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_calls); - stream->write_function(stream, "ob_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_failed_calls); - stream->write_function(stream, "ib_failed_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_failed_calls); - stream->write_function(stream, "ob_failed_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->interface_state); - stream->write_function(stream, "interface_state = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->phone_callflow); - stream->write_function(stream, "phone_callflow = %s\n", value); - stream->write_function(stream, "session_uuid_str = %s\n", tech_pvt->session_uuid_str); - stream->write_function(stream, "\n"); - - dump_event(tech_pvt); - } - - } - - } else if(found){ - stream->write_function(stream, "dumping interface '%s'\n\n", argv[0]); - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - - - stream->write_function(stream, "interface_name = %s\n", tech_pvt->name); - stream->write_function(stream, "interface_id = %s\n", tech_pvt->id); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->active); - stream->write_function(stream, "active = %s\n", value); - if(!tech_pvt->network_creg_not_supported){ - snprintf(value, sizeof(value)-1, "%d", tech_pvt->not_registered); - stream->write_function(stream, "not_registered = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->home_network_registered); - stream->write_function(stream, "home_network_registered = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->roaming_registered); - stream->write_function(stream, "roaming_registered = %s\n", value); - }else{ - stream->write_function(stream, "not_registered = %s\n", "N/A"); - stream->write_function(stream, "home_network_registered = %s\n", "N/A"); - stream->write_function(stream, "roaming_registered = %s\n", "N/A"); - } - snprintf(value, sizeof(value)-1, "%d", tech_pvt->got_signal); - stream->write_function(stream, "got_signal = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->running); - stream->write_function(stream, "running = %s\n", value); - stream->write_function(stream, "imei = %s\n", tech_pvt->imei); - stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->controldev_dead); - stream->write_function(stream, "controldev_dead = %s\n", value); - stream->write_function(stream, "controldevice_name = %s\n", tech_pvt->controldevice_name); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->no_sound); - stream->write_function(stream, "no_sound = %s\n", value); -#ifdef GSMOPEN_ALSA - stream->write_function(stream, "alsacname = %s\n", tech_pvt->alsacname); - stream->write_function(stream, "alsapname = %s\n", tech_pvt->alsapname); -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiocindex); - stream->write_function(stream, "portaudiocindex = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiopindex); - stream->write_function(stream, "portaudiopindex = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexecho); - stream->write_function(stream, "speexecho = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexpreprocess); - stream->write_function(stream, "speexpreprocess = %s\n", value); -#endif// GSMOPEN_PORTAUDIO - snprintf(value, sizeof(value)-1, "%f", tech_pvt->playback_boost); - stream->write_function(stream, "playback_boost = %s\n", value); - snprintf(value, sizeof(value)-1, "%f", tech_pvt->capture_boost); - stream->write_function(stream, "capture_boost = %s\n", value); - stream->write_function(stream, "dialplan = %s\n", tech_pvt->dialplan); - stream->write_function(stream, "context = %s\n", tech_pvt->context); - stream->write_function(stream, "destination = %s\n", tech_pvt->destination); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_calls); - stream->write_function(stream, "ib_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_calls); - stream->write_function(stream, "ob_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_failed_calls); - stream->write_function(stream, "ib_failed_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_failed_calls); - stream->write_function(stream, "ob_failed_calls = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->interface_state); - stream->write_function(stream, "interface_state = %s\n", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->phone_callflow); - stream->write_function(stream, "phone_callflow = %s\n", value); - stream->write_function(stream, "session_uuid_str = %s\n", tech_pvt->session_uuid_str); - stream->write_function(stream, "\n"); - - dump_event(tech_pvt); - } else{ - stream->write_function(stream, "interface '%s' was not found\n", argv[0]); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_DUMP_SYNTAX); - } -end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} -SWITCH_STANDARD_API(gsmopen_boost_audio_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - //private_t *tech_pvt; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc == 1 || argc==3) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - //tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - - } else { - if (argc == 1) { - stream->write_function(stream,"[%s] capture boost is %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].capture_boost); - stream->write_function(stream,"[%s] playback boost is %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].playback_boost); - stream->write_function(stream, "%s usage: %s", argv[0], GSMOPEN_BOOST_AUDIO_SYNTAX); - goto end; - } else if ((strncmp("play", argv[1], strlen(argv[1])) == 0)) { - if (switch_is_number(argv[2])) { - stream->write_function(stream,"[%s] playback boost was %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].playback_boost); - gsmopen_store_boost(argv[2], &globals.GSMOPEN_INTERFACES[i].playback_boost); //FIXME - stream->write_function(stream,"[%s] playback boost is now %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].playback_boost); - } - }else if ((strncmp("capt", argv[1], strlen(argv[1])) == 0)) { - if (switch_is_number(argv[2])) { - stream->write_function(stream,"[%s] capture boost was %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].capture_boost); - gsmopen_store_boost(argv[2], &globals.GSMOPEN_INTERFACES[i].capture_boost); //FIXME - stream->write_function(stream,"[%s] capture boost is now %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].capture_boost); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_BOOST_AUDIO_SYNTAX); - } - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_BOOST_AUDIO_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - - -#if 0 -int gsmopen_transfer(private_t * tech_pvt, char *id, char *value) -{ - char msg_to_gsmopen[1024]; - int i; - int found = 0; - private_t *giovatech; - struct timeval timenow; - - switch_mutex_lock(globals.mutex); - - gettimeofday(&timenow, NULL); - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - - giovatech = &globals.GSMOPEN_INTERFACES[i]; - //NOTICA("gsmopen interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->gsmopen_user=%s\n", GSMOPEN_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->gsmopen_user); - //FIXME check a timestamp here - if (strlen(giovatech->gsmopen_call_id) && (giovatech->interface_state != GSMOPEN_STATE_DOWN) && (!strcmp(giovatech->gsmopen_user, tech_pvt->gsmopen_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 500000)) { //0.5sec - found = 1; - DEBUGA_GSMOPEN - ("FOUND (name=%s, giovatech->interface_state=%d != GSMOPEN_STATE_DOWN) && (giovatech->gsmopen_user=%s == tech_pvt->gsmopen_user=%s) && (giovatech->callid_number=%s == value=%s)\n", - GSMOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->gsmopen_user, tech_pvt->gsmopen_user, giovatech->callid_number, - value) - break; - } - } - } - - if (found) { - //tech_pvt->callid_number[0]='\0'; - //sprintf(msg_to_gsmopen, "ALTER CALL %s END HANGUP", id); - //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen); - switch_mutex_unlock(globals.mutex); - return 0; - } - DEBUGA_GSMOPEN("NOT FOUND\n", GSMOPEN_P_LOG); - - if (!tech_pvt || !tech_pvt->gsmopen_call_id || !strlen(tech_pvt->gsmopen_call_id)) { - /* we are not inside an active call */ - DEBUGA_GSMOPEN("We're NO MORE in a call now %s\n", GSMOPEN_P_LOG, (tech_pvt && tech_pvt->gsmopen_call_id) ? tech_pvt->gsmopen_call_id : ""); - switch_mutex_unlock(globals.mutex); - - } else { - - /* we're owned, we're in a call, let's try to transfer */ - /************************** TODO - Checking here if it is possible to transfer this call to Test2 - -> GET CALL 288 CAN_TRANSFER Test2 - <- CALL 288 CAN_TRANSFER test2 TRUE - **********************************/ - - private_t *available_gsmopen_interface = NULL; - - gettimeofday(&timenow, NULL); - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - - giovatech = &globals.GSMOPEN_INTERFACES[i]; - //NOTICA("gsmopen interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->gsmopen_user=%s\n", GSMOPEN_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->gsmopen_user); - //FIXME check a timestamp here - if (strlen(giovatech->gsmopen_transfer_call_id) && (giovatech->interface_state != GSMOPEN_STATE_DOWN) && (!strcmp(giovatech->gsmopen_user, tech_pvt->gsmopen_user)) && (!strcmp(giovatech->transfer_callid_number, value)) && ((((timenow.tv_sec - giovatech->transfer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->transfer_time.tv_usec)) < 1000000)) { //1.0 sec - found = 1; - DEBUGA_GSMOPEN - ("FOUND (name=%s, giovatech->interface_state=%d != GSMOPEN_STATE_DOWN) && (giovatech->gsmopen_user=%s == tech_pvt->gsmopen_user=%s) && (giovatech->transfer_callid_number=%s == value=%s)\n", - GSMOPEN_P_LOG, giovatech->name, giovatech->interface_state, - giovatech->gsmopen_user, tech_pvt->gsmopen_user, giovatech->transfer_callid_number, value) - break; - } - } - } - - if (found) { - //tech_pvt->callid_number[0]='\0'; - //sprintf(msg_to_gsmopen, "ALTER CALL %s END HANGUP", id); - //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen); - switch_mutex_unlock(globals.mutex); - return 0; - } - DEBUGA_GSMOPEN("NOT FOUND\n", GSMOPEN_P_LOG); - - available_gsmopen_interface = find_available_gsmopen_interface_rr(tech_pvt); - if (available_gsmopen_interface) { - /* there is a gsmopen interface idle, let's transfer the call to it */ - - //FIXME write a timestamp here - gettimeofday(&tech_pvt->transfer_time, NULL); - switch_copy_string(tech_pvt->gsmopen_transfer_call_id, id, sizeof(tech_pvt->gsmopen_transfer_call_id) - 1); - - switch_copy_string(tech_pvt->transfer_callid_number, value, sizeof(tech_pvt->transfer_callid_number) - 1); - - DEBUGA_GSMOPEN - ("Let's transfer the gsmopen_call %s to %s interface (with gsmopen_user: %s), because we are already in a gsmopen call(%s)\n", - GSMOPEN_P_LOG, tech_pvt->gsmopen_call_id, available_gsmopen_interface->name, available_gsmopen_interface->gsmopen_user, id); - - //FIXME why this? the inbound call will come, eventually, on that other interface - //available_gsmopen_interface->ib_calls++; - - sprintf(msg_to_gsmopen, "ALTER CALL %s TRANSFER %s", id, available_gsmopen_interface->gsmopen_user); - //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen); - if (tech_pvt->interface_state == GSMOPEN_STATE_SELECTED) { - tech_pvt->interface_state = GSMOPEN_STATE_IDLE; //we marked it GSMOPEN_STATE_SELECTED just in case it has to make an outbound call - } - } else { - /* no gsmopen interfaces idle, do nothing */ - DEBUGA_GSMOPEN - ("Not answering the gsmopen_call %s, because we are already in a gsmopen call(%s) and not transferring, because no other gsmopen interfaces are available\n", - GSMOPEN_P_LOG, id, tech_pvt->gsmopen_call_id); - sprintf(msg_to_gsmopen, "ALTER CALL %s END HANGUP", id); - //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen); - } - switch_sleep(10000); - DEBUGA_GSMOPEN - ("We have NOT answered a GSM RING from gsmopen_call %s, because we are already in a gsmopen call (%s)\n", - GSMOPEN_P_LOG, id, tech_pvt->gsmopen_call_id); - - switch_mutex_unlock(globals.mutex); - } - return 0; -} -#endif //0 - -void *gsmopen_do_gsmopenapi_thread_func(void *obj) -{ - - private_t *tech_pvt = (private_t *) obj; - time_t now_timestamp; - - //if (gsmopen_present(GSMopenHandles)) - while (running && tech_pvt->running) { - int res; - //gsmopen_sleep(1000000); //1 sec - //DEBUGA_GSMOPEN("ciao!\n", GSMOPEN_P_LOG); - res = gsmopen_serial_read(tech_pvt); - if (res == -1) { //manage the graceful interface shutdown - tech_pvt->controldev_dead = 1; - close(tech_pvt->controldevfd); - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running=0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active=0; - tech_pvt->name[0]='\0'; - switch_sleep(1000000); - } else if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL && tech_pvt->interface_state == GSMOPEN_STATE_RING - && tech_pvt->phone_callflow != CALLFLOW_CALL_HANGUP_REQUESTED) { - //WARNINGA("INCOMING RING\n", GSMOPEN_P_LOG); - - gsmopen_ring(tech_pvt); - - //FIXME gsmopen_answer(tech_pvt); - //new_inbound_channel(tech_pvt); - //FIXME if (!gsmopen_new(p, AST_STATE_RING, tech_pvt->context)) { - //FIXME ERRORA("gsmopen_new failed! BAD BAD BAD\n", GSMOPEN_P_LOG); - //FIXME } - - - } else if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL && tech_pvt->interface_state == GSMOPEN_STATE_DIALING) { - WARNINGA("WE'RE DIALING, let's take the earlymedia\n", GSMOPEN_P_LOG); - tech_pvt->interface_state = CALLFLOW_STATUS_EARLYMEDIA; - remote_party_is_early_media(tech_pvt); - //new_inbound_channel(tech_pvt); - //FIXME if (!gsmopen_new(p, AST_STATE_RING, tech_pvt->context)) { - //FIXME ERRORA("gsmopen_new failed! BAD BAD BAD\n", GSMOPEN_P_LOG); - //FIXME } - - - - - } else if (tech_pvt->interface_state == CALLFLOW_CALL_REMOTEANSWER) { - WARNINGA("REMOTE PARTY ANSWERED\n", GSMOPEN_P_LOG); - outbound_channel_answered(tech_pvt); - //new_inbound_channel(tech_pvt); - //FIXME if (!gsmopen_new(p, AST_STATE_RING, tech_pvt->context)) { - //FIXME ERRORA("gsmopen_new failed! BAD BAD BAD\n", GSMOPEN_P_LOG); - //FIXME } - } - switch_sleep(100); //give other threads a chance - time(&now_timestamp); - - if ((now_timestamp - tech_pvt->gsmopen_serial_synced_timestamp) > tech_pvt->gsmopen_serial_sync_period) { //TODO find a sensible period. 5min? in config? - gsmopen_serial_sync(tech_pvt); - gsmopen_serial_getstatus_AT(tech_pvt); - } - } - DEBUGA_GSMOPEN("EXIT\n", GSMOPEN_P_LOG); - //running = 0; - return NULL; - -} - - -SWITCH_STANDARD_API(sendsms_function) -{ - char *mycmd = NULL, *argv[3] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX); - goto end; - } - - if (argc < 3) { - stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX); - goto end; - } - - if (argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Trying to send your SMS: interface=%s, dest=%s, text=%s\n", argv[0], argv[1], argv[2]); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; - } else { - //gsmopen_sendsms(tech_pvt, (char *) argv[1], (char *) argv[2]); - NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", GSMOPEN_P_LOG, GSMOPEN_CHAT_PROTO, tech_pvt->name, - argv[1], "SIMPLE MESSAGE", switch_str_nil(argv[2]), tech_pvt->name); - - compat_chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->name, argv[1], "SIMPLE MESSAGE", switch_str_nil(argv[2]), NULL, tech_pvt->name); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -int dump_event_full(private_t * tech_pvt, int is_alarm, int alarm_code, const char *alarm_message) -{ - switch_event_t *event; - char value[512]; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - switch_status_t status; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if(session){ - channel = switch_core_session_get_channel(session); - } - - if (is_alarm){ - ERRORA("ALARM on interface %s: \n", GSMOPEN_P_LOG, tech_pvt->name ); - status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ALARM); - }else{ - DEBUGA_GSMOPEN("DUMP on interface %s: \n", GSMOPEN_P_LOG, tech_pvt->name ); - status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_DUMP); - } - if (status == SWITCH_STATUS_SUCCESS) { - if (is_alarm){ - snprintf(value, sizeof(value)-1, "%d", alarm_code); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm_code", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm_message", alarm_message); - } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_name", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_id", tech_pvt->id); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->active); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "active", value); - if(!tech_pvt->network_creg_not_supported){ - snprintf(value, sizeof(value)-1, "%d", tech_pvt->not_registered); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "not_registered", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->home_network_registered); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "home_network_registered", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->roaming_registered); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "roaming_registered", value); - }else{ - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "not_registered", "N/A"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "home_network_registered", "N/A"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "roaming_registered", "N/A"); - } - snprintf(value, sizeof(value)-1, "%d", tech_pvt->got_signal); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "got_signal", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->running); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "running", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imei", tech_pvt->imei); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imsi", tech_pvt->imsi); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->controldev_dead); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "controldev_dead", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "controldevice_name", tech_pvt->controldevice_name); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->no_sound); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "no_sound", value); -#ifdef GSMOPEN_ALSA - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alsacname", tech_pvt->alsacname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alsapname", tech_pvt->alsapname); -#endif// GSMOPEN_ALSA -#ifdef GSMOPEN_PORTAUDIO - snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiocindex); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "portaudiocindex", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiopindex); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "portaudiopindex", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexecho); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "speexecho", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexpreprocess); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "speexpreprocess", value); -#endif// GSMOPEN_PORTAUDIO - snprintf(value, sizeof(value)-1, "%f", tech_pvt->playback_boost); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "playback_boost", value); - snprintf(value, sizeof(value)-1, "%f", tech_pvt->capture_boost); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "capture_boost", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialplan", tech_pvt->dialplan); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", tech_pvt->context); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "destination", tech_pvt->destination); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ib_calls", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ob_calls", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_failed_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ib_failed_calls", value); - snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_failed_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ob_failed_calls", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->interface_state); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_state", value); - snprintf(value, sizeof(value)-1, "%d", tech_pvt->phone_callflow); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "phone_callflow", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "session_uuid_str", tech_pvt->session_uuid_str); - if (strlen(tech_pvt->session_uuid_str)) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true"); - } else { //no session - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false"); - } - if (channel) { - switch_channel_event_set_data(channel, event); - } - switch_event_fire(&event); - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name); - } - - if (session) { - switch_core_session_rwunlock(session); - } - return 0; -} - -int dump_event(private_t * tech_pvt) -{ - return dump_event_full(tech_pvt, 0, 0, NULL); -} - - -int alarm_event(private_t * tech_pvt, int alarm_code, const char *alarm_message) -{ - return dump_event_full(tech_pvt, 1, alarm_code, alarm_message); -} - -int sms_incoming(private_t * tech_pvt) -{ - switch_event_t *event; - switch_core_session_t *session = NULL; - int event_sent_to_esl = 0; - - //DEBUGA_GSMOPEN("received SMS on interface %s: %s\n", GSMOPEN_P_LOG, tech_pvt->name, tech_pvt->sms_message); - DEBUGA_GSMOPEN("received SMS on interface %s: DATE=%s, SENDER=%s, BODY=%s|\n", GSMOPEN_P_LOG, tech_pvt->name, tech_pvt->sms_date, tech_pvt->sms_sender, - tech_pvt->sms_body); - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", GSMOPEN_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->sms_sender); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "date", tech_pvt->sms_date); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "userdataheader", tech_pvt->sms_userdataheader); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "datacodingscheme", tech_pvt->sms_datacodingscheme); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "servicecentreaddress", tech_pvt->sms_servicecentreaddress); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "messagetype", "%d", tech_pvt->sms_messagetype); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - switch_event_add_body(event, "%s\n", tech_pvt->sms_body); - if (session) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true"); - if (switch_core_session_queue_event(session, &event) != SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true"); - switch_event_fire(&event); - } - } else { //no session - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false"); - switch_event_fire(&event); - event_sent_to_esl = 1; - } - - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name); - } - - if (!event_sent_to_esl) { - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", GSMOPEN_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->sms_sender); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "date", tech_pvt->sms_date); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "datacodingscheme", tech_pvt->sms_datacodingscheme); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "servicecentreaddress", tech_pvt->sms_servicecentreaddress); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "messagetype", "%d", tech_pvt->sms_messagetype); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id); - switch_event_add_body(event, "%s\n", tech_pvt->sms_body); - if (session) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true"); - } else { //no session - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false"); - } - switch_event_fire(&event); - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name); - } - } - - if (session) { - switch_core_session_rwunlock(session); - } - //memset(&tech_pvt->chatmessages[which], '\0', sizeof(&tech_pvt->chatmessages[which]) ); - //memset(tech_pvt->sms_message, '\0', sizeof(tech_pvt->sms_message)); - return 0; -} - - -#ifdef NOTDEF -SWITCH_STANDARD_API(gsmopen_chat_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - //int tried =0; - int i; - int found = 0; - //char skype_msg[1024]; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_CHAT_SYNTAX); - goto end; - } - - if (argc < 3) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_CHAT_SYNTAX); - goto end; - } - - if (argv[0]) { - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - goto end; - } else { - - //chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint); - //chat_send(p*roto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint); - //chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE", switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, hint); - - NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", GSMOPEN_P_LOG, GSMOPEN_CHAT_PROTO, tech_pvt->skype_user, - argv[1], "SIMPLE MESSAGE", switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), tech_pvt->name); - - chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE", - switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, tech_pvt->name); - - //NOTICA("TEXT is: %s\n", GSMOPEN_P_LOG, (char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1] ); - //snprintf(skype_msg, sizeof(skype_msg), "CHAT CREATE %s", argv[1]); - //gsmopen_signaling_write(tech_pvt, skype_msg); - //switch_sleep(100); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_CHAT_SYNTAX); - goto end; - } - -#ifdef NOTDEF - - found = 0; - - while (!found) { - for (i = 0; i < MAX_CHATS; i++) { - if (!strcmp(tech_pvt->chats[i].dialog_partner, argv[1])) { - snprintf(skype_msg, sizeof(skype_msg), "CHATMESSAGE %s %s", tech_pvt->chats[i].chatname, - (char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]); - gsmopen_signaling_write(tech_pvt, skype_msg); - found = 1; - break; - } - } - if (found) { - break; - } - if (tried > 1000) { - stream->write_function(stream, "ERROR: no chat with dialog_partner='%s' was found\n", argv[1]); - break; - } - switch_sleep(1000); - } -#endif //NOTDEF - - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} -#endif // NOTDEF - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet expandtab: - */ diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/usb-cm-108-2.txt b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/usb-cm-108-2.txt deleted file mode 100644 index 551f42bab6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/usb-cm-108-2.txt +++ /dev/null @@ -1,62 +0,0 @@ -state.default { - control.1 { - comment.access 'read write' - comment.type BOOLEAN - comment.count 1 - iface MIXER - name 'Mic Playback Switch' - value false - } - control.2 { - comment.access 'read write' - comment.type INTEGER - comment.count 1 - comment.range '0 - 32' - iface MIXER - name 'Mic Playback Volume' - value 0 - } - control.3 { - comment.access 'read write' - comment.type BOOLEAN - comment.count 1 - iface MIXER - name 'Speaker Playback Switch' - value true - } - control.4 { - comment.access 'read write' - comment.type INTEGER - comment.count 2 - comment.range '0 - 151' - iface MIXER - name 'Speaker Playback Volume' - value.0 6 - value.1 6 - } - control.5 { - comment.access 'read write' - comment.type BOOLEAN - comment.count 1 - iface MIXER - name 'Mic Capture Switch' - value true - } - control.6 { - comment.access 'read write' - comment.type INTEGER - comment.count 1 - comment.range '0 - 16' - iface MIXER - name 'Mic Capture Volume' - value 5 - } - control.7 { - comment.access 'read write' - comment.type BOOLEAN - comment.count 1 - iface MIXER - name 'Auto Gain Control' - value false - } -} diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/Makefile b/src/mod/endpoints/mod_gsmopen/asterisk/Makefile deleted file mode 100644 index 6aed86266e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/Makefile +++ /dev/null @@ -1,81 +0,0 @@ -# -# Asterisk -- A telephony toolkit for Linux. -# -# Makefile for channel drivers -# -# Copyright (C) 1999-2005, Mark Spencer -# -# Mark Spencer -# -# Edited By Belgarath <> Aug 28 2004 -# Added bare bones ultrasparc-linux support. -# -# This program is free software, distributed under the terms of -# the GNU General Public License -# - -#ASTERISK INCLUDE FILES -#The directory that contains the Asterisk include files (eg: /usr/include or /usr/include/asterisk or /usr/src/asterisk/include or ...) -#AST_INCLUDE_DIR=/usr/src/off_dev/asterisk-1.2.rev137401/include -AST_INCLUDE_DIR=/usr/src/asterisk-1.4.27.1/include -#AST_INCLUDE_DIR=/usr/src/asterisk-1.6.0.10/include - -#ASTERISK VERSION -#Uncomment one of the following lines to match your Asterisk series -#CFLAGS+=-DASTERISK_VERSION_1_2 -CFLAGS+=-DASTERISK_VERSION_1_4 -#CFLAGS+=-DASTERISK_VERSION_1_6_0 - -CFLAGS+=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -CFLAGS+=-g3 - - - -CFLAGS+=-I$(AST_INCLUDE_DIR) -I. -CFLAGS+=-D_REENTRANT -D_GNU_SOURCE -#CFLAGS+=-O6 -#CFLAGS+=-march=i586 -CFLAGS+=-fomit-frame-pointer -ifeq ($(shell uname -m),x86_64) -CFLAGS+=-fPIC -endif - -SVNDEF := -D'CELLIAX_SVN_VERSION="$(shell svnversion -n .)"' -CFLAGS += $(SVNDEF) - - -SOLINK=-shared -Xlinker -x -CHANNEL_LIBS=chan_celliax.so -CC=gcc - -OSARCH=$(shell uname -s) - -ifeq ($(findstring CYGWIN,$(OSARCH)),CYGWIN) -# definition of pthread_kill as a printf (or as a noop) is required for Asterisk (and celliax) to run on Cygwin -# without it, each time (often) pthread_kill is called (by any thread, with any signal, URG included), bad things happen -CC=gcc -D pthread_kill=cyg_no_pthreadkill -AST_DLL_DIR=/home/maruzz/devel/svn_asterisk_branches_12 -CYGSOLINK=-Wl,--out-implib=lib$@.a -Wl,--export-all-symbols cyg_no_pthread_kill.o -CYGSOLIB=-L/usr/lib/w32api -lrpcrt4 -L/lib/mingw -lwinmm -L$(AST_DLL_DIR) -lasterisk.dll -L$(AST_DLL_DIR)/res -lres_features.so -CHANNEL_LIBS=cyg_no_pthread_kill.o chan_celliax.so -endif - -all: $(CHANNEL_LIBS) - -clean: - rm -f *.so *.o *.so.a - - -#chan_celliax section begins - -#to debug threads and lock on 1.4 uncomment the following -#CFLAGS+=-include /usr/src/asterisk/include/asterisk/autoconfig.h - -cyg_no_pthread_kill.o: cyg_no_pthread_kill.c - $(CC) $(CFLAGS) -c -o cyg_no_pthread_kill.o cyg_no_pthread_kill.c -chan_celliax.o: chan_celliax.c - $(CC) $(CFLAGS) -c -o chan_celliax.o chan_celliax.c -chan_celliax.so: chan_celliax.o celliax_spandsp.o celliax_libcsv.o celliax_additional.o - $(CC) $(SOLINK) -o $@ ${CYGSOLINK} chan_celliax.o celliax_spandsp.o celliax_libcsv.o celliax_additional.o -lm -ldl -lasound ${CYGSOLIB} -#chan_celliax section ends - diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/README b/src/mod/endpoints/mod_gsmopen/asterisk/README deleted file mode 100644 index c5921ca6b3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/README +++ /dev/null @@ -1,96 +0,0 @@ -************************************************************** -* CHAN_CELLIAX DRIVER FOR AN EXISTING ASTERISK INSTALLATION -* (works for Asterisk 1.2.xx 1.4.xx 1.6.0.xx series) -* (do NOT works for Asterisk 1.6.1.xx series) -************************************************************** -============================================================== -1) To build celliax you need the ALSA development libraries -============================================================== - -To build celliax on Linux you need to install ALSA-dev libs - -You can do it on Debian/Ubuntu with: -# apt-get install libasound2-dev - -You can do it on Fedora/CentOS with: -# yum --nogpgcheck -y install alsa-lib-devel - -=============================================================== -2) build chan_celliax -=============================================================== - -go into the celliax source directory, edit the Makefile, -insert the asterisk version (1.2.x or 1.4.x or 1.6.0.x, -NOT 1.6.1.x), the location of your asterisk sources, then - -# make clean -# make - -copy chan_celliax.so in the asterisk modules directory - -=============================================================== -2) configure chan_celliax and asterisk -=============================================================== - -edit and copy celliax.conf in the asterisk configuration -directory - -copy ciapalo (or your program that accepts text in stdini) in -the location defined in celliax.conf (sms_receiving_program) - -edit modules.conf and put noload in front of *BOTH* chan_oss.so -AND chan_alsa.so AND chan_console.so - -copy asound.conf in /etc/asound.conf - -if you enable debug in logger.conf and "set debug 100" on -Asterisk, you'll get *a lot* of info on celliax inner workings - -=============================================================== -3) Troubleshooting -=============================================================== -Check that you set the correct serial device in celliax.conf -You can check how the device is called on your platform with: -dmesg | grep ttyU -dmesg | grep ttyA - -Check that you set the correct audio device in celliax.conf -You can check how the device is called on your platform with: -aplay -l -it will give you the number to put on "plughw:N" in celliax.conf - -Check the volume for both play and capture, and that capture -is activated (press spacebar when alsamixer in capture mode) -alsamixer -c[soundcard_number] -Vplay -alsamixer -c[soundcard_number] -Vcapture -we found good results with capt(31) autogain(on) speaker(75) - -If you get double digits (bounces) on DTMFs, check if the capture -volume is too high - -The SMSs are managed in Unicode (UTF8) for international characters -compatibility. Check that your console and/or text editor displays -UTF8 characters - -If you have bad sound, it's a timing problem. Use a 1000HZ kernel, -or add a timing device (ztdummy or zaptel interfaces) -*************************************************************** -* END CHAN_CELLIAX DRIVER FOR AN EXISTING ASTERISK INSTALLATION -*************************************************************** - - - -chan_celliax adds to Asterisk the DIALPLAN application: - - CelliaxSendsms - -You can type at the Asterisk CLI 'show application [application]' -to obtain more specific info on usage. - - - -Enjoy! - --giovanni - -< gmaruzz at gmail dot com > diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/asound.conf b/src/mod/endpoints/mod_gsmopen/asterisk/asound.conf deleted file mode 100644 index 71d6119670..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/asound.conf +++ /dev/null @@ -1,2 +0,0 @@ -#defaults.pcm.rate_converter "speexrate" -defaults.pcm.rate_converter "linear" diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax.conf b/src/mod/endpoints/mod_gsmopen/asterisk/celliax.conf deleted file mode 100644 index 1b84c577d8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax.conf +++ /dev/null @@ -1,205 +0,0 @@ -;; -;; -; Celliax Asterisk Driver -; -; Configuration file -; lines beginning with semicolon (" are ignored (commented out) -; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; The first interface (named line0) -[line0] -;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;; -; general settings, valid on all platforms -; -; -; Default language -; -language=en -; -; Default context (is overridden with @context syntax) -; -context=default -; -; Default extension (in extensions.conf) where incoming calls land -; -extension=s -; -;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;; -; Debugging settings, valid globally for all interfaces on all platforms -; -; the debug values are global for all the interfaces. -; -; default is no celliax debugging output, you **have** to activate debugging here to obtain debugging from celliax -; -; To see the debugging output you have to "set debug 100" from the Asterisk CLI or launch -; Asterisk with -ddddddddddd option, and have the logger.conf file activating debug info for console and messages -; -; You can activate each of the following separately, but you can't disactivate. Eg: debug_at=no does not subtract debug_at from debug_all -; debug_all activate all possible debugging info -; -;debug_all=yes -debug_at=yes -;debug_fbus2=yes -debug_serial=yes -debug_pbx=yes -debug_sound=yes -;debug_locks=yes -debug_call=yes -;debug_monitorlocks=yes -;debug_cvm=yes - -;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;; -; This is the program that will receive in stdin the incoming SMSs -sms_receiving_program=/usr/local/asterisk/usr/sbin/ciapalo - -;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;; -; serial settings, valid for all platforms -; -;control_device_protocol can be AT or FBUS2 or NO_SERIAL (with NO_SERIAL the speed and name of the port are ignored) -control_device_protocol=at - -;speed of the serial port -control_device_speed=115200 - -;name of the serial port device -control_device_name=/dev/ttyACM0 ; this is a Celliax Official Device, recognized as a modem by Linux -;control_device_name=/dev/ttyUSB0 ; this is an alternative form of a Celliax Official Device, recognized as a modem by Linux - -;watch the soundcard for noise (ring), because the serial port do not tell us about incoming calls (eg 3310nokia), NO_SERIAL protocol watch for acoustic ring in any case -need_acoustic_ring=0 - -;audio noise threshold beyond which we declare there is a ring (512 is default, put it to 1024 or 2048 if you have false positive), ignored if not watching for ring -dsp_silence_threshold=1024 - -;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;; -; audio boost settings, valid for all platforms, to compensate for different soundcard/phone input/output signal levels -; tweak it if you get horrible (or not hearable) sound -; -;boost can be positive or negative (-40 to +40) in db -;experiment to find which values are best for your soundcard -playback_boost=0 ; -capture_boost=0 ; - -;;;;;;;;;;;;;;;;;;;;;;;;;;; -; which audio device to use -;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;names of the sound devices in linux -;if you don't use skype on this interface (eg don't need to share the audio device with other applications while celliax is running), use the plughw:n devices (plughw:0 is the first, plughw:1 is the second soundcard, etc). They have the best latency -;if you use skype on this interface use the default:n devices (default:0 is the first, default:1 is the second soundcard, etc). They have worst latency, but you can share them - -alsa_capture_device_name=plughw:1 -alsa_playback_device_name=plughw:1 - -alsa_period_size=160 -alsa_periods_in_buffer=4 - -;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;; -; at "modem" commands settings for this interface (if controldevice_protocol is not AT they are ignored) -; -;what the modem is expecting in the part of the dial command before the number to be dialed (eg: ATD) -;at_dial_pre_number=AT+CKPD="EEE -at_dial_pre_number=ATD -;what the modem is expecting in the part of the dial command after the number to be dialed. If you want it to wait for a semicolon (;), just comment out the followin line. Wait for semicolon is the default -;at_dial_post_number=S" -;what the modem will answer after succesful execution of the dial command -at_dial_expect=OK - -;command to hangup the current call -;at_hangup=AT+CKPD="EEE" -at_hangup=ATH -;what the modem will answer after succesful execution of the hangup command -at_hangup_expect=OK - -;command to answer an incoming call -at_answer=ATA -;what the modem will answer after succesful execution of the answer command -at_answer_expect=OK - -;pause right after serial port opening, before any command is sent, in usecs (1million usec= 1sec) -at_initial_pause=500000 -;custom commands to be sent after the initial pause and before the "built in" initialization commands, and what the modem is expected to send as reply -;the first empty string stop the preinit sending -at_preinit_1=atciapa ; nonsense entry, just to show the preinit -at_preinit_1_expect=OK -at_preinit_2= -at_preinit_2_expect= -at_preinit_3= -at_preinit_3_expect= -at_preinit_4= -at_preinit_4_expect= -at_preinit_5= -at_preinit_5_expect= -;pause right after the custom preinit commands, before any "built in" command is sent, in usecs (1million usec= 1sec) -at_after_preinit_pause=500000 -;custom commands to be sent after the "built in" initialization commands, and what the modem is expected to send as reply -;the first empty string stop the postinit sending -;at_postinit_1=atcucu ; nonsense entry, just to show the postinit -at_postinit_1=at+cmic=0,9 ; modem's microphone sensitivity (our spk) -at_postinit_1_expect=OK -at_postinit_2=AT+CKPD="EEE" ;send three "end" buttonpress, to have the phone in a sane state, ready to dialing with furter CKPDs ***THIS IS IMPORTANT, needed on c650*** -at_postinit_2_expect=OK -at_postinit_3=AT+CSSN=1,0 -at_postinit_3_expect=OK -at_postinit_4=at+sidet=0 ; no sidetone in modem, please -at_postinit_4_expect=OK -at_postinit_5=at+clvl=99 ; modem's speaker level, out mic -at_postinit_5_expect=OK - -;what command to query the battery status, and what the modem is expected to send as reply -at_query_battchg=AT+CBC -at_query_battchg_expect=OK -;what command to query the signal status, and what the modem is expected to send as reply -at_query_signal=AT+CSQ -at_query_signal_expect=OK - -;what command to send a DTMF -at_send_dtmf=AT+VTS - -;the modem will send us the following messages to signal that the visual indicators on the phone has changed because of events (without us to ask for them), loosely based on ETSI standard (see CIND/CIEV/CMER in ETSI). Variable by manufacturer and phone model -; no service -at_indicator_noservice_string=+CIEV: 2,0 -; no signal -at_indicator_nosignal_string=+CIEV: 5,0 -; low signal -at_indicator_lowsignal_string=+CIEV: 5,1 -; low battery -at_indicator_lowbattchg_string=+CIEV: 0,1 -; no battery battery -at_indicator_nobattchg_string=+CIEV: 0,0 -; call is up -at_indicator_callactive_string=+CIEV: 3,1 -; call is down -at_indicator_nocallactive_string=+CIEV: 3,0 -; call is no more in process -at_indicator_nocallsetup_string=+CIEV: 6,0 -; call incoming is in process -at_indicator_callsetupincoming_string=+CIEV: 6,1 -; call outgoing is in process -at_indicator_callsetupoutgoing_string=+CIEV: 6,2 -; remote party is ringing because of our call outgoing -at_indicator_callsetupremoteringing_string=+CIEV: 6,3 - -;call processing unsolicited messages, proprietary for each phone manufacturer -;the modem will send us the following mesage to signal that the line is idle (eg. after an outgoing call has failed, or after hangup) -at_call_idle=+MCST: 1 -;the modem will send us the following mesage to signal that there is an incoming voice call -at_call_incoming=+MCST: 2 -;the modem will send us the following mesage to signal that there is an active call (eg. the remote party has answered us, or we answered them) -;at_call_active=+MCST: 3 -at_call_active=+CSSI: 7 -;the modem will send us the following mesage to signal that our outgoing call has failed -at_call_failed=+MCST: 65 -;the modem will send us the following mesage to signal that our outgoing call is in the calling phase -;at_call_calling=+MCST: 64 -at_call_calling=+CSSI: 1 - diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax.h b/src/mod/endpoints/mod_gsmopen/asterisk/celliax.h deleted file mode 100644 index ed8c2b122c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax.h +++ /dev/null @@ -1,909 +0,0 @@ -//indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90 -#undef GIOVA48 -#define CELLIAX_ALSA -#ifndef _CELLIAX_H_ -#define _CELLIAX_H_ - -#ifndef CELLIAX_SVN_VERSION -#define CELLIAX_SVN_VERSION "????NO_REVISION???" -#endif - -#include /* needed here for conditional compilation on version.h */ - /* the following #defs are for LINUX */ -#ifndef __CYGWIN__ -#ifndef ASTERISK_VERSION_1_6_0 -#ifndef ASTERISK_VERSION_1_4 -#ifndef ASTERISK_VERSION_1_2 -#define ASTERISK_VERSION_1_4 -#if(ASTERISK_VERSION_NUM == 999999) -#undef ASTERISK_VERSION_1_4 -#elif(ASTERISK_VERSION_NUM < 10400) -#undef ASTERISK_VERSION_1_4 -#endif /* ASTERISK_VERSION_NUM == 999999 || ASTERISK_VERSION_NUM < 10400 */ -#endif /* ASTERISK_VERSION_1_2 */ -#endif /* ASTERISK_VERSION_1_4 */ -#endif /* ASTERISK_VERSION_1_6_0 */ -#ifdef ASTERISK_VERSION_1_2 -#undef ASTERISK_VERSION_1_4 -#endif /* ASTERISK_VERSION_1_2 */ -#ifdef ASTERISK_VERSION_1_6_0 -#define ASTERISK_VERSION_1_4 -#endif /* ASTERISK_VERSION_1_6_0 */ -#define CELLIAX_DIR -#undef CELLIAX_LIBCSV -#endif /* NOT __CYGWIN__ */ - /* the following #defs are for WINDOWS */ -#ifdef __CYGWIN__ -#undef ASTERISK_VERSION_1_4 -#undef ASTERISK_VERSION_1_6_0 -#define CELLIAX_DIR -#undef CELLIAX_LIBCSV -#endif /* __CYGWIN__ */ - -/* CELLIAX_CVM */ -#undef CELLIAX_CVM -/* CELLIAX_CVM */ - -#undef CELLIAX_FBUS2 -#define CELLIAX_DIR -#define CELLIAX_LIBCSV - -/* INCLUDES */ -#ifdef ASTERISK_VERSION_1_6_0 -#include /* some asterisk-devel package do not contains asterisk.h, but seems that is needed for the 1.6 series, at least from trunk */ -#endif /* ASTERISK_VERSION_1_6_0 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef ASTERISK_VERSION_1_4 -#include -#include -#endif /* ASTERISK_VERSION_1_4 */ -#ifndef CELLIAX_ALSA -#include "pablio.h" -#endif /* CELLIAX_ALSA */ -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ASTERISK_VERSION_1_6_0 -#include -#include -#endif /* ASTERISK_VERSION_1_6_0 */ -#ifdef ASTERISK_VERSION_1_4 -#include -#include -#include -#include -#endif /* ASTERISK_VERSION_1_4 */ -#ifdef ASTERISK_VERSION_1_2 -#include -#include -#endif /* ASTERISK_VERSION_1_2 */ -#ifdef HAVE_CONFIG_H -#include -#endif -#include "celliax_spandsp.h" -#ifdef CELLIAX_LIBCSV -#include "celliax_libcsv.h" -#endif /* CELLIAX_LIBCSV */ -#ifdef __CYGWIN__ -#include -#endif /* __CYGWIN__ */ -#ifndef AST_DIGIT_ANYDIG -#define AST_DIGIT_ANYDIG "0123456789*#" -#else -#warning Please review Celliax AST_DIGIT_ANYDIG -#endif -#ifndef _ASTERISK_H -#define AST_CONFIG_MAX_PATH 255 /* defined in asterisk.h, but some asterisk-devel package do not contains asterisk.h */ -extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH]; -int ast_register_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */ -void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */ -#endif -#ifdef CELLIAX_ALSA -#define ALSA_PCM_NEW_HW_PARAMS_API -#define ALSA_PCM_NEW_SW_PARAMS_API -#include -#endif /* CELLIAX_ALSA */ - -/* DEFINITIONS */ -/* LUIGI RIZZO's magic */ -/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must - * be representable in 16 bits to avoid overflows. - */ -#define BOOST_SCALE (1<<9) -#define BOOST_MAX 40 /* slightly less than 7 bits */ -/* call flow from the device */ -#define FBUS2_OUTGOING_ACK 999 -#define FBUS2_SECURITY_COMMAND_ON 444 -#define CALLFLOW_CALL_IDLE AST_STATE_DOWN -#define CALLFLOW_INCOMING_RING AST_STATE_RING -#define CALLFLOW_CALL_DIALING AST_STATE_DIALING -#define CALLFLOW_CALL_LINEBUSY AST_STATE_BUSY -#define CALLFLOW_CALL_ACTIVE 300 -#define CALLFLOW_INCOMING_HANGUP 100 -#define CALLFLOW_CALL_RELEASED 101 -#define CALLFLOW_CALL_NOCARRIER 102 -#define CALLFLOW_CALL_INFLUX 103 -#define CALLFLOW_CALL_INCOMING 104 -#define CALLFLOW_CALL_FAILED 105 -#define CALLFLOW_CALL_NOSERVICE 106 -#define CALLFLOW_CALL_OUTGOINGRESTRICTED 107 -#define CALLFLOW_CALL_SECURITYFAIL 108 -#define CALLFLOW_CALL_NOANSWER 109 -#define CALLFLOW_CALL_HANGUP_REQUESTED 110 - //fixme CALLFLOW_GOT_IMEI to be removed -#define CALLFLOW_GOT_IMEI 1009 - //fixme CALLFLOW_INCOMING_CALLID to be removed -#define CALLFLOW_INCOMING_CALLID 1019 -#define AT_OK 0 -#define AT_ERROR 1 -/* FBUS2 (old Nokia phones) undocumented proprietary protocol */ -#define FBUS2_ACK_BYTE 0x7f -#define FBUS2_CALL_CALLID 0x05 -#define FBUS2_CALL_HANGUP 0x04 -#define FBUS2_CALL_STATUS_OFF 0x01 -#define FBUS2_CALL_STATUS_ON 0x02 -#define FBUS2_COMMAND_BYTE_1 0x00 -#define FBUS2_COMMAND_BYTE_2 0x01 -#define FBUS2_DEVICE_PC 0x0c -#define FBUS2_DEVICE_PHONE 0x00 -#define FBUS2_IRDA_FRAME_ID 0x1c -#define FBUS2_IS_LAST_FRAME 0x01 -#define FBUS2_MAX_TRANSMIT_LENGTH 120 -#define FBUS2_NETWORK_STATUS_REGISTERED 0x71 -#define FBUS2_SECURIY_CALL_COMMAND_ANSWER 0x02 -#define FBUS2_SECURIY_CALL_COMMAND_CALL 0x01 -#define FBUS2_SECURIY_CALL_COMMAND_RELEASE 0x03 -#define FBUS2_SECURIY_CALL_COMMANDS 0x7c -#define FBUS2_SECURIY_EXTENDED_COMMAND_ON 0x01 -#define FBUS2_SECURIY_EXTENDED_COMMANDS 0x64 -#define FBUS2_SECURIY_IMEI_COMMAND_GET 0x00 -#define FBUS2_SECURIY_IMEI_COMMANDS 0x66 -#define FBUS2_SEQNUM_MAX 0x47 -#define FBUS2_SEQNUM_MIN 0x40 -#define FBUS2_SERIAL_FRAME_ID 0x1e -#define FBUS2_SMS_INCOMING 0x10 -#define FBUS2_TYPE_CALL 0x01 -#define FBUS2_TYPE_CALL_DIVERT 0x06 -#define FBUS2_TYPE_CALL_STATUS 0x0d -#define FBUS2_TYPE_NETWORK_STATUS 0x0a -#define FBUS2_TYPE_SECURITY 0x40 -#define FBUS2_TYPE_SMS 0x02 -#define FBUS2_TYPE_MODEL_ASK 0xd1 -#define FBUS2_TYPE_MODEL_ANSWER 0xd2 -//#define FBUS2_TYPE_MODEL_ANSWER 0xffffffd2 -#ifdef CELLIAX_CVM -#define CVM_BUSMAIL_SEQNUM_MAX 0x7 -#endif /* CELLIAX_CVM */ -/* debugging bitmask */ -#define DEBUG_SOUND 1 -#define DEBUG_SERIAL 2 -#define DEBUG_SKYPE 4 -#define DEBUG_AT 8 -#define DEBUG_FBUS2 16 -#define DEBUG_CALL 32 -#define DEBUG_LOCKS 64 -#define DEBUG_PBX 128 -#define DEBUG_MONITORLOCKS 256 -#ifndef CELLIAX_CVM -#define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS -#else -#define DEBUG_CVM 512 -#define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS|DEBUG_CVM -#endif /* CELLIAX_CVM */ -/* wrappers for ast_log */ -#define DEBUGA_SOUND(...) if (celliax_debug & DEBUG_SOUND) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SOUND %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_SERIAL(...) if (celliax_debug & DEBUG_SERIAL) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SERIAL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_SKYPE(...) if (celliax_debug & DEBUG_SKYPE) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SKYPE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_AT(...) if (celliax_debug & DEBUG_AT) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_AT %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_FBUS2(...) if (celliax_debug & DEBUG_FBUS2) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_FBUS2 %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_CALL(...) if (celliax_debug & DEBUG_CALL) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_PBX(...) if (celliax_debug & DEBUG_PBX) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#ifdef CELLIAX_CVM -#define DEBUGA_CVM(...) if (celliax_debug & DEBUG_CVM) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CVM %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#endif /* CELLIAX_CVM */ -#define ERRORA(...) ast_log(LOG_ERROR, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][ERROR %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define NOTICA(...) ast_log(LOG_NOTICE, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][NOTICE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define WARNINGA(...) ast_log(LOG_WARNING, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][WARNING %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -/* macros for logging */ -#define CELLIAX_P_LOG p ? p->owner : NULL, (unsigned long)pthread_self(), __LINE__, p ? p->name ? p->name : "none" : "none", p ? p->owner ? p->owner->_state : -1 : -1, p ? p->interface_state : -1, p ? p->phone_callflow : -1 -#define CELLIAX_TMP_LOG tmp ? tmp->owner : NULL, (unsigned long)pthread_self(), __LINE__, tmp ? tmp->name ? tmp->name : "none" : "none", tmp ? tmp->owner ? tmp->owner->_state : -1 : -1, tmp ? tmp->interface_state : -1, tmp ? tmp->phone_callflow : -1 -/* logging wrappers for ast_mutex_lock and ast_mutex_unlock */ -#define LOKKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); -#define UNLOCKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); -#define CVM_LOKKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "CVM_BUSMAIL_OUTGOING_LIST_LOCK" : "?????"); -#define CVM_UNLOCKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "CVM_BUSMAIL_OUTGOING_LIST_LOCK" : "?????"); -#define PUSHA_UNLOCKA(x) pthread_cleanup_push(celliax_unlocka_log, (void *) x); -#define POPPA_UNLOCKA(x) pthread_cleanup_pop(0); -#define MONITORLOKKA(x) if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); -#define MONITORUNLOCKA(x) if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); -/* macros used for config file parsing */ -#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) ) -#define M_END(x) x; -#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else -#ifdef ASTERISK_VERSION_1_6_0 -#define M_START(var, val) const char *__s = var; const char *__val = val; -#else -#define M_START(var, val) char *__s = var; char *__val = val; -#endif /* ASTERISK_VERSION_1_6_0 */ -#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst))) -#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) ) -/* which protocol we use to control the phone through serial device */ -#ifdef CELLIAX_CVM -#define PROTOCOL_CVM_BUSMAIL 5 -#endif /* CELLIAX_CVM */ -#define PROTOCOL_ALSA_VOICEMODEM 4 -#define PROTOCOL_AT 2 -#define PROTOCOL_FBUS2 1 -#define PROTOCOL_NO_SERIAL 3 -#ifndef GIOVA48 -#define CELLIAX_FRAME_SIZE 160 -#else //GIOVA48 -#define CELLIAX_FRAME_SIZE 960 -#endif //GIOVA48 -#define AT_BUFSIZ 8192 -#define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */ -#define AT_MESG_MAX_LINES 256 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */ - -#ifdef CELLIAX_CVM -/* MAIL PRIMITIVES */ -/* CVM -> CELLIAX */ -#define API_PP_LOCKED_IND 0x8558 //PP locked with FP -#define API_PP_UNLOCKED_IND 0x8559 //PP out of service, unlocked from FP - -#define API_PP_SETUP_IND 0x8574 //Incoming call to PP - -#define API_PP_SETUP_IND_CALL_TYPE_OFFSET 0x0 -#define API_PP_SETUP_IND_RING_TYPE_OFFSET 0x1 - -#define API_PP_SETUP_IND_CALL_EXT 0x0 -#define API_PP_SETUP_IND_CALL_INT 0x1 - -#define API_PP_SETUP_IND_RING_INT_CALL 0x40 -#define API_PP_SETUP_IND_RING_PAGE_ALL 0x46 - -#define API_PP_SETUP_ACK_IND 0x857F //internal connection established with FPs, waiting for handsetnumber - -#define API_PP_CONNECT_IND 0x8576 //air-link established with FPs -#define API_PP_CONNECT_CFM 0x8578 //PP answered incoming call - -#define API_PP_ALERT_IND 0x8581 -#define API_PP_ALERT_ON_IND 0x857D -#define API_PP_ALERT_OFF_IND 0x857E - -#define API_PP_SIGNAL_ON_IND 0x2F9C -#define API_PP_SIGNAL_OFF_IND 0x2F9D - -#define API_PP_RELEASE_IND 0x857B -#define API_PP_RELEASE_CFM 0x857A -#define API_PP_REJECT_IND 0x8564 - -#define API_PP_ACCESS_RIGHTS_CFM 0x8568 -#define API_PP_ACCESS_RIGHTS_REJ 0x8569 - -#define API_PP_DELETE_SUBS_CFM 0x8561 -#define API_PP_REMOTE_DELETE_SUBS_CFM 0x2F9F - -#define API_PP_CLIP_IND 0x2F93 -#define API_PP_SW_STATUS_IND 0x2FC2 -#define API_PP_MESSAGE_WAITING_IND 0x2FA1 - -#define CVM_PP_PLUG_STATUS_IND 0x2F4F -#define CVM_PP_LINE_STATUS_IND 0x2F53 -#define CVM_PP_ON_KEY_IND 0x2F64 - -#define API_PP_READ_RSSI_CFM 0x2FC7 -#define API_PP_ALERT_BROADCAST_IND 0x2FA3 - -/* CELLIAX -> CVM */ -#define API_PP_LOCK_REQ 0x8554 //select FP to lock once -#define API_PP_SETUP_REQ 0x8571 //setup air-link PP<->FP - -#define API_PP_KEYPAD_REQ 0x858A //send string for dialing - -#define API_PP_CONNECT_REQ 0x8577 //answer incoming call - -#define API_PP_ALERT_REQ 0x2F8D //inform FP that alering is started - -#define API_PP_RELEASE_REQ 0x8579 //release connection -#define API_PP_RELEASE_RES 0x857C //confirm FP initiated release of connection -#define API_PP_REJECT_REQ 0x8565 //PP reject incoming call - -#define API_PP_ACCESS_RIGHTS_REQ 0x8566 //init registration to FP -#define API_PP_DELETE_SUBS_REQ 0x8560 //deregister from FP (locally only in PP) -#define API_PP_REMOTE_DELETE_SUBS_REQ 0x2F9E //remotly deregister from FP - -#define API_PP_STOP_PROTOCOL_REQ 0x2FC4 //stop protocol from running (even registration) - -#define API_PP_READ_RSSI_REQ 0x2FC6 //RSSI readout request -#define API_PP_READ_RSSI_CFM 0x2FC7 //RSSI readout result - -#define CVM_PP_AUDIO_OPEN_REQ 0x2F0E //Enable audio -#define CVM_PP_AUDIO_CLOSE_REQ 0x2F0F //Disable audio - -#define CVM_PP_AUDIO_SET_VOLUME_REQ 0x2F1D //set volume - -#define CVM_PP_AUDIO_UNMUTE_MIC_REQ 0x2F1A //unmute mic -#define CVM_PP_AUDIO_MUTE_MIC_REQ 0x2F19 //mute mic - -#define CVM_PP_AUDIO_HS_PLUG_IND 0x2F1C //mute mic - -#define CVM_PP_AUDIO_OPEN_ADPCM_OFF_REQ 0x2F68 //open audio even before making connection - -/* END OF MAIL PRIMITIVES */ - -enum CvmLockState { - CVM_UNKNOWN_LOCK_STATE = 0, - CVM_UNLOCKED_TO_FP, - CVM_LOCKED_TO_FP -}; - -enum CvmRegisterState { - CVM_UNKNOWN_REGISTER_STATE = 0, - CVM_UNREGISTERED_TO_FP, - CVM_REGISTERED_TO_FP -}; - -#define BUSMAIL_MAIL_MAX_PARAMS_LENGTH 128 -#define BUSMAIL_MAX_FRAME_LENGTH (BUSMAIL_MAIL_MAX_PARAMS_LENGTH + 9) - -#define BUSMAIL_OFFSET_SOF 0 -#define BUSMAIL_OFFSET_LEN_MSB 1 -#define BUSMAIL_OFFSET_LEN_LSB 2 -#define BUSMAIL_OFFSET_HEADER 3 -#define BUSMAIL_OFFSET_MAIL BUSMAIL_OFFSET_MAIL_PROGRAM_ID -#define BUSMAIL_OFFSET_MAIL_PROGRAM_ID 4 -#define BUSMAIL_OFFSET_MAIL_TASK_ID 5 -#define BUSMAIL_OFFSET_MAIL_PRIMITIVE_MSB 7 -#define BUSMAIL_OFFSET_MAIL_PRIMITIVE_LSB 6 -#define BUSMAIL_OFFSET_MAIL_PARAMS 8 - -#define BUSMAIL_MAIL_PRIMITIVE_MSB 1 -#define BUSMAIL_MAIL_PRIMITIVE_LSB 0 -#define BUSMAIL_LEN_MSB 0 -#define BUSMAIL_LEN_LSB 1 - -#define BUSMAIL_SOF 0x10 - -#define BUSMAIL_MAIL_PROGRAM_ID 0x0 -#define BUSMAIL_MAIL_USERTASK_TASK_ID 0x0f -#define BUSMAIL_MAIL_TBHANDLE_TASK_ID 0x0 -#define BUSMAIL_MAIL_TASK_ID BUSMAIL_MAIL_USERTASK_TASK_ID - -#define BUSMAIL_HEADER_IC_BIT_MASK 0x80 -#define BUSMAIL_HEADER_SU_BIT_MASK 0x40 -#define BUSMAIL_HEADER_PF_BIT_MASK 0x08 -#define BUSMAIL_HEADER_TXSEQ_MASK 0x70 -#define BUSMAIL_HEADER_RXSEQ_MASK 0x07 -#define BUSMAIL_HEADER_SUID_MASK 0x30 -#define BUSMAIL_HEADER_UNID_MASK BUSMAIL_HEADER_SUID_MASK - -#define BUSMAIL_HEADER_INFO_FRAME 0x0 -#define BUSMAIL_HEADER_CTRL_FRAME 0x80 -#define BUSMAIL_HEADER_CTRL_SU_FRAME 0x0 -#define BUSMAIL_HEADER_CTRL_UN_FRAME 0x40 - -#define BUSMAIL_HEADER_UNID_SABM 0x0 -#define BUSMAIL_HEADER_SUID_RR 0x0 -#define BUSMAIL_HEADER_SUID_REJ 0x10 -#define BUSMAIL_HEADER_SUID_RNR 0x20 - -#define BUSMAIL_HEADER_SABM_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK | BUSMAIL_HEADER_UNID_MASK) -#define BUSMAIL_HEADER_SABM (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | BUSMAIL_HEADER_UNID_SABM) - -#define BUSMAIL_HEADER_REJ_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK | BUSMAIL_HEADER_SUID_MASK) -#define BUSMAIL_HEADER_REJ (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_REJ) - -#define BUSMAIL_HEADER_SU_FRAME_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK) -#define BUSMAIL_HEADER_SU_FRAME (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME) - -/*! - * \brief structure holding raw data to be send throught serial - */ -struct cvm_busmail_msg { - int valid; - unsigned char busmail_msg_buffer[BUSMAIL_MAX_FRAME_LENGTH]; - unsigned int busmail_msg_len; - - unsigned int tv_sec; - unsigned int tv_usec; - - unsigned char txseqno; - int acknowledged; - int how_many_sent; - int sent; - - struct cvm_busmail_msg *next; - struct cvm_busmail_msg *previous; -}; - -/*! - * \brief structure holding busmail frame, for internal use - */ -struct cvm_busmail_frame { - unsigned char busmail_sof; - unsigned char busmail_len[2]; - unsigned char busmail_header; - unsigned char busmail_mail_program_id; - unsigned char busmail_mail_task_id; - unsigned char busmail_mail_primitive[2]; - unsigned char busmail_mail_params_buffer[BUSMAIL_MAIL_MAX_PARAMS_LENGTH]; - unsigned int busmail_mail_params_buffer_len; - unsigned char busmail_crc; -}; -#endif /* CELLIAX_CVM */ - -/* CELLIAX INTERNAL STRUCTS */ - -/*! - * \brief structure for the linked list of FBUS2 Nokia proprietary protocol messages - */ -struct fbus2_msg { - int msg; - int seqnum; - int len; - int acknowledged; - int how_many_sent; - int sent; - unsigned int tv_sec; - unsigned int tv_usec; - unsigned char buffer[FBUS2_MAX_TRANSMIT_LENGTH + 10]; - struct fbus2_msg *next; - struct fbus2_msg *previous; -}; - -/*! - * \brief structure for storing the results of AT commands, in an array of AT_MESG_MAX_LINES * AT_MESG_MAX_LENGTH chars - */ -struct s_result { - int elemcount; - char result[AT_MESG_MAX_LINES][AT_MESG_MAX_LENGTH]; -}; - -/*! - * \brief PVT structure for a celliax interface (channel), created by celliax_mkif - */ -struct celliax_pvt { - char *name; /*!< \brief 'name' of the interface (channel) */ - int interface_state; /*!< \brief 'state' of the interface (channel) */ - int phone_callflow; /*!< \brief 'callflow' of the phone interface (as opposed to skype interface) */ - struct ast_channel *owner; /*!< \brief channel we belong to, possibly NULL */ - struct celliax_pvt *next; /*!< \brief Next interface (channel) in list */ - int readpos; /*!< \brief read position above */ - struct ast_frame read_f; /*!< \brief returned by oss_read */ - char context[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan context for this interface */ - char language[MAX_LANGUAGE]; /*!< \brief default Asterisk dialplan language for this interface */ - char exten[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan extension for this interface */ - struct ast_dsp *dsp; /*!< \brief Used for in-band DTMF detection */ - int celliax_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */ - int celliax_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ - char controldevice_name[50]; /*!< \brief name of the serial device controlling the interface, possibly none */ - int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */ - char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */ - int controldevfd; /*!< \brief serial controlling file descriptor for this interface */ - char callid_name[50]; - char callid_number[50]; - unsigned char rxm[255]; /*!< \brief read buffer for FBUS2 serial protocol controlling Nokia phones */ - unsigned char array[255]; /*!< \brief read buffer for FBUS2 serial protocol controlling Nokia phones */ - int arraycounter; /*!< \brief position in the 'array' read buffer for FBUS2 serial protocol controlling Nokia phones */ - int seqnumfbus; /*!< \brief sequential number of FBUS2 messages, hex, revolving */ - pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */ - struct fbus2_msg *fbus2_outgoing_list; /*!< \brief list used to track FBUS2 traffic acknowledgement and resending */ - ast_mutex_t fbus2_outgoing_list_lock; - int dsp_silence_threshold; - int need_acoustic_ring; /*!< \brief bool, this interface get the incoming ring from soundcard, not serial */ - char oss_write_buf[CELLIAX_FRAME_SIZE * 2]; - int oss_write_dst; - char oss_read_buf[CELLIAX_FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET]; /*!< in bytes */ - time_t celliax_serial_synced_timestamp; - time_t celliax_serial_sync_period; - time_t audio_play_reset_timestamp; - time_t audio_capture_reset_timestamp; - speed_t controldevice_speed; - struct s_result line_array; - struct timeval ringtime; - struct timeval call_incoming_time; - int at_result; - - char at_dial_pre_number[64]; - char at_dial_post_number[64]; - char at_dial_expect[64]; - unsigned int at_early_audio; - char at_hangup[64]; - char at_hangup_expect[64]; - char at_answer[64]; - char at_answer_expect[64]; - unsigned int at_initial_pause; - char at_preinit_1[64]; - char at_preinit_1_expect[64]; - char at_preinit_2[64]; - char at_preinit_2_expect[64]; - char at_preinit_3[64]; - char at_preinit_3_expect[64]; - char at_preinit_4[64]; - char at_preinit_4_expect[64]; - char at_preinit_5[64]; - char at_preinit_5_expect[64]; - unsigned int at_after_preinit_pause; - - char at_postinit_1[64]; - char at_postinit_1_expect[64]; - char at_postinit_2[64]; - char at_postinit_2_expect[64]; - char at_postinit_3[64]; - char at_postinit_3_expect[64]; - char at_postinit_4[64]; - char at_postinit_4_expect[64]; - char at_postinit_5[64]; - char at_postinit_5_expect[64]; - - char at_send_dtmf[64]; - - char at_query_battchg[64]; - char at_query_battchg_expect[64]; - char at_query_signal[64]; - char at_query_signal_expect[64]; - char at_call_idle[64]; - char at_call_incoming[64]; - char at_call_active[64]; - char at_call_failed[64]; - char at_call_calling[64]; - -#define CIEV_STRING_SIZE 64 - char at_indicator_noservice_string[64]; - char at_indicator_nosignal_string[64]; - char at_indicator_lowsignal_string[64]; - char at_indicator_lowbattchg_string[64]; - char at_indicator_nobattchg_string[64]; - char at_indicator_callactive_string[64]; - char at_indicator_nocallactive_string[64]; - char at_indicator_nocallsetup_string[64]; - char at_indicator_callsetupincoming_string[64]; - char at_indicator_callsetupoutgoing_string[64]; - char at_indicator_callsetupremoteringing_string[64]; - - int at_indicator_callp; - int at_indicator_callsetupp; - int at_indicator_roamp; - int at_indicator_battchgp; - int at_indicator_servicep; - int at_indicator_signalp; - - int at_has_clcc; - int at_has_ecam; - - double playback_boost; - double capture_boost; - int stripmsd; - int controldev_dead; - ast_mutex_t controldev_lock; - struct timeval fbus2_list_tv; - struct timezone fbus2_list_tz; - dtmf_rx_state_t dtmf_state; - int dtmf_inited; - pthread_t sync_thread; - pthread_t celliax_sound_monitor_thread; - pthread_t celliax_serial_monitor_thread; - int celliax_serial_monitoring; - int skype; /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */ - int phonebook_listing; - int phonebook_querying; - int phonebook_listing_received_calls; - - int phonebook_first_entry; - int phonebook_last_entry; - int phonebook_number_lenght; - int phonebook_text_lenght; - FILE *phonebook_writing_fp; - int celliax_dir_entry_extension_prefix; -#ifdef CELLIAX_CVM - char cvm_subsc_1_pin[20]; - char cvm_subsc_2_pin[20]; - int cvm_subsc_no; - int cvm_lock_state; - int cvm_register_state; - int cvm_volume_level; - int cvm_celliax_serial_delay; - unsigned char cvm_handset_no; - unsigned char cvm_fp_is_cvm; - unsigned char cvm_rssi; - - unsigned char busmail_rxseq_cvm_last; /*!< \brief sequential number of BUSMAIL messages, (0-7) */ - unsigned char busmail_txseq_celliax_last; /*!< \brief sequential number of BUSMAIL messages, (0-7) */ - - struct cvm_busmail_msg *cvm_busmail_outgoing_list; /*!< \brief list used to track CVM BUSMAIL traffic acknowledgement and resending */ - ast_mutex_t cvm_busmail_outgoing_list_lock; - - struct timeval cvm_busmail_list_tv; - struct timezone cvm_busmail_list_tz; -#endif /* CELLIAX_CVM */ -#ifdef CELLIAX_LIBCSV - int csv_separator_is_semicolon; - int csv_complete_name_pos; - int csv_email_pos; - int csv_home_phone_pos; - int csv_mobile_phone_pos; - int csv_business_phone_pos; - int csv_first_row_is_title; - int csv_fields; - int csv_rows; - char csv_complete_name[256]; - char csv_email[256]; - char csv_home_phone[256]; - char csv_mobile_phone[256]; - char csv_business_phone[256]; -#endif /* CELLIAX_LIBCSV */ - int audio_play_reset_period; - - char at_cmgw[16]; - - int isInputInterleaved; - int isOutputInterleaved; - int numInputChannels; - int numOutputChannels; - int framesPerCallback; -#ifndef CELLIAX_ALSA - PABLIO_Stream *stream; -#endif /* CELLIAX_ALSA */ - int audiopipe[2]; - int speexecho; - int speexpreprocess; - int portaudiocindex; /*!< \brief Index of the Portaudio capture audio device */ - int portaudiopindex; /*!< \brief Index of the Portaudio playback audio device */ - int control_to_send; - int unread_sms_msg_id; - int reading_sms_msg; - char sms_message[4800]; - int sms_cnmi_not_supported; - char sms_receiving_program[256]; - int celliax_dir_prefix; - int no_ucs2; -#ifdef CELLIAX_ALSA - snd_pcm_t *alsac; /*!< \brief handle of the ALSA capture audio device */ - snd_pcm_t *alsap; /*!< \brief handle of the ALSA playback audio device */ - char alsacname[50]; /*!< \brief name of the ALSA capture audio device */ - char alsapname[50]; /*!< \brief name of the ALSA playback audio device */ - int alsa_period_size; /*!< \brief ALSA period_size, in byte */ - int alsa_periods_in_buffer; /*!< \brief how many periods in ALSA buffer, to calculate buffer_size */ - unsigned long int alsa_buffer_size; /*!< \brief ALSA buffer_size, in byte */ - int alsawrite_filled; - int alsa_capture_is_mono; - int alsa_play_is_mono; - struct pollfd pfd; -#endif /* CELLIAX_ALSA */ - - struct timeval dtmf_timestamp; -}; - -/* LOCKS */ -/*! \brief Protect the celliax_usecnt */ -AST_MUTEX_DEFINE_STATIC(celliax_usecnt_lock); -/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not - * when it's doing something critical. */ -AST_MUTEX_DEFINE_STATIC(celliax_monlock); -/*! \brief Protect the interfaces list */ -AST_MUTEX_DEFINE_STATIC(celliax_iflock); - -/* FUNCTIONS */ - -/* module helpers functions */ -int load_module(void); -int unload_module(void); -int usecount(void); -char *description(void); -char *key(void); - -/* chan_celliax internal functions */ -void celliax_unlocka_log(void *x); -#ifdef CELLIAX_FBUS2 -int celliax_serial_sync_FBUS2(struct celliax_pvt *p); -int celliax_serial_answer_FBUS2(struct celliax_pvt *p); -int celliax_serial_call_FBUS2(struct celliax_pvt *p, char *dstr); -int celliax_serial_hangup_FBUS2(struct celliax_pvt *p); -int celliax_serial_config_FBUS2(struct celliax_pvt *p); -int celliax_serial_read_FBUS2(struct celliax_pvt *p); -int celliax_serial_getstatus_FBUS2(struct celliax_pvt *p); -int celliax_serial_get_seqnum_FBUS2(struct celliax_pvt *p); -int celliax_serial_security_command_FBUS2(struct celliax_pvt *p); -int celliax_serial_send_FBUS2(struct celliax_pvt *p, int len, unsigned char *buffer2); -int celliax_serial_list_acknowledge_FBUS2(struct celliax_pvt *p, int seqnum); -int celliax_serial_send_if_time_FBUS2(struct celliax_pvt *p); -int celliax_serial_write_FBUS2(struct celliax_pvt *p, unsigned char *MsgBuffer, - int MsgLength, unsigned char MsgType); -int celliax_serial_send_ack_FBUS2(struct celliax_pvt *p, unsigned char MsgType, - unsigned char MsgSequence); -struct fbus2_msg *celliax_serial_list_init_FBUS2(struct celliax_pvt *p); -int celliax_serial_list_print_FBUS2(struct celliax_pvt *p, struct fbus2_msg *list); - -#endif /* CELLIAX_FBUS2 */ - -#ifdef CELLIAX_CVM -int celliax_serial_sync_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_answer_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_call_CVM_BUSMAIL(struct celliax_pvt *p, char *dstr); -int celliax_serial_hangup_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_config_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_read_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_getstatus_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_send_CVM_BUSMAIL(struct celliax_pvt *p, int len, - unsigned char *mesg_ptr); -int celliax_serial_list_acknowledge_CVM_BUSMAIL(struct celliax_pvt *p, - unsigned char TxSeqNo); -int celliax_serial_send_if_time_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_write_CVM_BUSMAIL(struct celliax_pvt *p, - struct cvm_busmail_frame *busmail_frame); -int celliax_serial_send_ctrl_frame_CVM_BUSMAIL(struct celliax_pvt *p, - unsigned char FrameType); -int celliax_serial_send_info_frame_CVM_BUSMAIL(struct celliax_pvt *p, int FrameType, - unsigned char ParamsLen, - unsigned char *Params); -struct cvm_busmail_msg *celliax_serial_list_init_CVM_BUSMAIL(struct celliax_pvt *p); -int celliax_serial_list_print_CVM_BUSMAIL(struct celliax_pvt *p, - struct cvm_busmail_msg *list); -int celliax_serial_lists_free_CVM_BUSMAIL(struct celliax_pvt *p); - -#endif /* CELLIAX_CVM */ - -/* CHAN_CELLIAX.C */ -int celliax_queue_control(struct ast_channel *chan, int control); -struct celliax_pvt *celliax_console_find_desc(char *dev); -int celliax_serial_call(struct celliax_pvt *p, char *dstr); - -/* FUNCTIONS */ -/* PBX interface functions */ -struct ast_channel *celliax_request(const char *type, int format, void *data, int *cause); -int celliax_answer(struct ast_channel *c); -int celliax_hangup(struct ast_channel *c); -int celliax_call(struct ast_channel *c, char *idest, int timeout); -struct ast_frame *celliax_read(struct ast_channel *chan); -int celliax_write(struct ast_channel *c, struct ast_frame *f); -int celliax_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); -#ifndef ASTERISK_VERSION_1_4 -int celliax_indicate(struct ast_channel *c, int cond); -#else -int celliax_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen); -#endif -int celliax_devicestate(void *data); -#ifdef ASTERISK_VERSION_1_4 -int celliax_senddigit_begin(struct ast_channel *ast, char digit); -int celliax_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration); -#else /* ASTERISK_VERSION_1_4 */ -int celliax_senddigit(struct ast_channel *ast, char digit); -#endif /* ASTERISK_VERSION_1_4 */ - -/* chan_celliax internal functions */ - -struct celliax_pvt *celliax_mkif(struct ast_config *cfg, char *ctg, - int is_first_category); -struct ast_channel *celliax_new(struct celliax_pvt *p, int state, char *context); -int celliax_restart_monitor(void); -void *celliax_do_monitor(void *data); -void *celliax_do_audio_monitor(void *data); -int celliax_sound_boost(struct ast_frame *f, double boost); -int celliax_sound_init(struct celliax_pvt *p); -int celliax_sound_shutdown(struct celliax_pvt *p); -struct ast_frame *celliax_sound_dsp_analize(struct celliax_pvt *p, struct ast_frame *f, - int dsp_silence_threshold); -int celliax_sound_dsp_set(struct celliax_pvt *p, int dsp_silence_threshold, - int silence_suppression); -struct ast_frame *celliax_sound_read(struct celliax_pvt *p); -int celliax_sound_write(struct celliax_pvt *p, struct ast_frame *f); -int celliax_sound_monitor(struct celliax_pvt *p); -void *celliax_do_controldev_thread(void *data); -int celliax_serial_init(struct celliax_pvt *p, speed_t controldevice_speed); -int celliax_serial_monitor(struct celliax_pvt *p); -int celliax_serial_read(struct celliax_pvt *p); -int celliax_serial_sync(struct celliax_pvt *p); -int celliax_serial_getstatus(struct celliax_pvt *p); -int celliax_serial_config(struct celliax_pvt *p); -int celliax_serial_hangup(struct celliax_pvt *p); -int celliax_serial_answer(struct celliax_pvt *p); - -#define celliax_serial_write_AT_expect(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 1, 2) -#define celliax_serial_write_AT_expect_noexpcr(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 0, 2) -#define celliax_serial_write_AT_expect_noexpcr_tout(P, D, S, T) celliax_serial_write_AT_expect1(P, D, S, 0, T) -// 20.5 sec timeout, used for querying the SIM and sending SMSs -#define celliax_serial_write_AT_expect_longtime(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 1, 20) -#define celliax_serial_write_AT_expect_longtime_noexpcr(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 0, 20) -int celliax_serial_write_AT(struct celliax_pvt *p, const char *data); -int celliax_serial_write_AT_nocr(struct celliax_pvt *p, const char *data); -int celliax_serial_write_AT_ack(struct celliax_pvt *p, const char *data); -int celliax_serial_write_AT_ack_nocr_longtime(struct celliax_pvt *p, const char *data); -int celliax_serial_write_AT_noack(struct celliax_pvt *p, const char *data); -int celliax_serial_write_AT_expect1(struct celliax_pvt *p, const char *data, - const char *expected_string, int expect_crlf, - int seconds); -int celliax_serial_AT_expect(struct celliax_pvt *p, const char *expected_string, - int expect_crlf, int seconds); -int celliax_serial_read_AT(struct celliax_pvt *p, int look_for_ack, int timeout_usec, - int timeout_sec, const char *expected_string, int expect_crlf); -int celliax_serial_answer_AT(struct celliax_pvt *p); -int celliax_serial_hangup_AT(struct celliax_pvt *p); -int celliax_serial_config_AT(struct celliax_pvt *p); -int celliax_serial_call_AT(struct celliax_pvt *p, char *dstr); -int celliax_serial_sync_AT(struct celliax_pvt *p); -int celliax_serial_getstatus_AT(struct celliax_pvt *p); - -#ifdef ASTERISK_VERSION_1_6_0 -void celliax_store_boost(const char *s, double *boost); -#else -void celliax_store_boost(char *s, double *boost); -#endif /* ASTERISK_VERSION_1_6_0 */ -int celliax_console_set_active(int fd, int argc, char *argv[]); -#ifndef ASTERISK_VERSION_1_6_0 -int celliax_console_hangup(int fd, int argc, char *argv[]); -#else /* ASTERISK_VERSION_1_6_0 */ -char *celliax_console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); -#endif /* ASTERISK_VERSION_1_6_0 */ -int celliax_console_playback_boost(int fd, int argc, char *argv[]); -int celliax_console_capture_boost(int fd, int argc, char *argv[]); -int celliax_console_celliax(int fd, int argc, char *argv[]); -#ifdef CELLIAX_DIR -int celliax_console_celliax_dir_import(int fd, int argc, char *argv[]); -int celliax_console_celliax_dir_export(int fd, int argc, char *argv[]); -#endif /* CELLIAX_DIR */ -int celliax_console_dial(int fd, int argc, char *argv[]); -int celliax_console_sendsms(int fd, int argc, char *argv[]); -int celliax_portaudio_init(struct celliax_pvt *p); -int celliax_portaudio_shutdown(struct celliax_pvt *p); -struct ast_frame *celliax_portaudio_read(struct celliax_pvt *p); -int celliax_portaudio_write(struct celliax_pvt *p, struct ast_frame *f); -int celliax_portaudio_devlist(struct celliax_pvt *p); -#ifdef CELLIAX_DIR -int celliax_dir_exec(struct ast_channel *chan, void *data); -int celliax_dir_create_extensions(void); -int celliax_dir_play_mailbox_owner(struct ast_channel *chan, char *context, - char *dialcontext, char *ext, char *name); -struct ast_config *celliax_dir_realtime(char *context); -int celliax_dir_do(struct ast_channel *chan, struct ast_config *cfg, char *context, - char *dialcontext, char digit, int last); -#endif /* CELLIAX_DIR */ -#ifdef CELLIAX_LIBCSV -void celliax_cb1(char *s, size_t len, void *data); -void celliax_cb2(char c, void *data); -#endif /* CELLIAX_LIBCSV */ -int celliax_sendsms(struct ast_channel *c, void *data); -int celliax_console_echo(int fd, int argc, char *argv[]); -int celliax_console_at(int fd, int argc, char *argv[]); -#ifdef ASTERISK_VERSION_1_2 -int celliax_manager_sendsms(struct mansession *s, struct message *m); -#endif //ASTERISK_VERSION_1_2 -#ifdef ASTERISK_VERSION_1_4 -int celliax_manager_sendsms(struct mansession *s, const struct message *m); -#endif //ASTERISK_VERSION_1_4 -int utf_to_ucs2(struct celliax_pvt *p, char *utf_in, size_t inbytesleft, char *ucs2_out, - size_t outbytesleft); -int ucs2_to_utf8(struct celliax_pvt *p, char *ucs2_in, char *utf8_out, - size_t outbytesleft); -#endif /* _CELLIAX_H_ */ -#ifdef CELLIAX_ALSA -int console_alsa_period(int fd, int argc, char *argv[]); -#endif /* CELLIAX_ALSA */ -#ifdef CELLIAX_ALSA -int alsa_init(struct celliax_pvt *p); -int alsa_shutdown(struct celliax_pvt *p); -snd_pcm_t *alsa_open_dev(struct celliax_pvt *p, snd_pcm_stream_t stream); -struct ast_frame *alsa_read(struct celliax_pvt *p); -int alsa_write(struct celliax_pvt *p, struct ast_frame *f); -#endif /* CELLIAX_ALSA */ diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c deleted file mode 100644 index efae699ab7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c +++ /dev/null @@ -1,7027 +0,0 @@ -//indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90 -#include "celliax.h" -#include "iconv.h" - -extern int celliax_debug; -extern char *celliax_console_active; -extern char celliax_type[]; -extern struct celliax_pvt *celliax_iflist; -extern int celliax_dir_entry_extension; - -#ifndef GIOVA48 -#define SAMPLES_PER_FRAME 160 -#else // GIOVA48 -#define SAMPLES_PER_FRAME 960 -#endif // GIOVA48 - -#ifdef CELLIAX_ALSA -/*! \brief ALSA pcm format, according to endianess */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -snd_pcm_format_t celliax_format = SND_PCM_FORMAT_S16_LE; -#else -snd_pcm_format_t celliax_format = SND_PCM_FORMAT_S16_BE; -#endif - -/*! - * \brief Initialize the ALSA soundcard channels (capture AND playback) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the celliax_pvt of the interface - * - * This function call alsa_open_dev to initialize the ALSA soundcard for each channel (capture AND playback) used by one interface (a multichannel soundcard can be used by multiple interfaces). Called by sound_init - * - * \return zero on success, -1 on error. - */ -int alsa_init(struct celliax_pvt *p) -{ - p->alsac = alsa_open_dev(p, SND_PCM_STREAM_CAPTURE); - if (!p->alsac) { - ERRORA("Failed opening ALSA capture device: %s\n", CELLIAX_P_LOG, p->alsacname); - if (alsa_shutdown(p)) { - ERRORA("alsa_shutdown failed\n", CELLIAX_P_LOG); - return -1; - } - return -1; - } - p->alsap = alsa_open_dev(p, SND_PCM_STREAM_PLAYBACK); - if (!p->alsap) { - ERRORA("Failed opening ALSA playback device: %s\n", CELLIAX_P_LOG, p->alsapname); - if (alsa_shutdown(p)) { - ERRORA("alsa_shutdown failed\n", CELLIAX_P_LOG); - return -1; - } - return -1; - } - - /* make valgrind very happy */ - snd_config_update_free_global(); - return 0; -} - -/*! - * \brief Shutdown the ALSA soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the celliax_pvt of the interface - * - * This function shutdown the ALSA soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces). Called by sound_init - * - * \return zero on success, -1 on error. - */ - -int alsa_shutdown(struct celliax_pvt *p) -{ - - int err; - - if (p->alsap) { - err = snd_pcm_drop(p->alsap); - if (err < 0) { - ERRORA("device [%s], snd_pcm_drop failed with error '%s'\n", CELLIAX_P_LOG, - p->alsapname, snd_strerror(err)); - return -1; - } - err = snd_pcm_close(p->alsap); - if (err < 0) { - ERRORA("device [%s], snd_pcm_close failed with error '%s'\n", CELLIAX_P_LOG, - p->alsapname, snd_strerror(err)); - return -1; - } - } - if (p->alsac) { - err = snd_pcm_drop(p->alsac); - if (err < 0) { - ERRORA("device [%s], snd_pcm_drop failed with error '%s'\n", CELLIAX_P_LOG, - p->alsacname, snd_strerror(err)); - return -1; - } - err = snd_pcm_close(p->alsac); - if (err < 0) { - ERRORA("device [%s], snd_pcm_close failed with error '%s'\n", CELLIAX_P_LOG, - p->alsacname, snd_strerror(err)); - return -1; - } - } - - return 0; -} - -/*! - * \brief Setup and open the ALSA device (capture OR playback) - * \param p the celliax_pvt of the interface - * \param stream the ALSA capture/playback definition - * - * This function setup and open the ALSA device (capture OR playback). Called by alsa_init - * - * \return zero on success, -1 on error. - */ -snd_pcm_t *alsa_open_dev(struct celliax_pvt * p, snd_pcm_stream_t stream) -{ - - snd_pcm_t *handle = NULL; - snd_pcm_hw_params_t *params; - snd_pcm_sw_params_t *swparams; - snd_pcm_uframes_t buffer_size; - int err; - size_t n; - //snd_pcm_uframes_t xfer_align; - unsigned int rate; - snd_pcm_uframes_t start_threshold, stop_threshold; - snd_pcm_uframes_t period_size = 0; - snd_pcm_uframes_t chunk_size = 0; - int start_delay = 0; - int stop_delay = 0; - snd_pcm_state_t state; - snd_pcm_info_t *info; - - period_size = p->alsa_period_size; - - snd_pcm_hw_params_alloca(¶ms); - snd_pcm_sw_params_alloca(&swparams); - - if (stream == SND_PCM_STREAM_CAPTURE) { - err = snd_pcm_open(&handle, p->alsacname, stream, 0 | SND_PCM_NONBLOCK); - } else { - err = snd_pcm_open(&handle, p->alsapname, stream, 0 | SND_PCM_NONBLOCK); - } - if (err < 0) { - ERRORA - ("snd_pcm_open failed with error '%s' on device '%s', if you are using a plughw:n device please change it to be a default:n device (so to allow it to be shared with other concurrent programs), or maybe you are using an ALSA voicemodem and slmodemd" - " is running?\n", CELLIAX_P_LOG, snd_strerror(err), - stream == SND_PCM_STREAM_CAPTURE ? p->alsacname : p->alsapname); - return NULL; - } - - snd_pcm_info_alloca(&info); - - if ((err = snd_pcm_info(handle, info)) < 0) { - ERRORA("info error: %s", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - - err = snd_pcm_nonblock(handle, 1); - if (err < 0) { - ERRORA("nonblock setting error: %s", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - ERRORA("Broken configuration for this PCM, no configurations available: %s\n", - CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - - err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); - if (err < 0) { - ERRORA("Access type not available: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - err = snd_pcm_hw_params_set_format(handle, params, celliax_format); - if (err < 0) { - ERRORA("Sample format non available: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - err = snd_pcm_hw_params_set_channels(handle, params, 1); - if (err < 0) { - DEBUGA_SOUND("Channels count set failed: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } -#if 1 - unsigned int chan_num; - err = snd_pcm_hw_params_get_channels(params, &chan_num); - if (err < 0) { - ERRORA("Channels count non available: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - if (chan_num < 1 || chan_num > 2) { - ERRORA("Channels count MUST BE 1 or 2, it is: %d\n", CELLIAX_P_LOG, chan_num); - ERRORA("Channels count MUST BE 1 or 2, it is: %d on %s %s\n", CELLIAX_P_LOG, chan_num, - p->alsapname, p->alsacname); - return NULL; - } else { - if (chan_num == 1) { - if (stream == SND_PCM_STREAM_CAPTURE) - p->alsa_capture_is_mono = 1; - else - p->alsa_play_is_mono = 1; - } else { - if (stream == SND_PCM_STREAM_CAPTURE) - p->alsa_capture_is_mono = 0; - else - p->alsa_play_is_mono = 0; - } - } -#else - p->alsa_capture_is_mono = 1; - p->alsa_play_is_mono = 1; -#endif - -#if 0 - unsigned int buffer_time = 0; - unsigned int period_time = 0; - snd_pcm_uframes_t period_frames = 0; - snd_pcm_uframes_t buffer_frames = 0; - - if (buffer_time == 0 && buffer_frames == 0) { - err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, 0); - assert(err >= 0); - if (buffer_time > 500000) - buffer_time = 500000; - } - if (period_time == 0 && period_frames == 0) { - if (buffer_time > 0) - period_time = buffer_time / 4; - else - period_frames = buffer_frames / 4; - } - if (period_time > 0) - err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, 0); - else - err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_frames, 0); - assert(err >= 0); - if (buffer_time > 0) { - err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0); - } else { - err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_frames); - } -#endif - -#if 1 - rate = p->celliax_sound_rate; - err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0); - if ((float) p->celliax_sound_rate * 1.05 < rate - || (float) p->celliax_sound_rate * 0.95 > rate) { - WARNINGA("Rate is not accurate (requested = %iHz, got = %iHz)\n", CELLIAX_P_LOG, - p->celliax_sound_rate, rate); - } - - if (err < 0) { - ERRORA("Error setting rate: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - p->celliax_sound_rate = rate; - - err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, 0); - - if (err < 0) { - ERRORA("Error setting period_size: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - - p->alsa_period_size = period_size; - - p->alsa_buffer_size = p->alsa_period_size * p->alsa_periods_in_buffer; - - err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &p->alsa_buffer_size); - - if (err < 0) { - ERRORA("Error setting buffer_size: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } -#endif - - err = snd_pcm_hw_params(handle, params); - if (err < 0) { - ERRORA("Unable to install hw params: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - - snd_pcm_hw_params_get_period_size(params, &chunk_size, 0); - snd_pcm_hw_params_get_buffer_size(params, &buffer_size); - if (chunk_size == buffer_size) { - ERRORA("Can't use period equal to buffer size (%lu == %lu)\n", CELLIAX_P_LOG, - chunk_size, buffer_size); - return NULL; - } - - snd_pcm_sw_params_current(handle, swparams); - -#if 0 - err = snd_pcm_sw_params_get_xfer_align(swparams, &xfer_align); - if (err < 0) { - ERRORA("Unable to obtain xfer align: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } - NOTICA("xfer_align: %d\n", CELLIAX_P_LOG, xfer_align); - /* for some reason, on some platforms, xfer_align here is zero, that gives a floating point exception later. So, let's try to force it to 160, the frame size used by celliax */ - xfer_align = p->alsa_period_size; - NOTICA("xfer_align: %d\n", CELLIAX_P_LOG, xfer_align); - - err = snd_pcm_sw_params_set_xfer_align(handle, swparams, xfer_align); - if (err < 0) { - ERRORA("Error setting xfer_align: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } - NOTICA("xfer_align: %d\n", CELLIAX_P_LOG, xfer_align); - - err = snd_pcm_sw_params_get_xfer_align(swparams, &xfer_align); - if (err < 0) { - ERRORA("Unable to obtain xfer align: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } - NOTICA("xfer_align: %d\n", CELLIAX_P_LOG, xfer_align); -#endif - - /* - if (sleep_min) - xfer_align = 1; - err = snd_pcm_sw_params_set_sleep_min(handle, swparams, - 0); - - if (err < 0) { - ERRORA("Error setting slep_min: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } - */ - n = chunk_size; - err = snd_pcm_sw_params_set_avail_min(handle, swparams, n); - if (err < 0) { - ERRORA("Error setting avail_min: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } -#if 0 - /* round up to closest transfer boundary */ - if (xfer_align == 0) { //so to avoid floating point exception ???? - xfer_align = 160; - } - //original n = (buffer_size / xfer_align) * xfer_align; - n = (chunk_size / xfer_align) * xfer_align; -#endif - if (stream == SND_PCM_STREAM_CAPTURE) { - start_delay = 1; - } - if (start_delay <= 0) { - start_threshold = n + (double) rate *start_delay / 1000000; - } else { - start_threshold = (double) rate *start_delay / 1000000; - } - if (start_threshold < 1) - start_threshold = 1; - if (start_threshold > n) - start_threshold = n; - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold); - if (err < 0) { - ERRORA("Error setting start_threshold: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } - - if (stop_delay <= 0) - stop_threshold = buffer_size + (double) rate *stop_delay / 1000000; - else - stop_threshold = (double) rate *stop_delay / 1000000; - - if (stream == SND_PCM_STREAM_CAPTURE) { - stop_threshold = -1; - } - - err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); - - if (err < 0) { - ERRORA("Error setting stop_threshold: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } -#if 0 - err = snd_pcm_sw_params_set_xfer_align(handle, swparams, xfer_align); - - if (err < 0) { - ERRORA("Error setting xfer_align: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } -#endif - - if (snd_pcm_sw_params(handle, swparams) < 0) { - ERRORA("Error installing software parameters: %s\n", CELLIAX_P_LOG, - snd_strerror(err)); - } - - err = snd_pcm_poll_descriptors_count(handle); - if (err <= 0) { - ERRORA("Unable to get a poll descriptors count, error is %s\n", CELLIAX_P_LOG, - snd_strerror(err)); - return NULL; - } - - if (err != 1) { //number of poll descriptors - DEBUGA_SOUND("Can't handle more than one device\n", CELLIAX_P_LOG); - return NULL; - } - - err = snd_pcm_poll_descriptors(handle, &p->pfd, err); - if (err != 1) { - ERRORA("snd_pcm_poll_descriptors failed, %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - DEBUGA_SOUND("Acquired fd %d from the poll descriptor\n", CELLIAX_P_LOG, p->pfd.fd); - - if (stream == SND_PCM_STREAM_CAPTURE) { - p->celliax_sound_capt_fd = p->pfd.fd; - } - - state = snd_pcm_state(handle); - - if (state != SND_PCM_STATE_RUNNING) { - if (state != SND_PCM_STATE_PREPARED) { - err = snd_pcm_prepare(handle); - if (err) { - ERRORA("snd_pcm_prepare failed, %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - DEBUGA_SOUND("prepared!\n", CELLIAX_P_LOG); - } - if (stream == SND_PCM_STREAM_CAPTURE) { - err = snd_pcm_start(handle); - if (err) { - ERRORA("snd_pcm_start failed, %s\n", CELLIAX_P_LOG, snd_strerror(err)); - return NULL; - } - DEBUGA_SOUND("started!\n", CELLIAX_P_LOG); - } - } - if (option_debug > 1) { - snd_output_t *output = NULL; - err = snd_output_stdio_attach(&output, stdout, 0); - if (err < 0) { - ERRORA("snd_output_stdio_attach failed: %s\n", CELLIAX_P_LOG, snd_strerror(err)); - } - snd_pcm_dump(handle, output); - } - if (option_debug > 1) - DEBUGA_SOUND("ALSA handle = %ld\n", CELLIAX_P_LOG, (long int) handle); - return handle; - -} - -/*! \brief Read audio frames from interface */ - -struct ast_frame *alsa_read(struct celliax_pvt *p) -{ - static struct ast_frame f; - static short __buf[CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - static short __buf2[(CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2]; - short *buf; - short *buf2; - static int readpos = 0; - static int left = CELLIAX_FRAME_SIZE; - snd_pcm_state_t state; - int r = 0; - int off = 0; - int error = 0; - //time_t now_timestamp; - - //memset(&f, 0, sizeof(struct ast_frame)); //giova - - f.frametype = AST_FRAME_NULL; - f.subclass = 0; - f.samples = 0; - f.datalen = 0; - f.data = NULL; - f.offset = 0; - f.src = celliax_type; - f.mallocd = 0; - f.delivery.tv_sec = 0; - f.delivery.tv_usec = 0; - - state = snd_pcm_state(p->alsac); - if (state != SND_PCM_STATE_RUNNING) { - DEBUGA_SOUND("ALSA read state is not SND_PCM_STATE_RUNNING\n", CELLIAX_P_LOG); - - if (state != SND_PCM_STATE_PREPARED) { - error = snd_pcm_prepare(p->alsac); - if (error) { - ERRORA("snd_pcm_prepare failed, %s\n", CELLIAX_P_LOG, snd_strerror(error)); - return &f; - } - DEBUGA_SOUND("prepared!\n", CELLIAX_P_LOG); - } - usleep(1000); - error = snd_pcm_start(p->alsac); - if (error) { - ERRORA("snd_pcm_start failed, %s\n", CELLIAX_P_LOG, snd_strerror(error)); - return &f; - } - DEBUGA_SOUND("started!\n", CELLIAX_P_LOG); - usleep(1000); - } - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - buf2 = __buf2 + ((AST_FRIENDLY_OFFSET / 2) * 2); - - if (p->alsa_capture_is_mono) { - r = snd_pcm_readi(p->alsac, buf + readpos, left); - } else { - r = snd_pcm_readi(p->alsac, buf2 + (readpos * 2), left); - - int a = 0; - int i = 0; - for (i = 0; i < (CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2;) { - __buf[a] = (__buf2[i] + __buf2[i + 1]) / 2; //comment out this line to use only left - //__buf[a] = __buf2[i]; // enable this line to use only left - a++; - i++; - i++; - } - } - - if (r == -EPIPE) { - ERRORA("XRUN read\n\n\n\n\n", CELLIAX_P_LOG); - return &f; - } else if (r == -ESTRPIPE) { - ERRORA("-ESTRPIPE\n", CELLIAX_P_LOG); - return &f; - - } else if (r == -EAGAIN) { - DEBUGA_SOUND("ALSA read -EAGAIN, the soundcard is not ready to be read by celliax\n", - CELLIAX_P_LOG); - while (r == -EAGAIN) { - usleep(1000); - - if (p->alsa_capture_is_mono) { - r = snd_pcm_readi(p->alsac, buf + readpos, left); - } else { - r = snd_pcm_readi(p->alsac, buf2 + (readpos * 2), left); - - int a = 0; - int i = 0; - for (i = 0; i < (CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2;) { - __buf[a] = (__buf2[i] + __buf2[i + 1]) / 2; - a++; - i++; - i++; - } - } - - } - } else if (r < 0) { - WARNINGA("ALSA Read error: %s\n", CELLIAX_P_LOG, snd_strerror(r)); - } else if (r >= 0) { - //DEBUGA_SOUND("read: r=%d, readpos=%d, left=%d, off=%d\n", CELLIAX_P_LOG, r, readpos, left, off); - off -= r; //what is the meaning of this? a leftover, probably - } - /* Update positions */ - readpos += r; - left -= r; - - if (readpos >= CELLIAX_FRAME_SIZE) { - /* A real frame */ - readpos = 0; - left = CELLIAX_FRAME_SIZE; - - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = CELLIAX_FRAME_SIZE; - f.datalen = CELLIAX_FRAME_SIZE * 2; - f.data = buf; - f.offset = AST_FRIENDLY_OFFSET; - f.src = celliax_type; - f.mallocd = 0; -#ifdef ALSA_MONITOR - alsa_monitor_read((char *) buf, CELLIAX_FRAME_SIZE * 2); -#endif - - } - return &f; -} - -/*! \brief Write audio frames to interface */ -int alsa_write(struct celliax_pvt *p, struct ast_frame *f) -{ - static char sizbuf[8000]; - static char sizbuf2[16000]; - static char silencebuf[8000]; - static int sizpos = 0; - int len = sizpos; - int pos; - int res = 0; - time_t now_timestamp; - /* size_t frames = 0; */ - snd_pcm_state_t state; - snd_pcm_sframes_t delayp1; - snd_pcm_sframes_t delayp2; - - /* We have to digest the frame in 160-byte portions */ - if (f->datalen > sizeof(sizbuf) - sizpos) { - ERRORA("Frame too large\n", CELLIAX_P_LOG); - res = -1; - } else { - memcpy(sizbuf + sizpos, f->data, f->datalen); - len += f->datalen; - pos = 0; -#ifdef ALSA_MONITOR - alsa_monitor_write(sizbuf, len); -#endif - state = snd_pcm_state(p->alsap); - if (state == SND_PCM_STATE_XRUN) { - int i; - - DEBUGA_SOUND - ("You've got an ALSA write XRUN in the past (celliax can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file\n", - CELLIAX_P_LOG, p->alsa_periods_in_buffer); - res = snd_pcm_prepare(p->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", CELLIAX_P_LOG, snd_strerror(res)); - } else { - res = snd_pcm_format_set_silence(celliax_format, silencebuf, len / 2); - if (res < 0) { - DEBUGA_SOUND("Silence error %s\n", CELLIAX_P_LOG, snd_strerror(res)); - res = -1; - } - for (i = 0; i < (p->alsa_periods_in_buffer - 1); i++) { - res = snd_pcm_writei(p->alsap, silencebuf, len / 2); - if (res != len / 2) { - DEBUGA_SOUND("Write returned a different quantity: %d\n", CELLIAX_P_LOG, res); - res = -1; - } else if (res < 0) { - DEBUGA_SOUND("Write error %s\n", CELLIAX_P_LOG, snd_strerror(res)); - res = -1; - } - } - } - - } - - res = snd_pcm_delay(p->alsap, &delayp1); - if (res < 0) { - DEBUGA_SOUND("Error %d on snd_pcm_delay: \"%s\"\n", CELLIAX_P_LOG, res, - snd_strerror(res)); - res = snd_pcm_prepare(p->alsap); - if (res) { - DEBUGA_SOUND("snd_pcm_prepare failed: '%s'\n", CELLIAX_P_LOG, snd_strerror(res)); - } - res = snd_pcm_delay(p->alsap, &delayp1); - } - - delayp2 = snd_pcm_avail_update(p->alsap); - if (delayp2 < 0) { - DEBUGA_SOUND("Error %d on snd_pcm_avail_update: \"%s\"\n", CELLIAX_P_LOG, - (int) delayp2, snd_strerror(delayp2)); - - res = snd_pcm_prepare(p->alsap); - if (res) { - DEBUGA_SOUND("snd_pcm_prepare failed: '%s'\n", CELLIAX_P_LOG, snd_strerror(res)); - } - delayp2 = snd_pcm_avail_update(p->alsap); - } - - if ( /* delayp1 != 0 && delayp1 != 160 */ - delayp1 < 160 || delayp2 > p->alsa_buffer_size) { - - res = snd_pcm_prepare(p->alsap); - if (res) { - DEBUGA_SOUND - ("snd_pcm_prepare failed while trying to prevent an ALSA write XRUN: %s, delayp1=%d, delayp2=%d\n", - CELLIAX_P_LOG, snd_strerror(res), (int) delayp1, (int) delayp2); - } else { - - int i; - for (i = 0; i < (p->alsa_periods_in_buffer - 1); i++) { - res = snd_pcm_format_set_silence(celliax_format, silencebuf, len / 2); - if (res < 0) { - DEBUGA_SOUND("Silence error %s\n", CELLIAX_P_LOG, snd_strerror(res)); - res = -1; - } - res = snd_pcm_writei(p->alsap, silencebuf, len / 2); - if (res < 0) { - DEBUGA_SOUND("Write error %s\n", CELLIAX_P_LOG, snd_strerror(res)); - res = -1; - } else if (res != len / 2) { - DEBUGA_SOUND("Write returned a different quantity: %d\n", CELLIAX_P_LOG, res); - res = -1; - } - } - - DEBUGA_SOUND - ("PREVENTING an ALSA write XRUN (celliax can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file. delayp1=%d, delayp2=%d\n", - CELLIAX_P_LOG, p->alsa_periods_in_buffer, (int) delayp1, (int) delayp2); - } - - } - - memset(sizbuf2, 0, sizeof(sizbuf2)); - if (p->alsa_play_is_mono) { - res = snd_pcm_writei(p->alsap, sizbuf, len / 2); - } else { - int a = 0; - int i = 0; - for (i = 0; i < 8000;) { - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i--; - sizbuf2[a] = sizbuf[i]; // comment out this line to use only left - a++; - i++; - sizbuf2[a] = sizbuf[i]; // comment out this line to use only left - a++; - i++; - } - res = snd_pcm_writei(p->alsap, sizbuf2, len); - } - if (res == -EPIPE) { - DEBUGA_SOUND - ("ALSA write EPIPE (XRUN) (celliax can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file. delayp1=%d, delayp2=%d\n", - CELLIAX_P_LOG, p->alsa_periods_in_buffer, (int) delayp1, (int) delayp2); - res = snd_pcm_prepare(p->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", CELLIAX_P_LOG, snd_strerror(res)); - } else { - - if (p->alsa_play_is_mono) { - res = snd_pcm_writei(p->alsap, sizbuf, len / 2); - } else { - int a = 0; - int i = 0; - for (i = 0; i < 8000;) { - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i--; - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i++; - } - res = snd_pcm_writei(p->alsap, sizbuf2, len); - } - - } - - } else { - if (res == -ESTRPIPE) { - ERRORA("You've got some big problems\n", CELLIAX_P_LOG); - } else if (res == -EAGAIN) { - res = 0; - } else if (res < 0) { - ERRORA("Error %d on audio write: \"%s\"\n", CELLIAX_P_LOG, res, - snd_strerror(res)); - } - } - } - - if (p->audio_play_reset_period) { - time(&now_timestamp); - if ((now_timestamp - p->audio_play_reset_timestamp) > p->audio_play_reset_period) { - if (option_debug) - DEBUGA_SOUND("reset audio play\n", CELLIAX_P_LOG); - res = snd_pcm_wait(p->alsap, 1000); - if (res < 0) { - ERRORA("audio play wait failed: %s\n", CELLIAX_P_LOG, snd_strerror(res)); - } - res = snd_pcm_drop(p->alsap); - if (res) { - ERRORA("audio play drop failed: %s\n", CELLIAX_P_LOG, snd_strerror(res)); - } - res = snd_pcm_prepare(p->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", CELLIAX_P_LOG, snd_strerror(res)); - } - res = snd_pcm_wait(p->alsap, 1000); - if (res < 0) { - ERRORA("audio play wait failed: %s\n", CELLIAX_P_LOG, snd_strerror(res)); - } - time(&p->audio_play_reset_timestamp); - } - } - res = 0; - if (res > 0) - res = 0; - return res; -} - - -/*! \brief Write audio frames to interface */ -#endif /* CELLIAX_ALSA */ - -#ifdef CELLIAX_PORTAUDIO -int celliax_portaudio_devlist(struct celliax_pvt *p) -{ - int i, numDevices; - const PaDeviceInfo *deviceInfo; - - numDevices = Pa_GetDeviceCount(); - if (numDevices < 0) { - return 0; - } - for (i = 0; i < numDevices; i++) { - deviceInfo = Pa_GetDeviceInfo(i); - NOTICA - ("Found PORTAUDIO device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - CELLIAX_P_LOG, i, deviceInfo->name, deviceInfo->maxInputChannels, - deviceInfo->maxOutputChannels); - } - - return numDevices; -} - -int celliax_portaudio_init(struct celliax_pvt *p) -{ - PaError err; - int c; - PaStreamParameters inputParameters, outputParameters; - int numdevices; - const PaDeviceInfo *deviceInfo; - -#ifndef GIOVA48 - setenv("PA_ALSA_PLUGHW", "1", 1); -#endif // GIOVA48 - - err = Pa_Initialize(); - if (err != paNoError) - return err; - - numdevices = celliax_portaudio_devlist(p); - - if (p->portaudiocindex > (numdevices - 1)) { - ERRORA("Portaudio Capture id=%d is out of range: valid id are from 0 to %d\n", - CELLIAX_P_LOG, p->portaudiocindex, (numdevices - 1)); - return -1; - } - - if (p->portaudiopindex > (numdevices - 1)) { - ERRORA("Portaudio Playback id=%d is out of range: valid id are from 0 to %d\n", - CELLIAX_P_LOG, p->portaudiopindex, (numdevices - 1)); - return -1; - } - //inputParameters.device = 0; - if (p->portaudiocindex != -1) { - inputParameters.device = p->portaudiocindex; - } else { - inputParameters.device = Pa_GetDefaultInputDevice(); - } - deviceInfo = Pa_GetDeviceInfo(inputParameters.device); - NOTICA - ("Using INPUT PORTAUDIO device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - CELLIAX_P_LOG, inputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - if (deviceInfo->maxInputChannels == 0) { - ERRORA - ("No INPUT channels on device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - CELLIAX_P_LOG, inputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - return -1; - } - inputParameters.channelCount = 1; - inputParameters.sampleFormat = paInt16; - //inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultHighInputLatency; - inputParameters.suggestedLatency = 0.1; - inputParameters.hostApiSpecificStreamInfo = NULL; - - //outputParameters.device = 3; - if (p->portaudiopindex != -1) { - outputParameters.device = p->portaudiopindex; - } else { - outputParameters.device = Pa_GetDefaultOutputDevice(); - } - deviceInfo = Pa_GetDeviceInfo(outputParameters.device); - NOTICA - ("Using OUTPUT PORTAUDIO device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - CELLIAX_P_LOG, outputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - if (deviceInfo->maxOutputChannels == 0) { - ERRORA - ("No OUTPUT channels on device: id=%d\tname=%s\tmax input channels=%d\tmax output channels=%d\n", - CELLIAX_P_LOG, inputParameters.device, deviceInfo->name, - deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - return -1; - } -#ifndef GIOVA48 - outputParameters.channelCount = 1; -#else // GIOVA48 - outputParameters.channelCount = 2; -#endif // GIOVA48 - outputParameters.sampleFormat = paInt16; - //outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultHighOutputLatency; - outputParameters.suggestedLatency = 0.1; - outputParameters.hostApiSpecificStreamInfo = NULL; - -/* build the pipe that will be polled on by pbx */ - c = pipe(p->audiopipe); - if (c) { - ERRORA("Unable to create audio pipe\n", CELLIAX_P_LOG); - return -1; - } - fcntl(p->audiopipe[0], F_SETFL, O_NONBLOCK); - fcntl(p->audiopipe[1], F_SETFL, O_NONBLOCK); - - err = -#ifndef GIOVA48 - OpenAudioStream(&p->stream, &inputParameters, &outputParameters, 8000, - paDitherOff | paClipOff, SAMPLES_PER_FRAME, p->audiopipe[1], - &p->speexecho, &p->speexpreprocess, &p->owner); - -#else // GIOVA48 - OpenAudioStream(&p->stream, &inputParameters, &outputParameters, 48000, - paDitherOff | paClipOff, SAMPLES_PER_FRAME, p->audiopipe[1], - &p->speexecho, &p->speexpreprocess, &p->owner); - -#endif // GIOVA48 - if (err != paNoError) { - ERRORA("Unable to open audio stream: %s\n", CELLIAX_P_LOG, Pa_GetErrorText(err)); - return -1; - } - -/* the pipe is our audio fd for pbx to poll on */ - p->celliax_sound_capt_fd = p->audiopipe[0]; - - return 0; -} - -int celliax_portaudio_write(struct celliax_pvt *p, struct ast_frame *f) -{ - int samples; -#ifdef GIOVA48 - //short buf[CELLIAX_FRAME_SIZE * 2]; - short buf[3840]; - short *buf2; - - //ERRORA("1 f->datalen=: %d\n", CELLIAX_P_LOG, f->datalen); - - memset(buf, '\0', CELLIAX_FRAME_SIZE * 2); - - buf2 = f->data; - - int i = 0, a = 0; - - for (i = 0; i < f->datalen / sizeof(short); i++) { -//stereo, 2 chan 48 -> mono 8 - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - buf[a] = buf2[i]; - a++; - /* - */ - } - f->data = &buf; - f->datalen = f->datalen * 6; - //ERRORA("2 f->datalen=: %d\n", CELLIAX_P_LOG, f->datalen); - //f->datalen = f->datalen; -#endif // GIOVA48 - -#ifdef ASTERISK_VERSION_1_6_0_1 - samples = - WriteAudioStream(p->stream, (short *) f->data.ptr, - (int) (f->datalen / sizeof(short))); -#else - samples = - WriteAudioStream(p->stream, (short *) f->data, (int) (f->datalen / sizeof(short))); -#endif /* ASTERISK_VERSION_1_6_0_1 */ - - if (samples != (int) (f->datalen / sizeof(short))) - ERRORA("WriteAudioStream wrote: %d of %d\n", CELLIAX_P_LOG, samples, - (int) (f->datalen / sizeof(short))); - - return 0; -} - -struct ast_frame *celliax_portaudio_read(struct celliax_pvt *p) -{ - static struct ast_frame f; - static short __buf[CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - short *buf; - static short __buf2[CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - short *buf2; - int samples; - char c; - - memset(__buf, '\0', (CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2)); - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - - memset(__buf2, '\0', (CELLIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2)); - - buf2 = __buf2 + AST_FRIENDLY_OFFSET / 2; - - f.frametype = AST_FRAME_NULL; - f.subclass = 0; - f.samples = 0; - f.datalen = 0; - -#ifdef ASTERISK_VERSION_1_6_0_1 - f.data.ptr = NULL; -#else - f.data = NULL; -#endif /* ASTERISK_VERSION_1_6_0_1 */ - f.offset = 0; - f.src = celliax_type; - f.mallocd = 0; - f.delivery.tv_sec = 0; - f.delivery.tv_usec = 0; - - if ((samples = ReadAudioStream(p->stream, buf, SAMPLES_PER_FRAME)) == 0) { - //do nothing - } else { -#ifdef GIOVA48 - int i = 0, a = 0; - - samples = samples / 6; - for (i = 0; i < samples; i++) { - buf2[i] = buf[a]; - a = a + 6; //mono, 1 chan 48 -> 8 - } - buf = buf2; - - /* A real frame */ - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = CELLIAX_FRAME_SIZE / 6; - f.datalen = CELLIAX_FRAME_SIZE * 2 / 6; -#else // GIOVA48 - /* A real frame */ - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = CELLIAX_FRAME_SIZE; - f.datalen = CELLIAX_FRAME_SIZE * 2; -#endif // GIOVA48 - -#ifdef ASTERISK_VERSION_1_6_0_1 - f.data.ptr = buf; -#else - f.data = buf; -#endif /* ASTERISK_VERSION_1_6_0_1 */ - f.offset = AST_FRIENDLY_OFFSET; - f.src = celliax_type; - f.mallocd = 0; - } - - read(p->audiopipe[0], &c, 1); - - return &f; -} - -int celliax_portaudio_shutdown(struct celliax_pvt *p) -{ - PaError err; - - err = CloseAudioStream(p->stream); - - if (err != paNoError) - ERRORA("not able to CloseAudioStream\n", CELLIAX_P_LOG); - - Pa_Terminate(); - return 0; -} -#endif // CELLIAX_PORTAUDIO - -int celliax_serial_sync_AT(struct celliax_pvt *p) -{ - usleep(10000); /* 10msec */ - time(&p->celliax_serial_synced_timestamp); - return 0; -} - -int celliax_serial_getstatus_AT(struct celliax_pvt *p) -{ - int res; - - if (p->owner) { - if (p->owner->_state != AST_STATE_UP && p->owner->_state != AST_STATE_DOWN) { - DEBUGA_AT("No getstatus, we're neither UP nor DOWN\n", CELLIAX_P_LOG); - return 0; - } - } - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - res = celliax_serial_write_AT_ack(p, "AT"); - if (res) { - ERRORA("AT was not acknowledged, continuing but maybe there is a problem\n", - CELLIAX_P_LOG); - } - usleep(1000); - - if (strlen(p->at_query_battchg)) { - res = - celliax_serial_write_AT_expect(p, p->at_query_battchg, p->at_query_battchg_expect); - if (res) { - WARNINGA("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_query_battchg, p->at_query_battchg_expect); - } - usleep(1000); - } - - if (strlen(p->at_query_signal)) { - res = - celliax_serial_write_AT_expect(p, p->at_query_signal, p->at_query_signal_expect); - if (res) { - WARNINGA("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_query_signal, p->at_query_signal_expect); - } - usleep(1000); - } - //FIXME all the following commands in config! - - if (p->sms_cnmi_not_supported) { - res = celliax_serial_write_AT_ack(p, "AT+MMGL=\"HEADER ONLY\""); - if (res) { - WARNINGA - ("%s does not get %s from the modem, maybe a long msg is incoming. If this cellmodem is not a Motorola, you are arriving here because your cellmodem do not supports CNMI kind of incoming SMS alert; please let it know to the developers of Celliax. If this cellmodem is a Motorola and this message keeps repeating, and you cannot correctly receive SMSs from this interface, please manually clean all messages from the cellmodem/SIM. Continuing.\n", - CELLIAX_P_LOG, "AT+MMGL=\"HEADER ONLY\"", "OK"); - } else { - usleep(1000); - if (p->unread_sms_msg_id) { - char at_command[256]; - - if (p->no_ucs2 == 0) { - res = celliax_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\""); - if (res) { - ERRORA - ("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone\n", - CELLIAX_P_LOG); - memset(p->sms_message, 0, sizeof(p->sms_message)); - } - } - - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGR=%d", p->unread_sms_msg_id); - memset(p->sms_message, 0, sizeof(p->sms_message)); - - p->reading_sms_msg = 1; - res = celliax_serial_write_AT_ack(p, at_command); - p->reading_sms_msg = 0; - if (res) { - ERRORA - ("AT+CMGR (read SMS) do not got OK from the phone, message sent was:|||%s|||\n", - CELLIAX_P_LOG, at_command); - } - res = celliax_serial_write_AT_ack(p, "AT+CSCS=\"GSM\""); - if (res) { - ERRORA - ("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", - CELLIAX_P_LOG); - } - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGD=%d", p->unread_sms_msg_id); /* delete the message */ - p->unread_sms_msg_id = 0; - res = celliax_serial_write_AT_ack(p, at_command); - if (res) { - ERRORA - ("AT+CMGD (Delete SMS) do not got OK from the phone, message sent was:|||%s|||\n", - CELLIAX_P_LOG, at_command); - } - - if (strlen(p->sms_message)) { - - manager_event(EVENT_FLAG_SYSTEM, "CELLIAXincomingsms", - "Interface: %s\r\nSMS_Message: %s\r\n", p->name, p->sms_message); - - if (strlen(p->sms_receiving_program)) { - int fd1[2]; - pid_t pid1; - char *arg1[] = { p->sms_receiving_program, (char *) NULL }; - int i; - - NOTICA("incoming SMS message:>>>%s<<<\n", CELLIAX_P_LOG, p->sms_message); - pipe(fd1); - pid1 = switch_fork(); - - if (pid1 == 0) { //child - int err; - - dup2(fd1[0], 0); // Connect stdin to pipe output - close(fd1[1]); // close input pipe side - setsid(); //session id - err = execvp(arg1[0], arg1); //exec our program, with stdin connected to pipe output - if (err) { - ERRORA - ("'sms_receiving_program' is set in config file to '%s', and it gave us back this error: %d, (%s). SMS received was:---%s---\n", - CELLIAX_P_LOG, p->sms_receiving_program, err, strerror(errno), - p->sms_message); - } - close(fd1[0]); // close output pipe side - } //starting here continue the parent - close(fd1[0]); // close output pipe side - // write the msg on the pipe input - for (i = 0; i < strlen(p->sms_message); i++) { - write(fd1[1], &p->sms_message[i], 1); - } - close(fd1[1]); // close pipe input, let our program know we've finished - } else { - ERRORA - ("got SMS incoming message, but 'sms_receiving_program' is not set in config file. SMS received was:---%s---\n", - CELLIAX_P_LOG, p->sms_message); - } - } -#if 1 //is this one needed? maybe it can interrupt an incoming call that is just to announce itself - if (p->phone_callflow == CALLFLOW_CALL_IDLE - && p->interface_state == AST_STATE_DOWN && p->owner == NULL) { - /* we're not in a call, neither calling */ - res = celliax_serial_write_AT_ack(p, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA - ("AT+CKPD=\"EEE\" (cellphone screen back to user) do not got OK from the phone\n", - CELLIAX_P_LOG); - } - } -#endif - } - } - } - - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - return 0; -} - -int celliax_serial_read_AT(struct celliax_pvt *p, int look_for_ack, int timeout_usec, - int timeout_sec, const char *expected_string, int expect_crlf) -{ - int select_err; - int res; - fd_set read_fds; - struct timeval timeout; - char tmp_answer[AT_BUFSIZ]; - char tmp_answer2[AT_BUFSIZ]; - char *tmp_answer_ptr; - char *last_line_ptr; - int i = 0; - int read_count = 0; - int la_counter = 0; - int at_ack = -1; - int la_read = 0; - - FD_ZERO(&read_fds); - FD_SET(p->controldevfd, &read_fds); - - //NOTICA (" INSIDE this celliax_serial_device %s \n", CELLIAX_P_LOG, p->controldevice_name); - tmp_answer_ptr = tmp_answer; - memset(tmp_answer, 0, sizeof(char) * AT_BUFSIZ); - - timeout.tv_sec = timeout_sec; - timeout.tv_usec = timeout_usec; - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - - while ((select_err = select(p->controldevfd + 1, &read_fds, NULL, NULL, &timeout)) > 0) { - timeout.tv_sec = timeout_sec; //reset the timeout, linux modify it - timeout.tv_usec = timeout_usec; //reset the timeout, linux modify it - read_count = - read(p->controldevfd, tmp_answer_ptr, AT_BUFSIZ - (tmp_answer_ptr - tmp_answer)); - - if (read_count == 0) { - ERRORA - ("read 0 bytes!!! Nenormalno! Marking this celliax_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - CELLIAX_P_LOG, p->controldevice_name); - p->controldev_dead = 1; - close(p->controldevfd); - UNLOCKA(&p->controldev_lock); - if (p->owner) { - p->owner->hangupcause = AST_CAUSE_FAILURE; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - return -1; - } - - if (option_debug > 90) { - //DEBUGA_AT("1 read %d bytes, --|%s|--\n", CELLIAX_P_LOG, read_count, tmp_answer_ptr); - //DEBUGA_AT("2 read %d bytes, --|%s|--\n", CELLIAX_P_LOG, read_count, tmp_answer); - } - tmp_answer_ptr = tmp_answer_ptr + read_count; - - char *token_ptr; - - la_counter = 0; - memset(tmp_answer2, 0, sizeof(char) * AT_BUFSIZ); - strcpy(tmp_answer2, tmp_answer); - if ((token_ptr = strtok(tmp_answer2, "\n\r"))) { - last_line_ptr = token_ptr; - strncpy(p->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH); - if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) { - WARNINGA - ("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n", - CELLIAX_P_LOG, token_ptr, p->line_array.result[la_counter]); - } - la_counter++; - while ((token_ptr = strtok(NULL, "\n\r"))) { - last_line_ptr = token_ptr; - strncpy(p->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH); - if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) { - WARNINGA - ("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n", - CELLIAX_P_LOG, token_ptr, p->line_array.result[la_counter]); - } - la_counter++; - } - } else { - last_line_ptr = tmp_answer; - } - - if (expected_string && !expect_crlf) { - DEBUGA_AT - ("last_line_ptr=|%s|, expected_string=|%s|, expect_crlf=%d, memcmp(last_line_ptr, expected_string, strlen(expected_string)) = %d\n", - CELLIAX_P_LOG, last_line_ptr, expected_string, expect_crlf, memcmp(last_line_ptr, - expected_string, - strlen - (expected_string))); - } - - if (expected_string && !expect_crlf - && !memcmp(last_line_ptr, expected_string, strlen(expected_string)) - ) { - strncpy(p->line_array.result[la_counter], last_line_ptr, AT_MESG_MAX_LENGTH); - // match expected string -> accept it withtout CRLF - la_counter++; - - } - /* if the last line read was not a complete line, we'll read the rest in the future */ - else if (tmp_answer[strlen(tmp_answer) - 1] != '\r' - && tmp_answer[strlen(tmp_answer) - 1] != '\n') - la_counter--; - - /* let's list the complete lines read so far, without re-listing the lines that has yet been listed */ - if (option_debug > 1) { - for (i = la_read; i < la_counter; i++) - DEBUGA_AT("Read line %d: |%s|\n", CELLIAX_P_LOG, i, p->line_array.result[i]); - } - - /* let's interpret the complete lines read so far (WITHOUT looking for OK, ERROR, and EXPECTED_STRING), without re-interpreting the lines that has been yet interpreted, so we're sure we don't miss anything */ - for (i = la_read; i < la_counter; i++) { - - if ((strcmp(p->line_array.result[i], "RING") == 0)) { - /* with first RING we wait for callid */ - gettimeofday(&(p->ringtime), NULL); - /* give CALLID (+CLIP) a chance, wait for the next RING before answering */ - if (p->phone_callflow == CALLFLOW_INCOMING_RING) { - /* we're at the second ring, set the interface state, will be answered by celliax_do_monitor */ - DEBUGA_AT("|%s| got second RING\n", CELLIAX_P_LOG, p->line_array.result[i]); - p->interface_state = AST_STATE_RING; - } else { - /* we're at the first ring, so there is no CALLID yet thus clean the previous one - just in case we don't receive the caller identification in this new call */ - memset(p->callid_name, 0, sizeof(p->callid_name)); - memset(p->callid_number, 0, sizeof(p->callid_number)); - /* only send AT+CLCC? if the device previously reported its support */ - if (p->at_has_clcc != 0) { - /* we're at the first ring, try to get CALLID (with +CLCC) */ - DEBUGA_AT("|%s| got first RING, sending AT+CLCC?\n", CELLIAX_P_LOG, - p->line_array.result[i]); - res = celliax_serial_write_AT_noack(p, "AT+CLCC?"); - if (res) { - ERRORA("AT+CLCC? (call list) was not correctly sent to the phone\n", - CELLIAX_P_LOG); - } - } else { - DEBUGA_AT("|%s| got first RING, but not sending AT+CLCC? as this device " - "seems not to support\n", CELLIAX_P_LOG, p->line_array.result[i]); - } - } - p->phone_callflow = CALLFLOW_INCOMING_RING; - } - - if ((strncmp(p->line_array.result[i], "+CLCC", 5) == 0)) { - /* with clcc we wait for clip */ - memset(p->callid_name, 0, sizeof(p->callid_name)); - memset(p->callid_number, 0, sizeof(p->callid_number)); - int commacount = 0; - int a = 0; - int b = 0; - int c = 0; - - for (a = 0; a < strlen(p->line_array.result[i]); a++) { - - if (p->line_array.result[i][a] == ',') { - commacount++; - } - if (commacount == 5) { - if (p->line_array.result[i][a] != ',' && p->line_array.result[i][a] != '"') { - p->callid_number[b] = p->line_array.result[i][a]; - b++; - } - } - if (commacount == 7) { - if (p->line_array.result[i][a] != ',' && p->line_array.result[i][a] != '"') { - p->callid_name[c] = p->line_array.result[i][a]; - c++; - } - } - } - - p->phone_callflow = CALLFLOW_INCOMING_RING; - DEBUGA_AT("|%s| CLCC CALLID: name is %s, number is %s\n", CELLIAX_P_LOG, - p->line_array.result[i], - p->callid_name[0] ? p->callid_name : "not available", - p->callid_number[0] ? p->callid_number : "not available"); - } - - if ((strncmp(p->line_array.result[i], "+CLIP", 5) == 0)) { - /* with CLIP, we want to answer right away */ - memset(p->callid_name, 0, sizeof(p->callid_name)); - memset(p->callid_number, 0, sizeof(p->callid_number)); - - int commacount = 0; - int a = 0; - int b = 0; - int c = 0; - - for (a = 7; a < strlen(p->line_array.result[i]); a++) { - if (p->line_array.result[i][a] == ',') { - commacount++; - } - if (commacount == 0) { - if (p->line_array.result[i][a] != ',' && p->line_array.result[i][a] != '"') { - p->callid_number[b] = p->line_array.result[i][a]; - b++; - } - } - if (commacount == 4) { - if (p->line_array.result[i][a] != ',' && p->line_array.result[i][a] != '"') { - p->callid_name[c] = p->line_array.result[i][a]; - c++; - } - } - } - - if (p->interface_state != AST_STATE_RING) { - gettimeofday(&(p->call_incoming_time), NULL); - DEBUGA_AT("AST_STATE_RING call_incoming_time.tv_sec=%ld\n", - CELLIAX_P_LOG, p->call_incoming_time.tv_sec); - - } - - p->interface_state = AST_STATE_RING; - p->phone_callflow = CALLFLOW_INCOMING_RING; - DEBUGA_AT("|%s| CLIP INCOMING CALLID: name is %s, number is %s\n", CELLIAX_P_LOG, - p->line_array.result[i], - p->callid_name[0] != 1 ? p->callid_name : "not available", - p->callid_number[0] ? p->callid_number : "not available"); - } - - if ((strcmp(p->line_array.result[i], "BUSY") == 0)) { - p->phone_callflow = CALLFLOW_CALL_LINEBUSY; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_LINEBUSY\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - ast_setstate(p->owner, AST_STATE_BUSY); - celliax_queue_control(p->owner, AST_CONTROL_BUSY); - } else { - ERRORA("Why BUSY now?\n", CELLIAX_P_LOG); - } - } - if ((strcmp(p->line_array.result[i], "NO ANSWER") == 0)) { - p->phone_callflow = CALLFLOW_CALL_NOANSWER; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_NOANSWER\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - p->owner->hangupcause = AST_CAUSE_NO_ANSWER; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } else { - ERRORA("Why NO ANSWER now?\n", CELLIAX_P_LOG); - } - } - if ((strcmp(p->line_array.result[i], "NO CARRIER") == 0)) { - if (p->phone_callflow != CALLFLOW_CALL_HANGUP_REQUESTED) { - p->phone_callflow = CALLFLOW_CALL_NOCARRIER; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_NOCARRIER\n", CELLIAX_P_LOG, - p->line_array.result[i]); - p->control_to_send = 0; - usleep(20000); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - p->owner->hangupcause = AST_CAUSE_FAILURE; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } else { - ERRORA("Why NO CARRIER now?\n", CELLIAX_P_LOG); - } - } - } - - if ((strncmp(p->line_array.result[i], "+CBC:", 5) == 0)) { - int power_supply, battery_strenght, err; - - power_supply = battery_strenght = 0; - - err = - sscanf(&p->line_array.result[i][6], "%d,%d", &power_supply, &battery_strenght); - if (err < 2) { - DEBUGA_AT("|%s| is not formatted as: |+CBC: xx,yy| now trying |+CBC:xx,yy|\n", - CELLIAX_P_LOG, p->line_array.result[i]); - - err = - sscanf(&p->line_array.result[i][5], "%d,%d", &power_supply, - &battery_strenght); - DEBUGA_AT("|%s| +CBC: Powered by %s, battery strenght=%d\n", CELLIAX_P_LOG, - p->line_array.result[i], power_supply ? "power supply" : "battery", - battery_strenght); - - } - - if (err < 2) { - DEBUGA_AT("|%s| is not formatted as: |+CBC:xx,yy| giving up\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - else { - if (option_debug > 1) - DEBUGA_AT("|%s| +CBC: Powered by %s, battery strenght=%d\n", CELLIAX_P_LOG, - p->line_array.result[i], power_supply ? "power supply" : "battery", - battery_strenght); - if (!power_supply) { - if (battery_strenght < 10) { - ERRORA("|%s| BATTERY ALMOST EXHAUSTED\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } else if (battery_strenght < 20) { - WARNINGA("|%s| BATTERY LOW\n", CELLIAX_P_LOG, p->line_array.result[i]); - - } - - } - } - - } - - if ((strncmp(p->line_array.result[i], "+CSQ:", 5) == 0)) { - int signal_quality, ber, err; - - signal_quality = ber = 0; - - err = sscanf(&p->line_array.result[i][6], "%d,%d", &signal_quality, &ber); - if (option_debug > 1) - DEBUGA_AT("|%s| +CSQ: Signal Quality: %d, Error Rate=%d\n", CELLIAX_P_LOG, - p->line_array.result[i], signal_quality, ber); - if (err < 2) { - ERRORA("|%s| is not formatted as: |+CSQ: xx,yy|\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } else { - if (signal_quality < 11 || signal_quality == 99) { - WARNINGA - ("|%s| CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or additional antenna\n", - CELLIAX_P_LOG, p->line_array.result[i]); - } else if (signal_quality < 15) { - WARNINGA("|%s| CELLPHONE GETS SIGNAL LOW\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - } - - } - - } - if ((strncmp(p->line_array.result[i], "+CMGW:", 6) == 0)) { - int err; - - err = sscanf(&p->line_array.result[i][7], "%s", p->at_cmgw); - DEBUGA_AT("|%s| +CMGW: %s\n", CELLIAX_P_LOG, p->line_array.result[i], p->at_cmgw); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+CMGW: xxxx|\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - } - - /* at_call_* are unsolicited messages sent by the modem to signal us about call processing activity and events */ - if ((strcmp(p->line_array.result[i], p->at_call_idle) == 0)) { - p->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_IDLE\n", CELLIAX_P_LOG, p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - DEBUGA_AT("just received a remote HANGUP\n", CELLIAX_P_LOG); - p->owner->hangupcause = AST_CAUSE_NORMAL; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - DEBUGA_AT("just sent AST_CONTROL_HANGUP\n", CELLIAX_P_LOG); - } - } - - if ((strcmp(p->line_array.result[i], p->at_call_incoming) == 0)) { - - //char list_command[64]; - - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_INCOMING\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - if (p->phone_callflow != CALLFLOW_CALL_INCOMING - && p->phone_callflow != CALLFLOW_INCOMING_RING) { - //mark the time of CALLFLOW_CALL_INCOMING - gettimeofday(&(p->call_incoming_time), NULL); - p->phone_callflow = CALLFLOW_CALL_INCOMING; - DEBUGA_AT("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld\n", - CELLIAX_P_LOG, p->call_incoming_time.tv_sec); - - } - } - - if ((strcmp(p->line_array.result[i], p->at_call_active) == 0)) { - p->phone_callflow = CALLFLOW_CALL_ACTIVE; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_ACTIVE\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - if (p->owner && p->interface_state == CALLFLOW_CALL_DIALING) { - DEBUGA_PBX("just received a remote ANSWER\n", CELLIAX_P_LOG); - if (p->owner->_state != AST_STATE_UP) { - celliax_queue_control(p->owner, AST_CONTROL_RINGING); - DEBUGA_PBX("just sent AST_CONTROL_RINGING\n", CELLIAX_P_LOG); - DEBUGA_PBX("going to send AST_CONTROL_ANSWER\n", CELLIAX_P_LOG); - celliax_queue_control(p->owner, AST_CONTROL_ANSWER); - DEBUGA_PBX("just sent AST_CONTROL_ANSWER\n", CELLIAX_P_LOG); - } - } else { - } - p->interface_state = AST_STATE_UP; - DEBUGA_PBX("just interface_state UP\n", CELLIAX_P_LOG); - } - - if ((strcmp(p->line_array.result[i], p->at_call_calling) == 0)) { - p->phone_callflow = CALLFLOW_CALL_DIALING; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_DIALING\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - if ((strcmp(p->line_array.result[i], p->at_call_failed) == 0)) { - p->phone_callflow = CALLFLOW_CALL_FAILED; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_FAILED\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - p->owner->hangupcause = AST_CAUSE_FAILURE; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - } - - if ((strncmp(p->line_array.result[i], "+CSCA:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug > 1) - DEBUGA_AT("|%s| +CSCA: Message Center Address!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strncmp(p->line_array.result[i], "+CMGF:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug > 1) - DEBUGA_AT("|%s| +CMGF: Message Format!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strncmp(p->line_array.result[i], "+CMTI:", 6) == 0)) { //TODO SMS FIXME in config! - int err; - int pos; - - //FIXME all the following commands in config! - if (option_debug) - DEBUGA_AT("|%s| +CMTI: Incoming SMS!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - err = sscanf(&p->line_array.result[i][12], "%d", &pos); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+CMTI: \"MT\",xx|\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } else { - DEBUGA_AT("|%s| +CMTI: Incoming SMS in position: %d!\n", CELLIAX_P_LOG, - p->line_array.result[i], pos); - p->unread_sms_msg_id = pos; - usleep(1000); - - if (p->unread_sms_msg_id) { - char at_command[256]; - - if (p->no_ucs2 == 0) { - res = celliax_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\""); - if (res) { - ERRORA - ("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone, continuing\n", - CELLIAX_P_LOG); - //memset(p->sms_message, 0, sizeof(p->sms_message)); - } - } - - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGR=%d", p->unread_sms_msg_id); - memset(p->sms_message, 0, sizeof(p->sms_message)); - - p->reading_sms_msg = 1; - res = celliax_serial_write_AT_ack(p, at_command); - p->reading_sms_msg = 0; - if (res) { - ERRORA - ("AT+CMGR (read SMS) do not got OK from the phone, message sent was:|||%s|||\n", - CELLIAX_P_LOG, at_command); - } - res = celliax_serial_write_AT_ack(p, "AT+CSCS=\"GSM\""); - if (res) { - ERRORA - ("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", - CELLIAX_P_LOG); - } - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGD=%d", p->unread_sms_msg_id); /* delete the message */ - p->unread_sms_msg_id = 0; - res = celliax_serial_write_AT_ack(p, at_command); - if (res) { - ERRORA - ("AT+CMGD (Delete SMS) do not got OK from the phone, message sent was:|||%s|||\n", - CELLIAX_P_LOG, at_command); - } - - if (strlen(p->sms_message)) { - manager_event(EVENT_FLAG_SYSTEM, "CELLIAXincomingsms", - "Interface: %s\r\nSMS_Message: %s\r\n", p->name, - p->sms_message); - if (strlen(p->sms_receiving_program)) { - int fd1[2]; - pid_t pid1; - char *arg1[] = { p->sms_receiving_program, (char *) NULL }; - int i; - - NOTICA("incoming SMS message:>>>%s<<<\n", CELLIAX_P_LOG, p->sms_message); - pipe(fd1); - pid1 = switch_fork(); - - if (pid1 == 0) { //child - int err; - - dup2(fd1[0], 0); // Connect stdin to pipe output - close(fd1[1]); // close input pipe side - close(p->controldevfd); - setsid(); //session id - err = execvp(arg1[0], arg1); //exec our program, with stdin connected to pipe output - if (err) { - ERRORA - ("'sms_receiving_program' is set in config file to '%s', and it gave us back this error: %d, (%s). SMS received was:---%s---\n", - CELLIAX_P_LOG, p->sms_receiving_program, err, strerror(errno), - p->sms_message); - } - close(fd1[0]); // close output pipe side - } -//starting here continue the parent - close(fd1[0]); // close output pipe side - // write the msg on the pipe input - for (i = 0; i < strlen(p->sms_message); i++) { - write(fd1[1], &p->sms_message[i], 1); - } - close(fd1[1]); // close pipe input, let our program know we've finished - } else { - ERRORA - ("got SMS incoming message, but 'sms_receiving_program' is not set in config file. SMS received was:---%s---\n", - CELLIAX_P_LOG, p->sms_message); - } - } -#if 1 //is this one needed? maybe it can interrupt an incoming call that is just to announce itself - if (p->phone_callflow == CALLFLOW_CALL_IDLE - && p->interface_state == AST_STATE_DOWN && p->owner == NULL) { - /* we're not in a call, neither calling */ - res = celliax_serial_write_AT_ack(p, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA - ("AT+CKPD=\"EEE\" (cellphone screen back to user) do not got OK from the phone\n", - CELLIAX_P_LOG); - } - } -#endif - } //unread_msg_id - - } //CMTI well formatted - - } //CMTI - - if ((strncmp(p->line_array.result[i], "+MMGL:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config! - int err = 0; - //int unread_msg_id=0; - - if (option_debug) - DEBUGA_AT("|%s| +MMGL: Listing Motorola SMSs!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - err = sscanf(&p->line_array.result[i][7], "%d", &p->unread_sms_msg_id); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+MMGL: xx|\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - } - if ((strncmp(p->line_array.result[i], "+CMGL:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_AT("|%s| +CMGL: Listing SMSs!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - if ((strncmp(p->line_array.result[i], "+MMGR:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config! - if (option_debug) - DEBUGA_AT("|%s| +MMGR: Reading Motorola SMS!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->reading_sms_msg) - p->reading_sms_msg++; - } - if ((strncmp(p->line_array.result[i], "+CMGR: \"STO U", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_AT("|%s| +CMGR: Reading stored UNSENT SMS!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } else if ((strncmp(p->line_array.result[i], "+CMGR: \"STO S", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_AT("|%s| +CMGR: Reading stored SENT SMS!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } else if ((strncmp(p->line_array.result[i], "+CMGR: \"REC R", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_AT("|%s| +CMGR: Reading received READ SMS!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } else if ((strncmp(p->line_array.result[i], "+CMGR: \"REC U", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_AT("|%s| +CMGR: Reading received UNREAD SMS!\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->reading_sms_msg) - p->reading_sms_msg++; - } - - if ((strcmp(p->line_array.result[i], "+MCST: 17") == 0)) { /* motorola call processing unsolicited messages */ - p->phone_callflow = CALLFLOW_CALL_INFLUX; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_INFLUX\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], "+MCST: 68") == 0)) { /* motorola call processing unsolicited messages */ - p->phone_callflow = CALLFLOW_CALL_NOSERVICE; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_NOSERVICE\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - p->owner->hangupcause = AST_CAUSE_FAILURE; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - } - if ((strcmp(p->line_array.result[i], "+MCST: 70") == 0)) { /* motorola call processing unsolicited messages */ - p->phone_callflow = CALLFLOW_CALL_OUTGOINGRESTRICTED; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_OUTGOINGRESTRICTED\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - p->owner->hangupcause = AST_CAUSE_FAILURE; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - } - if ((strcmp(p->line_array.result[i], "+MCST: 72") == 0)) { /* motorola call processing unsolicited messages */ - p->phone_callflow = CALLFLOW_CALL_SECURITYFAIL; - if (option_debug > 1) - DEBUGA_AT("|%s| CALLFLOW_CALL_SECURITYFAIL\n", CELLIAX_P_LOG, - p->line_array.result[i]); - if (p->interface_state != AST_STATE_DOWN && p->owner) { - p->owner->hangupcause = AST_CAUSE_FAILURE; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - } - - if ((strncmp(p->line_array.result[i], "+CPBR", 5) == 0)) { /* phonebook stuff begins */ - - if (p->phonebook_querying) { /* probably phonebook struct begins */ - int err, first_entry, last_entry, number_lenght, text_lenght; - - if (option_debug) - DEBUGA_AT("phonebook struct: |%s|\n", CELLIAX_P_LOG, p->line_array.result[i]); - - err = - sscanf(&p->line_array.result[i][8], "%d-%d),%d,%d", &first_entry, &last_entry, - &number_lenght, &text_lenght); - if (err < 4) { - - err = - sscanf(&p->line_array.result[i][7], "%d-%d,%d,%d", &first_entry, - &last_entry, &number_lenght, &text_lenght); - } - - if (err < 4) { - ERRORA - ("phonebook struct: |%s| is nor formatted as: |+CPBR: (1-750),40,14| neither as: |+CPBR: 1-750,40,14|\n", - CELLIAX_P_LOG, p->line_array.result[i]); - } else { - - if (option_debug) - DEBUGA_AT - ("First entry: %d, last entry: %d, phone number max lenght: %d, text max lenght: %d\n", - CELLIAX_P_LOG, first_entry, last_entry, number_lenght, text_lenght); - p->phonebook_first_entry = first_entry; - p->phonebook_last_entry = last_entry; - p->phonebook_number_lenght = number_lenght; - p->phonebook_text_lenght = text_lenght; - } - - } else { /* probably phonebook entry begins */ - - if (p->phonebook_listing) { - int err, entry_id, entry_type; - - char entry_number[256]; - char entry_text[256]; - - if (option_debug) - DEBUGA_AT("phonebook entry: |%s|\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - err = - sscanf(&p->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", - &entry_id, entry_number, &entry_type, entry_text); - if (err < 4) { - ERRORA - ("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n", - CELLIAX_P_LOG, err, p->line_array.result[i]); - } else { - //TODO: sanitize entry_text - if (option_debug) - DEBUGA_AT("Number: %s, Text: %s, Type: %d\n", CELLIAX_P_LOG, entry_number, - entry_text, entry_type); - /* write entry in phonebook file */ - if (p->phonebook_writing_fp) { - celliax_dir_entry_extension++; - - fprintf(p->phonebook_writing_fp, - "%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n", - entry_number, entry_text, "no", - p->celliax_dir_entry_extension_prefix, "2", - celliax_dir_entry_extension, "yes", "not_specified"); - fprintf(p->phonebook_writing_fp, - "%s => ,%sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n", - entry_number, entry_text, "no", - p->celliax_dir_entry_extension_prefix, "3", - celliax_dir_entry_extension, "yes", "not_specified"); - } - } - - } - - if (p->phonebook_listing_received_calls) { - int err, entry_id, entry_type; - - char entry_number[256] = ""; - char entry_text[256] = ""; - - if (option_debug) - DEBUGA_AT("phonebook entry: |%s|\n", CELLIAX_P_LOG, - p->line_array.result[i]); - - err = - sscanf(&p->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", - &entry_id, entry_number, &entry_type, entry_text); - if (err < 1) { //we match only on the progressive id, maybe the remote party has not sent its number, and/or there is no corresponding text entry in the phone directory - ERRORA - ("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n", - CELLIAX_P_LOG, err, p->line_array.result[i]); - } else { - //TODO: sanitize entry_text - - if (option_debug) - DEBUGA_AT("Number: %s, Text: %s, Type: %d\n", CELLIAX_P_LOG, entry_number, - entry_text, entry_type); - memset(p->callid_name, 0, sizeof(p->callid_name)); - memset(p->callid_number, 0, sizeof(p->callid_number)); - strncpy(p->callid_name, entry_text, sizeof(p->callid_name)); - strncpy(p->callid_number, entry_number, sizeof(p->callid_number)); - if (option_debug) - DEBUGA_AT("incoming callid: Text: %s, Number: %s\n", CELLIAX_P_LOG, - p->callid_name, p->callid_number); - - DEBUGA_AT("|%s| CPBR INCOMING CALLID: name is %s, number is %s\n", - CELLIAX_P_LOG, p->line_array.result[i], - p->callid_name[0] != 1 ? p->callid_name : "not available", - p->callid_number[0] ? p->callid_number : "not available"); - - /* mark the time of RING */ - gettimeofday(&(p->ringtime), NULL); - p->interface_state = AST_STATE_RING; - p->phone_callflow = CALLFLOW_INCOMING_RING; - - } - - } - - else { - DEBUGA_AT("phonebook entry: |%s|\n", CELLIAX_P_LOG, p->line_array.result[i]); - - } - } - - } - - if ((strncmp(p->line_array.result[i], "*ECAV", 5) == 0) || (strncmp(p->line_array.result[i], "*ECAM", 5) == 0)) { /* sony-ericsson call processing unsolicited messages */ - int res, ccid, ccstatus, calltype, processid, exitcause, number, type; - res = ccid = ccstatus = calltype = processid = exitcause = number = type = 0; - res = - sscanf(&p->line_array.result[i][6], "%d,%d,%d,%d,%d,%d,%d", &ccid, &ccstatus, - &calltype, &processid, &exitcause, &number, &type); - /* only changes the phone_callflow if enought parameters were parsed */ - if (res >= 3) { - switch (ccstatus) { - case 0: - if (p->owner) { - ast_setstate(p->owner, AST_STATE_DOWN); - p->owner->hangupcause = AST_CAUSE_NORMAL; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - p->phone_callflow = CALLFLOW_CALL_IDLE; - p->interface_state = AST_STATE_DOWN; - if (option_debug > 1) - DEBUGA_AT("|%s| Sony-Ericsson *ECAM/*ECAV: IDLE\n", CELLIAX_P_LOG, - p->line_array.result[i]); - break; - case 1: - if (option_debug > 1) - DEBUGA_AT("|%s| Sony-Ericsson *ECAM/*ECAV: CALLING\n", CELLIAX_P_LOG, - p->line_array.result[i]); - break; - case 2: - if (p->owner) { - ast_setstate(p->owner, AST_STATE_DIALING); - } - p->interface_state = CALLFLOW_CALL_DIALING; - if (option_debug > 1) - DEBUGA_AT("|%s| Sony-Ericsson *ECAM/*ECAV: CONNECTING\n", CELLIAX_P_LOG, - p->line_array.result[i]); - break; - case 3: - if (p->owner) { - ast_setstate(p->owner, AST_STATE_UP); - celliax_queue_control(p->owner, AST_CONTROL_ANSWER); - } - p->phone_callflow = CALLFLOW_CALL_ACTIVE; - p->interface_state = AST_STATE_UP; - if (option_debug > 1) - DEBUGA_AT("|%s| Sony-Ericsson *ECAM/*ECAV: ACTIVE\n", CELLIAX_P_LOG, - p->line_array.result[i]); - break; - case 4: - if (option_debug > 1) - DEBUGA_AT - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle HOLD event\n", - CELLIAX_P_LOG, p->line_array.result[i]); - break; - case 5: - if (option_debug > 1) - DEBUGA_AT - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle WAITING event\n", - CELLIAX_P_LOG, p->line_array.result[i]); - break; - case 6: - if (option_debug > 1) - DEBUGA_AT - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle ALERTING event\n", - CELLIAX_P_LOG, p->line_array.result[i]); - break; - case 7: - if (p->owner) { - ast_setstate(p->owner, AST_STATE_BUSY); - celliax_queue_control(p->owner, AST_CONTROL_BUSY); - } - p->phone_callflow = CALLFLOW_CALL_LINEBUSY; - p->interface_state = AST_STATE_BUSY; - if (option_debug > 1) - DEBUGA_AT("|%s| Sony-Ericsson *ECAM/*ECAV: BUSY\n", CELLIAX_P_LOG, - p->line_array.result[i]); - break; - } - } else { - if (option_debug > 1) - DEBUGA_AT("|%s| Sony-Ericsson *ECAM/*ECAV: could not parse parameters\n", - CELLIAX_P_LOG, p->line_array.result[i]); - } - - } - - /* at_indicator_* are unsolicited messages sent by the phone to signal us that some of its visual indicators on its screen has changed, based on CIND CMER ETSI docs */ - if ((strcmp(p->line_array.result[i], p->at_indicator_noservice_string) == 0)) { - if (option_debug > 1) - ERRORA("|%s| at_indicator_noservice_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_nosignal_string) == 0)) { - if (option_debug > 1) - ERRORA("|%s| at_indicator_nosignal_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_lowsignal_string) == 0)) { - if (option_debug > 1) - WARNINGA("|%s| at_indicator_lowsignal_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_lowbattchg_string) == 0)) { - if (option_debug > 1) - WARNINGA("|%s| at_indicator_lowbattchg_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_nobattchg_string) == 0)) { - if (option_debug > 1) - ERRORA("|%s| at_indicator_nobattchg_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_callactive_string) == 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| at_indicator_callactive_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_nocallactive_string) == 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| at_indicator_nocallactive_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_nocallsetup_string) == 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| at_indicator_nocallsetup_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_callsetupincoming_string) == - 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| at_indicator_callsetupincoming_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_callsetupoutgoing_string) == - 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| at_indicator_callsetupoutgoing_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - if ((strcmp(p->line_array.result[i], p->at_indicator_callsetupremoteringing_string) - == 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| at_indicator_callsetupremoteringing_string\n", CELLIAX_P_LOG, - p->line_array.result[i]); - } - - } - - /* let's look for OK, ERROR and EXPECTED_STRING in the complete lines read so far, without re-looking at the lines that has been yet looked at */ - for (i = la_read; i < la_counter; i++) { - if (expected_string) { - if ((strncmp(p->line_array.result[i], expected_string, strlen(expected_string)) - == 0)) { - if (option_debug > 1) - DEBUGA_AT("|%s| got what EXPECTED\n", CELLIAX_P_LOG, p->line_array.result[i]); - at_ack = AT_OK; - } - } else { - //if ((strcmp(p->line_array.result[i], "OK") == 0)) { - if ((strcmp(p->line_array.result[i], "OK") == 0) || (strcmp(p->line_array.result[i], "NO CARRIER") == 0) ) { - if (option_debug > 1) - DEBUGA_AT("got OK\n", CELLIAX_P_LOG); - at_ack = AT_OK; - } - } - if ((strcmp(p->line_array.result[i], "ERROR") == 0)) { - if (option_debug > 1) - DEBUGA_AT("got ERROR\n", CELLIAX_P_LOG); - at_ack = AT_ERROR; - } - - /* if we are reading an sms message from memory, put the line into the sms buffer if the line is not "OK" or "ERROR" */ - if (p->reading_sms_msg > 1 && at_ack == -1) { - int c; - char sms_body[16000]; - int err; - - if (strncmp(p->line_array.result[i], "+CMGR", 5) == 0) { /* we are reading the "header" of an SMS */ - char content[512]; - char content2[512]; - - memset(content, '\0', sizeof(content)); - - int inside_comma = 0; - int inside_quote = 0; - int d = 0; - - for (c = 0; c < strlen(p->line_array.result[i]); c++) { - if (p->line_array.result[i][c] == ',' - && p->line_array.result[i][c - 1] != '\\' && inside_quote == 0) { - if (inside_comma) { - inside_comma = 0; - //NOTICA("inside_comma=%d, inside_quote=%d, we're at=%s\n", CELLIAX_P_LOG, inside_comma, inside_quote, &p->line_array.result[i][c]); - } else { - inside_comma = 1; - //NOTICA("inside_comma=%d, inside_quote=%d, we're at=%s\n", CELLIAX_P_LOG, inside_comma, inside_quote, &p->line_array.result[i][c]); - } - } - if (p->line_array.result[i][c] == '"' - && p->line_array.result[i][c - 1] != '\\') { - if (inside_quote) { - inside_quote = 0; - //ERRORA("END_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", CELLIAX_P_LOG, inside_comma, inside_quote, &p->line_array.result[i][c]); - DEBUGA_AT("content=%s\n", CELLIAX_P_LOG, content); - - strncat(p->sms_message, "---", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - strncat(p->sms_message, content, - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - strncat(p->sms_message, "|||", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - - memset(content2, '\0', sizeof(content2)); - err = ucs2_to_utf8(p, content, content2, sizeof(content2)); - - strncat(p->sms_message, "---", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - if (!err) - strncat(p->sms_message, content2, - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - strncat(p->sms_message, "|||", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - memset(content, '\0', sizeof(content)); - d = 0; - } else { - inside_quote = 1; - //WARNINGA("START_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", CELLIAX_P_LOG, inside_comma, inside_quote, &p->line_array.result[i][c]); - } - } - if (inside_quote && p->line_array.result[i][c] != '"') { - - content[d] = p->line_array.result[i][c]; - d++; - - } - - } - } //it was the +CMGR answer from the cellphone - else { - strncat(p->sms_message, "---", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - strncat(p->sms_message, p->line_array.result[i], - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - strncat(p->sms_message, "|||", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - - memset(sms_body, '\0', sizeof(sms_body)); - err = ucs2_to_utf8(p, p->line_array.result[i], sms_body, sizeof(sms_body)); - - strncat(p->sms_message, "---", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - if (!err) - strncat(p->sms_message, sms_body, - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - strncat(p->sms_message, "|||", - ((sizeof(p->sms_message) - strlen(p->sms_message)) - 1)); - - DEBUGA_AT("sms_message=%s\n", CELLIAX_P_LOG, p->sms_message); - - } //it was the UCS2 from cellphone - - } //we were reading the SMS - - } - - la_read = la_counter; - - if (look_for_ack && at_ack > -1) - break; - - if (la_counter > AT_MESG_MAX_LINES) { - ERRORA("Too many lines in result (>%d). Stopping reader.\n", CELLIAX_P_LOG, - AT_MESG_MAX_LINES); - at_ack = AT_ERROR; - break; - } - } - - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - if (select_err == -1) { - ERRORA("select returned -1 on %s, setting controldev_dead, error was: %s\n", - CELLIAX_P_LOG, p->controldevice_name, strerror(errno)); - p->controldev_dead = 1; - close(p->controldevfd); - if (p->owner) - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - return -1; - } - - if (p->phone_callflow == CALLFLOW_CALL_INCOMING && p->call_incoming_time.tv_sec) { //after three sec of CALLFLOW_CALL_INCOMING, we assume the phone is incapable of notifying RING (eg: motorola c350), so we try to answer - char list_command[64]; - struct timeval call_incoming_timeout; - gettimeofday(&call_incoming_timeout, NULL); - call_incoming_timeout.tv_sec -= 3; - DEBUGA_AT - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - CELLIAX_P_LOG, p->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (call_incoming_timeout.tv_sec > p->call_incoming_time.tv_sec) { - - p->call_incoming_time.tv_sec = 0; - p->call_incoming_time.tv_usec = 0; - DEBUGA_AT - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - CELLIAX_P_LOG, p->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - res = celliax_serial_write_AT_ack(p, "AT+CPBS=RC"); - if (res) { - ERRORA - ("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", - CELLIAX_P_LOG); - } - p->phonebook_querying = 1; - res = celliax_serial_write_AT_ack(p, "AT+CPBR=?"); - if (res) { - ERRORA - ("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", - CELLIAX_P_LOG); - } - p->phonebook_querying = 0; - sprintf(list_command, "AT+CPBR=%d,%d", p->phonebook_first_entry, - p->phonebook_last_entry); - p->phonebook_listing_received_calls = 1; - res = celliax_serial_write_AT_expect_longtime(p, list_command, "OK"); - if (res) { - WARNINGA("AT+CPBR=%d,%d failed, continue\n", CELLIAX_P_LOG, - p->phonebook_first_entry, p->phonebook_last_entry); - } - p->phonebook_listing_received_calls = 0; - } - } - - if (p->phone_callflow == CALLFLOW_INCOMING_RING) { - struct timeval call_incoming_timeout; - gettimeofday(&call_incoming_timeout, NULL); - call_incoming_timeout.tv_sec -= 10; - DEBUGA_AT - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - CELLIAX_P_LOG, p->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (call_incoming_timeout.tv_sec > p->ringtime.tv_sec) { - ERRORA("Ringing stopped and I have not answered. Why?\n", CELLIAX_P_LOG); - DEBUGA_AT - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - CELLIAX_P_LOG, p->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (p->owner) { - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - p->owner->hangupcause = AST_CAUSE_FAILURE; - } - } - } - p->line_array.elemcount = la_counter; - //NOTICA (" OUTSIDE this celliax_serial_device %s \n", CELLIAX_P_LOG, p->controldevice_name); - if (look_for_ack) - return at_ack; - else - return 0; -} - -int celliax_serial_write_AT(struct celliax_pvt *p, const char *data) -{ - int howmany; - int i; - int res; - int count; - - howmany = strlen(data); - - for (i = 0; i < howmany; i++) { - res = write(p->controldevfd, &data[i], 1); - - if (res != 1) { - DEBUGA_AT("Error sending (%.1s): %d (%s)\n", CELLIAX_P_LOG, &data[i], res, - strerror(errno)); - usleep(100000); - for (count = 0; count < 10; count++) { - res = write(p->controldevfd, &data[i], 1); - if (res == 1) { - DEBUGA_AT("Successfully RE-sent (%.1s): %d %d (%s)\n", CELLIAX_P_LOG, &data[i], - count, res, strerror(errno)); - break; - } else - DEBUGA_AT("Error RE-sending (%.1s): %d %d (%s)\n", CELLIAX_P_LOG, &data[i], - count, res, strerror(errno)); - usleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", CELLIAX_P_LOG, &data[i], count, - res, strerror(errno)); - return -1; - } - } - if (option_debug > 1) - DEBUGA_AT("sent data... (%.1s)\n", CELLIAX_P_LOG, &data[i]); - usleep(1000); /* release the cpu */ - } - - res = write(p->controldevfd, "\r", 1); - - if (res != 1) { - DEBUGA_AT("Error sending (carriage return): %d (%s)\n", CELLIAX_P_LOG, res, - strerror(errno)); - usleep(100000); - for (count = 0; count < 10; count++) { - res = write(p->controldevfd, "\r", 1); - - if (res == 1) { - DEBUGA_AT("Successfully RE-sent carriage return: %d %d (%s)\n", CELLIAX_P_LOG, - count, res, strerror(errno)); - break; - } else - DEBUGA_AT("Error RE-sending (carriage return): %d %d (%s)\n", CELLIAX_P_LOG, - count, res, strerror(errno)); - usleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (carriage return): %d %d (%s)\n", CELLIAX_P_LOG, count, - res, strerror(errno)); - return -1; - } - } - if (option_debug > 1) - DEBUGA_AT("sent (carriage return)\n", CELLIAX_P_LOG); - usleep(1000); /* release the cpu */ - - return howmany; -} - -int celliax_serial_write_AT_nocr(struct celliax_pvt *p, const char *data) -{ - int howmany; - int i; - int res; - int count; - - howmany = strlen(data); - - for (i = 0; i < howmany; i++) { - res = write(p->controldevfd, &data[i], 1); - - if (res != 1) { - DEBUGA_AT("Error sending (%.1s): %d (%s)\n", CELLIAX_P_LOG, &data[i], res, - strerror(errno)); - usleep(100000); - for (count = 0; count < 10; count++) { - res = write(p->controldevfd, &data[i], 1); - if (res == 1) - break; - else - DEBUGA_AT("Error RE-sending (%.1s): %d %d (%s)\n", CELLIAX_P_LOG, &data[i], - count, res, strerror(errno)); - usleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", CELLIAX_P_LOG, &data[i], count, - res, strerror(errno)); - return -1; - } - } - if (option_debug > 1) - DEBUGA_AT("sent data... (%.1s)\n", CELLIAX_P_LOG, &data[i]); - usleep(1000); /* release the cpu */ - } - - usleep(1000); /* release the cpu */ - - return howmany; -} - -int celliax_serial_write_AT_noack(struct celliax_pvt *p, const char *data) -{ - - if (option_debug > 1) - DEBUGA_AT("celliax_serial_write_AT_noack: %s\n", CELLIAX_P_LOG, data); - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - if (celliax_serial_write_AT(p, data) != strlen(data)) { - - ERRORA("Error sending data... (%s)\n", CELLIAX_P_LOG, strerror(errno)); - UNLOCKA(&p->controldev_lock); - return -1; - } - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - return 0; -} - -int celliax_serial_write_AT_ack(struct celliax_pvt *p, const char *data) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - if (option_debug > 1) - DEBUGA_AT("sending: %s\n", CELLIAX_P_LOG, data); - if (celliax_serial_write_AT(p, data) != strlen(data)) { - ERRORA("Error sending data... (%s) \n", CELLIAX_P_LOG, strerror(errno)); - UNLOCKA(&p->controldev_lock); - return -1; - } - - at_result = celliax_serial_read_AT(p, 1, 500000, 2, NULL, 1); // 2.5 sec timeout - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - return at_result; - -} - -int celliax_serial_write_AT_ack_nocr_longtime(struct celliax_pvt *p, const char *data) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - if (option_debug > 1) - DEBUGA_AT("sending: %s\n", CELLIAX_P_LOG, data); - if (celliax_serial_write_AT_nocr(p, data) != strlen(data)) { - ERRORA("Error sending data... (%s) \n", CELLIAX_P_LOG, strerror(errno)); - UNLOCKA(&p->controldev_lock); - return -1; - } - - at_result = celliax_serial_read_AT(p, 1, 500000, 20, NULL, 1); // 20.5 sec timeout - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - return at_result; - -} - -int celliax_serial_write_AT_expect1(struct celliax_pvt *p, const char *data, - const char *expected_string, int expect_crlf, - int seconds) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - if (option_debug > 1) - DEBUGA_AT("sending: %s, expecting: %s\n", CELLIAX_P_LOG, data, expected_string); - if (celliax_serial_write_AT(p, data) != strlen(data)) { - ERRORA("Error sending data... (%s) \n", CELLIAX_P_LOG, strerror(errno)); - UNLOCKA(&p->controldev_lock); - return -1; - } - - at_result = celliax_serial_read_AT(p, 1, 500000, seconds, expected_string, expect_crlf); // 20.5 sec timeout, used for querying the SIM and sending SMSs - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - return at_result; - -} - -int celliax_serial_AT_expect(struct celliax_pvt *p, const char *expected_string, - int expect_crlf, int seconds) -{ - int at_result = AT_ERROR; - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - if (option_debug > 1) - DEBUGA_AT("expecting: %s\n", CELLIAX_P_LOG, expected_string); - - at_result = celliax_serial_read_AT(p, 1, 500000, seconds, expected_string, expect_crlf); // 20.5 sec timeout, used for querying the SIM and sending SMSs - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - return at_result; - -} - -int celliax_serial_answer_AT(struct celliax_pvt *p) -{ - int res; - - res = celliax_serial_write_AT_expect(p, p->at_answer, p->at_answer_expect); - if (res) { - DEBUGA_AT - ("at_answer command failed, command used: %s, expecting: %s, trying with AT+CKPD=\"S\"\n", - CELLIAX_P_LOG, p->at_answer, p->at_answer_expect); - - res = celliax_serial_write_AT_ack(p, "AT+CKPD=\"S\""); - if (res) { - ERRORA("at_answer command failed, command used: 'AT+CKPD=\"S\"', giving up\n", - CELLIAX_P_LOG); - return -1; - } - } - //p->interface_state = AST_STATE_UP; - //p->phone_callflow = CALLFLOW_CALL_ACTIVE; - DEBUGA_AT("AT: call answered\n", CELLIAX_P_LOG); - return 0; -} - -int celliax_serial_hangup_AT(struct celliax_pvt *p) -{ - int res; - - if (p->interface_state != AST_STATE_DOWN) { - res = celliax_serial_write_AT_expect(p, p->at_hangup, p->at_hangup_expect); - if (res) { - DEBUGA_AT - ("at_hangup command failed, command used: %s, trying to use AT+CKPD=\"EEE\"\n", - CELLIAX_P_LOG, p->at_hangup); - res = celliax_serial_write_AT_ack(p, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA("at_hangup command failed, command used: 'AT+CKPD=\"EEE\"'\n", - CELLIAX_P_LOG); - return -1; - } - } - } - p->interface_state = AST_STATE_DOWN; - p->phone_callflow = CALLFLOW_CALL_IDLE; - return 0; -} - -int celliax_serial_config_AT(struct celliax_pvt *p) -{ - int res; - -/* initial_pause? */ - if (p->at_initial_pause) { - DEBUGA_AT("sleeping for %d usec\n", CELLIAX_P_LOG, p->at_initial_pause); - usleep(p->at_initial_pause); - } - -/* go until first empty preinit string, or last preinit string */ - while (1) { - - if (strlen(p->at_preinit_1)) { - res = celliax_serial_write_AT_expect(p, p->at_preinit_1, p->at_preinit_1_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_preinit_1, p->at_preinit_1_expect); - } - } else { - break; - } - - if (strlen(p->at_preinit_2)) { - res = celliax_serial_write_AT_expect(p, p->at_preinit_2, p->at_preinit_2_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_preinit_2, p->at_preinit_2_expect); - } - } else { - break; - } - - if (strlen(p->at_preinit_3)) { - res = celliax_serial_write_AT_expect(p, p->at_preinit_3, p->at_preinit_3_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_preinit_3, p->at_preinit_3_expect); - } - } else { - break; - } - - if (strlen(p->at_preinit_4)) { - res = celliax_serial_write_AT_expect(p, p->at_preinit_4, p->at_preinit_4_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_preinit_4, p->at_preinit_4_expect); - } - } else { - break; - } - - if (strlen(p->at_preinit_5)) { - res = celliax_serial_write_AT_expect(p, p->at_preinit_5, p->at_preinit_5_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_preinit_5, p->at_preinit_5_expect); - } - } else { - break; - } - - break; - } - -/* after_preinit_pause? */ - if (p->at_after_preinit_pause) { - DEBUGA_AT("sleeping for %d usec\n", CELLIAX_P_LOG, p->at_after_preinit_pause); - usleep(p->at_after_preinit_pause); - } - - /* phone, brother, art you alive? */ - res = celliax_serial_write_AT_ack(p, "AT"); - if (res) { - ERRORA("no response to AT\n", CELLIAX_P_LOG); - return -1; - } - /* for motorola, bring it back to "normal" mode if it happens to be in another mode */ - res = celliax_serial_write_AT_ack(p, "AT+mode=0"); - if (res) { - DEBUGA_AT("AT+mode=0 does not get OK from the phone. If it is NOT Motorola," - " no problem.\n", CELLIAX_P_LOG); - } - usleep(50000); - /* for motorola end */ - - /* reset AT configuration to phone default */ - res = celliax_serial_write_AT_ack(p, "ATZ"); - if (res) { - DEBUGA_AT("ATZ failed\n", CELLIAX_P_LOG); - } - - /* disable AT command echo */ - res = celliax_serial_write_AT_ack(p, "ATE0"); - if (res) { - DEBUGA_AT("ATE0 failed\n", CELLIAX_P_LOG); - } - - /* disable extended error reporting */ - res = celliax_serial_write_AT_ack(p, "AT+CMEE=0"); - if (res) { - DEBUGA_AT("AT+CMEE failed\n", CELLIAX_P_LOG); - } - - /* various phone manufacturer identifier */ - char at_command[5]; - int i; - for (i = 0; i < 10; i++) { - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "ATI%d", i); - res = celliax_serial_write_AT_ack(p, at_command); - if (res) { - DEBUGA_AT("ATI%d command failed, continue\n", CELLIAX_P_LOG, i); - } - } - - /* phone manufacturer */ - res = celliax_serial_write_AT_ack(p, "AT+CGMI"); - if (res) { - DEBUGA_AT("AT+CGMI failed\n", CELLIAX_P_LOG); - } - - /* phone model */ - res = celliax_serial_write_AT_ack(p, "AT+CGMM"); - if (res) { - DEBUGA_AT("AT+CGMM failed\n", CELLIAX_P_LOG); - } - - res = celliax_serial_write_AT_ack(p, "AT+CGSN"); - if (res) { - DEBUGA_AT("AT+CGSN failed\n", CELLIAX_P_LOG); - } - -/* this take a lot of time to complete on devices with slow serial link (eg.: 9600bps) */ -#if 0 - /* ask for the list of supported AT commands, useful to implement new models and debugging */ - res = celliax_serial_write_AT_ack(p, "AT+CLAC"); - if (res) { - DEBUGA_AT("AT+CLAC failed, continue\n", CELLIAX_P_LOG); - } -#endif - /* signal incoming SMS with a +CMTI unsolicited msg */ - res = celliax_serial_write_AT_ack(p, "AT+CNMI=3,1,0,0,0"); - if (res) { - DEBUGA_AT("AT+CNMI=3,1,0,0,0 failed, continue\n", CELLIAX_P_LOG); - p->sms_cnmi_not_supported = 1; - p->celliax_serial_sync_period = 30; - } - /* what is the Message Center address (number) to which the SMS has to be sent? */ - res = celliax_serial_write_AT_ack(p, "AT+CSCA?"); - if (res) { - DEBUGA_AT("AT+CSCA? failed, continue\n", CELLIAX_P_LOG); - } - /* what is the Message Format of SMSs? */ - res = celliax_serial_write_AT_ack(p, "AT+CMGF?"); - if (res) { - DEBUGA_AT("AT+CMGF? failed, continue\n", CELLIAX_P_LOG); - } - res = celliax_serial_write_AT_ack(p, "AT+CMGF=1"); //TODO: support phones that only accept pdu mode - if (res) { - ERRORA("Error setting SMS sending mode to TEXT on the cellphone\n", CELLIAX_P_LOG); - return RESULT_FAILURE; - } - /* what is the Charset of SMSs? */ - res = celliax_serial_write_AT_ack(p, "AT+CSCS?"); - if (res) { - DEBUGA_AT("AT+CSCS? failed, continue\n", CELLIAX_P_LOG); - } - - p->no_ucs2 = 0; - res = celliax_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\""); - if (res) { - WARNINGA - ("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone, let's try with 'GSM'\n", - CELLIAX_P_LOG); - p->no_ucs2 = 1; - } - - if (p->no_ucs2) { - res = celliax_serial_write_AT_ack(p, "AT+CSCS=\"GSM\""); - if (res) { - WARNINGA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", - CELLIAX_P_LOG); - } - //res = celliax_serial_write_AT_ack(p, "AT+CSMP=17,167,0,16"); //"flash", class 0 sms 7 bit - res = celliax_serial_write_AT_ack(p, "AT+CSMP=17,167,0,0"); //normal, 7 bit message - if (res) { - WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", CELLIAX_P_LOG); - } - } else { - //res = celliax_serial_write_AT_ack(p, "AT+CSMP=17,167,0,20"); //"flash", class 0 sms 16 bit unicode - res = celliax_serial_write_AT_ack(p, "AT+CSMP=17,167,0,8"); //unicode, 16 bit message - if (res) { - WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", CELLIAX_P_LOG); - } - } - - /* is the unsolicited reporting of mobile equipment event supported? */ - res = celliax_serial_write_AT_ack(p, "AT+CMER=?"); - if (res) { - DEBUGA_AT("AT+CMER=? failed, continue\n", CELLIAX_P_LOG); - } - /* request unsolicited reporting of mobile equipment indicators' events, to be screened by categories reported by +CIND=? */ - res = celliax_serial_write_AT_ack(p, "AT+CMER=3,0,0,1"); - if (res) { - DEBUGA_AT("AT+CMER=? failed, continue\n", CELLIAX_P_LOG); - } - - /* is the solicited reporting of mobile equipment indications supported? */ - - res = celliax_serial_write_AT_ack(p, "AT+CIND=?"); - if (res) { - DEBUGA_AT("AT+CIND=? failed, continue\n", CELLIAX_P_LOG); - } - - /* is the unsolicited reporting of call monitoring supported? sony-ericsson specific */ - res = celliax_serial_write_AT_ack(p, "AT*ECAM=?"); - if (res) { - DEBUGA_AT("AT*ECAM=? failed, continue\n", CELLIAX_P_LOG); - } - /* enable the unsolicited reporting of call monitoring. sony-ericsson specific */ - res = celliax_serial_write_AT_ack(p, "AT*ECAM=1"); - if (res) { - DEBUGA_AT("AT*ECAM=1 failed, continue\n", CELLIAX_P_LOG); - p->at_has_ecam = 0; - } else { - p->at_has_ecam = 1; - } - - /* disable unsolicited signaling of call list */ - res = celliax_serial_write_AT_ack(p, "AT+CLCC=0"); - if (res) { - DEBUGA_AT("AT+CLCC=0 failed, continue\n", CELLIAX_P_LOG); - p->at_has_clcc = 0; - } else { - p->at_has_clcc = 1; - } - - /* give unsolicited caller id when incoming call */ - res = celliax_serial_write_AT_ack(p, "AT+CLIP=1"); - if (res) { - DEBUGA_AT("AT+CLIP failed, continue\n", CELLIAX_P_LOG); - } - /* for motorola */ - res = celliax_serial_write_AT_ack(p, "AT+MCST=1"); /* motorola call control codes - (to know when call is disconnected (they - don't give you "no carrier") */ - if (res) { - DEBUGA_AT("AT+MCST=1 does not get OK from the phone. If it is NOT Motorola," - " no problem.\n", CELLIAX_P_LOG); - } - /* for motorola end */ - -/* go until first empty postinit string, or last postinit string */ - while (1) { - - if (strlen(p->at_postinit_1)) { - res = celliax_serial_write_AT_expect(p, p->at_postinit_1, p->at_postinit_1_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_postinit_1, p->at_postinit_1_expect); - } - } else { - break; - } - - if (strlen(p->at_postinit_2)) { - res = celliax_serial_write_AT_expect(p, p->at_postinit_2, p->at_postinit_2_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_postinit_2, p->at_postinit_2_expect); - } - } else { - break; - } - - if (strlen(p->at_postinit_3)) { - res = celliax_serial_write_AT_expect(p, p->at_postinit_3, p->at_postinit_3_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_postinit_3, p->at_postinit_3_expect); - } - } else { - break; - } - - if (strlen(p->at_postinit_4)) { - res = celliax_serial_write_AT_expect(p, p->at_postinit_4, p->at_postinit_4_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_postinit_4, p->at_postinit_4_expect); - } - } else { - break; - } - - if (strlen(p->at_postinit_5)) { - res = celliax_serial_write_AT_expect(p, p->at_postinit_5, p->at_postinit_5_expect); - if (res) { - DEBUGA_AT("%s does not get %s from the phone. Continuing.\n", CELLIAX_P_LOG, - p->at_postinit_5, p->at_postinit_5_expect); - } - } else { - break; - } - - break; - } - - return 0; -} - -int celliax_serial_call_AT(struct celliax_pvt *p, char *dstr) -{ - int res; - char at_command[256]; - - if (option_debug) - DEBUGA_PBX("Dialing %s\n", CELLIAX_P_LOG, dstr); - memset(at_command, 0, sizeof(at_command)); - p->phone_callflow = CALLFLOW_CALL_DIALING; - p->interface_state = AST_STATE_DIALING; - ast_uri_decode(dstr); - size_t fixdstr = strspn(dstr, AST_DIGIT_ANYDIG); - if (fixdstr == 0) { - ERRORA("dial command failed because of invalid dial number. dial string was: %s\n", - CELLIAX_P_LOG, dstr); - return -1; - } - dstr[fixdstr] = '\0'; - sprintf(at_command, "%s%s%s", p->at_dial_pre_number, dstr, p->at_dial_post_number); - res = celliax_serial_write_AT_expect(p, at_command, p->at_dial_expect); - if (res) { - ERRORA("dial command failed, dial string was: %s\n", CELLIAX_P_LOG, at_command); - return -1; - } - // jet - early audio - if (p->at_early_audio) { - ast_queue_control(p->owner, AST_CONTROL_ANSWER); - } - - return 0; -} - -int celliax_console_at(int fd, int argc, char *argv[]) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - char at_cmd[1024]; - int i, a, c; - - if (argc == 1) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" console for celliax_at, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - if (p->controldevprotocol != PROTOCOL_AT) { - ast_cli(fd, - "The \"current\" console is not connected to an 'AT modem' (cellphone)\n"); - return RESULT_SUCCESS; - } - - memset(at_cmd, 0, sizeof(at_cmd)); - c = 0; - for (i = 1; i < argc; i++) { - for (a = 0; a < strlen(argv[i]); a++) { - at_cmd[c] = argv[i][a]; - c++; - if (c == 1022) - break; - } - if (i != argc - 1) { - at_cmd[c] = ' '; - c++; - } - if (c == 1023) - break; - } - celliax_serial_write_AT_noack(p, at_cmd); - return RESULT_SUCCESS; -} - -#ifdef ASTERISK_VERSION_1_2 -int celliax_manager_sendsms(struct mansession *s, struct message *m) -#endif //ASTERISK_VERSION_1_2 -#ifdef ASTERISK_VERSION_1_4 -int celliax_manager_sendsms(struct mansession *s, const struct message *m) -#endif //ASTERISK_VERSION_1_4 -{ - int ret; - char command[512]; - const char *interfacename = astman_get_header(m, "Interface"); - const char *destinationnumber = astman_get_header(m, "Number"); - const char *text = astman_get_header(m, "Text"); - const char *action_id = astman_get_header(m, "ActionID"); - - if (ast_strlen_zero(interfacename)) { - astman_send_error(s, m, "Interface: missing.\n"); - return 0; - } - if (ast_strlen_zero(destinationnumber)) { - astman_send_error(s, m, "Number: missing.\n"); - return 0; - } - if (ast_strlen_zero(text)) { - astman_send_error(s, m, "Text: missing.\n"); - return 0; - } - if (ast_strlen_zero(action_id)) { - astman_send_error(s, m, "ActionID: missing.\n"); - return 0; - } - - memset(command, 0, sizeof(command)); - - sprintf(command, "%s/%s|%s|", interfacename, destinationnumber, text); - - ret = celliax_sendsms(NULL, (void *) &command); - -#ifndef ASTERISK_VERSION_1_4 - if (!ret) { - ast_cli(s->fd, "Response: Success\r\n"); - if (!ast_strlen_zero(action_id)) - ast_cli(s->fd, "ActionID: %s\r\n", action_id); - ast_cli(s->fd, "\r\n"); - return RESULT_SUCCESS; - } else { - ast_cli(s->fd, "Response: Error\r\n"); - if (!ast_strlen_zero(action_id)) - ast_cli(s->fd, "ActionID: %s\r\n", action_id); - ast_cli(s->fd, "Message: celliax_manager_sendsms failed\r\n"); - ast_cli(s->fd, "\r\n"); - return 0; - } -#else /* ASTERISK_VERSION_1_4 */ - if (!ret) { - astman_append(s, "Response: Success\r\n"); - if (!ast_strlen_zero(action_id)) - astman_append(s, "ActionID: %s\r\n", action_id); - astman_append(s, "\r\n"); - return RESULT_SUCCESS; - } else { - astman_append(s, "Response: Error\r\n"); - if (!ast_strlen_zero(action_id)) - astman_append(s, "ActionID: %s\r\n", action_id); - astman_append(s, "Message: celliax_manager_sendsms failed\r\n"); - astman_append(s, "\r\n"); - return 0; - } -#endif /* ASTERISK_VERSION_1_4 */ - - return RESULT_SUCCESS; //never reached -} - -int ucs2_to_utf8(struct celliax_pvt *p, char *ucs2_in, char *utf8_out, - size_t outbytesleft) -{ - char converted[16000]; - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - size_t inbytesleft; - int c; - char stringa[5]; - double hexnum; - int i = 0; - - memset(converted, '\0', sizeof(converted)); - - DEBUGA_AT("ucs2_in=%s\n", CELLIAX_P_LOG, ucs2_in); - /* cicopet */ - for (c = 0; c < strlen(ucs2_in); c++) { - sprintf(stringa, "0x%c%c", ucs2_in[c], ucs2_in[c + 1]); - c++; - hexnum = strtod(stringa, NULL); - converted[i] = hexnum; - i++; - } - - outbuf = utf8_out; - inbuf = converted; - - iconv_format = iconv_open("UTF8", "UCS-2BE"); - if (iconv_format == (iconv_t) - 1) { - ERRORA("error: %s\n", CELLIAX_P_LOG, strerror(errno)); - return -1; - } - - inbytesleft = i; - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (iconv_res == (size_t) - 1) { - DEBUGA_AT("ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - CELLIAX_P_LOG, inbuf, inbytesleft, outbuf, outbytesleft, converted, - utf8_out); - DEBUGA_AT("error: %s %d\n", CELLIAX_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_AT - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - CELLIAX_P_LOG, iconv_res, inbuf, inbytesleft, outbuf, outbytesleft, converted, - utf8_out); - iconv_close(iconv_format); - - return 0; -} - -int utf_to_ucs2(struct celliax_pvt *p, char *utf_in, size_t inbytesleft, char *ucs2_out, - size_t outbytesleft) -{ - /* cicopet */ - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - char converted[16000]; - int i; - char stringa[16]; - char stringa2[16]; - - memset(converted, '\0', sizeof(converted)); - - outbuf = converted; - inbuf = utf_in; - - iconv_format = iconv_open("UCS-2BE", "UTF8"); - if (iconv_format == (iconv_t) - 1) { - ERRORA("error: %s\n", CELLIAX_P_LOG, strerror(errno)); - return -1; - } - outbytesleft = 16000; - - DEBUGA_AT("in=%s, inleft=%d, out=%s, outleft=%d, utf_in=%s, converted=%s\n", - CELLIAX_P_LOG, inbuf, inbytesleft, outbuf, outbytesleft, utf_in, converted); - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (iconv_res == (size_t) - 1) { - ERRORA("error: %s %d\n", CELLIAX_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_AT - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, utf_in=%s, converted=%s\n", - CELLIAX_P_LOG, iconv_res, inbuf, inbytesleft, outbuf, outbytesleft, utf_in, - converted); - iconv_close(iconv_format); - - for (i = 0; i < 16000 - outbytesleft; i++) { - memset(stringa, '\0', sizeof(stringa)); - memset(stringa2, '\0', sizeof(stringa2)); - sprintf(stringa, "%02X", converted[i]); - DEBUGA_AT("character is |%02X|\n", CELLIAX_P_LOG, converted[i]); - stringa2[0] = stringa[strlen(stringa) - 2]; - stringa2[1] = stringa[strlen(stringa) - 1]; - strncat(ucs2_out, stringa2, ((outbytesleft - strlen(ucs2_out)) - 1)); //add the received line to the buffer - DEBUGA_AT("stringa=%s, stringa2=%s, ucs2_out=%s\n", CELLIAX_P_LOG, stringa, stringa2, - ucs2_out); - } - return 0; -} - -int celliax_sendsms(struct ast_channel *c, void *data) -{ - char *idest = data; - char rdest[256]; - struct celliax_pvt *p = NULL; - char *device; - char *dest; - char *text; - char *stringp = NULL; - int found = 0; - int failed = 0; - - strncpy(rdest, idest, sizeof(rdest) - 1); - ast_log(LOG_DEBUG, "CelliaxSendsms: %s\n", rdest); - ast_log(LOG_DEBUG, "START\n"); - /* we can use celliax_request to get the channel, but celliax_request would look for onowned channels, and probably we can send SMSs while a call is ongoing - * - */ - - stringp = rdest; - device = strsep(&stringp, "/"); - dest = strsep(&stringp, "|"); - text = strsep(&stringp, "|"); - - if (!device) { - ast_log(LOG_ERROR, - "CelliaxSendsms app do not recognize '%s'. Requires a destination with slashes (interfacename/destinationnumber, TEXT)\n", - idest); - return -1; - } - - if (!dest) { - ast_log(LOG_ERROR, - "CelliaxSendsms app do not recognize '%s'. Requires a destination with slashes (interfacename/destinationnumber, TEXT)\n", - idest); - return -1; - } - - if (!text) { - ast_log(LOG_ERROR, - "CelliaxSendsms app do not recognize '%s'. Requires a destination with slashes (interfacename/destinationnumber, TEXT)\n", - idest); - return -1; - } - - ast_log(LOG_DEBUG, "interfacename:%s, destinationnumber:%s, text:%s\n", device, dest, - text); - - /* lock the interfaces' list */ - LOKKA(&celliax_iflock); - /* make a pointer to the first interface in the interfaces list */ - p = celliax_iflist; - /* Search for the requested interface and verify if is unowned */ - //TODO implement groups a la chan_zap - while (p) { - size_t length = strlen(p->name); - /* is this the requested interface? */ - if (strncmp(device, p->name, length) == 0) { - /* this is the requested interface! */ - if (option_debug) - DEBUGA_AT("FOUND! interfacename:%s, destinationnumber:%s, text:%s, p->name=%s\n", - CELLIAX_P_LOG, device, dest, text, p->name); - found = 1; - break; - - } - /* not yet found, next please */ - p = p->next; - } - /* unlock the interfaces' list */ - UNLOCKA(&celliax_iflock); - - if (!found) { - ast_log(LOG_ERROR, "Interface '%s' requested by CelliaxSendsms NOT FOUND\n", device); - return RESULT_FAILURE; - } - - if (p->controldevprotocol != PROTOCOL_AT) { - ERRORA("CelliaxSendsms supports only AT command cellphones at the moment :-( !\n", - CELLIAX_P_LOG); - return RESULT_FAILURE; - } - - if (p->controldevprotocol == PROTOCOL_AT) { - int err = 0; - char smscommand[16000]; - memset(smscommand, '\0', sizeof(smscommand)); - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - - if (p->no_ucs2) { - sprintf(smscommand, "AT+CMGS=\"%s\"", dest); //TODO: support phones that only accept pdu mode - } else { - char dest2[1048]; - - err = celliax_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\""); - if (err) { - ERRORA - ("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone\n", - CELLIAX_P_LOG); - } - - memset(dest2, '\0', sizeof(dest2)); - utf_to_ucs2(p, dest, strlen(dest), dest2, sizeof(dest2)); - sprintf(smscommand, "AT+CMGS=\"%s\"", dest2); //TODO: support phones that only accept pdu mode - } - //TODO: support phones that only accept pdu mode - //TODO would be better to lock controldev here - err = celliax_serial_write_AT_noack(p, smscommand); - if (err) { - ERRORA("Error sending SMS\n", CELLIAX_P_LOG); - failed = 1; - goto uscita; - } - err = celliax_serial_AT_expect(p, "> ", 0, 1); // wait 1.5s for the prompt, no crlf -#if 1 - if (err) { - DEBUGA_AT - ("Error or timeout getting prompt '> ' for sending sms directly to the remote party. BTW, seems that we cannot do that with Motorola c350, so we'll write to cellphone memory, then send from memory\n", - CELLIAX_P_LOG); - - err = celliax_serial_write_AT_ack(p, "ATE1"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!! - if (err) { - ERRORA("Error activating echo from modem\n", CELLIAX_P_LOG); - } - p->at_cmgw[0] = '\0'; - sprintf(smscommand, "AT+CMGW=\"%s\"", dest); //TODO: support phones that only accept pdu mode - err = celliax_serial_write_AT_noack(p, smscommand); - if (err) { - ERRORA("Error writing SMS destination to the cellphone memory\n", CELLIAX_P_LOG); - failed = 1; - goto uscita; - } - err = celliax_serial_AT_expect(p, "> ", 0, 1); // wait 1.5s for the prompt, no crlf - if (err) { - ERRORA - ("Error or timeout getting prompt '> ' for writing sms text in cellphone memory\n", - CELLIAX_P_LOG); - failed = 1; - goto uscita; - } - } -#endif - - //sprintf(text,"ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大"); //let's test the beauty of utf - memset(smscommand, '\0', sizeof(smscommand)); - if (p->no_ucs2) { - sprintf(smscommand, "%s", text); - } else { - utf_to_ucs2(p, text, strlen(text), smscommand, sizeof(smscommand)); - } - - smscommand[strlen(smscommand)] = 0x1A; - DEBUGA_AT("smscommand len is: %d, text is:|||%s|||\n", CELLIAX_P_LOG, - strlen(smscommand), smscommand); - - err = celliax_serial_write_AT_ack_nocr_longtime(p, smscommand); - //TODO would be better to unlock controldev here - if (err) { - ERRORA("Error writing SMS text to the cellphone memory\n", CELLIAX_P_LOG); - //return RESULT_FAILURE; - failed = 1; - goto uscita; - } - if (p->at_cmgw[0]) { - sprintf(smscommand, "AT+CMSS=%s", p->at_cmgw); - err = celliax_serial_write_AT_expect_longtime(p, smscommand, "OK"); - if (err) { - ERRORA("Error sending SMS from the cellphone memory\n", CELLIAX_P_LOG); - //return RESULT_FAILURE; - failed = 1; - goto uscita; - } - - err = celliax_serial_write_AT_ack(p, "ATE0"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!! - if (err) { - ERRORA("Error de-activating echo from modem\n", CELLIAX_P_LOG); - } - } - uscita: - usleep(1000); - - if (p->at_cmgw[0]) { - - /* let's see what we've sent, just for check TODO: Motorola it's not reliable! Motorola c350 tells that all was sent, but is not true! It just sends how much it fits into one SMS FIXME: need an algorithm to calculate how many ucs2 chars fits into an SMS. It make difference based, probably, on the GSM alphabet translation, or so */ - sprintf(smscommand, "AT+CMGR=%s", p->at_cmgw); - err = celliax_serial_write_AT_ack(p, smscommand); - if (err) { - ERRORA("Error reading SMS back from the cellphone memory\n", CELLIAX_P_LOG); - } - - /* let's delete from cellphone memory what we've sent */ - sprintf(smscommand, "AT+CMGD=%s", p->at_cmgw); - err = celliax_serial_write_AT_ack(p, smscommand); - if (err) { - ERRORA("Error deleting SMS from the cellphone memory\n", CELLIAX_P_LOG); - } - - p->at_cmgw[0] = '\0'; - } - //usleep(500000); //.5 secs - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - } - - ast_log(LOG_DEBUG, "FINISH\n"); - if (failed) - return -1; - else - return RESULT_SUCCESS; -} - -#ifdef CELLIAX_DIR -/* For simplicity, I'm keeping the format compatible with the voicemail config, - but i'm open to suggestions for isolating it */ -#define CELLIAX_DIR_CONFIG "directoriax.conf" - -/* How many digits to read in */ -#define CELLIAX_DIR_NUMDIGITS 3 - -struct ast_config *celliax_dir_realtime(char *context) -{ - //TODO: all the realtime stuff has to be re-made - struct ast_config *cfg; - struct celliax_pvt *p = NULL; -#ifdef ASTERISK_VERSION_1_6_0 - struct ast_flags config_flags = { 0 }; -#endif /* ASTERISK_VERSION_1_6_0 */ - - /* Load flat file config. */ -#ifdef ASTERISK_VERSION_1_6_0 - cfg = ast_config_load(CELLIAX_DIR_CONFIG, config_flags); -#else - cfg = ast_config_load(CELLIAX_DIR_CONFIG); -#endif /* ASTERISK_VERSION_1_6_0 */ - - if (!cfg) { - /* Loading config failed. */ - WARNINGA - ("Loading directoriax.conf config file failed. It's not necessary, continuing.\n", - CELLIAX_P_LOG); - return NULL; - } - return cfg; -} - -static char *celliax_dir_convert(char *lastname) -{ - char *tmp; - int lcount = 0; - tmp = malloc(CELLIAX_DIR_NUMDIGITS + 1); - if (tmp) { - while ((*lastname > 32) && lcount < CELLIAX_DIR_NUMDIGITS) { - switch (toupper(*lastname)) { - case '1': - tmp[lcount++] = '1'; - break; - case '2': - case 'A': - case 'B': - case 'C': - tmp[lcount++] = '2'; - break; - case '3': - case 'D': - case 'E': - case 'F': - tmp[lcount++] = '3'; - break; - case '4': - case 'G': - case 'H': - case 'I': - tmp[lcount++] = '4'; - break; - case '5': - case 'J': - case 'K': - case 'L': - tmp[lcount++] = '5'; - break; - case '6': - case 'M': - case 'N': - case 'O': - tmp[lcount++] = '6'; - break; - case '7': - case 'P': - case 'Q': - case 'R': - case 'S': - tmp[lcount++] = '7'; - break; - case '8': - case 'T': - case 'U': - case 'V': - tmp[lcount++] = '8'; - break; - case '9': - case 'W': - case 'X': - case 'Y': - case 'Z': - tmp[lcount++] = '9'; - break; - } - lastname++; - } - tmp[lcount] = '\0'; - } - return tmp; -} - -int celliax_console_celliax_dir_export(int fd, int argc, char *argv[]) -{ - struct ast_config *cfg; - - struct ast_variable *v; - char *start, *pos, *stringp, *space, *options = NULL, *conv = NULL; - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - char *context = "default"; - char *s; - char *var, *value; - int fromcell = 0; - int fromskype = 0; - char name[256] = ""; - char phonebook_direct_calling_ext[7] = ""; - char write_entry_command[256] = ""; - char entry_number[256] = ""; - char entry_text[256] = ""; - char final_entry_text[256] = ""; - int res; - int tocell = 0; -#ifdef CELLIAX_LIBCSV - int tocsv = 0; - int tovcf = 0; -#endif /* CELLIAX_LIBCSV */ - - if (argc < 3 || argc > 4) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, "No \"current\" console ???, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - - if (!strcasecmp(argv[1], "tocell")) - tocell = 1; -#ifdef CELLIAX_LIBCSV - else if (!strcasecmp(argv[1], "tocsv")) - tocsv = 1; - else if (!strcasecmp(argv[1], "tovcf")) - tovcf = 1; -#endif /* CELLIAX_LIBCSV */ - else { - ast_cli(fd, -#ifdef CELLIAX_LIBCSV - "\n\nYou have neither specified 'tocell' nor 'tocsv'\n\n"); -#else /* CELLIAX_LIBCSV */ - "\n\nYou have not specified 'tocell'\n\n"); -#endif /* CELLIAX_LIBCSV */ - return RESULT_SHOWUSAGE; - } - if (tocell) - if (p->controldevprotocol != PROTOCOL_AT) { - ast_cli(fd, - "Exporting to the cellphone phonebook is currently supported only on \"AT\" cellphones :( !\n"); - return RESULT_SUCCESS; - } -#ifdef CELLIAX_LIBCSV - if (tocsv || tovcf) - if (argc != 4) { - ast_cli(fd, "\n\nYou have to specify a filename with 'tocsv'\n\n"); - return RESULT_SHOWUSAGE; - } -#endif /* CELLIAX_LIBCSV */ - - if (option_debug) - NOTICA("celliax_cellphonenumber is: %s\n", CELLIAX_P_LOG, argv[2]); - -#ifdef CELLIAX_LIBCSV - if (tocsv) { - if (option_debug) - NOTICA("filename is: %s\n", CELLIAX_P_LOG, argv[3]); - //ast_cli(fd, "\n\nnot yet implemented :P \n"); - //return RESULT_SUCCESS; - } - if (tovcf) { - if (option_debug) - NOTICA("filename is: %s\n", CELLIAX_P_LOG, argv[3]); - ast_cli(fd, "\n\nnot yet implemented :P \n"); - return RESULT_SUCCESS; - } -#endif /* CELLIAX_LIBCSV */ - - cfg = celliax_dir_realtime(context); - if (!cfg) { - return -1; - } - - if (tocell) { - /* which phonebook to use, use the SIM */ - res = celliax_serial_write_AT_ack(p, "AT+CPBS=SM"); - if (res) { - WARNINGA("AT+CPBS=SM failed, continue\n", CELLIAX_P_LOG); - } - /* which phonebook to use, trying to use phone, not SIM */ - res = celliax_serial_write_AT_ack(p, "AT+CPBS=ME"); - if (res) { - WARNINGA("AT+CPBS=ME failed, continue\n", CELLIAX_P_LOG); - } - /* retrieve the fields lenght in the selected phonebook */ - p->phonebook_querying = 1; - res = celliax_serial_write_AT_ack(p, "AT+CPBR=?"); - if (res) { - WARNINGA("AT+CPBR=? failed, continue\n", CELLIAX_P_LOG); - } - p->phonebook_querying = 0; - - v = ast_variable_browse(cfg, context); - /* Find all candidate extensions */ - while (v) { - /* Find a candidate extension */ - start = strdup(v->value); - if (strcasestr(start, "fromcell=yes")) { - fromcell = 1; - fromskype = 0; - - } - if (strcasestr(start, "fromskype=yes")) { - fromcell = 0; - fromskype = 1; - - } - - if (start && !strcasestr(start, "hidefromdir=yes")) { - memset(name, 0, sizeof(name)); - memset(phonebook_direct_calling_ext, 0, sizeof(phonebook_direct_calling_ext)); - memset(write_entry_command, 0, sizeof(write_entry_command)); - memset(entry_number, 0, sizeof(entry_number)); - memset(entry_text, 0, sizeof(entry_text)); - memset(final_entry_text, 0, sizeof(final_entry_text)); - - DEBUGA_AT("v->name=%s\n", CELLIAX_P_LOG, v->name); - DEBUGA_AT("v->value=%s\n", CELLIAX_P_LOG, v->value); - - stringp = start; - strsep(&stringp, ","); - pos = strsep(&stringp, ","); - if (pos) { - ast_copy_string(name, pos, sizeof(name)); - if (strchr(pos, ' ')) { - space = strchr(pos, ' '); - *space = '\0'; - } - if (pos) { - conv = celliax_dir_convert(pos); - DEBUGA_AT("%s%s<\n", CELLIAX_P_LOG, pos, conv); - - options = strdup(v->value); - strsep(&options, ","); - strsep(&options, ","); - strsep(&options, ","); - strsep(&options, ","); - DEBUGA_AT("options=%s\n", CELLIAX_P_LOG, options); - - while ((s = strsep(&options, "|"))) { - value = s; - if ((var = strsep(&value, "=")) && value) { - DEBUGA_AT("var=%s value=%s\n", CELLIAX_P_LOG, var, value); - if (!strcmp(var, "phonebook_direct_calling_ext")) - strncpy(phonebook_direct_calling_ext, value, 6); - } - } - - res = - snprintf(entry_number, p->phonebook_number_lenght + 1, "%s%s%d%s%s", - argv[2], "p", p->celliax_dir_prefix, "p", - phonebook_direct_calling_ext); - if (res == (p->phonebook_number_lenght + 1) - || res > (p->phonebook_number_lenght + 1)) { - ERRORA("entry_number truncated, was: '%s%s%d%s%s', now is: '%s'\n", - CELLIAX_P_LOG, argv[2], "p", p->celliax_dir_prefix, "p", - phonebook_direct_calling_ext, entry_number); - //FIXME: abort ??? - - } - - res = snprintf(final_entry_text, p->phonebook_text_lenght + 1, "%s", name); //FIXME result not checked - - res = - snprintf(write_entry_command, sizeof(write_entry_command) - 1, - "AT+CPBW=,\"%s\",,\"%s\"", entry_number, final_entry_text); - if (res == (sizeof(write_entry_command) - 1) - || res > (sizeof(write_entry_command) - 1)) { - WARNINGA - ("write_entry_command truncated, was supposed: 'AT+CPBW=,\"%s\",,\"%s\"', now is: '%s'\n", - CELLIAX_P_LOG, entry_number, final_entry_text, write_entry_command); - } - //if (option_debug) - NOTICA("%s\n", CELLIAX_P_LOG, write_entry_command); - } - } - if (conv) - free(conv); - if (start) - free(start); - if (options) - free(options); - } - v = v->next; - } - } -#ifdef CELLIAX_LIBCSV - if (tocsv) { - - v = ast_variable_browse(cfg, context); - /* Find all candidate extensions */ - while (v) { - /* Find a candidate extension */ - start = strdup(v->value); - if (strcasestr(start, "fromcell=yes")) { - fromcell = 1; - fromskype = 0; - - } - if (strcasestr(start, "fromskype=yes")) { - fromcell = 0; - fromskype = 1; - - } - - if (start && !strcasestr(start, "hidefromdir=yes")) { - memset(name, 0, sizeof(name)); - memset(phonebook_direct_calling_ext, 0, sizeof(phonebook_direct_calling_ext)); - memset(write_entry_command, 0, sizeof(write_entry_command)); - memset(entry_number, 0, sizeof(entry_number)); - memset(entry_text, 0, sizeof(entry_text)); - memset(final_entry_text, 0, sizeof(final_entry_text)); - - DEBUGA_AT("v->name=%s\n", CELLIAX_P_LOG, v->name); - DEBUGA_AT("v->value=%s\n", CELLIAX_P_LOG, v->value); - - stringp = start; - strsep(&stringp, ","); - pos = strsep(&stringp, ","); - if (pos) { - ast_copy_string(name, pos, sizeof(name)); - if (strchr(pos, ' ')) { - space = strchr(pos, ' '); - *space = '\0'; - } - if (pos) { - conv = celliax_dir_convert(pos); - DEBUGA_AT("%s%s<\n", CELLIAX_P_LOG, pos, conv); - - options = strdup(v->value); - strsep(&options, ","); - strsep(&options, ","); - strsep(&options, ","); - strsep(&options, ","); - DEBUGA_AT("options=%s\n", CELLIAX_P_LOG, options); - - while ((s = strsep(&options, "|"))) { - value = s; - if ((var = strsep(&value, "=")) && value) { - DEBUGA_AT("var=%s value=%s\n", CELLIAX_P_LOG, var, value); - if (!strcmp(var, "phonebook_direct_calling_ext")) - strncpy(phonebook_direct_calling_ext, value, 6); - } - } - - //FIXME choose a logic for fields maximum lenght - res = - snprintf(entry_number, sizeof(entry_number) - 1, "%s%s%d%s%s", argv[2], "p", - p->celliax_dir_prefix, "p", phonebook_direct_calling_ext); - if (res == (sizeof(entry_number) - 1) - || res > (sizeof(entry_number) - 1)) { - ERRORA("entry_number truncated, was: '%s%s%d%s%s', now is: '%s'\n", - CELLIAX_P_LOG, argv[2], "p", p->celliax_dir_prefix, "p", - phonebook_direct_calling_ext, entry_number); - //FIXME: abort ??? - - } - - res = snprintf(final_entry_text, sizeof(final_entry_text) - 1, "%s", name); //FIXME result not checked - - int i, a; - - a = 0; - for (i = 0; i < p->csv_complete_name_pos - 1; i++) { - if (p->csv_separator_is_semicolon) - write_entry_command[a] = ';'; - else - write_entry_command[a] = ','; - a++; - } - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - - write_entry_command[a] = '"'; - a++; - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - for (i = 0; i < strlen(final_entry_text); i++) { - write_entry_command[a] = final_entry_text[i]; - a++; - } - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - write_entry_command[a] = '"'; - a++; - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - for (i = 0; i < (p->csv_business_phone_pos - p->csv_complete_name_pos); i++) { - if (p->csv_separator_is_semicolon) - write_entry_command[a] = ';'; - else - write_entry_command[a] = ','; - a++; - } - - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - - write_entry_command[a] = '"'; - a++; - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - for (i = 0; i < strlen(entry_number); i++) { - write_entry_command[a] = entry_number[i]; - a++; - } - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - write_entry_command[a] = '"'; - a++; - //NOTICA("i=%d a=%d\n", CELLIAX_P_LOG, i, a); - - if (option_debug) - NOTICA("%s\n", CELLIAX_P_LOG, write_entry_command); - } - } - if (conv) - free(conv); - if (start) - free(start); - if (options) - free(options); - } - v = v->next; - } - - } - if (tovcf) { -//TODO implementation here - } -#endif /* CELLIAX_LIBCSV */ - ast_config_destroy(cfg); - return 0; -} - -#ifdef CELLIAX_LIBCSV - -void celliax_cb1(char *s, size_t len, void *data) -{ - struct celliax_pvt *p = data; - char field_content[256]; - - p->csv_fields++; - memset(field_content, 0, sizeof(field_content)); - strncpy(field_content, s, - sizeof(field_content) > (len + 1) ? len : (sizeof(field_content) - 1)); - if (p->csv_fields == p->csv_complete_name_pos) { - strncpy(p->csv_complete_name, field_content, sizeof(p->csv_complete_name) - 1); - } - if (p->csv_fields == p->csv_email_pos) { - strncpy(p->csv_email, field_content, sizeof(p->csv_email) - 1); - } - if (p->csv_fields == p->csv_home_phone_pos) { - strncpy(p->csv_home_phone, field_content, sizeof(p->csv_home_phone) - 1); - } - if (p->csv_fields == p->csv_mobile_phone_pos) { - strncpy(p->csv_mobile_phone, field_content, sizeof(p->csv_mobile_phone) - 1); - } - if (p->csv_fields == p->csv_business_phone_pos) { - strncpy(p->csv_business_phone, field_content, sizeof(p->csv_business_phone) - 1); - } -} - -void celliax_cb2(char c, void *data) -{ - struct celliax_pvt *p = data; - - p->csv_rows++; - p->csv_fields = 0; - - if (p->csv_first_row_is_title && p->csv_rows == 1) { - //do nothing - } else { - if (strlen(p->csv_complete_name)) { - if (option_debug) - NOTICA - ("ROW %d ENDED, complete_name=%s, email=%s, home_phone=%s, mobile_phone=%s, business_phone=%s\n", - CELLIAX_P_LOG, p->csv_rows, - strlen(p->csv_complete_name) ? p->csv_complete_name : "N/A", - strlen(p->csv_email) ? p->csv_email : "N/A", - strlen(p->csv_home_phone) ? p->csv_home_phone : "N/A", - strlen(p->csv_mobile_phone) ? p->csv_mobile_phone : "N/A", - strlen(p->csv_business_phone) ? p->csv_business_phone : "N/A"); - } - - /* write entries in phonebook file */ - if (p->phonebook_writing_fp) { - celliax_dir_entry_extension++; - - if (strlen(p->csv_complete_name)) { - /* let's start with home_phone */ - if (strlen(p->csv_home_phone)) { - fprintf(p->phonebook_writing_fp, - "%s => ,%s %sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcsv=%s|phonebook_entry_owner=%s\n", - p->csv_home_phone, p->csv_complete_name, "HOME", "no", - p->celliax_dir_entry_extension_prefix, "2", celliax_dir_entry_extension, - "yes", "not_specified"); - fprintf(p->phonebook_writing_fp, - "%s => ,%s %sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcsv=%s|phonebook_entry_owner=%s\n", - p->csv_home_phone, p->csv_complete_name, "HOME", "no", - p->celliax_dir_entry_extension_prefix, "3", celliax_dir_entry_extension, - "yes", "not_specified"); - } - - /* now business_phone */ - if (strlen(p->csv_business_phone)) { - fprintf(p->phonebook_writing_fp, - "%s => ,%s %sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcsv=%s|phonebook_entry_owner=%s\n", - p->csv_business_phone, p->csv_complete_name, "BIZ", "no", - p->celliax_dir_entry_extension_prefix, "2", celliax_dir_entry_extension, - "yes", "not_specified"); - fprintf(p->phonebook_writing_fp, - "%s => ,%s %sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcsv=%s|phonebook_entry_owner=%s\n", - p->csv_business_phone, p->csv_complete_name, "BIZ", "no", - p->celliax_dir_entry_extension_prefix, "3", celliax_dir_entry_extension, - "yes", "not_specified"); - } - - /* let's end with mobile_phone */ - if (strlen(p->csv_mobile_phone)) { - fprintf(p->phonebook_writing_fp, - "%s => ,%s %sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcsv=%s|phonebook_entry_owner=%s\n", - p->csv_mobile_phone, p->csv_complete_name, "CELL", "no", - p->celliax_dir_entry_extension_prefix, "2", celliax_dir_entry_extension, - "yes", "not_specified"); - fprintf(p->phonebook_writing_fp, - "%s => ,%s %sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcsv=%s|phonebook_entry_owner=%s\n", - p->csv_mobile_phone, p->csv_complete_name, "CELL", "no", - p->celliax_dir_entry_extension_prefix, "3", celliax_dir_entry_extension, - "yes", "not_specified"); - } - } - - } - - } -} - -#endif /* CELLIAX_LIBCSV */ - -int celliax_console_celliax_dir_import(int fd, int argc, char *argv[]) -{ - int res; - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - char list_command[64]; - char fn[256]; - char date[256] = ""; - time_t t; - char *configfile = CELLIAX_DIR_CONFIG; - int add_to_celliax_dir_conf = 1; - //int fromskype = 0; - int fromcell = 0; -#ifdef CELLIAX_LIBCSV - int fromcsv = 0; - int fromvcf = 0; -#endif /* CELLIAX_LIBCSV */ - - if (argc < 3 || argc > 4) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, "No \"current\" console ???, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - - if (!strcasecmp(argv[1], "add")) - add_to_celliax_dir_conf = 1; - else if (!strcasecmp(argv[1], "replace")) - add_to_celliax_dir_conf = 0; - else { - ast_cli(fd, "\n\nYou have neither specified 'add' nor 'replace'\n\n"); - return RESULT_SHOWUSAGE; - } - - //if (!strcasecmp(argv[2], "fromskype")) - //fromskype = 1; - //else - - if (!strcasecmp(argv[2], "fromcell")) - fromcell = 1; -#ifdef CELLIAX_LIBCSV - else if (!strcasecmp(argv[2], "fromcsv")) - fromcsv = 1; - else if (!strcasecmp(argv[2], "fromvcf")) - fromvcf = 1; -#endif /* CELLIAX_LIBCSV */ - else { - ast_cli(fd, "\n\nYou have neither specified 'fromcell' neither 'fromcsv'\n\n"); - return RESULT_SHOWUSAGE; - } - -#ifdef CELLIAX_LIBCSV - if (fromcsv || fromvcf) - if (argc != 4) { - ast_cli(fd, - "\n\nYou have to specify a filename with 'fromcsv' or with 'fromvcf'\n\n"); - return RESULT_SHOWUSAGE; - } -#endif /* CELLIAX_LIBCSV */ - if (fromcell) - if (p->controldevprotocol != PROTOCOL_AT) { - ast_cli(fd, - "Importing from cellphone is currently supported only on \"AT\" cellphones :( !\n"); - //fclose(p->phonebook_writing_fp); - //celliax_dir_create_extensions(); - return RESULT_SUCCESS; - } - - if (fromcell) - if (argc != 3) { - ast_cli(fd, "\n\nYou don't have to specify a filename with 'fromcell'\n\n"); - return RESULT_SHOWUSAGE; - } -#ifdef CELLIAX_LIBCSV - if (fromvcf) { - if (option_debug) - NOTICA("filename is: %s\n", CELLIAX_P_LOG, argv[3]); - ast_cli(fd, "\n\nnot yet implemented :P \n"); - return RESULT_SUCCESS; - } -#endif /* CELLIAX_LIBCSV */ - - /*******************************************************************************************/ - - if (configfile[0] == '/') { - ast_copy_string(fn, configfile, sizeof(fn)); - } else { - snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, configfile); - } - if (option_debug) - NOTICA("Opening '%s'\n", CELLIAX_P_LOG, fn); - time(&t); - ast_copy_string(date, ctime(&t), sizeof(date)); - - if (add_to_celliax_dir_conf) - p->phonebook_writing_fp = fopen(fn, "a+"); - else - p->phonebook_writing_fp = fopen(fn, "w+"); - - if (p->phonebook_writing_fp) { - if (add_to_celliax_dir_conf) { - if (option_debug) - NOTICA("Opened '%s' for appending \n", CELLIAX_P_LOG, fn); - fprintf(p->phonebook_writing_fp, ";!\n"); - fprintf(p->phonebook_writing_fp, ";! Update Date: %s", date); - fprintf(p->phonebook_writing_fp, ";! Updated by: %s, %d\n", __FILE__, __LINE__); - fprintf(p->phonebook_writing_fp, ";!\n"); - } else { - if (option_debug) - NOTICA("Opened '%s' for writing \n", CELLIAX_P_LOG, fn); - fprintf(p->phonebook_writing_fp, ";!\n"); - fprintf(p->phonebook_writing_fp, ";! Automatically generated configuration file\n"); - fprintf(p->phonebook_writing_fp, ";! Filename: %s (%s)\n", configfile, fn); - fprintf(p->phonebook_writing_fp, ";! Creation Date: %s", date); - fprintf(p->phonebook_writing_fp, ";! Generated by: %s, %d\n", __FILE__, __LINE__); - fprintf(p->phonebook_writing_fp, ";!\n"); - fprintf(p->phonebook_writing_fp, "[general]\n\n"); - fprintf(p->phonebook_writing_fp, "[default]\n"); - } - -#ifdef CELLIAX_LIBCSV - //FIXME: if add_to_celliax_dir_conf parse the "old" config file, so to have the correct next entry id-exten - if (fromcsv) { - if (option_debug) - NOTICA("filename is: %s\n", CELLIAX_P_LOG, argv[3]); - -/************************/ - FILE *fp; - struct csv_parser *csvp; - char buf[1024]; - size_t bytes_read; - unsigned char options = 0; - - p->csv_rows = 0; - p->csv_fields = 0; - - if (p->csv_separator_is_semicolon) { - if (csv_init(&csvp, options | CSV_USE_SEMICOLON_SEPARATOR) != 0) { - ERRORA("Failed to initialize csv parser\n", CELLIAX_P_LOG); - return RESULT_SUCCESS; - } - } else { - if (csv_init(&csvp, options) != 0) { - ERRORA("Failed to initialize csv parser\n", CELLIAX_P_LOG); - return RESULT_SUCCESS; - } - - } - - fp = fopen(argv[3], "rb"); - if (!fp) { - ERRORA("Failed to open %s: %s\n", CELLIAX_P_LOG, argv[3], strerror(errno)); - return RESULT_SUCCESS; - } - while ((bytes_read = fread(buf, 1, 1024, fp)) > 0) { - if (csv_parse(csvp, buf, bytes_read, celliax_cb1, celliax_cb2, p) != bytes_read) { - ERRORA("Error while parsing file: %s\n", CELLIAX_P_LOG, - csv_strerror(csv_error(csvp))); - } - } - - csv_fini(csvp, celliax_cb1, celliax_cb2, p); - - if (ferror(fp)) { - ERRORA("Error while reading file %s\n", CELLIAX_P_LOG, argv[3]); - fclose(fp); - return RESULT_SUCCESS; - } - - fclose(fp); - if (option_debug) - NOTICA("%s: %d fields, %d rows\n", CELLIAX_P_LOG, argv[3], p->csv_fields, - p->csv_rows); - - csv_free(csvp); - - /**************************/ - } -#endif /* CELLIAX_LIBCSV */ - - /*******************************************************************************************/ - //if (fromskype) { - //ast_cli(fd, - //"Skype not supported in celliax_dir. Load chan_skypiax and use skypiax_dir!\n"); - //} - - /*******************************************************************************************/ - if (fromcell) { - /* which phonebook to use, use the SIM */ - res = celliax_serial_write_AT_ack(p, "AT+CPBS=SM"); - if (res) { - WARNINGA("AT+CPBS=SM failed, continue\n", CELLIAX_P_LOG); - } - /* which phonebook to use, trying to use combined phone+SIM */ - res = celliax_serial_write_AT_ack(p, "AT+CPBS=MT"); - if (res) { - WARNINGA("AT+CPBS=MT failed, continue\n", CELLIAX_P_LOG); - } - /* How many entries in phonebook */ - p->phonebook_querying = 1; - res = celliax_serial_write_AT_ack(p, "AT+CPBR=?"); - if (res) { - WARNINGA("AT+CPBR=? failed, continue\n", CELLIAX_P_LOG); - } - p->phonebook_querying = 0; - /* list entries in phonebook, give the SIM the time to answer */ - WARNINGA - ("About to querying the cellphone phonebook, if the SIM do not answer may stuck here for 20 seconds... Don't worry.\n", - CELLIAX_P_LOG); - sprintf(list_command, "AT+CPBR=%d,%d", p->phonebook_first_entry, - p->phonebook_last_entry); - p->phonebook_listing = 1; - res = celliax_serial_write_AT_expect_longtime(p, list_command, "OK"); - if (res) { - WARNINGA("AT+CPBR=%d,%d failed, continue\n", CELLIAX_P_LOG, - p->phonebook_first_entry, p->phonebook_last_entry); - } - p->phonebook_listing = 0; - } - /*******************************************************************************************/ -#ifdef CELLIAX_LIBCSV - if (fromvcf) { - //TODO implementation here - } -#endif /* CELLIAX_LIBCSV */ - - } else { - ast_cli(fd, "\n\nfailed to open the directoriax.conf configuration file: %s\n", fn); - ERRORA("failed to open the directoriax.conf configuration file: %s\n", CELLIAX_P_LOG, - fn); - return RESULT_FAILURE; - } - - fclose(p->phonebook_writing_fp); - //celliax_dir_create_extensions(); - - return RESULT_SUCCESS; -} - -#endif /* CELLIAX_DIR */ - -#ifdef CELLIAX_FBUS2 - -int celliax_serial_getstatus_FBUS2(struct celliax_pvt *p) -{ - unsigned char MsgBuffer[7]; - int res; - int how_many_reads = 0; - - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - - MsgBuffer[0] = FBUS2_COMMAND_BYTE_1; - MsgBuffer[1] = FBUS2_COMMAND_BYTE_2; - MsgBuffer[2] = 0x00; - MsgBuffer[3] = 0x03; - MsgBuffer[4] = 0x00; - MsgBuffer[5] = FBUS2_IS_LAST_FRAME; - MsgBuffer[6] = celliax_serial_get_seqnum_FBUS2(p); - - if (option_debug > 1) - DEBUGA_FBUS2("asking model, outseqnum %.2X \n", CELLIAX_P_LOG, MsgBuffer[6]); - celliax_serial_write_FBUS2(p, MsgBuffer, 7, FBUS2_TYPE_MODEL_ASK); - usleep(1000); - res = celliax_serial_read_FBUS2(p); //we don't have no monitor neither do_controldev_thread - if (res == -1) { - ERRORA("failed celliax_serial_read_FBUS2\n", CELLIAX_P_LOG); - UNLOCKA(&p->controldev_lock); - return -1; - } - while (res != MsgBuffer[6] && res != FBUS2_TYPE_MODEL_ANSWER) { - usleep(1000); - res = celliax_serial_read_FBUS2(p); - how_many_reads++; - if (res == -1) { - ERRORA("failed celliax_serial_read_FBUS2\n", CELLIAX_P_LOG); - UNLOCKA(&p->controldev_lock); - return -1; - } - if (how_many_reads > 10) { - ERRORA("no expected results in %d celliax_serial_read_FBUS2\n", CELLIAX_P_LOG, - how_many_reads); - UNLOCKA(&p->controldev_lock); - return -1; - } - } - - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - return 0; -} - -int celliax_serial_sync_FBUS2(struct celliax_pvt *p) -{ - unsigned char initc = 0x55; /* FBUS2 initialization char */ - int c, rt; - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - /* init the link (sync receive uart) */ - for (c = 0; c < 55; c++) { /* 55 times */ - usleep(10000); - rt = write(p->controldevfd, &initc, 1); - if (rt != 1) { - ERRORA("serial error: %s", CELLIAX_P_LOG, strerror(errno)); - UNLOCKA(&p->controldev_lock); - return -1; - } - } - time(&p->celliax_serial_synced_timestamp); - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - return 0; -} - -int celliax_serial_answer_FBUS2(struct celliax_pvt *p) -{ - unsigned char MsgBuffer[6]; - - celliax_serial_security_command_FBUS2(p); - - MsgBuffer[0] = FBUS2_COMMAND_BYTE_1; - MsgBuffer[1] = FBUS2_COMMAND_BYTE_2; - MsgBuffer[2] = FBUS2_SECURIY_CALL_COMMANDS; - MsgBuffer[3] = FBUS2_SECURIY_CALL_COMMAND_ANSWER; - MsgBuffer[4] = FBUS2_IS_LAST_FRAME; - MsgBuffer[5] = celliax_serial_get_seqnum_FBUS2(p); - if (option_debug > 1) - DEBUGA_FBUS2("celliax_serial_answer_FBUS2, outseqnum %.2X \n", CELLIAX_P_LOG, - MsgBuffer[5]); - celliax_serial_write_FBUS2(p, MsgBuffer, 6, FBUS2_TYPE_SECURITY); - DEBUGA_FBUS2("FBUS2: sent commands to answer the call\n", CELLIAX_P_LOG); - p->interface_state = AST_STATE_UP; //FIXME - - return 0; -} - -int celliax_serial_call_FBUS2(struct celliax_pvt *p, char *dstr) -{ - unsigned char MsgBufferNum[255]; - int i; - - celliax_serial_security_command_FBUS2(p); - - MsgBufferNum[0] = FBUS2_COMMAND_BYTE_1; - MsgBufferNum[1] = FBUS2_COMMAND_BYTE_2; - MsgBufferNum[2] = FBUS2_SECURIY_CALL_COMMANDS; - MsgBufferNum[3] = FBUS2_SECURIY_CALL_COMMAND_CALL; - for (i = 0; i < strlen(dstr); i++) { - MsgBufferNum[4 + i] = dstr[i]; - } - MsgBufferNum[4 + strlen(dstr)] = 0x00; /* required by FBUS2 prot */ - MsgBufferNum[4 + strlen(dstr) + 1] = FBUS2_IS_LAST_FRAME; - MsgBufferNum[4 + strlen(dstr) + 2] = celliax_serial_get_seqnum_FBUS2(p); - if (option_debug > 1) - DEBUGA_FBUS2("celliax_serial_call_FBUS2, outseqnum %.2X \n", CELLIAX_P_LOG, - MsgBufferNum[4 + strlen(dstr) + 2]); - celliax_serial_write_FBUS2(p, MsgBufferNum, 5 + strlen(dstr) + 2, FBUS2_TYPE_SECURITY); - - p->phone_callflow = CALLFLOW_CALL_DIALING; - p->interface_state = AST_STATE_DIALING; - if (option_debug) - DEBUGA_FBUS2("FBUS2: sent commands to call\n", CELLIAX_P_LOG); - return 0; -} - -int celliax_serial_hangup_FBUS2(struct celliax_pvt *p) -{ - unsigned char MsgBuffer[6]; - - if (p->interface_state != AST_STATE_DOWN) { - celliax_serial_security_command_FBUS2(p); - - MsgBuffer[0] = FBUS2_COMMAND_BYTE_1; - MsgBuffer[1] = FBUS2_COMMAND_BYTE_2; - MsgBuffer[2] = FBUS2_SECURIY_CALL_COMMANDS; - MsgBuffer[3] = FBUS2_SECURIY_CALL_COMMAND_RELEASE; - MsgBuffer[4] = FBUS2_IS_LAST_FRAME; - MsgBuffer[5] = celliax_serial_get_seqnum_FBUS2(p); - - if (option_debug > 1) - DEBUGA_FBUS2("celliax_serial_hangup_FBUS2, outseqnum %.2X \n", CELLIAX_P_LOG, - MsgBuffer[5]); - celliax_serial_write_FBUS2(p, MsgBuffer, 6, FBUS2_TYPE_SECURITY); - - DEBUGA_FBUS2("FBUS2: sent commands to hangup the call\n", CELLIAX_P_LOG); - - } - p->interface_state = AST_STATE_DOWN; //FIXME - p->phone_callflow = CALLFLOW_CALL_IDLE; //FIXME - return 0; -} - -int celliax_serial_config_FBUS2(struct celliax_pvt *p) -{ - unsigned char MsgBuffer[6]; - int res; - int how_many_reads = 0; - - MsgBuffer[0] = FBUS2_COMMAND_BYTE_1; - MsgBuffer[1] = FBUS2_COMMAND_BYTE_2; - MsgBuffer[2] = FBUS2_SECURIY_EXTENDED_COMMANDS; - MsgBuffer[3] = FBUS2_SECURIY_EXTENDED_COMMAND_ON; - MsgBuffer[4] = FBUS2_IS_LAST_FRAME; - MsgBuffer[5] = celliax_serial_get_seqnum_FBUS2(p); - - if (option_debug > 1) - DEBUGA_FBUS2("activating security commands for getting IMEI, outseqnum %.2X \n", - CELLIAX_P_LOG, MsgBuffer[5]); - celliax_serial_write_FBUS2(p, MsgBuffer, 6, FBUS2_TYPE_SECURITY); - res = celliax_serial_read_FBUS2(p); //we don't have no monitor neither do_controldev_thread - if (res == -1) { - ERRORA("failed celliax_serial_read_FBUS2\n", CELLIAX_P_LOG); - return -1; - } - while (res != MsgBuffer[5] && res != FBUS2_SECURIY_EXTENDED_COMMAND_ON) { - usleep(1000); - res = celliax_serial_read_FBUS2(p); - how_many_reads++; - if (res == -1) { - ERRORA("failed celliax_serial_read_FBUS2\n", CELLIAX_P_LOG); - return -1; - } - if (how_many_reads > 10) { - ERRORA("no expected results in %d celliax_serial_read_FBUS2\n", CELLIAX_P_LOG, - how_many_reads); - return -1; - } - } - - MsgBuffer[0] = FBUS2_COMMAND_BYTE_1; - MsgBuffer[1] = FBUS2_COMMAND_BYTE_2; - MsgBuffer[2] = FBUS2_SECURIY_IMEI_COMMANDS; - MsgBuffer[3] = FBUS2_SECURIY_IMEI_COMMAND_GET; - MsgBuffer[4] = FBUS2_IS_LAST_FRAME; - MsgBuffer[5] = celliax_serial_get_seqnum_FBUS2(p); - if (option_debug > 1) - DEBUGA_FBUS2("celliax_serial_get_IMEI_init_FBUS2, outseqnum %.2X \n", CELLIAX_P_LOG, - MsgBuffer[5]); - celliax_serial_write_FBUS2(p, MsgBuffer, 6, FBUS2_TYPE_SECURITY); - res = celliax_serial_read_FBUS2(p); //we don't have no monitor neither do_controldev_thread - if (res == -1) { - ERRORA("failed celliax_serial_read_FBUS2\n", CELLIAX_P_LOG); - return -1; - } - how_many_reads = 0; - while (res != MsgBuffer[5] && res != CALLFLOW_GOT_IMEI) { - usleep(1000); - res = celliax_serial_read_FBUS2(p); - how_many_reads++; - if (res == -1) { - ERRORA("failed celliax_serial_read_FBUS2\n", CELLIAX_P_LOG); - return -1; - } - if (how_many_reads > 10) { - ERRORA("no expected results in %d celliax_serial_read_FBUS2\n", CELLIAX_P_LOG, - how_many_reads); - //FIXME return -1; - return 0; - } - } - - if (option_debug > 1) - DEBUGA_FBUS2("xxxxx GOT IMEI xxxxx res=%d %.2X \n", CELLIAX_P_LOG, res, res); - - return 0; -} - -int celliax_serial_get_seqnum_FBUS2(struct celliax_pvt *p) -{ - if (p->seqnumfbus > FBUS2_SEQNUM_MAX || p->seqnumfbus < FBUS2_SEQNUM_MIN) { - ERRORA("p->seqnumfbus: %2.X\n", CELLIAX_P_LOG, p->seqnumfbus); - p->seqnumfbus = FBUS2_SEQNUM_MIN; - } - - if (p->seqnumfbus == FBUS2_SEQNUM_MAX) { - p->seqnumfbus = FBUS2_SEQNUM_MIN; - } else { - p->seqnumfbus++; - } - if (option_debug > 10) - DEBUGA_FBUS2("sqnum: %2.X\n", CELLIAX_P_LOG, p->seqnumfbus); - return p->seqnumfbus; -} - -int celliax_serial_security_command_FBUS2(struct celliax_pvt *p) -{ - unsigned char MsgBuffer[6]; - - MsgBuffer[0] = FBUS2_COMMAND_BYTE_1; - MsgBuffer[1] = FBUS2_COMMAND_BYTE_2; - MsgBuffer[2] = FBUS2_SECURIY_EXTENDED_COMMANDS; - MsgBuffer[3] = FBUS2_SECURIY_EXTENDED_COMMAND_ON; - MsgBuffer[4] = FBUS2_IS_LAST_FRAME; - MsgBuffer[5] = celliax_serial_get_seqnum_FBUS2(p); - - if (option_debug > 1) - DEBUGA_FBUS2("activating security commands, outseqnum %.2X \n", CELLIAX_P_LOG, - MsgBuffer[5]); - celliax_serial_write_FBUS2(p, MsgBuffer, 6, FBUS2_TYPE_SECURITY); - return 0; -} - -/*! - * \brief Write on the serial port for all the FBUS2 (old Nokia) functions - * \param p celliax_pvt - * \param len lenght of buffer2 - * \param buffer2 chars to be written - * - * Write on the serial port for all the FBUS2 (old Nokia) functions - * - * \return the number of chars written on the serial, - * that can be different from len (or negative) in case of errors. - */ -int celliax_serial_send_FBUS2(struct celliax_pvt *p, int len, unsigned char *mesg_ptr) -{ - int ret; - size_t actual = 0; - unsigned char *mesg_ptr2 = mesg_ptr; - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - do { - ret = write(p->controldevfd, mesg_ptr, len - actual); - if (ret < 0 && errno == EAGAIN) - continue; - if (ret < 0) { - if (actual != len) - ERRORA("celliax_serial_write error: %s", CELLIAX_P_LOG, strerror(errno)); - UNLOCKA(&p->controldev_lock); - return -1; - } - actual += ret; - mesg_ptr += ret; - usleep(10000); - } while (actual < len); - - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - if (option_debug > 10) { - int i; - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - - for (i = 0; i < len; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", mesg_ptr2[i]); - if (debug_buf_pos > ((char *) &debug_buf + 1000)) - break; - } - DEBUGA_FBUS2("%s was sent down the wire\n", CELLIAX_P_LOG, debug_buf); - } - - return 0; -} - -/*! - * \brief Flags as acknowledged an FBUS2 message previously sent - * \param p celliax_pvt - * \param seqnum identifier of the message to be acknowledged - * - * Called upon receiving an FBUS2 acknoledgement message, browse the fbus2_outgoing_list - * looking for the seqnum sent FBUS2 message, and flags it as acknowledged. - * (if an outgoing FBUS2 message is not aknowledged by the cellphone in a while, - * it will be retransmitted) - * - * \return 0 on error, 1 otherwise - */ -int celliax_serial_list_acknowledge_FBUS2(struct celliax_pvt *p, int seqnum) -{ - struct fbus2_msg *ptr; - - ptr = p->fbus2_outgoing_list; - if (ptr == NULL) { - ERRORA("fbus2_outgoing_list is NULL ?\n", CELLIAX_P_LOG); - return -1; - } - PUSHA_UNLOCKA(&p->fbus2_outgoing_list_lock); - LOKKA(&p->fbus2_outgoing_list_lock); - while (ptr->next != NULL) - ptr = ptr->next; - while (ptr->acknowledged == 0) { - if (ptr->seqnum == seqnum) { - ptr->acknowledged = 1; - if (option_debug > 1) - DEBUGA_FBUS2("Acknowledgment to %.2X\n", CELLIAX_P_LOG, seqnum); - - DEBUGA_FBUS2("PREFREE OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_FBUS2(p, p->fbus2_outgoing_list); - if (ptr->previous) { - if (ptr->next) { - ptr->previous->next = ptr->next; - } else { - ptr->previous->next = NULL; - } - } - if (ptr->next) { - if (ptr->previous) { - ptr->next->previous = ptr->previous; - } else { - ptr->next->previous = NULL; - } - } - - if ((NULL == ptr->next) && (NULL == ptr->previous)) { /* bug catched by Wojciech Andralojc */ - if (option_debug > 1) - DEBUGA_FBUS2("FREEING LAST\n", CELLIAX_P_LOG); - p->fbus2_outgoing_list = NULL; - p->fbus2_outgoing_list = celliax_serial_list_init_FBUS2(p); - } - - free(ptr); - DEBUGA_FBUS2("POSTFREE OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_FBUS2(p, p->fbus2_outgoing_list); - - break; - } - if (ptr->previous != NULL) { - ptr = ptr->previous; - } else { - ERRORA - ("The phone sent us an acknowledgement referring to a msg with a seqnum that is not in our sent list: %.2X\n", - CELLIAX_P_LOG, seqnum); - break; - } - } - UNLOCKA(&p->fbus2_outgoing_list_lock); - POPPA_UNLOCKA(&p->fbus2_outgoing_list_lock); - return 0; -} - -/*! - * \brief Sends an FBUS2 message or resends it if it was not acknowledged - * \param p celliax_pvt - * - * Called by celliax_serial_read_FBUS2, browse the fbus2_outgoing_list looking for FBUS2 messages to be sent, - * or for FBUS2 messages previously sent but not yet acknoledged. - * (if an outgoing FBUS2 message is not aknowledged by the cellphone in a while, - * it will be retransmitted) - * - * \return 0 on error, 1 otherwise - */ -int celliax_serial_send_if_time_FBUS2(struct celliax_pvt *p) -{ - struct fbus2_msg *ptr; - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - ptr = p->fbus2_outgoing_list; - if (ptr == NULL) { - ERRORA("fbus2_outgoing_list is NULL ?\n", CELLIAX_P_LOG); - return -1; - } - while (ptr->next != NULL) { - WARNINGA("fbus2_outgoing_list->next is not null ?\n", CELLIAX_P_LOG); - ptr = ptr->next; //FIXME what to do? - } - while (ptr->sent == 0 && ptr->acknowledged == 0) { - if (ptr->previous != NULL) { - ptr = ptr->previous; - } else - break; - } - while (ptr->sent == 1 && ptr->acknowledged == 0) { - if (ptr->previous != NULL) { - ptr = ptr->previous; - } else - break; - } - if (ptr->sent == 1 && ptr->acknowledged == 1) { - if (ptr->next != NULL) { - ptr = ptr->next; - } - } - if (ptr->sent == 1 && ptr->acknowledged == 0 && ptr->msg > 0) { - if ((tv.tv_sec * 1000 + tv.tv_usec / 1000) > - ((ptr->tv_sec * 1000 + ptr->tv_usec / 1000) + 1000)) { - - PUSHA_UNLOCKA(&p->fbus2_outgoing_list_lock); - LOKKA(&p->fbus2_outgoing_list_lock); - - if (ptr->sent == 1 && ptr->acknowledged == 0 && ptr->msg > 0) { //retest, maybe has been changed? - if ((tv.tv_sec * 1000 + tv.tv_usec / 1000) > ((ptr->tv_sec * 1000 + ptr->tv_usec / 1000) + 1000)) { //retest, maybe has been changed? - - if (option_debug > 1) - DEBUGA_FBUS2("RESEND %.2X, passed %ld ms, sent %d times\n", CELLIAX_P_LOG, - ptr->seqnum, - ((tv.tv_sec * 1000 + tv.tv_usec / 1000) - - (ptr->tv_sec * 1000 + ptr->tv_usec / 1000)), - ptr->how_many_sent); - if (ptr->how_many_sent > 9) { - ERRORA("RESEND %.2X, passed %ld ms, sent %d times\n", CELLIAX_P_LOG, - ptr->seqnum, - ((tv.tv_sec * 1000 + tv.tv_usec / 1000) - - (ptr->tv_sec * 1000 + ptr->tv_usec / 1000)), ptr->how_many_sent); - - UNLOCKA(&p->fbus2_outgoing_list_lock); - return -1; - } - - celliax_serial_send_FBUS2(p, ptr->len, ptr->buffer); - if (ptr->buffer[3] == FBUS2_ACK_BYTE) { - if (option_debug > 1) - DEBUGA_FBUS2("RESEND ACK, passed %ld ms, sent %d times\n", CELLIAX_P_LOG, - ((tv.tv_sec * 1000 + tv.tv_usec / 1000) - - (ptr->tv_sec * 1000 + ptr->tv_usec / 1000)), - ptr->how_many_sent); - ptr->acknowledged = 1; - ptr->msg = FBUS2_OUTGOING_ACK; - } - ptr->tv_sec = tv.tv_sec; - ptr->tv_usec = tv.tv_usec; - ptr->sent = 1; - ptr->how_many_sent++; - if (option_debug > 1) { - DEBUGA_FBUS2("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_FBUS2(p, p->fbus2_outgoing_list); - DEBUGA_FBUS2("OUTGOING list END\n", CELLIAX_P_LOG); - } - - } - } - - UNLOCKA(&p->fbus2_outgoing_list_lock); - POPPA_UNLOCKA(&p->fbus2_outgoing_list_lock); - } - } - if (ptr->sent == 0 && ptr->acknowledged == 0 && ptr->msg > 0) { - - PUSHA_UNLOCKA(&p->fbus2_outgoing_list_lock); - LOKKA(&p->fbus2_outgoing_list_lock); - - if (ptr->sent == 0 && ptr->acknowledged == 0 && ptr->msg > 0) { //retest, maybe has been changed? - - if (option_debug > 1) - DEBUGA_FBUS2("SENDING 1st TIME %.2X\n", CELLIAX_P_LOG, ptr->seqnum); - celliax_serial_send_FBUS2(p, ptr->len, ptr->buffer); - if (ptr->buffer[3] == FBUS2_ACK_BYTE) { - if (option_debug > 1) - DEBUGA_FBUS2("SENDING 1st TIME ACK\n", CELLIAX_P_LOG); - ptr->acknowledged = 1; - ptr->msg = FBUS2_OUTGOING_ACK; - } - ptr->tv_sec = tv.tv_sec; - ptr->tv_usec = tv.tv_usec; - ptr->sent = 1; - ptr->how_many_sent++; - if (option_debug > 1) { - DEBUGA_FBUS2("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_FBUS2(p, p->fbus2_outgoing_list); - DEBUGA_FBUS2("OUTGOING list END\n", CELLIAX_P_LOG); - } - - } - - UNLOCKA(&p->fbus2_outgoing_list_lock); - POPPA_UNLOCKA(&p->fbus2_outgoing_list_lock); - - } - return 0; -} - -int celliax_serial_write_FBUS2(struct celliax_pvt *p, unsigned char *MsgBuffer, - int MsgLength, unsigned char MsgType) -{ - unsigned char buffer2[FBUS2_MAX_TRANSMIT_LENGTH + 10]; - unsigned char checksum = 0; - int i, len; - struct timeval tv; - struct timezone tz; - - buffer2[0] = FBUS2_SERIAL_FRAME_ID; - buffer2[1] = FBUS2_DEVICE_PHONE; /* destination */ - buffer2[2] = FBUS2_DEVICE_PC; /* source */ - buffer2[3] = MsgType; - buffer2[4] = 0x00; /* required by protocol */ - buffer2[5] = MsgLength; - - memcpy(buffer2 + 6, MsgBuffer, MsgLength); - len = MsgLength + 6; - - /* Odd messages require additional padding 0x00 byte */ - if (MsgLength % 2) - buffer2[len++] = 0x00; /* optional PaddingByte */ - - checksum = 0; - for (i = 0; i < len; i += 2) - checksum ^= buffer2[i]; - buffer2[len++] = checksum; /* ChkSum1 */ - - checksum = 0; - for (i = 1; i < len; i += 2) - checksum ^= buffer2[i]; - buffer2[len++] = checksum; /* ChkSum2 */ - - if (option_debug > 10) { - int i; - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - - for (i = 0; i < len; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", buffer2[i]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - if (buffer2[3] == FBUS2_ACK_BYTE) { - DEBUGA_FBUS2("%s to be written, ACK\n", CELLIAX_P_LOG, debug_buf); - } else { - DEBUGA_FBUS2("%s to be written\n", CELLIAX_P_LOG, debug_buf); - } - } - - gettimeofday(&tv, &tz); - - if (buffer2[3] != FBUS2_ACK_BYTE) { - p->fbus2_outgoing_list = celliax_serial_list_init_FBUS2(p); - p->fbus2_outgoing_list->msg = 11; - - p->fbus2_outgoing_list->len = len; - for (i = 0; i < len; i++) { - p->fbus2_outgoing_list->buffer[i] = buffer2[i]; - } - p->fbus2_outgoing_list->seqnum = MsgBuffer[MsgLength - 1]; - if (option_debug > 1) { - DEBUGA_FBUS2("OUTGOING LIST seqnum is %2.X\n", CELLIAX_P_LOG, - MsgBuffer[MsgLength - 1]); - - DEBUGA_FBUS2("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_FBUS2(p, p->fbus2_outgoing_list); - DEBUGA_FBUS2("OUTGOING list END\n", CELLIAX_P_LOG); - } - } else { - usleep(100); - celliax_serial_send_FBUS2(p, len, buffer2); - } - - return 0; -} - -int celliax_serial_send_ack_FBUS2(struct celliax_pvt *p, unsigned char MsgType, - unsigned char MsgSequence) -{ - unsigned char buffer2[2]; - - buffer2[0] = MsgType; - buffer2[1] = (MsgSequence - FBUS2_SEQNUM_MIN); - - if (option_debug > 1) - DEBUGA_FBUS2("SENDING ACK to %2.X, seqack %2.X \n", CELLIAX_P_LOG, MsgSequence, - (MsgSequence - FBUS2_SEQNUM_MIN)); - /* Sending to phone */ - return celliax_serial_write_FBUS2(p, buffer2, 2, FBUS2_ACK_BYTE); -} - -struct fbus2_msg *celliax_serial_list_init_FBUS2(struct celliax_pvt *p) -{ - struct fbus2_msg *list; - list = p->fbus2_outgoing_list; - - PUSHA_UNLOCKA(&p->fbus2_outgoing_list_lock); - LOKKA(&p->fbus2_outgoing_list_lock); - if (list == NULL) { - list = malloc(sizeof(*(list))); - list->msg = 0; - list->seqnum = 0; - list->len = 0; - list->acknowledged = 0; - list->how_many_sent = 0; - list->sent = 0; - list->tv_sec = 0; - list->tv_usec = 0; - list->next = NULL; - list->previous = NULL; - } - if (list->msg != 0) { - struct fbus2_msg *new; - new = malloc(sizeof(*new)); - new->msg = 0; - new->seqnum = 0; - new->len = 0; - new->acknowledged = 0; - new->how_many_sent = 0; - new->sent = 0; - new->tv_sec = 0; - new->tv_usec = 0; - new->next = NULL; - new->previous = list; - list->next = new; - list = new; - } - UNLOCKA(&p->fbus2_outgoing_list_lock); - POPPA_UNLOCKA(&p->fbus2_outgoing_list_lock); - return list; -} - -int celliax_serial_list_print_FBUS2(struct celliax_pvt *p, struct fbus2_msg *list) -{ - struct fbus2_msg *ptr; - ptr = list; - while (ptr) { - if (option_debug > 3) - DEBUGA_FBUS2 - ("PTR msg is: %d, seqnum is %.2X, tv_sec is %d, tv_usec is %d, acknowledged is: %d," - " sent is:%d, how_many_sent is: %d\n", CELLIAX_P_LOG, ptr->msg, ptr->seqnum, - ptr->tv_sec, ptr->tv_usec, ptr->acknowledged, ptr->sent, ptr->how_many_sent); - ptr = ptr->previous; - } - return 0; -} - -int celliax_serial_read_FBUS2(struct celliax_pvt *p) -{ - int read_count; - int select_err; - fd_set read_fds; - struct timeval timeout; - int fbus_mesg = 0; - int i; - - FD_ZERO(&read_fds); - FD_SET(p->controldevfd, &read_fds); - timeout.tv_sec = 0; - timeout.tv_usec = 50000; - - if ((select_err = select(p->controldevfd + 1, &read_fds, NULL, NULL, &timeout)) > 0) { - timeout.tv_sec = 0; //reset the timeout, linux modify it - timeout.tv_usec = 50000; //reset the timeout, linux modify it - PUSHA_UNLOCKA(&p->controldev_lock); - LOKKA(&p->controldev_lock); - while ((select_err = - select(p->controldevfd + 1, &read_fds, NULL, NULL, &timeout)) > 0) { - gettimeofday(&p->fbus2_list_tv, &p->fbus2_list_tz); - read_count = read(p->controldevfd, p->rxm, 255); - - if (read_count == 0) { - ERRORA - ("read 0 bytes!!! Nenormalno! Marking this celliax_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - CELLIAX_P_LOG, p->controldevice_name); - p->controldev_dead = 1; - close(p->controldevfd); - UNLOCKA(&p->controldev_lock); - if (p->owner) { - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - p->owner->hangupcause = AST_CAUSE_FAILURE; - } - return -1; - } - if (option_debug > 10) { - int c; - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - for (c = 0; c < read_count; c++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", p->rxm[c]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - DEBUGA_FBUS2("%s READ AT seconds=%ld usec=%6ld read_count=%d\n", CELLIAX_P_LOG, - debug_buf, p->fbus2_list_tv.tv_sec, p->fbus2_list_tv.tv_usec, - read_count); - } - - for (i = 0; i < read_count; i++) { - if (p->rxm[i] == FBUS2_DEVICE_PHONE && p->rxm[i - 1] == FBUS2_DEVICE_PC - && p->rxm[i - 2] == FBUS2_SERIAL_FRAME_ID) { - /* if we have identified the start of an fbus2 frame sent to us by the phone */ - /* clean the array, copy into it the beginning of the frame, move the counter in the array after the last byte copied */ - memset(p->array, 0, 255); - p->array[0] = FBUS2_SERIAL_FRAME_ID; - p->array[1] = FBUS2_DEVICE_PC; - p->arraycounter = 2; - } - if (p->rxm[i] == FBUS2_SERIAL_FRAME_ID && read_count == 1) { /* quick hack to try to identify the lone char - at the beginning a frame, often returned by - ark3116 based datacables */ - /* if we have identified the start of an fbus2 frame sent to us by the phone */ - /* clean the array, copy into it the beginning of the frame, move the counter in the array after the last byte copied */ - memset(p->array, 0, 255); - p->arraycounter = 0; - } - - /* continue copying into the array, until... */ - p->array[p->arraycounter] = p->rxm[i]; - /* we reach the end of the incoming frame, its lenght is in the p->array[5] byte, plus overhead */ - if (p->arraycounter == p->array[5] + 7) { - /* start categorizing frames */ - int seqnum; - int known = 0; - - /* ACK frames are always of lenght 10, without padding */ - seqnum = p->array[p->arraycounter - 2]; - /* first step in categorizing frames, look at the general kind of frame, in p->array[3] */ - switch (p->array[3]) { -/****************************************************************/ - case FBUS2_ACK_BYTE: - /* this is an ACKnowledgement frame sent to us in reply to an item we sent, take note we were ACKnowledged, no need to resend the item */ - if (option_debug > 1) - DEBUGA_FBUS2("INCOMING ACK, seqack %.2X \n", CELLIAX_P_LOG, seqnum); - if (seqnum == 0x80) { /* reset */ - seqnum = 0x00; - DEBUGA_FBUS2 - ("seqack was 0x80, interpreting as 0x00, first acknowledgement (session begin?) of our first sent item 0x40\n", - CELLIAX_P_LOG); - } - /* an ACK frame has the same seqnum as the item it acknowledge, minus 0x40, so here we obtain the seqnum of the item that has been ACKnowledged */ - fbus_mesg = seqnum + FBUS2_SEQNUM_MIN; - /* take note that the item sent was ACKnowledged, so no need to resend it */ - celliax_serial_list_acknowledge_FBUS2(p, fbus_mesg); - /* this frame has been categorized, bail out from the loop */ - known = 1; - break; -/****************************************************************/ - case FBUS2_TYPE_CALL_DIVERT: - if (option_debug > 1) - DEBUGA_FBUS2("CALL DIVERT SIGNALING seqnum %.2X \n", CELLIAX_P_LOG, seqnum); - fbus_mesg = FBUS2_TYPE_CALL_DIVERT; - /* this signal us that we have some settings in line divert, let's use it as activation of the line when we call */ - if (p->interface_state == AST_STATE_DIALING) { - p->interface_state = AST_STATE_UP; - p->phone_callflow = CALLFLOW_CALL_ACTIVE; - ast_setstate(p->owner, AST_STATE_RINGING); - celliax_queue_control(p->owner, AST_CONTROL_ANSWER); - if (option_debug) - DEBUGA_FBUS2 - ("call is active, I know it's not yet true, but 3310 do not give us remote answer signaling\n", - CELLIAX_P_LOG); - } - /* this frame has been categorized, bail out from the loop */ - known = 1; - break; - -/****************************************************************/ - /* this kind of frames is an answer to "ask model" actions */ - case FBUS2_TYPE_MODEL_ANSWER: - if (1) { - int newline = 0; - int c = i = 0; - unsigned char model[10]; - for (i = 10; i < p->arraycounter; i++) { - if (p->array[i] == '\n') - newline++; - if (newline == 2) { - if (p->array[i] != '\n') { - model[c] = p->array[i]; - c++; - } - } - if (newline == 3) { - break; - } - if (c == 9) - break; - } - model[c] = '\0'; - DEBUGA_FBUS2("FBUS2 PHONE MODEL is: %s, inseqnum %.2X \n", CELLIAX_P_LOG, - model, seqnum); - } - known = 1; - fbus_mesg = FBUS2_TYPE_MODEL_ANSWER; - break; -/****************************************************************/ - /* this kind of frames is an answer to "security enabled" actions */ - case FBUS2_TYPE_SECURITY: - switch (p->array[8]) { - /* this subkind of frames is an answer to "security enabled" CALL actions */ - case FBUS2_SECURIY_CALL_COMMANDS: - switch (p->array[9]) { - /* this sub-subkind of frames tell us that we answered the call */ - case FBUS2_SECURIY_CALL_COMMAND_ANSWER: - p->interface_state = AST_STATE_UP; - p->phone_callflow = CALLFLOW_CALL_ACTIVE; - - /* set the channel state to UP, we've answered */ - if (ast_setstate(p->owner, AST_STATE_UP)) { - ERRORA("ast_setstate failed, BAD\n", CELLIAX_P_LOG); - } - - if (option_debug > 1) - DEBUGA_FBUS2("ANSWERED CALL, inseqnum %.2X \n", CELLIAX_P_LOG, seqnum); - known = 1; - break; - /* this sub-subkind of frames tell us that we released the call */ - case FBUS2_SECURIY_CALL_COMMAND_RELEASE: - p->interface_state = AST_STATE_DOWN; - p->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_FBUS2("RELEASED CALL, inseqnum %.2X \n", CELLIAX_P_LOG, seqnum); - fbus_mesg = CALLFLOW_CALL_RELEASED; - known = 1; - break; - } - break; - /* this subkind of frames is an answer to "enable security commands" action */ - case FBUS2_SECURIY_EXTENDED_COMMANDS: - if (option_debug > 1) - DEBUGA_FBUS2("SECURITY EXTENDED COMMANDS ON, inseqnum %.2X \n", - CELLIAX_P_LOG, seqnum); - fbus_mesg = FBUS2_SECURIY_EXTENDED_COMMAND_ON; - known = 1; - break; - /* this subkind of frames is an answer to "get IMEI" action */ - case FBUS2_SECURIY_IMEI_COMMANDS: - if (option_debug > 1) - DEBUGA_FBUS2("CALLFLOW_GOT_IMEI, inseqnum %.2X \n", CELLIAX_P_LOG, - seqnum); - fbus_mesg = CALLFLOW_GOT_IMEI; - known = 1; - break; - } - break; -/****************************************************************/ - /* this kind of frames is about SMSs */ - case FBUS2_TYPE_SMS: - switch (p->array[9]) { - /* this subkind of frames is about an INCOMING SMS */ - case FBUS2_SMS_INCOMING: - if (option_debug > 1) - DEBUGA_FBUS2("SMS, inseqnum %.2X \n", CELLIAX_P_LOG, seqnum); - known = 1; - break; - } - break; -/****************************************************************/ - /* this kind of frames is about PHONE CALLs */ - case FBUS2_TYPE_CALL: - switch (p->array[9]) { - int a; - /* this subkind of frame is about the CALL has been HUNGUP */ - case FBUS2_CALL_HANGUP: - p->interface_state = AST_STATE_DOWN; - p->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_FBUS2("REMOTE PARTY HANG UP, inseqnum %.2X \n", CELLIAX_P_LOG, - seqnum); - fbus_mesg = CALLFLOW_INCOMING_HANGUP; - known = 1; - break; - /* this subkind of frame is about the remote CALLID (not signaled by 3310) */ - case FBUS2_CALL_CALLID: - if (option_debug > 1) - DEBUGA_FBUS2("CALLID, inseqnum %.2X \n", CELLIAX_P_LOG, seqnum); - memset(p->callid_name, 0, sizeof(p->callid_name)); - memset(p->callid_number, 0, sizeof(p->callid_number)); - for (a = 0; a < p->array[12]; a++) { - p->callid_number[a] = p->array[12 + a + 1]; - } - for (a = 0; a < p->array[12 + 1 + p->array[12]] + 1; a++) { - p->callid_name[a] = p->array[12 + 1 + a + p->array[12] + 1]; - } - if (option_debug > 1) - DEBUGA_FBUS2("CALLFLOW_INCOMING_CALLID: name is %s, number is %s\n", - CELLIAX_P_LOG, - p->callid_name[0] != 1 ? p->callid_name : "not available", - p->callid_number[0] ? p->callid_number : "not available"); - fbus_mesg = CALLFLOW_INCOMING_CALLID; - p->phone_callflow = CALLFLOW_INCOMING_RING; - p->interface_state = AST_STATE_RING; - known = 1; - break; - } - break; -/****************************************************************/ - /* this kind of frames is about NETWORK STATUS */ - case FBUS2_TYPE_NETWORK_STATUS: - switch (p->array[9]) { - /* this subkind of frames is NETWORK STATUS REGISTERED */ - case FBUS2_NETWORK_STATUS_REGISTERED: - if (option_debug > 1) - DEBUGA_FBUS2("NETWORK STATUS REGISTERED, inseqnum %.2X \n", CELLIAX_P_LOG, - seqnum); - if (p->callid_name[0] == 0 && p->owner - && p->interface_state != AST_STATE_DOWN) { - p->interface_state = AST_STATE_DOWN; - p->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug) - NOTICA("We think we are using a nokia3310, so NETWORK STATUS REGISTERED" - " is interpreted as REMOTE PARTY HANG UP during a call, because" - " Nokia 3310 give no hint about remote hangup. Nokia 3310" - " does not signal the CALLID, while other nokias at least put" - " callid_name[0]=1 (also if no callid was transmitted by remote" - " party), we use this lack of CALLID as a sign of 3310nness." - " Outside a call, or when CALLID has been signaled, NETWORK STATUS" - " REGISTERED is ignored.\n", CELLIAX_P_LOG); - fbus_mesg = CALLFLOW_INCOMING_HANGUP; - } - known = 1; - break; - } - break; -/****************************************************************/ - /* this kind of frames is about CALL STATUS */ - case FBUS2_TYPE_CALL_STATUS: - switch (p->array[12]) { - /* this subkind of frames is about CALL STATUS OFF */ - case FBUS2_CALL_STATUS_OFF: - p->interface_state = AST_STATE_DOWN; - p->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_FBUS2("STATUS call in progress OFF, inseqnum %.2X \n", - CELLIAX_P_LOG, seqnum); - fbus_mesg = CALLFLOW_INCOMING_HANGUP; - known = 1; - break; - /* this subkind of frames is about CALL STATUS ON */ - case FBUS2_CALL_STATUS_ON: - if (option_debug > 1) - DEBUGA_FBUS2("STATUS call in progress ON, inseqnum %.2X \n", - CELLIAX_P_LOG, seqnum); - known = 1; - break; - } -/****************************************************************/ - break; - } - - /* categorization of frame is ended, if it has not been recognized, whine */ - if (!known) { - WARNINGA("FBUS2 MSG UNKNOWN, inseqnum %.2X\n", CELLIAX_P_LOG, seqnum); - } - - /* let's print our frame */ - if (option_debug > 1) { - int i; - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - for (i = 0; i < p->arraycounter + 1; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", p->array[i]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - DEBUGA_FBUS2("%s is the RECEIVED FRAME inseqnum %.2X\n", CELLIAX_P_LOG, - debug_buf, seqnum); - } - - /* if the frame we received is not an ACK frame, let's ACKnowledge it */ - if (p->array[0] == FBUS2_SERIAL_FRAME_ID && p->array[3] != FBUS2_ACK_BYTE) { - celliax_serial_send_ack_FBUS2(p, p->array[3], seqnum); - } - } - p->arraycounter++; - } - } - UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - } - /* oooops, select returned error, got a kill/cancel or problems with the serial file descriptor */ - if (select_err == -1) { - if (errno != EINTR) { - ERRORA - ("select returned -1 on %s, marking controldev as dead, errno was: %d, error was: %s\n", - CELLIAX_P_LOG, p->controldevice_name, errno, strerror(errno)); - p->controldev_dead = 1; - close(p->controldevfd); - if (p->owner) - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - return -1; - } else { - WARNINGA("select returned -1 on %s, errno was: %d, EINTR, error was: %s\n", - CELLIAX_P_LOG, p->controldevice_name, errno, strerror(errno)); - return 0; - } - } - /* OK, reading done, let's browse the list of pending frames to be sent, and act on it */ - if (celliax_serial_send_if_time_FBUS2(p)) { - ERRORA("celliax_serial_send_if_time_FBUS2 failed!\n", CELLIAX_P_LOG); - return -1; - } - - if (fbus_mesg == CALLFLOW_INCOMING_HANGUP) { - if (p->owner) { - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - DEBUGA_FBUS2("phone call ended\n", CELLIAX_P_LOG); - } - } - - return fbus_mesg; //FIXME breaks the convention of returning 0 on success -} - -#endif /* CELLIAX_FBUS2 */ - -#ifdef CELLIAX_CVM - -int celliax_serial_sync_CVM_BUSMAIL(struct celliax_pvt *p) -{ - usleep(1000); /* 1msec */ - time(&p->celliax_serial_synced_timestamp); - return 0; -} - -int celliax_serial_answer_CVM_BUSMAIL(struct celliax_pvt *p) -{ - if (AST_STATE_RING == p->interface_state) { - DEBUGA_CVM("Sending commands to answer an incomming call...\n", CELLIAX_P_LOG); - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_CONNECT_REQ, 0, NULL); - - } else { - DEBUGA_CVM - ("SKIPPING Sending commands to answer an incomming call, because: !AST_STATE_RING\n", - CELLIAX_P_LOG); - } - - return 0; -} - -int celliax_serial_call_CVM_BUSMAIL(struct celliax_pvt *p, char *dstr) -{ - unsigned char bCallType = 0x01; /* INTERNAL */ - - unsigned char DialReqBuff[2]; - - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_SETUP_REQ, sizeof(bCallType), - &bCallType); - - while (AST_STATE_DOWN == p->interface_state) { - usleep(10000); //10msec - } - - if (AST_STATE_DIALING == p->interface_state) { - /* as for now, we only support internal calls */ - /* "0" - call speaker phone */ - /* "1" - call handset #1 */ - /* "2" - call handset #2 */ - /* ... */ - - DialReqBuff[0] = 1; /* number of digits to send */ - DialReqBuff[1] = dstr[0]; /* digit to send */ - - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_KEYPAD_REQ, 2, DialReqBuff); - } - - if (option_debug) - NOTICA("CVM_BUSMAIL: sent commands to call\n", CELLIAX_P_LOG); - return 0; -} - -int celliax_serial_hangup_CVM_BUSMAIL(struct celliax_pvt *p) -{ - unsigned char bReason = 0x0; /* Normal hang-up */ - - if (p->interface_state != AST_STATE_DOWN) { - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_RELEASE_REQ, sizeof(bReason), - &bReason); - - DEBUGA_CVM("CVM_BUSMAIL: sent commands to hangup the call\n", CELLIAX_P_LOG); - - } else { - DEBUGA_CVM("CVM_BUSMAIL: sent commands to hangup skipped because: AST_STATE_DOWN\n", - CELLIAX_P_LOG); - } - - return 0; -} - -int celliax_serial_config_CVM_BUSMAIL(struct celliax_pvt *p) -{ - int res; - int how_many_reads = 0; - unsigned char SubcriptionNo = p->cvm_subsc_no; - unsigned char RegistartionData[5]; - - p->cvm_lock_state = CVM_UNKNOWN_LOCK_STATE; - p->cvm_register_state = CVM_UNKNOWN_REGISTER_STATE; - - PUSHA_UNLOCKA(&p->controldev_lock); - CVM_LOKKA(&p->controldev_lock); - - if (option_debug > 1) - DEBUGA_CVM("Try to init communication with CVM...\n", CELLIAX_P_LOG); - - /* CVM after reset sends SABM CTRL frame, let's assume that CVM already sent it, that's the reply... */ - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, - BUSMAIL_HEADER_CTRL_FRAME | - BUSMAIL_HEADER_CTRL_UN_FRAME | - BUSMAIL_HEADER_UNID_SABM); - /* usleep(10000); *//* 10ms */ - - /* Now we are sending SABM CTRL frame, if CVM is out there, it should reply... */ - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, - BUSMAIL_HEADER_CTRL_FRAME | - BUSMAIL_HEADER_CTRL_UN_FRAME | - BUSMAIL_HEADER_UNID_SABM | - (BUSMAIL_HEADER_PF_BIT_MASK & 0xFF)); -// usleep(1000); - - res = celliax_serial_read_CVM_BUSMAIL(p); //we don't have no monitor neither do_controldev_thread - - DEBUGA_CVM("celliax_serial_read_CVM_BUSMAIL res= %X, expected %X\n", CELLIAX_P_LOG, res, - (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | - BUSMAIL_HEADER_SABM)); - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - how_many_reads = 0; - - while ((res & 0xF0) != - (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | BUSMAIL_HEADER_SABM)) - { - - usleep(1000); - res = celliax_serial_read_CVM_BUSMAIL(p); - how_many_reads++; - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - if (how_many_reads > 10) { - ERRORA("no expected results in %d celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG, - how_many_reads); - - ERRORA("Unable to initialize cmmunication with CVM...\n", CELLIAX_P_LOG); - - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - } - - DEBUGA_CVM("Communication with CVM initialized successfully...\n", CELLIAX_P_LOG); - - DEBUGA_CVM("Attempt to lock to FP...\n", CELLIAX_P_LOG); - - /* Try to connect to FP, try to lock to FP, maybe we registered with it in the past... */ - /* CVM can hold up to 2 subscriptions in its EEPROM, celliax.conf contains number we should try */ - /* eg. cvm_subscription_no = 1 */ - - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_LOCK_REQ, sizeof(SubcriptionNo), - &SubcriptionNo); - - usleep(10000); - - res = celliax_serial_read_CVM_BUSMAIL(p); //we don't have no monitor neither do_controldev_thread - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - how_many_reads = 0; - - while (CVM_UNKNOWN_LOCK_STATE == p->cvm_lock_state) { - -/* - if (0 == (how_many_reads % 10)) - { - DEBUGA_CVM("Attempt to lock to FP... %d\n", CELLIAX_P_LOG, how_many_reads/10 ); - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_LOCK_REQ, sizeof(SubcriptionNo) ,&SubcriptionNo); - } -*/ - - usleep(100000); - - res = celliax_serial_read_CVM_BUSMAIL(p); - how_many_reads++; - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - if (how_many_reads > 50) { - ERRORA("no expected results in %d celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG, - how_many_reads); - - ERRORA("Unable to lock to FP...\n", CELLIAX_P_LOG); - break; - } - } - - if (CVM_LOCKED_TO_FP == p->cvm_lock_state) { - DEBUGA_CVM("CVM locked to FP successfully...\n", CELLIAX_P_LOG); - } else { - DEBUGA_CVM("Lock to FP failed, Attempt to register to FP...\n", CELLIAX_P_LOG); - - RegistartionData[0] = SubcriptionNo; - RegistartionData[1] = 0xFF; - RegistartionData[2] = 0xFF; - - if (1 == SubcriptionNo) { - RegistartionData[3] = - (((p->cvm_subsc_1_pin[3] - 0x30) & 0x0F) << 4) | ((p->cvm_subsc_1_pin[2] - - 0x30) & 0x0F); - RegistartionData[4] = - (((p->cvm_subsc_1_pin[1] - 0x30) & 0x0F) << 4) | ((p->cvm_subsc_1_pin[0] - - 0x30) & 0x0F); - } else { - RegistartionData[3] = - (((p->cvm_subsc_2_pin[3] - 0x30) & 0x0F) << 4) | ((p->cvm_subsc_2_pin[2] - - 0x30) & 0x0F); - RegistartionData[4] = - (((p->cvm_subsc_2_pin[1] - 0x30) & 0x0F) << 4) | ((p->cvm_subsc_2_pin[0] - - 0x30) & 0x0F); - } - - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_ACCESS_RIGHTS_REQ, - sizeof(RegistartionData), - RegistartionData); - - usleep(100000); - - res = celliax_serial_read_CVM_BUSMAIL(p); //we don't have no monitor neither do_controldev_thread - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - how_many_reads = 0; - - while (CVM_UNKNOWN_REGISTER_STATE == p->cvm_register_state) { - - if (0 == (how_many_reads % 50)) { - DEBUGA_CVM("Attempt to register to FP... %d\n", CELLIAX_P_LOG, - how_many_reads / 10); - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_ACCESS_RIGHTS_REQ, - sizeof(RegistartionData), - RegistartionData); - } - - /* up to 5 minutes for registration.... */ - usleep(1000000); - res = celliax_serial_read_CVM_BUSMAIL(p); - how_many_reads++; - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - if (how_many_reads > 300) { - ERRORA("no expected results in %d celliax_serial_read_CVM_BUSMAIL\n", - CELLIAX_P_LOG, how_many_reads); - - ERRORA("Unable to communication with CVM...\n", CELLIAX_P_LOG); - - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - } - - if (CVM_REGISTERED_TO_FP != p->cvm_register_state) { - ERRORA("Unable to register to FP...\n", CELLIAX_P_LOG); - - CVM_UNLOCKA(&p->controldev_lock); - return -1; - - } else { - DEBUGA_CVM("CVM registered to FP successfully...\n", CELLIAX_P_LOG); - DEBUGA_CVM("Attempt to lock to FP...\n", CELLIAX_P_LOG); - - /* Try to connect to FP, try to lock to FP, maybe we registered with it in the past... */ - /* CVM can hold up to 2 subscriptions in its EEPROM, celliax.conf contains number we should try */ - /* eg. cvm_subscription_no = 1 */ - - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_LOCK_REQ, - sizeof(SubcriptionNo), &SubcriptionNo); - - usleep(10000); - - res = celliax_serial_read_CVM_BUSMAIL(p); //we don't have no monitor neither do_controldev_thread - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - how_many_reads = 0; - - while (CVM_UNKNOWN_LOCK_STATE == p->cvm_lock_state) { - - if (0 == (how_many_reads % 10)) { - DEBUGA_CVM("Attempt to lock to FP... %d\n", CELLIAX_P_LOG, how_many_reads / 10); - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_ACCESS_RIGHTS_REQ, - sizeof(RegistartionData), - RegistartionData); - } - - usleep(10000); - res = celliax_serial_read_CVM_BUSMAIL(p); - how_many_reads++; - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - if (how_many_reads > 100) { - ERRORA("no expected results in %d celliax_serial_read_CVM_BUSMAIL\n", - CELLIAX_P_LOG, how_many_reads); - - ERRORA("Unable to communication with CVM...\n", CELLIAX_P_LOG); - - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - } - - if (CVM_LOCKED_TO_FP != p->cvm_lock_state) { - ERRORA("Unable to lock to FP...\n", CELLIAX_P_LOG); - - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } else { - DEBUGA_CVM("CVM locked to FP successfully...\n", CELLIAX_P_LOG); - } - } - } - - usleep(100000); - - CVM_UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - return 0; - -} - -int celliax_serial_read_CVM_BUSMAIL(struct celliax_pvt *p) -{ - int read_count; - int select_err; - fd_set read_fds; - struct timeval timeout; - int cvm_busmail_mesg = 0; - unsigned char busmail_crc = 0; - unsigned char MsgCrc = 0; - unsigned char MsgHeader = 0; - unsigned char MsgTxSeqNo = 0; - unsigned char MsgRxSeqNo = 0; - unsigned char MsgTaskId = 0; - unsigned char MsgProgId = 0; - unsigned char MsgPrimitiveLSB = 0; - unsigned char MsgPrimitiveMSB = 0; - unsigned int MsgPrimitive = 0; - - int i = 0; - - FD_ZERO(&read_fds); - FD_SET(p->controldevfd, &read_fds); - timeout.tv_sec = 0; - timeout.tv_usec = 10000; - - if ((select_err = select(p->controldevfd + 1, &read_fds, NULL, NULL, &timeout)) > 0) { - timeout.tv_sec = 0; //reset the timeout, linux modify it - timeout.tv_usec = 10000; //reset the timeout, linux modify it - PUSHA_UNLOCKA(&p->controldev_lock); - CVM_LOKKA(&p->controldev_lock); - - while ((select_err = - select(p->controldevfd + 1, &read_fds, NULL, NULL, &timeout)) > 0) { - gettimeofday(&p->cvm_busmail_list_tv, &p->cvm_busmail_list_tz); - read_count = read(p->controldevfd, p->rxm, 255); - - if (read_count == 0) { - ERRORA - ("read 0 bytes!!! Nenormalno! Marking this celliax_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the CVM is stuck, switched off or power down.\n", - CELLIAX_P_LOG, p->controldevice_name); - - p->controldev_dead = 1; - close(p->controldevfd); - CVM_UNLOCKA(&p->controldev_lock); - - if (p->owner) - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - return -1; - } - - if (option_debug > 10) { - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - for (i = 0; i < read_count; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", p->rxm[i]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - - DEBUGA_CVM("%s READ AT seconds=%ld usec=%6ld read_count=%d\n", CELLIAX_P_LOG, - debug_buf, p->cvm_busmail_list_tv.tv_sec, - p->cvm_busmail_list_tv.tv_usec, read_count); - } - - for (i = 0; i < read_count; i++) { - if (p->rxm[i] == BUSMAIL_SOF) { - /* if we have identified the start of an busmail frame sent to us by the CVM */ - /* clean the array, copy into it the beginning of the frame, move the counter in the array after the last byte copied */ - memset(p->array, 0, 255); - p->array[0] = p->rxm[i]; - p->arraycounter = 1; - } - - /* buffer overload protection */ - if (255 == p->arraycounter) { - p->arraycounter = 1; - } - - /* continue copying into the array, until... */ - p->array[p->arraycounter - 1] = p->rxm[i]; - - /* we reach the end of the incoming frame, its lenght is in the p->array[BUSMAIL_OFFSET_LEN_LSB] byte, plus overhead */ - if (p->arraycounter == p->array[BUSMAIL_OFFSET_LEN_LSB] + 4) { - - tcflush(p->controldevfd, TCIFLUSH); /* PL2303HX bug? */ - /* start categorizing frames */ - - if (option_debug > 10) { - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - - for (i = 0; i < p->arraycounter; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", p->array[i]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - - DEBUGA_CVM("%s was received, Starting to categorize this frame\n", - CELLIAX_P_LOG, debug_buf); - } - - int known = 0; - int j = 0; - - busmail_crc = 0; - MsgCrc = p->array[p->arraycounter - 1]; - - busmail_crc = (unsigned char) (p->array[BUSMAIL_OFFSET_HEADER] + busmail_crc); - - for (j = BUSMAIL_OFFSET_MAIL; j < (p->arraycounter - 1); j++) { - busmail_crc = (unsigned char) (p->array[j] + busmail_crc); - } - - if (busmail_crc != MsgCrc) { - WARNINGA("BUSMAIL MSG CRC FAILED!, MsgCrc %.2X, calcd %.2X, dropping frame\n", - CELLIAX_P_LOG, MsgCrc, busmail_crc); - } else { - /* first step in categorizing frames, look at the general kind of frame, in p->array[BUSMAIL_OFFSET_HEADER] */ - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL MSG CRC, MsgCrc %.2X, calcd %.2X...\n", CELLIAX_P_LOG, - MsgCrc, busmail_crc); - - MsgHeader = p->array[BUSMAIL_OFFSET_HEADER]; - cvm_busmail_mesg = MsgHeader; - - switch (MsgHeader & BUSMAIL_HEADER_IC_BIT_MASK) { - case BUSMAIL_HEADER_INFO_FRAME: - /* analyzis of frame header */ - MsgTxSeqNo = ((MsgHeader & BUSMAIL_HEADER_TXSEQ_MASK) >> 4); - MsgRxSeqNo = ((MsgHeader & BUSMAIL_HEADER_RXSEQ_MASK)); - - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_INFO_FRAME TxSeq %X, RxSeq %X\n", - CELLIAX_P_LOG, MsgTxSeqNo, MsgRxSeqNo); - - if (((p->busmail_rxseq_cvm_last + 1) & 0x7) != MsgTxSeqNo) { - /* some CVM frames are missing, TxSeq of this frame is higher then expected */ - /* reject, I expected p->busmail_rxseq_cvm_last + 1, resend it to me, please */ - - WARNINGA("CVM TxSeq %X, does not match expected value %X\n", - CELLIAX_P_LOG, MsgTxSeqNo, - (p->busmail_rxseq_cvm_last + 1) & 0x7); - -// celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_REJ); - - if (((p->busmail_rxseq_cvm_last) & 0x7) == MsgTxSeqNo) { - - WARNINGA - ("It looks like our ACK to this frame was MIA :), lets ACK the frame one more time...\n", - CELLIAX_P_LOG); - - /* if the frame we received informs us that other side is waiting for ACK, let's ACK it */ - /* even if it is unknown to us */ - if (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_PF_BIT_MASK) { - if (BUSMAIL_HEADER_SABM == - (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_SABM_MASK)) { - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, (unsigned char) - (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | BUSMAIL_HEADER_UNID_SABM)); - } else { - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, (unsigned char) - (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_RR)); - } - } - } - - break; - } else { - /* we expected packet with this seq no. */ - /* CVM ACKed our frames with info frame */ - celliax_serial_list_acknowledge_CVM_BUSMAIL(p, MsgRxSeqNo); - - /* save it but limit it to 3 bits only (valid values: 0-7) */ - p->busmail_rxseq_cvm_last = MsgTxSeqNo; - p->busmail_rxseq_cvm_last &= 0x7; - - /* if the frame we received informs us that other side is waiting for ACK, let's ACK it */ - /* even if it is unknown to us */ - if (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_PF_BIT_MASK) { - if (BUSMAIL_HEADER_SABM == - (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_SABM_MASK)) { - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, (unsigned char) - (BUSMAIL_HEADER_CTRL_FRAME - | - BUSMAIL_HEADER_CTRL_UN_FRAME - | - BUSMAIL_HEADER_UNID_SABM)); - } else { - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, (unsigned char) - (BUSMAIL_HEADER_CTRL_FRAME - | - BUSMAIL_HEADER_CTRL_SU_FRAME - | - BUSMAIL_HEADER_SUID_RR)); - } - } - - } - - /* frame header OK, let's see what's inside mail field */ - MsgTaskId = p->array[BUSMAIL_OFFSET_MAIL_TASK_ID]; - MsgProgId = p->array[BUSMAIL_OFFSET_MAIL_PROGRAM_ID]; - MsgPrimitiveLSB = p->array[BUSMAIL_OFFSET_MAIL_PRIMITIVE_LSB]; - MsgPrimitiveMSB = p->array[BUSMAIL_OFFSET_MAIL_PRIMITIVE_MSB]; - MsgPrimitive = MsgPrimitiveMSB << 8 | MsgPrimitiveLSB; - - if (option_debug > 1) - DEBUGA_CVM - ("BUSMAIL_HEADER_INFO_FRAME ProgId %X, TaskId %X, Primitive %X %X\n", - CELLIAX_P_LOG, MsgProgId, MsgTaskId, MsgPrimitiveMSB, MsgPrimitiveLSB); - - switch (MsgPrimitive) { - - case API_PP_ACCESS_RIGHTS_REJ: - /* FP rejected our registration... */ - WARNINGA("API_PP_ACCESS_RIGHTS_REJ, FP rejected our registration...\n", - CELLIAX_P_LOG); - - p->cvm_register_state = CVM_UNREGISTERED_TO_FP; - p->cvm_lock_state = CVM_UNKNOWN_LOCK_STATE; - known = 1; - break; - - case API_PP_ACCESS_RIGHTS_CFM: - /* FP accepted our registration... */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_ACCESS_RIGHTS_CFM, FP accepted our registration...\n", - CELLIAX_P_LOG); - - p->cvm_register_state = CVM_REGISTERED_TO_FP; - p->cvm_lock_state = CVM_UNKNOWN_LOCK_STATE; - p->cvm_handset_no = p->array[BUSMAIL_OFFSET_MAIL_PARAMS + 0]; - p->cvm_fp_is_cvm = p->array[BUSMAIL_OFFSET_MAIL_PARAMS + 1]; - - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_ACCESS_RIGHTS_CFM, FP accepted our registration, Our handset no. is %d, CVM? %X\n", - CELLIAX_P_LOG, p->cvm_handset_no, p->cvm_fp_is_cvm); - - known = 1; - break; - - case API_PP_LOCKED_IND: - /* CVM is connected to FP */ - if (option_debug > 1) - DEBUGA_CVM("API_PP_LOCKED_IND, Connection to FP completed...\n", - CELLIAX_P_LOG); - - p->cvm_register_state = CVM_REGISTERED_TO_FP; - p->cvm_lock_state = CVM_LOCKED_TO_FP; - known = 1; - break; - - case API_PP_UNLOCKED_IND: - /* CVM is unlocked with FP, Out of service */ - WARNINGA - ("API_PP_UNLOCKED_IND, CVM is unlocked with FP, Out of service !!!\n", - CELLIAX_P_LOG); - - p->cvm_lock_state = CVM_UNLOCKED_TO_FP; - known = 1; - break; - - case API_PP_SETUP_ACK_IND: - /* Outgoing call, connection to FP established, FP is waiting for a number to dial */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_SETUP_ACK_IND, connection to FP established, FP is waiting for a numer to dial...\n", - CELLIAX_P_LOG); - - if (AST_STATE_DOWN == p->interface_state) { - p->interface_state = AST_STATE_DIALING; - } - - known = 1; - break; - - case API_PP_ALERT_IND: - /* Outgoing call, Remote end is ringing */ - if (option_debug > 1) - DEBUGA_CVM("API_PP_ALERT_IND, remote end is ringing...\n", - CELLIAX_P_LOG); - - if (AST_STATE_DIALING == p->interface_state) { - p->interface_state = AST_STATE_RINGING; - } - - known = 1; - break; - - case API_PP_CONNECT_IND: - /* Outgoing call, the remote end answered our call */ - if (option_debug > 1) - DEBUGA_CVM("API_PP_CONNECT_IND, our call was answered...\n", - CELLIAX_P_LOG); - - if (AST_STATE_RINGING == p->interface_state) { - - /* let's open audio and have a chat */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_OPEN_REQ, 0, - NULL); - - unsigned char volume = (unsigned char) p->cvm_volume_level; - celliax_serial_send_info_frame_CVM_BUSMAIL(p, - CVM_PP_AUDIO_SET_VOLUME_REQ, - sizeof(volume), &volume); - - /* let's unmute mic and have a chat */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, - CVM_PP_AUDIO_UNMUTE_MIC_REQ, - 0, NULL); - - /* let's switch to headset, because we fried normal output.... */ -/* unsigned char headset_on = (unsigned char) 1; - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_HS_PLUG_IND, sizeof(headset_on), &headset_on); -*/ - p->interface_state = AST_STATE_UP; - ast_setstate(p->owner, AST_STATE_RINGING); - celliax_queue_control(p->owner, AST_CONTROL_ANSWER); - } - - known = 1; - break; - - case API_PP_REJECT_IND: - /* Outgoing/Incoming call, FP rejected our connection... */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_REJECT_IND, FP or ther PP rejected our connection...\n", - CELLIAX_P_LOG); - - if (AST_STATE_RING == p->interface_state && p->owner) { - /* Attempt to answer incoming call rejected by FP or PP */ - if (option_debug > 1) - DEBUGA_CVM("Was it PAGE_ALL CALL, that we should not answered?\n", - CELLIAX_P_LOG); - - p->interface_state = AST_STATE_DOWN; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - - } else if (AST_STATE_DOWN != p->interface_state && p->owner) { - /* Outgoing call rejected by other PP or FP */ - p->interface_state = AST_STATE_BUSY; - ast_setstate(p->owner, AST_STATE_BUSY); - celliax_queue_control(p->owner, AST_CONTROL_BUSY); - } - - known = 1; - break; - - case API_PP_SIGNAL_ON_IND: - /* Ringback, ignore it... */ - if (option_debug > 1) - DEBUGA_CVM("API_PP_SIGNAL_ON_IND, Ringback, ignore it...\n", - CELLIAX_P_LOG); - - known = 1; - break; - - case API_PP_SIGNAL_OFF_IND: - /* Ringback, ignore it... */ - if (option_debug > 1) - DEBUGA_CVM("API_PP_SIGNAL_OFF_IND, Ringback, ignore it...\n", - CELLIAX_P_LOG); - - known = 1; - break; - - case API_PP_SETUP_IND: - /* Incoming call, Somebody is calling us */ - - if (option_debug > 1) - DEBUGA_CVM("API_PP_SETUP_IND, somebody is calling us...\n", - CELLIAX_P_LOG); - - if (AST_STATE_DOWN == p->interface_state) { - - if (API_PP_SETUP_IND_CALL_INT == - p->array[BUSMAIL_OFFSET_MAIL_PARAMS + - API_PP_SETUP_IND_CALL_TYPE_OFFSET]) { - DEBUGA_CVM("INTERNAL CALL, receive it...\n", CELLIAX_P_LOG); - - p->interface_state = AST_STATE_RING; - - /* inform calling end, that we know about his call, and that we are alerting */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_ALERT_REQ, 0, - NULL); - - /* let's open audio before valid mac, to remove noise... */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, - CVM_PP_AUDIO_OPEN_ADPCM_OFF_REQ, - 0, NULL); - - } else { - DEBUGA_CVM("NOT an INTERNAL CALL, CALL TYPE %X, just ignore it...\n", - CELLIAX_P_LOG, - p->array[BUSMAIL_OFFSET_MAIL_PARAMS + - API_PP_SETUP_IND_CALL_TYPE_OFFSET]); - - /* inform calling end, that we know about his call, and that we are alerting OR not :) */ - /* probably it is needed so FP does not remove us from PP list :) */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_ALERT_REQ, 0, - NULL); - } - - } else { - WARNINGA - ("Ignore incoming call, Wrong interface state, current state %X\n", - CELLIAX_P_LOG, p->interface_state); - } - - known = 1; - break; - - case API_PP_ALERT_OFF_IND: - /* Incoming call, We should stop alerting about incoming call... */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_ALERT_OFF_IND, Ringback, stop alerting about incoming call...\n", - CELLIAX_P_LOG); - - known = 1; - break; - - case API_PP_ALERT_ON_IND: - /* Incoming call, We should stop alerting about incoming call... */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_ALERT_ON_IND, Ringback, start alerting about incoming call...\n", - CELLIAX_P_LOG); -/* - if (AST_STATE_DOWN == p->interface_state) { - DEBUGA_CVM("Somebody is calling us, we see a PP_ALERT_ON_IND, receive it...\n", CELLIAX_P_LOG); - p->interface_state = AST_STATE_RING; - } -*/ - known = 1; - break; - - case API_PP_CONNECT_CFM: - /* Incoming call, Confirmation for request to answer incoming call... */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_CONNECT_CFM, Confirmation for request to answer incoming call...\n", - CELLIAX_P_LOG); - - if (AST_STATE_RING == p->interface_state && p->owner) { - - p->interface_state = AST_STATE_UP; - ast_setstate(p->owner, AST_STATE_UP); - - /* let's open audio and have a chat */ -// celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_OPEN_ADPCM_OFF_REQ, 0, NULL); - - /* let's open audio and have a chat */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_OPEN_REQ, 0, - NULL); - - unsigned char volume = (unsigned char) p->cvm_volume_level; - celliax_serial_send_info_frame_CVM_BUSMAIL(p, - CVM_PP_AUDIO_SET_VOLUME_REQ, - sizeof(volume), &volume); - - /* let's unmute mic and have a chat */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, - CVM_PP_AUDIO_UNMUTE_MIC_REQ, - 0, NULL); - - /* let's switch to headset, because we fried normal output.... */ -/* unsigned char headset_on = (unsigned char) 1; - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_HS_PLUG_IND, sizeof(headset_on), &headset_on); -*/ - } else { - WARNINGA - ("Ignore connection cfm, Wrong interface state, current state %X\n", - CELLIAX_P_LOG, p->interface_state); - } - - known = 1; - break; - - case API_PP_RELEASE_CFM: - /* Confirmation for request to hangup a call... */ - if (option_debug > 1) - DEBUGA_CVM - ("API_PP_RELEASE_CFM, Confirmation for request to hangup a call..\n", - CELLIAX_P_LOG); - - if (AST_STATE_UP == p->interface_state) { - /* let's close audio */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_CLOSE_REQ, 0, - NULL); - - /* let's unmute mic and have a chat */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_MUTE_MIC_REQ, - 0, NULL); - } - - p->interface_state = AST_STATE_DOWN; - - known = 1; - break; - - case API_PP_RELEASE_IND: - /* FP releases connection to CVM... */ - if (option_debug > 1) - DEBUGA_CVM("API_PP_RELEASE_IND, FP releases connection to CVM...\n", - CELLIAX_P_LOG); - - if (AST_STATE_UP == p->interface_state && p->owner) { - /* let's close audio */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, CVM_PP_AUDIO_CLOSE_REQ, 0, - NULL); - p->interface_state = AST_STATE_DOWN; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - - } else if (AST_STATE_RING == p->interface_state && p->owner) { - /* workaround for PAGE ALL CALL, FIXME!!!! */ - if (option_debug > 1) - DEBUGA_CVM("WAS IT A PAGE ALL ???...\n", CELLIAX_P_LOG); - - p->interface_state = AST_STATE_UP; - usleep(100000); - - p->interface_state = AST_STATE_DOWN; - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - } - - /* we need to ACK release */ - celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_RELEASE_RES, 0, - NULL); - - known = 1; - break; - - case API_PP_READ_RSSI_CFM: - if (option_debug > 1) - DEBUGA_CVM("API_PP_READ_RSSI_CFM, RSSI readout...\n", CELLIAX_P_LOG); - - p->cvm_rssi = p->array[BUSMAIL_OFFSET_MAIL_PARAMS + 0]; - int rssi_percent = p->cvm_rssi * 100 / 0x3F; - if (option_debug > 1) - DEBUGA_CVM("RSSI is %X, %d%%...\n", CELLIAX_P_LOG, p->cvm_rssi, - rssi_percent); - - known = 1; - break; - default: - WARNINGA("UNKNOWN MsgPrimitive!!! %X\n", CELLIAX_P_LOG, MsgPrimitive); - break; - } - - break; - - case BUSMAIL_HEADER_CTRL_FRAME: - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_CTRL_FRAME\n", CELLIAX_P_LOG); - - switch (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_SU_BIT_MASK) { - case BUSMAIL_HEADER_CTRL_SU_FRAME: - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_CTRL_SU_FRAME\n", CELLIAX_P_LOG); - - switch (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_SUID_MASK) { - case BUSMAIL_HEADER_SUID_REJ: - /* CVM Reject, CVM missed one of our packets, it will be resend, do nothing */ - MsgRxSeqNo = - ((p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_RXSEQ_MASK)); - - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_SUID_REJ, RxSeq %X\n", CELLIAX_P_LOG, - MsgRxSeqNo); - - /* Even that it is CVM Reject packet, it still ACKs some packets */ - celliax_serial_list_acknowledge_CVM_BUSMAIL(p, MsgRxSeqNo); - - known = 1; - break; - case BUSMAIL_HEADER_SUID_RNR: - /* CVM Receiver Not Ready, answer to packet that we sent, do nothing, it will be resend later */ - MsgRxSeqNo = - ((p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_RXSEQ_MASK)); - - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_SUID_RNR, RxSeq %X\n", CELLIAX_P_LOG, - MsgRxSeqNo); - - known = 1; - break; - case BUSMAIL_HEADER_SUID_RR: - /* CVM ACKs our packets */ - MsgRxSeqNo = - ((p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_RXSEQ_MASK)); - - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_SUID_RR, RxSeq %X\n", CELLIAX_P_LOG, - MsgRxSeqNo); - - /* CVM ACKed our frames with RR frame */ - celliax_serial_list_acknowledge_CVM_BUSMAIL(p, MsgRxSeqNo); - - known = 1; - break; - - default: - WARNINGA("BUSMAIL_HEADER_SUID_UNKNOWN!!!\n", CELLIAX_P_LOG); - break; - } - break; - - case BUSMAIL_HEADER_CTRL_UN_FRAME: - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_CTRL_UN_FRAME\n", CELLIAX_P_LOG); - - switch (p->array[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_UNID_MASK) { - - case BUSMAIL_HEADER_UNID_SABM: - if (option_debug > 1) - DEBUGA_CVM("BUSMAIL_HEADER_UNID_SABM\n", CELLIAX_P_LOG); - /* reset seq counters */ - p->busmail_txseq_celliax_last = 0xFF; - p->busmail_rxseq_cvm_last = 0xFF; - - celliax_serial_lists_free_CVM_BUSMAIL(p); - /* if needed, reply will be send by code at the end of switch statements */ - known = 1; - break; - - default: - WARNINGA("BUSMAIL_HEADER_UNID_UNKNOWN!!!\n", CELLIAX_P_LOG); - break; - } - break; - - default: - WARNINGA("BUSMAIL_HEADER_CTRL_UNKNOWN!!!\n", CELLIAX_P_LOG); - break; - } - break; - - default: - WARNINGA("BUSMAIL_HEADER_UNKNOWN!!!\n", CELLIAX_P_LOG); - break; - } - - } - - /* categorization of frame is ended, if it has not been recognized, whine */ - if (!known) { - WARNINGA("BUSMAIL MSG UNKNOWN or REJECTED!\n", CELLIAX_P_LOG); - } - } - p->arraycounter++; - } - } - CVM_UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - } - - /* oooops, select returned error, got a kill/cancel or problems with the serial file descriptor */ - if (select_err == -1) { - if (errno != EINTR) { - ERRORA - ("select returned -1 on %s, marking controldev as dead, errno was: %d, error was: %s\n", - CELLIAX_P_LOG, p->controldevice_name, errno, strerror(errno)); - - p->controldev_dead = 1; - close(p->controldevfd); - - if (p->owner) - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - return -1; - - } else { - WARNINGA("select returned -1 on %s, errno was: %d, EINTR, error was: %s\n", - CELLIAX_P_LOG, p->controldevice_name, errno, strerror(errno)); - return 0; - } - } - /* OK, reading done, let's browse the list of pending frames to be sent, and act on it */ - if (celliax_serial_send_if_time_CVM_BUSMAIL(p)) { - ERRORA("celliax_serial_send_if_time_CVM_BUSMAIL failed!\n", CELLIAX_P_LOG); - return -1; - } - - return cvm_busmail_mesg; //FIXME breaks the convention of returning 0 on success -} - -int celliax_serial_getstatus_CVM_BUSMAIL(struct celliax_pvt *p) -{ - int res; - int how_many_reads = 0; - - PUSHA_UNLOCKA(&p->controldev_lock); - CVM_LOKKA(&p->controldev_lock); - - if (option_debug > 1) - DEBUGA_CVM("Sending RR CTRL frame wit PF bit set\n", CELLIAX_P_LOG); - - /* this ctrl frame can be used as low level keep alive */ - celliax_serial_send_ctrl_frame_CVM_BUSMAIL(p, - BUSMAIL_HEADER_CTRL_FRAME | - BUSMAIL_HEADER_CTRL_SU_FRAME | - BUSMAIL_HEADER_SUID_RR | - (BUSMAIL_HEADER_PF_BIT_MASK & 0xFF)); - - //usleep(1000); - - res = celliax_serial_read_CVM_BUSMAIL(p); //we don't have no monitor neither do_controldev_thread - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - while ((res & 0xF0) != - (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | - BUSMAIL_HEADER_SUID_RR)) { - - usleep(1000); - res = celliax_serial_read_CVM_BUSMAIL(p); - how_many_reads++; - - if (res == -1) { - ERRORA("failed celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - - if (how_many_reads > 10) { - ERRORA("no expected results in %d celliax_serial_read_CVM_BUSMAIL\n", CELLIAX_P_LOG, - how_many_reads); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - } - - //celliax_serial_send_info_frame_CVM_BUSMAIL(p, API_PP_READ_RSSI_REQ, 0, NULL); - - CVM_UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - return 0; - -} - -/*! - * \brief Write on the serial port for all the CVM_BUSMAIL functions - * \param p celliax_pvt - * \param len lenght of buffer2 - * \param buffer2 chars to be written - * - * Write on the serial port for all the CVM_BUSMAIL functions - * - * \return the number of chars written on the serial, - * that can be different from len (or negative) in case of errors. - */ -int celliax_serial_send_CVM_BUSMAIL(struct celliax_pvt *p, int len, - unsigned char *mesg_ptr) -{ - int ret; - size_t actual = 0; - unsigned char *mesg_ptr2 = mesg_ptr; - PUSHA_UNLOCKA(&p->controldev_lock); - CVM_LOKKA(&p->controldev_lock); - do { - ret = write(p->controldevfd, mesg_ptr, len - actual); - if (ret < 0 && errno == EAGAIN) - continue; - if (ret < 0) { - if (actual != len) - ERRORA("celliax_serial_write error: %s", CELLIAX_P_LOG, strerror(errno)); - CVM_UNLOCKA(&p->controldev_lock); - return -1; - } - actual += ret; - mesg_ptr += ret; - usleep(10000); -// usleep(p->cvm_celliax_serial_delay*1000); - } while (actual < len); - - usleep(p->cvm_celliax_serial_delay * 1000); - -// tcdrain(p->controldevfd); - - CVM_UNLOCKA(&p->controldev_lock); - POPPA_UNLOCKA(&p->controldev_lock); - - if (option_debug > 10) { - int i; - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - - for (i = 0; i < len; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", mesg_ptr2[i]); - if (debug_buf_pos > ((char *) &debug_buf + 1000)) - break; - } - DEBUGA_CVM("%s was sent down the wire\n", CELLIAX_P_LOG, debug_buf); - } - - return 0; -} - -/*! - * \brief Flags as acknowledged an BUSMAIL message previously sent - * \param p celliax_pvt - * \param seqnum identifier of the message to be acknowledged - * - * Called upon receiving an BUSMAIL acknoledgement message, browse the cvm_busmail_outgoing_list - * looking for the seqnum sent BUSMAIL message, and flags it as acknowledged. - * (if an outgoing BUSMAIL message is not aknowledged by the cellphone in a while, - * it will be retransmitted) - * - * \return 0 on error, 1 otherwise - */ -int celliax_serial_list_acknowledge_CVM_BUSMAIL(struct celliax_pvt *p, - unsigned char AckTxSeqNo) -{ - struct cvm_busmail_msg *ptr = NULL; - struct cvm_busmail_msg *old = NULL; - - unsigned char MsgTxSeqNo; - unsigned char MsgRxSeqNo; - - ptr = p->cvm_busmail_outgoing_list; - - if (ptr == NULL) { - ERRORA("cvm_busmail_outgoing_list is NULL ?\n", CELLIAX_P_LOG); - return -1; - } - - PUSHA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - CVM_LOKKA(&p->cvm_busmail_outgoing_list_lock); -/* - DEBUGA_CVM("PREFREE OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); -*/ - while (ptr->next != NULL) - ptr = ptr->next; - - while (ptr) { - - if ((1 == ptr->valid) && (0 == ptr->acknowledged) && (0 != ptr->sent)) { - MsgTxSeqNo = - ((ptr->busmail_msg_buffer[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_TXSEQ_MASK) >> - 4); - MsgRxSeqNo = - ((ptr->busmail_msg_buffer[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_RXSEQ_MASK)); - -/* - if (option_debug > 1) - DEBUGA_CVM("OUTGOING LIST TxSeq is %X, RxSeq is %X\n", CELLIAX_P_LOG, MsgTxSeqNo, MsgRxSeqNo); -*/ - unsigned char TxToAck = 0; - - if (0 == AckTxSeqNo) { - TxToAck = 7; - } else { - TxToAck = AckTxSeqNo - 1; - } - - if (MsgTxSeqNo <= TxToAck) { - - if (option_debug > 1) - DEBUGA_CVM("Msg with TxSeq=%X ACKed with CvmRxSeq=%X\n", CELLIAX_P_LOG, - MsgTxSeqNo, AckTxSeqNo); - - old = ptr; - old->acknowledged = 1; - old->valid = 0; - ptr = old->previous; - - if (old->previous) { - if (old->next) { - old->previous->next = old->next; - } else { - old->previous->next = NULL; - } - } - - if (old->next) { - if (old->previous) { - old->next->previous = old->previous; - } else { - old->next->previous = NULL; - } - } - - if ((NULL == old->next) && (NULL == old->previous)) { - if (option_debug > 1) { - DEBUGA_CVM("FREEING LAST\n", CELLIAX_P_LOG); - } - - p->cvm_busmail_outgoing_list = NULL; - p->cvm_busmail_outgoing_list = celliax_serial_list_init_CVM_BUSMAIL(p); - } - -/* - if (option_debug > 1) - DEBUGA_CVM("FREEING TxSeq is %X, RxSeq is %X\n", CELLIAX_P_LOG, MsgTxSeqNo, MsgRxSeqNo); -*/ - - free(old); - - } else { - ptr = ptr->previous; - } - - } else { - ptr = ptr->previous; - } - } - -/* - DEBUGA_CVM("POSTFREE OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); -*/ - - CVM_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - POPPA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - return 0; -} - -/*! - * \brief Sends an FBUS2 message or resends it if it was not acknowledged - * \param p celliax_pvt - * - * Called by celliax_serial_read_CVM_BUSMAIL, browse the fbus2_outgoing_list looking for FBUS2 messages to be sent, - * or for FBUS2 messages previously sent but not yet acknoledged. - * (if an outgoing FBUS2 message is not aknowledged by the cellphone in a while, - * it will be retransmitted) - * - * \return 0 on error, 1 otherwise - */ -int celliax_serial_send_if_time_CVM_BUSMAIL(struct celliax_pvt *p) -{ - struct cvm_busmail_msg *ptr; - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - ptr = p->cvm_busmail_outgoing_list; - - if (ptr == NULL) { -/* ERRORA("cvm_busmail_outgoing_list is NULL ?\n", CELLIAX_P_LOG); */ - WARNINGA("cvm_busmail_outgoing_list is NULL, nothing to send...\n", CELLIAX_P_LOG); - -/* return -1; */ - return 0; - - } - - while (ptr->next != NULL) { - WARNINGA("cvm_busmail_outgoing_list->next is not null ?\n", CELLIAX_P_LOG); - ptr = ptr->next; //FIXME what to do? - } - - while (ptr->sent == 0 && ptr->acknowledged == 0) { - if (ptr->previous != NULL) { - ptr = ptr->previous; - } else - break; - } - - while (ptr->sent == 1 && ptr->acknowledged == 0) { - if (ptr->previous != NULL) { - ptr = ptr->previous; - } else - break; - } - - if (ptr->sent == 1 && ptr->acknowledged == 1) { - if (ptr->next != NULL) { - ptr = ptr->next; - } - } - - if (ptr->sent == 1 && ptr->acknowledged == 0 && ptr->valid == 1) { - if ((tv.tv_sec * 1000 + tv.tv_usec / 1000) > - ((ptr->tv_sec * 1000 + ptr->tv_usec / 1000) + 1000)) { - - PUSHA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - CVM_LOKKA(&p->cvm_busmail_outgoing_list_lock); - - if (ptr->sent == 1 && ptr->acknowledged == 0 && ptr->valid == 1) { //retest, maybe has been changed? - if ((tv.tv_sec * 1000 + tv.tv_usec / 1000) > ((ptr->tv_sec * 1000 + ptr->tv_usec / 1000) + 1000)) { //retest, maybe has been changed? - - if (option_debug > 1) - DEBUGA_CVM("RESEND TxSeq=%X, passed %ld ms, sent %d times\n", CELLIAX_P_LOG, - ptr->txseqno, - ((tv.tv_sec * 1000 + tv.tv_usec / 1000) - - (ptr->tv_sec * 1000 + ptr->tv_usec / 1000)), ptr->how_many_sent); - - if (ptr->how_many_sent > 9) { - ERRORA("RESEND TxSeq=%X, passed %ld ms, sent %d times\n", CELLIAX_P_LOG, - ptr->txseqno, - ((tv.tv_sec * 1000 + tv.tv_usec / 1000) - - (ptr->tv_sec * 1000 + ptr->tv_usec / 1000)), ptr->how_many_sent); - - CVM_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - return -1; - } - - celliax_serial_send_CVM_BUSMAIL(p, ptr->busmail_msg_len, - ptr->busmail_msg_buffer); - - ptr->tv_sec = tv.tv_sec; - ptr->tv_usec = tv.tv_usec; - ptr->sent = 1; - ptr->how_many_sent++; -/* - if (option_debug > 1) { - DEBUGA_CVM("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); - DEBUGA_CVM("OUTGOING list END\n", CELLIAX_P_LOG); - } -*/ - } - } - - CVM_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - POPPA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - } - } - - if (ptr->sent == 0 && ptr->acknowledged == 0 && ptr->valid == 1) { - - PUSHA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - CVM_LOKKA(&p->cvm_busmail_outgoing_list_lock); - - if (ptr->sent == 0 && ptr->acknowledged == 0 && ptr->valid == 1) { //retest, maybe has been changed? - - if (option_debug > 1) - DEBUGA_CVM("SENDING 1st TIME TxSeq=%X\n", CELLIAX_P_LOG, ptr->txseqno); - - celliax_serial_send_CVM_BUSMAIL(p, ptr->busmail_msg_len, ptr->busmail_msg_buffer); - - ptr->tv_sec = tv.tv_sec; - ptr->tv_usec = tv.tv_usec; - ptr->sent = 1; - ptr->how_many_sent++; -/* - if (option_debug > 1) { - DEBUGA_CVM("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); - DEBUGA_CVM("OUTGOING list END\n", CELLIAX_P_LOG); - } -*/ - } - - CVM_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - POPPA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - - } - return 0; -} - -int celliax_serial_write_CVM_BUSMAIL(struct celliax_pvt *p, - struct cvm_busmail_frame *busmail_frame) -{ - unsigned char buffer2[BUSMAIL_MAX_FRAME_LENGTH]; - int i = 0; - int len = 0; - unsigned int busmail_len_total = 0; - - busmail_frame->busmail_sof = BUSMAIL_SOF; - busmail_frame->busmail_crc = 0; - -/* because of Rx Tx SEQ HEADER fields problem, update when these fields are filled with correct data - busmail_frame->busmail_crc = (unsigned char)(busmail_frame->busmail_header + busmail_frame->busmail_crc); -*/ - - buffer2[BUSMAIL_OFFSET_SOF] = busmail_frame->busmail_sof; - buffer2[BUSMAIL_OFFSET_HEADER] = busmail_frame->busmail_header; - - if ((buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_IC_BIT_MASK) == - BUSMAIL_HEADER_INFO_FRAME) { - len = - BUSMAIL_OFFSET_MAIL_PARAMS + busmail_frame->busmail_mail_params_buffer_len + - sizeof(busmail_frame->busmail_crc); - busmail_len_total = - busmail_frame->busmail_mail_params_buffer_len + - sizeof(busmail_frame->busmail_header) - + sizeof(busmail_frame->busmail_mail_program_id) + - sizeof(busmail_frame->busmail_mail_task_id) + 2; - - if (option_debug > 1) - DEBUGA_CVM("INFO frame to send\n", CELLIAX_P_LOG); - - buffer2[BUSMAIL_OFFSET_MAIL_PROGRAM_ID] = busmail_frame->busmail_mail_program_id; - buffer2[BUSMAIL_OFFSET_MAIL_TASK_ID] = busmail_frame->busmail_mail_task_id; - buffer2[BUSMAIL_OFFSET_MAIL_PRIMITIVE_LSB] = - busmail_frame->busmail_mail_primitive[BUSMAIL_MAIL_PRIMITIVE_LSB]; - buffer2[BUSMAIL_OFFSET_MAIL_PRIMITIVE_MSB] = - busmail_frame->busmail_mail_primitive[BUSMAIL_MAIL_PRIMITIVE_MSB]; - - if (busmail_frame->busmail_mail_params_buffer_len) { - memcpy(buffer2 + BUSMAIL_OFFSET_MAIL_PARAMS, - busmail_frame->busmail_mail_params_buffer, - busmail_frame->busmail_mail_params_buffer_len); - } - - for (i = 0; i < busmail_frame->busmail_mail_params_buffer_len; i++) { - busmail_frame->busmail_crc = - (unsigned char) (busmail_frame->busmail_mail_params_buffer[i] + - busmail_frame->busmail_crc); - } - - busmail_frame->busmail_crc += busmail_frame->busmail_mail_program_id; - busmail_frame->busmail_crc += busmail_frame->busmail_mail_task_id; - busmail_frame->busmail_crc += - busmail_frame->busmail_mail_primitive[BUSMAIL_MAIL_PRIMITIVE_LSB]; - busmail_frame->busmail_crc += - busmail_frame->busmail_mail_primitive[BUSMAIL_MAIL_PRIMITIVE_MSB]; - } else { - busmail_len_total = sizeof(busmail_frame->busmail_header); - len = BUSMAIL_OFFSET_MAIL + sizeof(busmail_frame->busmail_crc); - - if (option_debug > 1) - DEBUGA_CVM("CTRL frame to send\n", CELLIAX_P_LOG); - } - -/* - DEBUGA_CVM("Its len=%d\n", CELLIAX_P_LOG, len); -*/ - - busmail_frame->busmail_len[BUSMAIL_LEN_LSB] = - (unsigned char) (busmail_len_total & 0xFF); - busmail_frame->busmail_len[BUSMAIL_LEN_MSB] = (unsigned char) (busmail_len_total >> 8); - buffer2[BUSMAIL_OFFSET_LEN_MSB] = busmail_frame->busmail_len[BUSMAIL_LEN_MSB]; - buffer2[BUSMAIL_OFFSET_LEN_LSB] = busmail_frame->busmail_len[BUSMAIL_LEN_LSB]; - -/* - buffer2[len-1] = busmail_frame->busmail_crc; -*/ - buffer2[len - 1] = 0xFF; - - if ((buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_IC_BIT_MASK) == - BUSMAIL_HEADER_INFO_FRAME) { - /* if it is INFO frame, queue it */ - - /* update TxSeq and RxSeq bits */ - /* clear TxSeq and RxSeq bits */ - buffer2[BUSMAIL_OFFSET_HEADER] &= - ~(BUSMAIL_HEADER_RXSEQ_MASK | BUSMAIL_HEADER_TXSEQ_MASK); - - buffer2[BUSMAIL_OFFSET_HEADER] |= - (p->busmail_rxseq_cvm_last + 1) & BUSMAIL_HEADER_RXSEQ_MASK; - - p->busmail_txseq_celliax_last++; - p->busmail_txseq_celliax_last &= 0x07; - - buffer2[BUSMAIL_OFFSET_HEADER] |= - ((p->busmail_txseq_celliax_last) << 4) & BUSMAIL_HEADER_TXSEQ_MASK; - - /* update CRC */ - busmail_frame->busmail_crc += buffer2[BUSMAIL_OFFSET_HEADER]; - buffer2[len - 1] = busmail_frame->busmail_crc; - - p->cvm_busmail_outgoing_list = celliax_serial_list_init_CVM_BUSMAIL(p); - p->cvm_busmail_outgoing_list->busmail_msg_len = len; - - for (i = 0; i < len; i++) { - p->cvm_busmail_outgoing_list->busmail_msg_buffer[i] = buffer2[i]; - } - - if (option_debug > 10) { - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - - for (i = 0; i < len; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", buffer2[i]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - - if (option_debug > 1) - DEBUGA_CVM("INFO: %s was prepared to send\n", CELLIAX_P_LOG, debug_buf); - } - - if (option_debug > 1) { - DEBUGA_CVM("OUTGOING INFO Frame TxSeq is %X, RxSeq is %X\n", CELLIAX_P_LOG, - (buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_TXSEQ_MASK) >> 4, - buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_RXSEQ_MASK); -/* - DEBUGA_CVM("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); - DEBUGA_CVM("OUTGOING list END\n", CELLIAX_P_LOG); */ - } - p->cvm_busmail_outgoing_list->txseqno = - (unsigned char) (buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_TXSEQ_MASK) >> 4; - p->cvm_busmail_outgoing_list->valid = 1; /* ready to send (?) */ - - } else { - /* if it is CTRL frame, send it straight to the wire */ - if (BUSMAIL_HEADER_SABM != - (buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_SABM_MASK)) { - /*SABM ctrl frames have no RxSeq bits */ - - buffer2[BUSMAIL_OFFSET_HEADER] &= ~BUSMAIL_HEADER_RXSEQ_MASK; - - if (BUSMAIL_HEADER_REJ == - (buffer2[BUSMAIL_OFFSET_HEADER] & BUSMAIL_HEADER_REJ_MASK)) { - - if (option_debug > 1) - DEBUGA_CVM("CTRL REJ frame...\n", CELLIAX_P_LOG); - - if (0xFF != p->busmail_rxseq_cvm_last) { - buffer2[BUSMAIL_OFFSET_HEADER] |= - (p->busmail_rxseq_cvm_last + 1) & BUSMAIL_HEADER_RXSEQ_MASK; - } else { - if (option_debug > 1) - DEBUGA_CVM - ("Skipping sending REJ, because we just cleared RxSeq counter, and probably it was a packet that is invalid now...\n", - CELLIAX_P_LOG); - return 0; - } - - } else { - buffer2[BUSMAIL_OFFSET_HEADER] |= - (p->busmail_rxseq_cvm_last + 1) & BUSMAIL_HEADER_RXSEQ_MASK; - } - } - - /* update CRC */ - busmail_frame->busmail_crc += buffer2[BUSMAIL_OFFSET_HEADER]; - buffer2[len - 1] = busmail_frame->busmail_crc; - - if (option_debug > 10) { - char debug_buf[1024]; - char *debug_buf_pos; - - memset(debug_buf, 0, 1024); - debug_buf_pos = debug_buf; - - for (i = 0; i < len; i++) { - debug_buf_pos += sprintf(debug_buf_pos, "[%.2X] ", buffer2[i]); - if (debug_buf_pos > (char *) (&debug_buf + 1000)) - break; - } - - if (option_debug > 1) - DEBUGA_CVM("CTRL: %s was prepared to send\n", CELLIAX_P_LOG, debug_buf); - } -// usleep(100); - celliax_serial_send_CVM_BUSMAIL(p, len, buffer2); - } - - return 0; -} - -int celliax_serial_send_ctrl_frame_CVM_BUSMAIL(struct celliax_pvt *p, - unsigned char FrameType) -{ - /*FrameType parameter is really a busmail header with info neeeded to tell the frame type to send */ - struct cvm_busmail_frame busmail_frame; - - switch (FrameType & 0xF0) { - /* only higher nibble is important for us, do not take PF bit into considration */ - - case BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_RR: - case BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_REJ: - case BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_RNR: - case BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | BUSMAIL_HEADER_UNID_SABM: - - busmail_frame.busmail_header = - (FrameType & 0xF8); - - break; - - default: - WARNINGA("UNKNOWN CTRL TYPE specified, sending nothing!!!\n", CELLIAX_P_LOG); - return -1; - break; - } - - busmail_frame.busmail_mail_params_buffer_len = 0; - - /* Sending to CVM */ - return celliax_serial_write_CVM_BUSMAIL(p, &busmail_frame); -} - -int celliax_serial_send_info_frame_CVM_BUSMAIL(struct celliax_pvt *p, int FrameType, - unsigned char ParamsLen, - unsigned char *Params) -{ - /*FrameType parameter is really a Primitive ID */ - struct cvm_busmail_frame busmail_frame; - int i = 0; - busmail_frame.busmail_header = - (BUSMAIL_HEADER_PF_BIT_MASK & 0xFF) | BUSMAIL_HEADER_INFO_FRAME; - - busmail_frame.busmail_mail_primitive[BUSMAIL_MAIL_PRIMITIVE_LSB] = FrameType & 0xFF; - busmail_frame.busmail_mail_primitive[BUSMAIL_MAIL_PRIMITIVE_MSB] = - (FrameType >> 8) & 0xFF; - - busmail_frame.busmail_mail_program_id = BUSMAIL_MAIL_PROGRAM_ID; - busmail_frame.busmail_mail_task_id = BUSMAIL_MAIL_TASK_ID; - - for (i = 0; i < ParamsLen; i++) { - busmail_frame.busmail_mail_params_buffer[i] = Params[i]; - } - - busmail_frame.busmail_mail_params_buffer_len = ParamsLen; - - /* Sending to CVM */ - return celliax_serial_write_CVM_BUSMAIL(p, &busmail_frame); -} - -int celliax_serial_lists_free_CVM_BUSMAIL(struct celliax_pvt *p) -{ - struct cvm_busmail_msg *ptr, *prev; -/* - if (option_debug > 1) { - DEBUGA_CVM("START FREEING OUTGOING\n", CELLIAX_P_LOG); - DEBUGA_CVM("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); - DEBUGA_CVM("OUTGOING list END\n", CELLIAX_P_LOG); - } -*/ - ptr = p->cvm_busmail_outgoing_list; - - if (ptr) { - while (ptr->next != NULL) - ptr = ptr->next; - - while (ptr->previous != NULL) { - - if (option_debug > 1) - DEBUGA_CVM("FREED \n", CELLIAX_P_LOG); - - prev = ptr->previous; - free(ptr); - ptr = prev; - } - - free(ptr); - } - - if (option_debug > 1) - DEBUGA_CVM("LAST FREED \n", CELLIAX_P_LOG); - - p->cvm_busmail_outgoing_list = NULL; - p->cvm_busmail_outgoing_list = celliax_serial_list_init_CVM_BUSMAIL(p); - - if (option_debug > 1) { - DEBUGA_CVM("OUTGOING list:\n", CELLIAX_P_LOG); - celliax_serial_list_print_CVM_BUSMAIL(p, p->cvm_busmail_outgoing_list); - DEBUGA_CVM("OUTGOING list END\n", CELLIAX_P_LOG); - DEBUGA_CVM("STARTING FREE INGOING\n", CELLIAX_P_LOG); - } - - return 0; -} - -struct cvm_busmail_msg *celliax_serial_list_init_CVM_BUSMAIL(struct celliax_pvt *p) -{ - struct cvm_busmail_msg *list; - list = p->cvm_busmail_outgoing_list; - - PUSHA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - CVM_LOKKA(&p->cvm_busmail_outgoing_list_lock); - - if (list == NULL) { - list = malloc(sizeof(*(list))); - list->valid = 0; - list->busmail_msg_len = 0; - list->acknowledged = 0; - list->how_many_sent = 0; - list->sent = 0; - list->tv_sec = 0; - list->tv_usec = 0; - list->next = NULL; - list->previous = NULL; - } - - if (list->valid != 0) { - struct cvm_busmail_msg *new; - new = malloc(sizeof(*new)); - new->valid = 0; - new->busmail_msg_len = 0; - new->acknowledged = 0; - new->how_many_sent = 0; - new->sent = 0; - new->tv_sec = 0; - new->tv_usec = 0; - new->next = NULL; - new->previous = list; - list->next = new; - list = new; - } - - CVM_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - POPPA_UNLOCKA(&p->cvm_busmail_outgoing_list_lock); - - return list; -} - -int celliax_serial_list_print_CVM_BUSMAIL(struct celliax_pvt *p, - struct cvm_busmail_msg *list) -{ - struct cvm_busmail_msg *ptr; - ptr = list; - - if (ptr) { - while (ptr->next != NULL) - ptr = ptr->next; - - while (ptr) { - - if (option_debug > 3) - DEBUGA_CVM - ("PTR msg is: %d, seqnum is %.2X, tv_sec is %d, tv_usec is %d, acknowledged is: %d," - " sent is:%d, how_many_sent is: %d\n", CELLIAX_P_LOG, ptr->valid, - /*ptr->seqnum */ 44, - ptr->tv_sec, ptr->tv_usec, ptr->acknowledged, ptr->sent, ptr->how_many_sent); - - ptr = ptr->previous; - } - } - - return 0; -} - -#endif /* CELLIAX_CVM */ diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.c b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.c deleted file mode 100644 index 6b5dc3fe4b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.c +++ /dev/null @@ -1,356 +0,0 @@ -/* -libcsv - parse and write csv data -Copyright (C) 2007 Robert Gamble - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#if ___STDC_VERSION__ >= 199901L -# include -#else -# define SIZE_MAX ((size_t)-1) /* C89 doesn't have stdint.h or SIZE_MAX */ -#endif - -#include "celliax_libcsv.h" - -#define VERSION "1.0.0" - -#define ROW_NOT_BEGUN 0 -#define FIELD_NOT_BEGUN 1 -#define FIELD_BEGUN 2 -#define FIELD_MIGHT_HAVE_ENDED 3 - -/* - Explanation of states - ROW_NOT_BEGUN There have not been any fields encountered for this row - FIELD_NOT_BEGUN There have been fields but we are currently not in one - FIELD_BEGUN We are in a field - FIELD_MIGHT_HAVE_ENDED - We encountered a double quote inside a quoted field, the - field is either ended or the quote is literal -*/ - -#define MEM_BLK_SIZE 128 - -#define SUBMIT_FIELD(p) \ - do { \ - if (!(p)->quoted) \ - (p)->entry_pos -= (p)->spaces; \ - if (cb1) \ - cb1(p->entry_buf, (p)->entry_pos, data); \ - (p)->pstate = FIELD_NOT_BEGUN; \ - (p)->entry_pos = (p)->quoted = (p)->spaces = 0; \ - } while (0) - -#define SUBMIT_ROW(p, c) \ - do { \ - if (cb2) \ - cb2(c, data); \ - (p)->pstate = ROW_NOT_BEGUN; \ - (p)->entry_pos = (p)->quoted = (p)->spaces = 0; \ - } while (0) - -#define SUBMIT_CHAR(p, c) ((p)->entry_buf[(p)->entry_pos++] = (c)) - -static char *csv_errors[] = {"success", - "error parsing data while strict checking enabled", - "memory exhausted while increasing buffer size", - "data size too large", - "invalid status code"}; - -int -csv_error(struct csv_parser *p) -{ - return p->status; -} - -char * -csv_strerror(int status) -{ - if (status >= CSV_EINVALID || status < 0) - return csv_errors[CSV_EINVALID]; - else - return csv_errors[status]; -} - -int -csv_opts(struct csv_parser *p, unsigned char options) -{ - if (p == NULL) - return -1; - - p->options = options; - return 0; -} - -int -csv_init(struct csv_parser **p, unsigned char options) -{ - /* Initialize a csv_parser object returns 0 on success, -1 on error */ - if (p == NULL) - return -1; - - if ((*p = malloc(sizeof(struct csv_parser))) == NULL) - return -1; - - if ( ((*p)->entry_buf = malloc(MEM_BLK_SIZE)) == NULL ) { - free(*p); - return -1; - } - (*p)->pstate = ROW_NOT_BEGUN; - (*p)->quoted = 0; - (*p)->spaces = 0; - (*p)->entry_pos = 0; - (*p)->entry_size = MEM_BLK_SIZE; - (*p)->status = 0; - (*p)->options = options; - - return 0; -} - -void -csv_free(struct csv_parser *p) -{ - /* Free the entry_buffer and the csv_parser object */ - if (p == NULL) - return; - - if (p->entry_buf) - free(p->entry_buf); - - free(p); - return; -} - -int -csv_fini(struct csv_parser *p, void (*cb1)(char *, size_t, void *), void (*cb2)(char c, void *), void *data) -{ - /* Finalize parsing. Needed, for example, when file does not end in a newline */ - if (p == NULL) - return -1; - - switch (p->pstate) { - case FIELD_MIGHT_HAVE_ENDED: - p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */ - case FIELD_NOT_BEGUN: - case FIELD_BEGUN: - SUBMIT_FIELD(p); - SUBMIT_ROW(p, 0); - case ROW_NOT_BEGUN: /* Already ended properly */ - ; - } - - p->spaces = p->quoted = p->entry_pos = p->status = 0; - p->pstate = ROW_NOT_BEGUN; - - return 0; -} - -size_t -csv_parse(struct csv_parser *p, const char *s, size_t len, void (*cb1)(char *, size_t, void *), void (*cb2)(char c, void *), void *data) -{ - char c; /* The character we are currently processing */ - size_t pos = 0; /* The number of characters we have processed in this call */ - - while (pos < len) { - /* Check memory usage */ - if (p->entry_pos == p->entry_size) { - size_t to_add = MEM_BLK_SIZE; - void *vp; - while ( p->entry_size >= SIZE_MAX - to_add ) - to_add /= 2; - if (!to_add) { - p->status = CSV_ETOOBIG; - return pos; - } - while ((vp = realloc(p->entry_buf, p->entry_size + to_add)) == NULL) { - to_add /= 2; - if (!to_add) { - p->status = CSV_ENOMEM; - return pos; - } - } - p->entry_buf = vp; - p->entry_size += to_add; - } - - c = s[pos++]; - switch (p->pstate) { - case ROW_NOT_BEGUN: - case FIELD_NOT_BEGUN: - if (c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */ - continue; - } else if (c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */ - if (p->pstate == FIELD_NOT_BEGUN) { - SUBMIT_FIELD(p); - SUBMIT_ROW(p, c); - } else { /* ROW_NOT_BEGUN */ - /* Don't submit empty rows by default */ - if (p->options & CSV_REPALL_NL) { - SUBMIT_ROW(p, c); - } - } - continue; - } else if ( (!(p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_COMMA)) || ((p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_SEMICOLON)) ) { /* Comma or SemiColon */ - SUBMIT_FIELD(p); - break; - } else if (c == CSV_QUOTE) { /* Quote */ - p->pstate = FIELD_BEGUN; - p->quoted = 1; - } else { /* Anything else */ - p->pstate = FIELD_BEGUN; - p->quoted = 0; - SUBMIT_CHAR(p, c); - } - break; - case FIELD_BEGUN: - if (c == CSV_QUOTE) { /* Quote */ - if (p->quoted) { - SUBMIT_CHAR(p, c); - p->pstate = FIELD_MIGHT_HAVE_ENDED; - } else { - /* STRICT ERROR - double quote inside non-quoted field */ - if (p->options & CSV_STRICT) { - p->status = CSV_EPARSE; - return pos-1; - } - SUBMIT_CHAR(p, c); - p->spaces = 0; - } - } else if ((!(p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_COMMA)) || ((p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_SEMICOLON))) { /* Comma or SemiColon */ - if (p->quoted) { - SUBMIT_CHAR(p, c); - } else { - SUBMIT_FIELD(p); - } - } else if (c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */ - if (!p->quoted) { - SUBMIT_FIELD(p); - SUBMIT_ROW(p, c); - } else { - SUBMIT_CHAR(p, c); - } - } else if (!p->quoted && (c == CSV_SPACE || c == CSV_TAB)) { /* Tab or space for non-quoted field */ - SUBMIT_CHAR(p, c); - p->spaces++; - } else { /* Anything else */ - SUBMIT_CHAR(p, c); - p->spaces = 0; - } - break; - case FIELD_MIGHT_HAVE_ENDED: - /* This only happens when a quote character is encountered in a quoted field */ - if ((!(p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_COMMA)) || ((p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_SEMICOLON))) { /* Comma or SemiColon */ - p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */ - SUBMIT_FIELD(p); - } else if (c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */ - p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */ - SUBMIT_FIELD(p); - SUBMIT_ROW(p, c); - } else if (c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */ - SUBMIT_CHAR(p, c); - p->spaces++; - } else if (c == CSV_QUOTE) { /* Quote */ - if (p->spaces) { - /* STRICT ERROR - unescaped double quote */ - if (p->options & CSV_STRICT) { - p->status = CSV_EPARSE; - return pos-1; - } - p->spaces = 0; - SUBMIT_CHAR(p, c); - } else { - /* Two quotes in a row */ - p->pstate = FIELD_BEGUN; - } - } else { /* Anything else */ - /* STRICT ERROR - unescaped double quote */ - if (p->options & CSV_STRICT) { - p->status = CSV_EPARSE; - return pos-1; - } - p->pstate = FIELD_BEGUN; - p->spaces = 0; - SUBMIT_CHAR(p, c); - } - break; - default: - break; - } - } - return pos; -} - -size_t -csv_write (char *dest, size_t dest_size, const char *src, size_t src_size) -{ - size_t chars = 0; - - if (src == NULL) - return 0; - - if (dest == NULL) - dest_size = 0; - - if (dest_size > 0) - *dest++ = '"'; - chars++; - - while (src_size) { - if (*src == '"') { - if (dest_size > chars) - *dest++ = '"'; - if (chars < SIZE_MAX) chars++; - } - if (dest_size > chars) - *dest++ = *src; - if (chars < SIZE_MAX) chars++; - src_size--; - src++; - } - - if (dest_size > chars) - *dest = '"'; - if (chars < SIZE_MAX) chars++; - - return chars; -} - -int -csv_fwrite (FILE *fp, const char *src, size_t src_size) -{ - if (fp == NULL || src == NULL) - return 0; - - if (fputc('"', fp) == EOF) - return EOF; - - while (src_size) { - if (*src == '"') { - if (fputc('"', fp) == EOF) - return EOF; - } - if (fputc(*src, fp) == EOF) - return EOF; - src_size--; - src++; - } - - if (fputc('"', fp) == EOF) { - return EOF; - } - - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.h b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.h deleted file mode 100644 index 2a2e4465a9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_libcsv.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef LIBCSV_H__ -#define LIBCSV_H__ -#include -#include - -/* Error Codes */ -#define CSV_SUCCESS 0 -#define CSV_EPARSE 1 /* Parse error in strict mode */ -#define CSV_ENOMEM 2 /* Out of memory while increasing buffer size */ -#define CSV_ETOOBIG 3 /* Buffer larger than SIZE_MAX needed */ -#define CSV_EINVALID 4 /* Invalid code, should never receive this from csv_error */ - -/* parser options */ -#define CSV_STRICT 1 /* enable strict mode */ -#define CSV_REPALL_NL 2 /* report all unquoted carriage returns and linefeeds */ -#define CSV_USE_SEMICOLON_SEPARATOR 4 /* use CSV_SEMICOLON as separator instead of CSV_COMMA */ - -/* Character values */ -#define CSV_TAB 0x09 -#define CSV_SPACE 0x20 -#define CSV_CR 0x0d -#define CSV_LF 0x0a -#define CSV_COMMA 0x2c -#define CSV_SEMICOLON 0x3b /* ; */ -#define CSV_QUOTE 0x22 - -struct csv_parser { - int pstate; /* Parser state */ - int quoted; /* Is the current field a quoted field? */ - size_t spaces; /* Number of continious spaces after quote or in a non-quoted field */ - char * entry_buf; /* Entry buffer */ - size_t entry_pos; /* Current position in entry_buf (and current size of entry) */ - size_t entry_size; /* Size of buffer */ - int status; /* Operation status */ - unsigned char options; -}; - -int csv_init(struct csv_parser **p, unsigned char options); -int csv_fini(struct csv_parser *p, void (*cb1)(char *, size_t, void *), void (*cb2)(char, void *), void *data); -void csv_free(struct csv_parser *p); -int csv_error(struct csv_parser *p); -char * csv_strerror(int error); -size_t csv_parse(struct csv_parser *p, const char *s, size_t len, void (*cb1)(char *, size_t, void *), void (*cb2)(char, void *), void *data); -size_t csv_write(char *dest, size_t dest_size, const char *src, size_t src_size); -int csv_fwrite(FILE *fp, const char *src, size_t src_size); -int csv_opts(struct csv_parser *p, unsigned char options); - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.c b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.c deleted file mode 100644 index b18a498e8d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * echo.c - An echo cancellor, suitable for electrical and acoustic - * cancellation. This code does not currently comply with - * any relevant standards (e.g. G.164/5/7/8). One day.... - * - * Written by Steve Underwood - * - * Copyright (C) 2001, 2003 Steve Underwood - * - * Based on a bit from here, a bit from there, eye of toad, - * ear of bat, etc - plus, of course, my own 2 cents. - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: echo.c,v 1.20 2006/12/01 18:00:48 steveu Exp $ - */ - -/*! \file */ - -/* TODO: - Finish the echo suppressor option, however nasty suppression may be. - Add an option to reintroduce side tone at -24dB under appropriate conditions. - Improve double talk detector (iterative!) -*/ - -/* We need to differentiate between transmitted energy which will train the echo - canceller well (voice, white noise, and other broadband sources) and energy - which will train it badly (supervisory tones, DTMF, whistles, and other - narrowband sources). There are many ways this might be done. This canceller uses - a method based on the autocorrelation qualities of the transmitted signal. A rather - peaky autocorrelation function is a clear sign of a narrowband signal. We only need - perform the autocorrelation at well spaced intervals, so the compute load is not too - great. Multiple successive autocorrelation functions with a similar peaky shape are a - clear indication of a stationary narrowband signal. Using TKEO, it should be possible to - greatly reduce the compute requirement for narrowband detection. */ - -/* The FIR taps must be adapted as 32 bit values, to get the necessary finesse - in the adaption process. However, they are applied as 16 bit values (bits 30-15 - of the 32 bit values) in the FIR. For the working 16 bit values, we need 4 sets. - - 3 of the 16 bit sets are used on a rotating basis. Normally the canceller steps - round these 3 sets at regular intervals. Any time we detect double talk, we can go - back to the set from two steps ago with reasonable assurance it is a well adapted - set. We cannot just go back one step, as we may have rotated the sets just before - double talk or tone was detected, and that set may already be somewhat corrupted. - - When narrowband energy is detected we need to continue adapting to it, to echo - cancel it. However, the adaption will almost certainly be going astray. Broadband - (or even complex sequences of narrowband) energy will normally lead to a well - trained cancellor, with taps matching the impulse response of the channel. - For stationary narrowband energy, there is usually has an infinite number of - alternative tap sets which will cancel it well. A previously well trained set of - taps will tend to drift amongst the alternatives. When broadband energy resumes, the - taps may be a total mismatch for the signal, and could even amplify rather than - attenuate the echo. The solution is to use a fourth set of 16 bit taps. When we first - detect the narrowband energy we save the oldest of the group of three sets, but do - not change back to an older set. We let the canceller cancel, and it adaption drift - while the narrowband energy is present. When we detect the narrowband energy has ceased, - we switch to using the fourth set of taps which was saved. - - When we revert to an older set of taps, we must replace both the 16 bit and 32 bit - working tap sets. The saved 16 bit values are good enough to also be used as a replacement - for the 32 bit values. We loose the fractions, but they should soon settle down in a - reasonable way. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "celliax_spandsp.h" - -//#include "spandsp/telephony.h" -//#include "spandsp/logging.h" -//#include "spandsp/bit_operations.h" -//#include "spandsp/echo.h" - -//#include "bit_operations.h" -//#include "giova.h" - -#if !defined(NULL) -#define NULL (void *) 0 -#endif -#if !defined(FALSE) -#define FALSE 0 -#endif -#if !defined(TRUE) -#define TRUE (!FALSE) -#endif - -#if 0 -#define MIN_TX_POWER_FOR_ADAPTION 64*64 -#define MIN_RX_POWER_FOR_ADAPTION 64*64 - -static int narrowband_detect(echo_can_state_t * ec) -{ - int k; - int i; - float temp; - float scale; - float sf[128]; - float f_acf[128]; - int32_t acf[28]; - int score; - int len = 32; - int alen = 9; - - k = ec->curr_pos; - for (i = 0; i < len; i++) { - sf[i] = ec->fir_state.history[k++]; - if (k >= 256) - k = 0; - } - for (k = 0; k < alen; k++) { - temp = 0; - for (i = k; i < len; i++) - temp += sf[i] * sf[i - k]; - f_acf[k] = temp; - } - scale = 0x1FFFFFFF / f_acf[0]; - for (k = 0; k < alen; k++) - acf[k] = (int32_t) (f_acf[k] * scale); - score = 0; - for (i = 0; i < 9; i++) { - if (ec->last_acf[i] >= 0 && acf[i] >= 0) { - if ((ec->last_acf[i] >> 1) < acf[i] && acf[i] < (ec->last_acf[i] << 1)) - score++; - } else if (ec->last_acf[i] < 0 && acf[i] < 0) { - if ((ec->last_acf[i] >> 1) > acf[i] && acf[i] > (ec->last_acf[i] << 1)) - score++; - } - } - memcpy(ec->last_acf, acf, alen * sizeof(ec->last_acf[0])); - return score; -} - -static __inline__ void lms_adapt(echo_can_state_t * ec, int factor) -{ - int i; - -#if 0 - mmx_t *mmx_taps; - mmx_t *mmx_coeffs; - mmx_t *mmx_hist; - mmx_t mmx; - - mmx.w[0] = mmx.w[1] = mmx.w[2] = mmx.w[3] = factor; - mmx_hist = (mmx_t *) & fir->history[fir->curr_pos]; - mmx_taps = (mmx_t *) & fir->taps; - mmx_coeffs = (mmx_t *) fir->coeffs; - i = fir->taps; - movq_m2r(mmx, mm0); - while (i > 0) { - movq_m2r(mmx_hist[0], mm1); - movq_m2r(mmx_taps[0], mm0); - movq_m2r(mmx_taps[1], mm1); - movq_r2r(mm1, mm2); - pmulhw(mm0, mm1); - pmullw(mm0, mm2); - - pmaddwd_r2r(mm1, mm0); - pmaddwd_r2r(mm3, mm2); - paddd_r2r(mm0, mm4); - paddd_r2r(mm2, mm4); - movq_r2m(mm0, mmx_taps[0]); - movq_r2m(mm1, mmx_taps[0]); - movq_r2m(mm2, mmx_coeffs[0]); - mmx_taps += 2; - mmx_coeffs += 1; - mmx_hist += 1; - i -= 4; - ) - emms(); -#elif 0 - /* Update the FIR taps */ - for (i = ec->taps - 1; i >= 0; i--) { - /* Leak to avoid the coefficients drifting beyond the ability of the - adaption process to bring them back under control. */ - ec->fir_taps32[i] -= (ec->fir_taps32[i] >> 23); - ec->fir_taps32[i] += (ec->fir_state.history[i + ec->curr_pos] * factor); - ec->latest_correction = (ec->fir_state.history[i + ec->curr_pos] * factor); - ec->fir_taps16[ec->tap_set][i] = ec->fir_taps32[i] >> 15; - } -#else - int offset1; - int offset2; - - /* Update the FIR taps */ - offset2 = ec->curr_pos; - offset1 = ec->taps - offset2; - for (i = ec->taps - 1; i >= offset1; i--) { - ec->fir_taps32[i] += (ec->fir_state.history[i - offset1] * factor); - ec->fir_taps16[ec->tap_set][i] = (int16_t) (ec->fir_taps32[i] >> 15); - } - for (; i >= 0; i--) { - ec->fir_taps32[i] += (ec->fir_state.history[i + offset2] * factor); - ec->fir_taps16[ec->tap_set][i] = (int16_t) (ec->fir_taps32[i] >> 15); - } -#endif -} - -/*- End of function --------------------------------------------------------*/ - -#ifdef NOT_NEEDED -echo_can_state_t *echo_can_create(int len, int adaption_mode) -{ - echo_can_state_t *ec; - int i; - int j; - - ec = (echo_can_state_t *) malloc(sizeof(*ec)); - if (ec == NULL) - return NULL; - memset(ec, 0, sizeof(*ec)); - ec->taps = len; - ec->curr_pos = ec->taps - 1; - ec->tap_mask = ec->taps - 1; - if ((ec->fir_taps32 = (int32_t *) malloc(ec->taps * sizeof(int32_t))) == NULL) { - free(ec); - return NULL; - } - memset(ec->fir_taps32, 0, ec->taps * sizeof(int32_t)); - for (i = 0; i < 4; i++) { - if ((ec->fir_taps16[i] = (int16_t *) malloc(ec->taps * sizeof(int16_t))) == NULL) { - for (j = 0; j < i; j++) - free(ec->fir_taps16[j]); - free(ec->fir_taps32); - free(ec); - return NULL; - } - memset(ec->fir_taps16[i], 0, ec->taps * sizeof(int16_t)); - } - fir16_create(&ec->fir_state, ec->fir_taps16[0], ec->taps); - ec->rx_power_threshold = 10000000; - ec->geigel_max = 0; - ec->geigel_lag = 0; - ec->dtd_onset = FALSE; - ec->tap_set = 0; - ec->tap_rotate_counter = 1600; - ec->cng_level = 1000; - echo_can_adaption_mode(ec, adaption_mode); - return ec; -} - -/*- End of function --------------------------------------------------------*/ - -void echo_can_free(echo_can_state_t * ec) -{ - int i; - - fir16_free(&ec->fir_state); - free(ec->fir_taps32); - for (i = 0; i < 4; i++) - free(ec->fir_taps16[i]); - free(ec); -} - -/*- End of function --------------------------------------------------------*/ - -void echo_can_adaption_mode(echo_can_state_t * ec, int adaption_mode) -{ - ec->adaption_mode = adaption_mode; -} - -/*- End of function --------------------------------------------------------*/ - -void echo_can_flush(echo_can_state_t * ec) -{ - int i; - - for (i = 0; i < 4; i++) - ec->tx_power[i] = 0; - for (i = 0; i < 3; i++) - ec->rx_power[i] = 0; - ec->clean_rx_power = 0; - ec->nonupdate_dwell = 0; - - fir16_flush(&ec->fir_state); - ec->fir_state.curr_pos = ec->taps - 1; - memset(ec->fir_taps32, 0, ec->taps * sizeof(int32_t)); - for (i = 0; i < 4; i++) - memset(ec->fir_taps16[i], 0, ec->taps * sizeof(int16_t)); - - ec->curr_pos = ec->taps - 1; - - ec->supp_test1 = 0; - ec->supp_test2 = 0; - ec->supp1 = 0; - ec->supp2 = 0; - ec->vad = 0; - ec->cng_level = 1000; - ec->cng_filter = 0; - - ec->geigel_max = 0; - ec->geigel_lag = 0; - ec->dtd_onset = FALSE; - ec->tap_set = 0; - ec->tap_rotate_counter = 1600; - - ec->latest_correction = 0; - - memset(ec->last_acf, 0, sizeof(ec->last_acf)); - ec->narrowband_count = 0; - ec->narrowband_score = 0; -} - -/*- End of function --------------------------------------------------------*/ - -int sample_no = 0; - -int16_t echo_can_update(echo_can_state_t * ec, int16_t tx, int16_t rx) -{ - int32_t echo_value; - int clean_rx; - int nsuppr; - int score; - int i; - - sample_no++; - ec->latest_correction = 0; - /* Evaluate the echo - i.e. apply the FIR filter */ - /* Assume the gain of the FIR does not exceed unity. Exceeding unity - would seem like a rather poor thing for an echo cancellor to do :) - This means we can compute the result with a total disregard for - overflows. 16bits x 16bits -> 31bits, so no overflow can occur in - any multiply. While accumulating we may overflow and underflow the - 32 bit scale often. However, if the gain does not exceed unity, - everything should work itself out, and the final result will be - OK, without any saturation logic. */ - /* Overflow is very much possible here, and we do nothing about it because - of the compute costs */ - /* 16 bit coeffs for the LMS give lousy results (maths good, actual sound - bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems - best */ - echo_value = fir16(&ec->fir_state, tx); - - /* And the answer is..... */ - clean_rx = rx - echo_value; -//printf("echo is %" PRId32 "\n", echo_value); - /* That was the easy part. Now we need to adapt! */ - if (ec->nonupdate_dwell > 0) - ec->nonupdate_dwell--; - - /* Calculate short term power levels using very simple single pole IIRs */ - /* TODO: Is the nasty modulus approach the fastest, or would a real - tx*tx power calculation actually be faster? Using the squares - makes the numbers grow a lot! */ - ec->tx_power[3] += ((abs(tx) - ec->tx_power[3]) >> 5); - ec->tx_power[2] += ((tx * tx - ec->tx_power[2]) >> 8); - ec->tx_power[1] += ((tx * tx - ec->tx_power[1]) >> 5); - ec->tx_power[0] += ((tx * tx - ec->tx_power[0]) >> 3); - ec->rx_power[1] += ((rx * rx - ec->rx_power[1]) >> 6); - ec->rx_power[0] += ((rx * rx - ec->rx_power[0]) >> 3); - ec->clean_rx_power += ((clean_rx * clean_rx - ec->clean_rx_power) >> 6); - - score = 0; - /* If there is very little being transmitted, any attempt to train is - futile. We would either be training on the far end's noise or signal, - the channel's own noise, or our noise. Either way, this is hardly good - training, so don't do it (avoid trouble). */ - if (ec->tx_power[0] > MIN_TX_POWER_FOR_ADAPTION) { - /* If the received power is very low, either we are sending very little or - we are already well adapted. There is little point in trying to improve - the adaption under these circumstances, so don't do it (reduce the - compute load). */ - if (ec->tx_power[1] > ec->rx_power[0]) { - /* There is no (or little) far-end speech. */ - if (ec->nonupdate_dwell == 0) { - if (++ec->narrowband_count >= 160) { - ec->narrowband_count = 0; - score = narrowband_detect(ec); -//printf("Do the narrowband test %d at %d\n", score, ec->curr_pos); - if (score > 6) { - if (ec->narrowband_score == 0) - memcpy(ec->fir_taps16[3], ec->fir_taps16[(ec->tap_set + 1) % 3], - ec->taps * sizeof(int16_t)); - ec->narrowband_score += score; - } else { - if (ec->narrowband_score > 200) { -//printf("Revert to %d at %d\n", (ec->tap_set + 1)%3, sample_no); - memcpy(ec->fir_taps16[ec->tap_set], ec->fir_taps16[3], - ec->taps * sizeof(int16_t)); - memcpy(ec->fir_taps16[(ec->tap_set - 1) % 3], ec->fir_taps16[3], - ec->taps * sizeof(int16_t)); - for (i = 0; i < ec->taps; i++) - ec->fir_taps32[i] = ec->fir_taps16[3][i] << 15; - ec->tap_rotate_counter = 1600; - } - ec->narrowband_score = 0; - } - } - ec->dtd_onset = FALSE; - if (--ec->tap_rotate_counter <= 0) { -//printf("Rotate to %d at %d\n", ec->tap_set, sample_no); - ec->tap_rotate_counter = 1600; - ec->tap_set++; - if (ec->tap_set > 2) - ec->tap_set = 0; - ec->fir_state.coeffs = ec->fir_taps16[ec->tap_set]; - } - /* ... and we are not in the dwell time from previous speech. */ - if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) && ec->narrowband_score == 0) { - //nsuppr = saturate((clean_rx << 16)/ec->tx_power[1]); - //nsuppr = clean_rx/ec->tx_power[1]; - /* If a sudden surge in signal level (e.g. the onset of a tone - burst) cause an abnormally high instantaneous to average - signal power ratio, we could kick the adaption badly in the - wrong direction. This is because the tx_power takes too long - to react and rise. We need to stop too rapid adaption to the - new signal. We normalise to a value derived from the - instantaneous signal if it exceeds the peak by too much. */ - nsuppr = clean_rx; - /* Divide isn't very quick, but the "where is the top bit" and shift - instructions are single cycle. */ - if (tx > 4 * ec->tx_power[3]) - i = top_bit(tx) - 8; - else - i = top_bit(ec->tx_power[3]) - 8; - if (i > 0) - nsuppr >>= i; - lms_adapt(ec, nsuppr); - } - } - //printf("%10d %10d %10d %10d %10d\n", rx, clean_rx, nsuppr, ec->tx_power[1], ec->rx_power[1]); - //printf("%.4f\n", (float) ec->rx_power[1]/(float) ec->clean_rx_power); - } else { - if (!ec->dtd_onset) { -//printf("Revert to %d at %d\n", (ec->tap_set + 1)%3, sample_no); - memcpy(ec->fir_taps16[ec->tap_set], ec->fir_taps16[(ec->tap_set + 1) % 3], - ec->taps * sizeof(int16_t)); - memcpy(ec->fir_taps16[(ec->tap_set - 1) % 3], - ec->fir_taps16[(ec->tap_set + 1) % 3], ec->taps * sizeof(int16_t)); - for (i = 0; i < ec->taps; i++) - ec->fir_taps32[i] = ec->fir_taps16[(ec->tap_set + 1) % 3][i] << 15; - ec->tap_rotate_counter = 1600; - ec->dtd_onset = TRUE; - } - ec->nonupdate_dwell = NONUPDATE_DWELL_TIME; - } - } - - if (ec->rx_power[1]) - ec->vad = (8000 * ec->clean_rx_power) / ec->rx_power[1]; - else - ec->vad = 0; - if (ec->rx_power[1] > 2048 * 2048 && ec->clean_rx_power > 4 * ec->rx_power[1]) { - /* The EC seems to be making things worse, instead of better. Zap it! */ - memset(ec->fir_taps32, 0, ec->taps * sizeof(int32_t)); - for (i = 0; i < 4; i++) - memset(ec->fir_taps16[i], 0, ec->taps * sizeof(int16_t)); - } -#if defined(XYZZY) - if ((ec->adaption_mode & ECHO_CAN_USE_SUPPRESSOR)) { - ec->supp_test1 += - (ec->fir_state.history[ec->curr_pos] - - ec->fir_state.history[(ec->curr_pos - 7) & ec->tap_mask]); - ec->supp_test2 += - (ec->fir_state.history[(ec->curr_pos - 24) & ec->tap_mask] - - ec->fir_state.history[(ec->curr_pos - 31) & ec->tap_mask]); - if (ec->supp_test1 > 42 && ec->supp_test2 > 42) - supp_change = 25; - else - supp_change = 50; - supp = supp_change + k1 * ec->supp1 + k2 * ec->supp2; - ec->supp2 = ec->supp1; - ec->supp1 = supp; - clean_rx *= (1 - supp); - } -#endif - - if ((ec->adaption_mode & ECHO_CAN_USE_NLP)) { - /* Non-linear processor - a fancy way to say "zap small signals, to avoid - residual echo due to (uLaw/ALaw) non-linearity in the channel.". */ - if (ec->rx_power[1] < 30000000) { - if (!ec->cng) { - ec->cng_level = ec->clean_rx_power; - ec->cng = TRUE; - } - if ((ec->adaption_mode & ECHO_CAN_USE_CNG)) { - /* Very elementary comfort noise generation */ - /* Just random numbers rolled off very vaguely Hoth-like */ - ec->cng_rndnum = 1664525U * ec->cng_rndnum + 1013904223U; - ec->cng_filter = ((ec->cng_rndnum & 0xFFFF) - 32768 + 5 * ec->cng_filter) >> 3; - clean_rx = (ec->cng_filter * ec->cng_level) >> 17; - /* TODO: A better CNG, with more accurate (tracking) spectral shaping! */ - } else { - clean_rx = 0; - } -//clean_rx = -16000; - } else { - ec->cng = FALSE; - } - } else { - ec->cng = FALSE; - } - -//printf("Narrowband score %4d %5d at %d\n", ec->narrowband_score, score, sample_no); - /* Roll around the rolling buffer */ - if (ec->curr_pos <= 0) - ec->curr_pos = ec->taps; - ec->curr_pos--; - return (int16_t) clean_rx; -} - -#endif //NOT_NEEDED -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ -#endif - -#include -#include -#include -#include -#include -#include -#include - -//#include "spandsp/telephony.h" -//#include "spandsp/tone_detect.h" -//#include "spandsp/tone_generate.h" -//#include "spandsp/super_tone_rx.h" -//#include "giova.h" - -#if !defined(M_PI) -/* C99 systems may not define M_PI */ -#define M_PI 3.14159265358979323846264338327 -#endif - -//#define USE_3DNOW - -#define DEFAULT_DTMF_TX_LEVEL -10 -#define DEFAULT_DTMF_TX_ON_TIME 50 -#define DEFAULT_DTMF_TX_OFF_TIME 55 - -#define DTMF_THRESHOLD 8.0e7f -#define DTMF_NORMAL_TWIST 6.3f /* 8dB */ -#define DTMF_REVERSE_TWIST 2.5f /* 4dB */ -#define DTMF_RELATIVE_PEAK_ROW 6.3f /* 8dB */ -#define DTMF_RELATIVE_PEAK_COL 6.3f /* 8dB */ -#define DTMF_TO_TOTAL_ENERGY 42.0f - -static const float dtmf_row[] = { - 697.0f, 770.0f, 852.0f, 941.0f -}; -static const float dtmf_col[] = { - 1209.0f, 1336.0f, 1477.0f, 1633.0f -}; - -static const char dtmf_positions[] = "123A" "456B" "789C" "*0#D"; - -static goertzel_descriptor_t dtmf_detect_row[4]; -static goertzel_descriptor_t dtmf_detect_col[4]; - -// -//static int dtmf_tx_inited = 0; -//static tone_gen_descriptor_t dtmf_digit_tones[16]; - -#if defined(USE_3DNOW) -static __inline__ void _dtmf_goertzel_update(goertzel_state_t * s, float x[], int samples) -{ - int n; - float v; - int i; - float vv[16]; - - vv[4] = s[0].v2; - vv[5] = s[1].v2; - vv[6] = s[2].v2; - vv[7] = s[3].v2; - vv[8] = s[0].v3; - vv[9] = s[1].v3; - vv[10] = s[2].v3; - vv[11] = s[3].v3; - vv[12] = s[0].fac; - vv[13] = s[1].fac; - vv[14] = s[2].fac; - vv[15] = s[3].fac; - - //v1 = s->v2; - //s->v2 = s->v3; - //s->v3 = s->fac*s->v2 - v1 + x[0]; - - __asm__ __volatile__(" femms;\n" " movq 16(%%edx),%%mm2;\n" - " movq 24(%%edx),%%mm3;\n" " movq 32(%%edx),%%mm4;\n" - " movq 40(%%edx),%%mm5;\n" " movq 48(%%edx),%%mm6;\n" - " movq 56(%%edx),%%mm7;\n" " jmp 1f;\n" - " .align 32;\n" " 1: ;\n" " prefetch (%%eax);\n" - " movq %%mm3,%%mm1;\n" " movq %%mm2,%%mm0;\n" - " movq %%mm5,%%mm3;\n" " movq %%mm4,%%mm2;\n" - " pfmul %%mm7,%%mm5;\n" " pfmul %%mm6,%%mm4;\n" - " pfsub %%mm1,%%mm5;\n" " pfsub %%mm0,%%mm4;\n" - " movq (%%eax),%%mm0;\n" " movq %%mm0,%%mm1;\n" - " punpckldq %%mm0,%%mm1;\n" " add $4,%%eax;\n" - " pfadd %%mm1,%%mm5;\n" " pfadd %%mm1,%%mm4;\n" - " dec %%ecx;\n" " jnz 1b;\n" - " movq %%mm2,16(%%edx);\n" " movq %%mm3,24(%%edx);\n" - " movq %%mm4,32(%%edx);\n" " movq %%mm5,40(%%edx);\n" - " femms;\n"::"c"(samples), "a"(x), "d"(vv) - :"memory", "eax", "ecx"); - - s[0].v2 = vv[4]; - s[1].v2 = vv[5]; - s[2].v2 = vv[6]; - s[3].v2 = vv[7]; - s[0].v3 = vv[8]; - s[1].v3 = vv[9]; - s[2].v3 = vv[10]; - s[3].v3 = vv[11]; -} - -/*- End of function --------------------------------------------------------*/ -#endif - -int dtmf_rx(dtmf_rx_state_t * s, const int16_t amp[], int samples) -{ - float row_energy[4]; - float col_energy[4]; - float famp; - float v1; - int i; - int j; - int sample; - int best_row; - int best_col; - int limit; - uint8_t hit; - - hit = 0; - for (sample = 0; sample < samples; sample = limit) { - /* The block length is optimised to meet the DTMF specs. */ - if ((samples - sample) >= (102 - s->current_sample)) - limit = sample + (102 - s->current_sample); - else - limit = samples; -#if defined(USE_3DNOW) - _dtmf_goertzel_update(s->row_out, amp + sample, limit - sample); - _dtmf_goertzel_update(s->col_out, amp + sample, limit - sample); -#else - /* The following unrolled loop takes only 35% (rough estimate) of the - time of a rolled loop on the machine on which it was developed */ - for (j = sample; j < limit; j++) { - famp = amp[j]; - if (s->filter_dialtone) { - /* Sharp notches applied at 350Hz and 440Hz - the two common dialtone frequencies. - These are rather high Q, to achieve the required narrowness, without using lots of - sections. */ - v1 = 0.98356f * famp + 1.8954426f * s->z350_1 - 0.9691396f * s->z350_2; - famp = v1 - 1.9251480f * s->z350_1 + s->z350_2; - s->z350_2 = s->z350_1; - s->z350_1 = v1; - - v1 = 0.98456f * famp + 1.8529543f * s->z440_1 - 0.9691396f * s->z440_2; - famp = v1 - 1.8819938f * s->z440_1 + s->z440_2; - s->z440_2 = s->z440_1; - s->z440_1 = v1; - } - s->energy += famp * famp; - /* With GCC 2.95, the following unrolled code seems to take about 35% - (rough estimate) as long as a neat little 0-3 loop */ - v1 = s->row_out[0].v2; - s->row_out[0].v2 = s->row_out[0].v3; - s->row_out[0].v3 = s->row_out[0].fac * s->row_out[0].v2 - v1 + famp; - - v1 = s->col_out[0].v2; - s->col_out[0].v2 = s->col_out[0].v3; - s->col_out[0].v3 = s->col_out[0].fac * s->col_out[0].v2 - v1 + famp; - - v1 = s->row_out[1].v2; - s->row_out[1].v2 = s->row_out[1].v3; - s->row_out[1].v3 = s->row_out[1].fac * s->row_out[1].v2 - v1 + famp; - - v1 = s->col_out[1].v2; - s->col_out[1].v2 = s->col_out[1].v3; - s->col_out[1].v3 = s->col_out[1].fac * s->col_out[1].v2 - v1 + famp; - - v1 = s->row_out[2].v2; - s->row_out[2].v2 = s->row_out[2].v3; - s->row_out[2].v3 = s->row_out[2].fac * s->row_out[2].v2 - v1 + famp; - - v1 = s->col_out[2].v2; - s->col_out[2].v2 = s->col_out[2].v3; - s->col_out[2].v3 = s->col_out[2].fac * s->col_out[2].v2 - v1 + famp; - - v1 = s->row_out[3].v2; - s->row_out[3].v2 = s->row_out[3].v3; - s->row_out[3].v3 = s->row_out[3].fac * s->row_out[3].v2 - v1 + famp; - - v1 = s->col_out[3].v2; - s->col_out[3].v2 = s->col_out[3].v3; - s->col_out[3].v3 = s->col_out[3].fac * s->col_out[3].v2 - v1 + famp; - } -#endif - s->current_sample += (limit - sample); - if (s->current_sample < 102) - continue; - - /* We are at the end of a DTMF detection block */ - /* Find the peak row and the peak column */ - row_energy[0] = goertzel_result(&s->row_out[0]); - best_row = 0; - col_energy[0] = goertzel_result(&s->col_out[0]); - best_col = 0; - - for (i = 1; i < 4; i++) { - row_energy[i] = goertzel_result(&s->row_out[i]); - if (row_energy[i] > row_energy[best_row]) - best_row = i; - col_energy[i] = goertzel_result(&s->col_out[i]); - if (col_energy[i] > col_energy[best_col]) - best_col = i; - } - hit = 0; - /* Basic signal level test and the twist test */ - if (row_energy[best_row] >= DTMF_THRESHOLD && col_energy[best_col] >= DTMF_THRESHOLD - && col_energy[best_col] < row_energy[best_row] * s->reverse_twist - && col_energy[best_col] * s->normal_twist > row_energy[best_row]) { - /* Relative peak test ... */ - for (i = 0; i < 4; i++) { - if ((i != best_col - && col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) - || (i != best_row - && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) { - break; - } - } - /* ... and fraction of total energy test */ - if (i >= 4 - && (row_energy[best_row] + col_energy[best_col]) > - DTMF_TO_TOTAL_ENERGY * s->energy) { - hit = dtmf_positions[(best_row << 2) + best_col]; - } - } - /* The logic in the next test should ensure the following for different successive hit patterns: - -----ABB = start of digit B. - ----B-BB = start of digit B - ----A-BB = start of digit B - BBBBBABB = still in digit B. - BBBBBB-- = end of digit B - BBBBBBC- = end of digit B - BBBBACBB = B ends, then B starts again. - BBBBBBCC = B ends, then C starts. - BBBBBCDD = B ends, then D starts. - This can work with: - - Back to back differing digits. Back-to-back digits should - not happen. The spec. says there should be a gap between digits. - However, many real phones do not impose a gap, and rolling across - the keypad can produce little or no gap. - - It tolerates nasty phones that give a very wobbly start to a digit. - - VoIP can give sample slips. The phase jumps that produces will cause - the block it is in to give no detection. This logic will ride over a - single missed block, and not falsely declare a second digit. If the - hiccup happens in the wrong place on a minimum length digit, however - we would still fail to detect that digit. Could anything be done to - deal with that? Packet loss is clearly a no-go zone. - Note this is only relevant to VoIP using A-law, u-law or similar. - Low bit rate codecs scramble DTMF too much for it to be recognised, - and often slip in units larger than a sample. */ - if (hit != s->in_digit) { - if (s->last_hit != s->in_digit) { - /* We have two successive indications that something has changed. */ - /* To declare digit on, the hits must agree. Otherwise we declare tone off. */ - hit = (hit && hit == s->last_hit) ? hit : 0; -#if 0 - if (s->realtime_callback) { - /* Avoid reporting multiple no digit conditions on flaky hits */ - if (s->in_digit || hit) { - i = (s->in_digit - && !hit) ? -99 : rint(log10f(s->energy) * 10.0f - 20.08f - 90.30F + - DBM0_MAX_POWER); - s->realtime_callback(s->realtime_callback_data, hit, i); - } - } else { -#endif - if (hit) { - if (s->current_digits < MAX_DTMF_DIGITS) { - s->digits[s->current_digits++] = (char) hit; - s->digits[s->current_digits] = '\0'; - if (s->callback) { - s->callback(s->callback_data, s->digits, s->current_digits); - s->current_digits = 0; - } - } else { - s->lost_digits++; - } - } -#if 0 - } -#endif - s->in_digit = hit; - } - } - s->last_hit = hit; - /* Reinitialise the detector for the next block */ - for (i = 0; i < 4; i++) { - goertzel_reset(&s->row_out[i]); - goertzel_reset(&s->col_out[i]); - } - s->energy = 0.0f; - s->current_sample = 0; - } - if (s->current_digits && s->callback) { - s->callback(s->callback_data, s->digits, s->current_digits); - s->digits[0] = '\0'; - s->current_digits = 0; - } - return 0; -} - -/*- End of function --------------------------------------------------------*/ - -size_t dtmf_rx_get(dtmf_rx_state_t * s, char *buf, int max) -{ - if (max > s->current_digits) - max = s->current_digits; - if (max > 0) { - memcpy(buf, s->digits, max); - memmove(s->digits, s->digits + max, s->current_digits - max); - s->current_digits -= max; - } - buf[max] = '\0'; - return max; -} - -/*- End of function --------------------------------------------------------*/ - -#if 0 -void dtmf_rx_set_realtime_callback(dtmf_rx_state_t * s, tone_report_func_t callback, - void *user_data) -{ - s->realtime_callback = callback; - s->realtime_callback_data = user_data; -} -#endif -/*- End of function --------------------------------------------------------*/ - -void dtmf_rx_parms(dtmf_rx_state_t * s, int filter_dialtone, int twist, int reverse_twist) -{ - if (filter_dialtone >= 0) { - s->z350_1 = 0.0f; - s->z350_2 = 0.0f; - s->z440_1 = 0.0f; - s->z440_2 = 0.0f; - s->filter_dialtone = filter_dialtone; - } - if (twist >= 0) - s->normal_twist = powf(10.0f, twist / 10.0f); - if (reverse_twist >= 0) - s->reverse_twist = powf(10.0f, reverse_twist / 10.0f); -} - -/*- End of function --------------------------------------------------------*/ - -dtmf_rx_state_t *dtmf_rx_init(dtmf_rx_state_t * s, dtmf_rx_callback_t callback, - void *user_data) -{ - int i; - static int initialised = 0; - - s->callback = callback; - s->callback_data = user_data; - s->realtime_callback = NULL; - s->realtime_callback_data = NULL; - s->filter_dialtone = 0; - s->normal_twist = DTMF_NORMAL_TWIST; - s->reverse_twist = DTMF_REVERSE_TWIST; - - s->in_digit = 0; - s->last_hit = 0; - - if (!initialised) { - for (i = 0; i < 4; i++) { - make_goertzel_descriptor(&dtmf_detect_row[i], dtmf_row[i], 102); - make_goertzel_descriptor(&dtmf_detect_col[i], dtmf_col[i], 102); - } - initialised = 1; - } - for (i = 0; i < 4; i++) { - goertzel_init(&s->row_out[i], &dtmf_detect_row[i]); - goertzel_init(&s->col_out[i], &dtmf_detect_col[i]); - } - s->energy = 0.0f; - s->current_sample = 0; - s->lost_digits = 0; - s->current_digits = 0; - s->digits[0] = '\0'; - return s; -} - -/*- End of function --------------------------------------------------------*/ - -#if 0 -static void dtmf_tx_initialise(void) -{ - int row; - int col; - - if (dtmf_tx_inited) - return; - for (row = 0; row < 4; row++) { - for (col = 0; col < 4; col++) { - make_tone_gen_descriptor(&dtmf_digit_tones[row * 4 + col], (int) dtmf_row[row], - DEFAULT_DTMF_TX_LEVEL, (int) dtmf_col[col], - DEFAULT_DTMF_TX_LEVEL, DEFAULT_DTMF_TX_ON_TIME, - DEFAULT_DTMF_TX_OFF_TIME, 0, 0, FALSE); - } - } - dtmf_tx_inited = TRUE; -} - -/*- End of function --------------------------------------------------------*/ - -int dtmf_tx(dtmf_tx_state_t * s, int16_t amp[], int max_samples) -{ - int len; - size_t dig; - char *cp; - - len = 0; - if (s->tones.current_section >= 0) { - /* Deal with the fragment left over from last time */ - len = tone_gen(&(s->tones), amp, max_samples); - } - dig = 0; - while (dig < s->current_digits && len < max_samples) { - /* Step to the next digit */ - if ((cp = strchr(dtmf_positions, s->digits[dig++])) == NULL) - continue; - tone_gen_init(&(s->tones), &(s->tone_descriptors[cp - dtmf_positions])); - len += tone_gen(&(s->tones), amp + len, max_samples - len); - } - if (dig) { - /* Shift out the consumed digits */ - s->current_digits -= dig; - memmove(s->digits, s->digits + dig, s->current_digits); - } - return len; -} - -/*- End of function --------------------------------------------------------*/ - -size_t dtmf_tx_put(dtmf_tx_state_t * s, const char *digits) -{ - size_t len; - - /* This returns the number of characters that would not fit in the buffer. - The buffer will only be loaded if the whole string of digits will fit, - in which case zero is returned. */ - if ((len = strlen(digits)) > 0) { - if (s->current_digits + len <= MAX_DTMF_DIGITS) { - memcpy(s->digits + s->current_digits, digits, len); - s->current_digits += len; - len = 0; - } else { - len = MAX_DTMF_DIGITS - s->current_digits; - } - } - return len; -} - -/*- End of function --------------------------------------------------------*/ - -dtmf_tx_state_t *dtmf_tx_init(dtmf_tx_state_t * s) -{ - if (!dtmf_tx_inited) - dtmf_tx_initialise(); - s->tone_descriptors = dtmf_digit_tones; - tone_gen_init(&(s->tones), &dtmf_digit_tones[0]); - s->current_sample = 0; - s->current_digits = 0; - s->tones.current_section = -1; - return s; -} -#endif //NO TX -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ - -void make_goertzel_descriptor(goertzel_descriptor_t * t, float freq, int samples) -{ - //t->fac = 2.0f*cosf(2.0f*M_PI*(freq/(float) SAMPLE_RATE)); - t->fac = 2.0f * cosf(2.0f * M_PI * (freq / (float) 8000)); - t->samples = samples; -} - -/*- End of function --------------------------------------------------------*/ - -goertzel_state_t *goertzel_init(goertzel_state_t * s, goertzel_descriptor_t * t) -{ - if (s || (s = malloc(sizeof(goertzel_state_t)))) { - s->v2 = s->v3 = 0.0; - s->fac = t->fac; - s->samples = t->samples; - s->current_sample = 0; - } - return s; -} - -/*- End of function --------------------------------------------------------*/ - -void goertzel_reset(goertzel_state_t * s) -{ - s->v2 = s->v3 = 0.0; - s->current_sample = 0; -} - -/*- End of function --------------------------------------------------------*/ - -int goertzel_update(goertzel_state_t * s, const int16_t amp[], int samples) -{ - int i; - float v1; - - if (samples > s->samples - s->current_sample) - samples = s->samples - s->current_sample; - for (i = 0; i < samples; i++) { - v1 = s->v2; - s->v2 = s->v3; - s->v3 = s->fac * s->v2 - v1 + amp[i]; - } - s->current_sample += samples; - return samples; -} - -/*- End of function --------------------------------------------------------*/ - -float goertzel_result(goertzel_state_t * s) -{ - float v1; - - /* Push a zero through the process to finish things off. */ - v1 = s->v2; - s->v2 = s->v3; - s->v3 = s->fac * s->v2 - v1; - /* Now calculate the non-recursive side of the filter. */ - /* The result here is not scaled down to allow for the magnification - effect of the filter (the usual DFT magnification effect). */ - return s->v3 * s->v3 + s->v2 * s->v2 - s->v2 * s->v3 * s->fac; -} - -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.h b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.h deleted file mode 100644 index 2fed42d089..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.h +++ /dev/null @@ -1,1028 +0,0 @@ - -/* - * SpanDSP - a series of DSP components for telephony - * - * bit_operations.h - Various bit level operations, such as bit reversal - * - * Written by Steve Underwood - * - * Copyright (C) 2006 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: bit_operations.h,v 1.15 2007/02/23 13:16:13 steveu Exp $ - */ - -/*! \file */ - -#ifndef _CELLIAX_SPANDSP_H -#define _CELLIAX_SPANDSP_H - -#include - -/*! \brief Find the bit position of the highest set bit in a word - \param bits The word to be searched - \return The bit number of the highest set bit, or -1 if the word is zero. */ -static __inline__ int top_bit(unsigned int bits) -{ - int res; - -#if defined(__i386__) || defined(__x86_64__) -__asm__(" xorl %[res],%[res];\n" " decl %[res];\n" " bsrl %[bits],%[res]\n":[res] "=&r" - (res) -: [bits] "rm"(bits)); - return res; -#elif defined(__ppc__) || defined(__powerpc__) -__asm__("cntlzw %[res],%[bits];\n":[res] "=&r"(res) -: [bits] "r"(bits)); - return 31 - res; -#else - if (bits == 0) - return -1; - res = 0; - if (bits & 0xFFFF0000) { - bits &= 0xFFFF0000; - res += 16; - } - if (bits & 0xFF00FF00) { - bits &= 0xFF00FF00; - res += 8; - } - if (bits & 0xF0F0F0F0) { - bits &= 0xF0F0F0F0; - res += 4; - } - if (bits & 0xCCCCCCCC) { - bits &= 0xCCCCCCCC; - res += 2; - } - if (bits & 0xAAAAAAAA) { - bits &= 0xAAAAAAAA; - res += 1; - } - return res; -#endif -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Find the bit position of the lowest set bit in a word - \param bits The word to be searched - \return The bit number of the lowest set bit, or -1 if the word is zero. */ -static __inline__ int bottom_bit(unsigned int bits) -{ - int res; - -#if defined(__i386__) || defined(__x86_64__) -__asm__(" xorl %[res],%[res];\n" " decl %[res];\n" " bsfl %[bits],%[res]\n":[res] "=&r" - (res) -: [bits] "rm"(bits)); - return res; -#else - if (bits == 0) - return -1; - res = 31; - if (bits & 0x0000FFFF) { - bits &= 0x0000FFFF; - res -= 16; - } - if (bits & 0x00FF00FF) { - bits &= 0x00FF00FF; - res -= 8; - } - if (bits & 0x0F0F0F0F) { - bits &= 0x0F0F0F0F; - res -= 4; - } - if (bits & 0x33333333) { - bits &= 0x33333333; - res -= 2; - } - if (bits & 0x55555555) { - bits &= 0x55555555; - res -= 1; - } - return res; -#endif -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Bit reverse a byte. - \param data The byte to be reversed. - \return The bit reversed version of data. */ -static __inline__ uint8_t bit_reverse8(uint8_t x) -{ -#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__powerpc__) - /* If multiply is fast */ - return ((x * 0x0802U & 0x22110U) | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16; -#else - /* If multiply is slow, but we have a barrel shifter */ - x = (x >> 4) | (x << 4); - x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2); - return ((x & 0xAA) >> 1) | ((x & 0x55) << 1); -#endif -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Bit reverse a 16 bit word. - \param data The word to be reversed. - \return The bit reversed version of data. */ -uint16_t bit_reverse16(uint16_t data); - -/*! \brief Bit reverse a 32 bit word. - \param data The word to be reversed. - \return The bit reversed version of data. */ -uint32_t bit_reverse32(uint32_t data); - -/*! \brief Bit reverse each of the four bytes in a 32 bit word. - \param data The word to be reversed. - \return The bit reversed version of data. */ -uint32_t bit_reverse_4bytes(uint32_t data); - -#if defined(__x86_64__) -/*! \brief Bit reverse each of the eight bytes in a 64 bit word. - \param data The word to be reversed. - \return The bit reversed version of data. */ -uint64_t bit_reverse_8bytes(uint64_t data); -#endif - -/*! \brief Bit reverse each bytes in a buffer. - \param to The buffer to place the reversed data in. - \param from The buffer containing the data to be reversed. - \param The length of the data in the buffer. */ -void bit_reverse(uint8_t to[], const uint8_t from[], int len); - -/*! \brief Find the number of set bits in a 32 bit word. - \param x The word to be searched. - \return The number of set bits. */ -int one_bits32(uint32_t x); - -/*! \brief Create a mask as wide as the number in a 32 bit word. - \param x The word to be searched. - \return The mask. */ -uint32_t make_mask32(uint32_t x); - -/*! \brief Create a mask as wide as the number in a 16 bit word. - \param x The word to be searched. - \return The mask. */ -uint16_t make_mask16(uint16_t x); - -/*! \brief Find the least significant one in a word, and return a word - with just that bit set. - \param x The word to be searched. - \return The word with the single set bit. */ -static __inline__ uint32_t least_significant_one32(uint32_t x) -{ - return (x & (-(int32_t) x)); -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Find the most significant one in a word, and return a word - with just that bit set. - \param x The word to be searched. - \return The word with the single set bit. */ -static __inline__ uint32_t most_significant_one32(uint32_t x) -{ -#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__powerpc__) - return 1 << top_bit(x); -#else - x = make_mask32(x); - return (x ^ (x >> 1)); -#endif -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Find the parity of a byte. - \param x The byte to be checked. - \return 1 for odd, or 0 for even. */ -static __inline__ int parity8(uint8_t x) -{ - x = (x ^ (x >> 4)) & 0x0F; - return (0x6996 >> x) & 1; -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Find the parity of a 16 bit word. - \param x The word to be checked. - \return 1 for odd, or 0 for even. */ -static __inline__ int parity16(uint16_t x) -{ - x ^= (x >> 8); - x = (x ^ (x >> 4)) & 0x0F; - return (0x6996 >> x) & 1; -} - -/*- End of function --------------------------------------------------------*/ - -/*! \brief Find the parity of a 32 bit word. - \param x The word to be checked. - \return 1 for odd, or 0 for even. */ -static __inline__ int parity32(uint32_t x) -{ - x ^= (x >> 16); - x ^= (x >> 8); - x = (x ^ (x >> 4)) & 0x0F; - return (0x6996 >> x) & 1; -} - -/*- End of function --------------------------------------------------------*/ - -/*- End of file ------------------------------------------------------------*/ -/* - * SpanDSP - a series of DSP components for telephony - * - * fir.h - General telephony FIR routines - * - * Written by Steve Underwood - * - * Copyright (C) 2002 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: fir.h,v 1.8 2006/10/24 13:45:28 steveu Exp $ - */ - -/*! \page fir_page FIR filtering -\section fir_page_sec_1 What does it do? -???. - -\section fir_page_sec_2 How does it work? -???. -*/ - -#if 0 -#if defined(USE_MMX) || defined(USE_SSE2) -#include "mmx.h" -#endif - -/*! - 16 bit integer FIR descriptor. This defines the working state for a single - instance of an FIR filter using 16 bit integer coefficients. -*/ -typedef struct { - int taps; - int curr_pos; - const int16_t *coeffs; - int16_t *history; -} fir16_state_t; - -/*! - 32 bit integer FIR descriptor. This defines the working state for a single - instance of an FIR filter using 32 bit integer coefficients, and filtering - 16 bit integer data. -*/ -typedef struct { - int taps; - int curr_pos; - const int32_t *coeffs; - int16_t *history; -} fir32_state_t; - -/*! - Floating point FIR descriptor. This defines the working state for a single - instance of an FIR filter using floating point coefficients and data. -*/ -typedef struct { - int taps; - int curr_pos; - const float *coeffs; - float *history; -} fir_float_state_t; - -static __inline__ const int16_t *fir16_create(fir16_state_t * fir, const int16_t * coeffs, - int taps) -{ - fir->taps = taps; - fir->curr_pos = taps - 1; - fir->coeffs = coeffs; -#if defined(USE_MMX) || defined(USE_SSE2) - if ((fir->history = malloc(2 * taps * sizeof(int16_t)))) - memset(fir->history, 0, 2 * taps * sizeof(int16_t)); -#else - if ((fir->history = (int16_t *) malloc(taps * sizeof(int16_t)))) - memset(fir->history, 0, taps * sizeof(int16_t)); -#endif - return fir->history; -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ void fir16_flush(fir16_state_t * fir) -{ -#if defined(USE_MMX) || defined(USE_SSE2) - memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t)); -#else - memset(fir->history, 0, fir->taps * sizeof(int16_t)); -#endif -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ void fir16_free(fir16_state_t * fir) -{ - free(fir->history); -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ int16_t fir16(fir16_state_t * fir, int16_t sample) -{ - int i; - int32_t y; -#if defined(USE_MMX) - mmx_t *mmx_coeffs; - mmx_t *mmx_hist; - - fir->history[fir->curr_pos] = sample; - fir->history[fir->curr_pos + fir->taps] = sample; - - mmx_coeffs = (mmx_t *) fir->coeffs; - mmx_hist = (mmx_t *) & fir->history[fir->curr_pos]; - i = fir->taps; - pxor_r2r(mm4, mm4); - /* 8 samples per iteration, so the filter must be a multiple of 8 long. */ - while (i > 0) { - movq_m2r(mmx_coeffs[0], mm0); - movq_m2r(mmx_coeffs[1], mm2); - movq_m2r(mmx_hist[0], mm1); - movq_m2r(mmx_hist[1], mm3); - mmx_coeffs += 2; - mmx_hist += 2; - pmaddwd_r2r(mm1, mm0); - pmaddwd_r2r(mm3, mm2); - paddd_r2r(mm0, mm4); - paddd_r2r(mm2, mm4); - i -= 8; - } - movq_r2r(mm4, mm0); - psrlq_i2r(32, mm0); - paddd_r2r(mm0, mm4); - movd_r2m(mm4, y); - emms(); -#elif defined(USE_SSE2) - xmm_t *xmm_coeffs; - xmm_t *xmm_hist; - - fir->history[fir->curr_pos] = sample; - fir->history[fir->curr_pos + fir->taps] = sample; - - xmm_coeffs = (xmm_t *) fir->coeffs; - xmm_hist = (xmm_t *) & fir->history[fir->curr_pos]; - i = fir->taps; - pxor_r2r(xmm4, xmm4); - /* 16 samples per iteration, so the filter must be a multiple of 16 long. */ - while (i > 0) { - movdqu_m2r(xmm_coeffs[0], xmm0); - movdqu_m2r(xmm_coeffs[1], xmm2); - movdqu_m2r(xmm_hist[0], xmm1); - movdqu_m2r(xmm_hist[1], xmm3); - xmm_coeffs += 2; - xmm_hist += 2; - pmaddwd_r2r(xmm1, xmm0); - pmaddwd_r2r(xmm3, xmm2); - paddd_r2r(xmm0, xmm4); - paddd_r2r(xmm2, xmm4); - i -= 16; - } - movdqa_r2r(xmm4, xmm0); - psrldq_i2r(8, xmm0); - paddd_r2r(xmm0, xmm4); - movdqa_r2r(xmm4, xmm0); - psrldq_i2r(4, xmm0); - paddd_r2r(xmm0, xmm4); - movd_r2m(xmm4, y); -#else - int offset1; - int offset2; - - fir->history[fir->curr_pos] = sample; - - offset2 = fir->curr_pos; - offset1 = fir->taps - offset2; - y = 0; - for (i = fir->taps - 1; i >= offset1; i--) - y += fir->coeffs[i] * fir->history[i - offset1]; - for (; i >= 0; i--) - y += fir->coeffs[i] * fir->history[i + offset2]; -#endif - if (fir->curr_pos <= 0) - fir->curr_pos = fir->taps; - fir->curr_pos--; - return (int16_t) (y >> 15); -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ const int16_t *fir32_create(fir32_state_t * fir, const int32_t * coeffs, - int taps) -{ - fir->taps = taps; - fir->curr_pos = taps - 1; - fir->coeffs = coeffs; - fir->history = (int16_t *) malloc(taps * sizeof(int16_t)); - if (fir->history) - memset(fir->history, '\0', taps * sizeof(int16_t)); - return fir->history; -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ void fir32_flush(fir32_state_t * fir) -{ - memset(fir->history, 0, fir->taps * sizeof(int16_t)); -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ void fir32_free(fir32_state_t * fir) -{ - free(fir->history); -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ int16_t fir32(fir32_state_t * fir, int16_t sample) -{ - int i; - int32_t y; - int offset1; - int offset2; - - fir->history[fir->curr_pos] = sample; - offset2 = fir->curr_pos; - offset1 = fir->taps - offset2; - y = 0; - for (i = fir->taps - 1; i >= offset1; i--) - y += fir->coeffs[i] * fir->history[i - offset1]; - for (; i >= 0; i--) - y += fir->coeffs[i] * fir->history[i + offset2]; - if (fir->curr_pos <= 0) - fir->curr_pos = fir->taps; - fir->curr_pos--; - return (int16_t) (y >> 15); -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ const float *fir_float_create(fir_float_state_t * fir, - const float *coeffs, int taps) -{ - fir->taps = taps; - fir->curr_pos = taps - 1; - fir->coeffs = coeffs; - fir->history = (float *) malloc(taps * sizeof(float)); - if (fir->history) - memset(fir->history, '\0', taps * sizeof(float)); - return fir->history; -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ void fir_float_free(fir_float_state_t * fir) -{ - free(fir->history); -} - -/*- End of function --------------------------------------------------------*/ - -static __inline__ int16_t fir_float(fir_float_state_t * fir, int16_t sample) -{ - int i; - float y; - int offset1; - int offset2; - - fir->history[fir->curr_pos] = sample; - - offset2 = fir->curr_pos; - offset1 = fir->taps - offset2; - y = 0; - for (i = fir->taps - 1; i >= offset1; i--) - y += fir->coeffs[i] * fir->history[i - offset1]; - for (; i >= 0; i--) - y += fir->coeffs[i] * fir->history[i + offset2]; - if (fir->curr_pos <= 0) - fir->curr_pos = fir->taps; - fir->curr_pos--; - return (int16_t) y; -} - -/*- End of function --------------------------------------------------------*/ -#endif - -/*- End of file ------------------------------------------------------------*/ - -/* - * SpanDSP - a series of DSP components for telephony - * - * echo.h - An echo cancellor, suitable for electrical and acoustic - * cancellation. This code does not currently comply with - * any relevant standards (e.g. G.164/5/7/8). - * - * Written by Steve Underwood - * - * Copyright (C) 2001 Steve Underwood - * - * Based on a bit from here, a bit from there, eye of toad, - * ear of bat, etc - plus, of course, my own 2 cents. - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: echo.h,v 1.9 2006/10/24 13:45:28 steveu Exp $ - */ - -/*! \file */ - -/*! \page echo_can_page Line echo cancellation for voice - -\section echo_can_page_sec_1 What does it do? -This module aims to provide G.168-2002 compliant echo cancellation, to remove -electrical echoes (e.g. from 2-4 wire hybrids) from voice calls. - -\section echo_can_page_sec_2 How does it work? -The heart of the echo cancellor is FIR filter. This is adapted to match the echo -impulse response of the telephone line. It must be long enough to adequately cover -the duration of that impulse response. The signal transmitted to the telephone line -is passed through the FIR filter. Once the FIR is properly adapted, the resulting -output is an estimate of the echo signal received from the line. This is subtracted -from the received signal. The result is an estimate of the signal which originated -at the far end of the line, free from echos of our own transmitted signal. - -The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and was -introduced in 1960. It is the commonest form of filter adaption used in things -like modem line equalisers and line echo cancellers. There it works very well. -However, it only works well for signals of constant amplitude. It works very poorly -for things like speech echo cancellation, where the signal level varies widely. -This is quite easy to fix. If the signal level is normalised - similar to applying -AGC - LMS can work as well for a signal of varying amplitude as it does for a modem -signal. This normalised least mean squares (NLMS) algorithm is the commonest one used -for speech echo cancellation. Many other algorithms exist - e.g. RLS (essentially -the same as Kalman filtering), FAP, etc. Some perform significantly better than NLMS. -However, factors such as computational complexity and patents favour the use of NLMS. - -A simple refinement to NLMS can improve its performance with speech. NLMS tends -to adapt best to the strongest parts of a signal. If the signal is white noise, -the NLMS algorithm works very well. However, speech has more low frequency than -high frequency content. Pre-whitening (i.e. filtering the signal to flatten -its spectrum) the echo signal improves the adapt rate for speech, and ensures the -final residual signal is not heavily biased towards high frequencies. A very low -complexity filter is adequate for this, so pre-whitening adds little to the -compute requirements of the echo canceller. - -An FIR filter adapted using pre-whitened NLMS performs well, provided certain -conditions are met: - - - The transmitted signal has poor self-correlation. - - There is no signal being generated within the environment being cancelled. - -The difficulty is that neither of these can be guaranteed. - -If the adaption is performed while transmitting noise (or something fairly noise -like, such as voice) the adaption works very well. If the adaption is performed -while transmitting something highly correlative (typically narrow band energy -such as signalling tones or DTMF), the adaption can go seriously wrong. The reason -is there is only one solution for the adaption on a near random signal - the impulse -response of the line. For a repetitive signal, there are any number of solutions -which converge the adaption, and nothing guides the adaption to choose the generalised -one. Allowing an untrained canceller to converge on this kind of narrowband -energy probably a good thing, since at least it cancels the tones. Allowing a well -converged canceller to continue converging on such energy is just a way to ruin -its generalised adaption. A narrowband detector is needed, so adapation can be -suspended at appropriate times. - -The adaption process is based on trying to eliminate the received signal. When -there is any signal from within the environment being cancelled it may upset the -adaption process. Similarly, if the signal we are transmitting is small, noise -may dominate and disturb the adaption process. If we can ensure that the -adaption is only performed when we are transmitting a significant signal level, -and the environment is not, things will be OK. Clearly, it is easy to tell when -we are sending a significant signal. Telling, if the environment is generating a -significant signal, and doing it with sufficient speed that the adaption will -not have diverged too much more we stop it, is a little harder. - -The key problem in detecting when the environment is sourcing significant energy -is that we must do this very quickly. Given a reasonably long sample of the -received signal, there are a number of strategies which may be used to assess -whether that signal contains a strong far end component. However, by the time -that assessment is complete the far end signal will have already caused major -mis-convergence in the adaption process. An assessment algorithm is needed which -produces a fairly accurate result from a very short burst of far end energy. - -\section echo_can_page_sec_3 How do I use it? -The echo cancellor processes both the transmit and receive streams sample by -sample. The processing function is not declared inline. Unfortunately, -cancellation requires many operations per sample, so the call overhead is only a -minor burden. -*/ - -#define NONUPDATE_DWELL_TIME 600 /* 600 samples, or 75ms */ - -#if 0 -/* Mask bits for the adaption mode */ -#define ECHO_CAN_USE_NLP 0x01 -#define ECHO_CAN_USE_SUPPRESSOR 0x02 -#define ECHO_CAN_USE_CNG 0x04 -#define ECHO_CAN_USE_ADAPTION 0x08 - -/*! - G.168 echo canceller descriptor. This defines the working state for a line - echo canceller. -*/ -typedef struct { - int tx_power[4]; - int rx_power[3]; - int clean_rx_power; - - int rx_power_threshold; - int nonupdate_dwell; - - fir16_state_t fir_state; - /*! Echo FIR taps (16 bit version) */ - int16_t *fir_taps16[4]; - /*! Echo FIR taps (32 bit version) */ - int32_t *fir_taps32; - - int curr_pos; - - int taps; - int tap_mask; - int adaption_mode; - - int32_t supp_test1; - int32_t supp_test2; - int32_t supp1; - int32_t supp2; - int vad; - int cng; - /* Parameters for the Hoth noise generator */ - int cng_level; - int cng_rndnum; - int cng_filter; - - int16_t geigel_max; - int geigel_lag; - int dtd_onset; - int tap_set; - int tap_rotate_counter; - - int32_t latest_correction; /* Indication of the magnitude of the latest - adaption, or a code to indicate why adaption - was skipped, for test purposes */ - int32_t last_acf[28]; - int narrowband_count; - int narrowband_score; -} echo_can_state_t; - -/*! Create a voice echo canceller context. - \param len The length of the canceller, in samples. - \return The new canceller context, or NULL if the canceller could not be created. -*/ -echo_can_state_t *echo_can_create(int len, int adaption_mode); - -/*! Free a voice echo canceller context. - \param ec The echo canceller context. -*/ -void echo_can_free(echo_can_state_t * ec); - -/*! Flush (reinitialise) a voice echo canceller context. - \param ec The echo canceller context. -*/ -void echo_can_flush(echo_can_state_t * ec); - -/*! Set the adaption mode of a voice echo canceller context. - \param ec The echo canceller context. - \param adapt The mode. -*/ -void echo_can_adaption_mode(echo_can_state_t * ec, int adaption_mode); - -/*! Process a sample through a voice echo canceller. - \param ec The echo canceller context. - \param tx The transmitted audio sample. - \param rx The received audio sample. - \return The clean (echo cancelled) received sample. -*/ -int16_t echo_can_update(echo_can_state_t * ec, int16_t tx, int16_t rx); - -#endif -/*- End of file ------------------------------------------------------------*/ - -/*! - Floating point Goertzel filter descriptor. -*/ -typedef struct { - float fac; - int samples; -} goertzel_descriptor_t; - -/*! - Floating point Goertzel filter state descriptor. -*/ -typedef struct { - float v2; - float v3; - float fac; - int samples; - int current_sample; -} goertzel_state_t; - -/*! \brief Create a descriptor for use with either a Goertzel transform */ -void make_goertzel_descriptor(goertzel_descriptor_t * t, float freq, int samples); - -/*! \brief Initialise the state of a Goertzel transform. - \param s The Goertzel context. If NULL, a context is allocated with malloc. - \param t The Goertzel descriptor. - \return A pointer to the Goertzel state. */ -goertzel_state_t *goertzel_init(goertzel_state_t * s, goertzel_descriptor_t * t); - -/*! \brief Reset the state of a Goertzel transform. - \param s The Goertzel context. - \param t The Goertzel descriptor. - \return A pointer to the Goertzel state. */ -void goertzel_reset(goertzel_state_t * s); - -/*! \brief Update the state of a Goertzel transform. - \param s The Goertzel context - \param amp The samples to be transformed - \param samples The number of samples - \return The number of samples unprocessed */ -int goertzel_update(goertzel_state_t * s, const int16_t amp[], int samples); - -/*! \brief Evaluate the final result of a Goertzel transform. - \param s The Goertzel context - \return The result of the transform. */ -float goertzel_result(goertzel_state_t * s); - -/*! \brief Update the state of a Goertzel transform. - \param s The Goertzel context - \param amp The sample to be transformed. */ -static __inline__ void goertzel_sample(goertzel_state_t * s, int16_t amp) -{ - float v1; - - v1 = s->v2; - s->v2 = s->v3; - s->v3 = s->fac * s->v2 - v1 + amp; - s->current_sample++; -} - -/*- End of function --------------------------------------------------------*/ - -/* - * SpanDSP - a series of DSP components for telephony - * - * tone_detect.c - General telephony tone detection. - * - * Written by Steve Underwood - * - * Copyright (C) 2001-2003, 2005 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: tone_detect.c,v 1.31 2007/03/03 10:40:33 steveu Exp $ - */ - -/*! \file tone_detect.h */ - -#if !defined(M_PI) -/* C99 systems may not define M_PI */ -#define M_PI 3.14159265358979323846264338327 -#endif -/*! \page dtmf_rx_page DTMF receiver -\section dtmf_rx_page_sec_1 What does it do? -The DTMF receiver detects the standard DTMF digits. It is compliant with -ITU-T Q.23, ITU-T Q.24, and the local DTMF specifications of most administrations. -Its passes the test suites. It also scores *very* well on the standard -talk-off tests. - -The current design uses floating point extensively. It is not tolerant of DC. -It is expected that a DC restore stage will be placed before the DTMF detector. -Unless the dial tone filter is switched on, the detector has poor tolerance -of dial tone. Whether this matter depends on your application. If you are using -the detector in an IVR application you will need proper echo cancellation to -get good performance in the presence of speech prompts, so dial tone will not -exist. If you do need good dial tone tolerance, a dial tone filter can be -enabled in the detector. - -\section dtmf_rx_page_sec_2 How does it work? -Like most other DSP based DTMF detector's, this one uses the Goertzel algorithm -to look for the DTMF tones. What makes each detector design different is just how -that algorithm is used. - -Basic DTMF specs: - - Minimum tone on = 40ms - - Minimum tone off = 50ms - - Maximum digit rate = 10 per second - - Normal twist <= 8dB accepted - - Reverse twist <= 4dB accepted - - S/N >= 15dB will detect OK - - Attenuation <= 26dB will detect OK - - Frequency tolerance +- 1.5% will detect, +-3.5% will reject - -TODO: -*/ - -/*! \page dtmf_tx_page DTMF tone generation -\section dtmf_tx_page_sec_1 What does it do? - -The DTMF tone generation module provides for the generation of the -repertoire of 16 DTMF dual tones. - -\section dtmf_tx_page_sec_2 How does it work? -*/ - -#define MAX_DTMF_DIGITS 128 - -typedef void (*dtmf_rx_callback_t) (void *user_data, const char *digits, int len); - -/*! - DTMF generator state descriptor. This defines the state of a single - working instance of a DTMF generator. -*/ -#if 0 -typedef struct { - tone_gen_descriptor_t *tone_descriptors; - tone_gen_state_t tones; - char digits[MAX_DTMF_DIGITS + 1]; - int current_sample; - size_t current_digits; -} dtmf_tx_state_t; - -#endif - -/*! - DTMF digit detector descriptor. -*/ -typedef struct { - /*! Optional callback funcion to deliver received digits. */ - dtmf_rx_callback_t callback; - /*! An opaque pointer passed to the callback function. */ - void *callback_data; - /*! Optional callback funcion to deliver real time digit state changes. */ - //tone_report_func_t realtime_callback; - void *realtime_callback; - /*! An opaque pointer passed to the real time callback function. */ - void *realtime_callback_data; - /*! TRUE if dialtone should be filtered before processing */ - int filter_dialtone; - /*! Maximum acceptable "normal" (lower bigger than higher) twist ratio */ - float normal_twist; - /*! Maximum acceptable "reverse" (higher bigger than lower) twist ratio */ - float reverse_twist; - - /*! 350Hz filter state for the optional dialtone filter */ - float z350_1; - float z350_2; - /*! 440Hz filter state for the optional dialtone filter */ - float z440_1; - float z440_2; - - /*! Tone detector working states */ - goertzel_state_t row_out[4]; - goertzel_state_t col_out[4]; - /*! The accumlating total energy on the same period over which the Goertzels work. */ - float energy; - /*! The result of the last tone analysis. */ - uint8_t last_hit; - /*! The confirmed digit we are currently receiving */ - uint8_t in_digit; - /*! The current sample number within a processing block. */ - int current_sample; - - /*! The received digits buffer. This is a NULL terminated string. */ - char digits[MAX_DTMF_DIGITS + 1]; - /*! The number of digits currently in the digit buffer. */ - int current_digits; - /*! The number of digits which have been lost due to buffer overflows. */ - int lost_digits; -} dtmf_rx_state_t; - -#if 0 -/*! \brief Generate a buffer of DTMF tones. - \param s The DTMF generator context. - \param amp The buffer for the generated signal. - \param max_samples The required number of generated samples. - \return The number of samples actually generated. This may be less than - samples if the input buffer empties. */ -int dtmf_tx(dtmf_tx_state_t * s, int16_t amp[], int max_samples); - -/*! \brief Put a string of digits in a DTMF generator's input buffer. - \param s The DTMF generator context. - \param digits The string of digits to be added. - \return The number of digits actually added. This may be less than the - length of the digit string, if the buffer fills up. */ -size_t dtmf_tx_put(dtmf_tx_state_t * s, const char *digits); - -/*! \brief Initialise a DTMF tone generator context. - \param s The DTMF generator context. - \return A pointer to the DTMF generator context. */ -dtmf_tx_state_t *dtmf_tx_init(dtmf_tx_state_t * s); -#endif - -/*! Set a optional realtime callback for a DTMF receiver context. This function - is called immediately a confirmed state change occurs in the received DTMF. It - is called with the ASCII value for a DTMF tone pair, or zero to indicate no tone - is being received. - \brief Set a realtime callback for a DTMF receiver context. - \param s The DTMF receiver context. - \param callback Callback routine used to report the start and end of digits. - \param user_data An opaque pointer which is associated with the context, - and supplied in callbacks. */ -void dtmf_rx_set_realtime_callback(dtmf_rx_state_t * s, - //tone_report_func_t callback, - void *callback, void *user_data); - -/*! \brief Adjust a DTMF receiver context. - \param s The DTMF receiver context. - \param filter_dialtone TRUE to enable filtering of dialtone, FALSE - to disable, < 0 to leave unchanged. - \param twist Acceptable twist, in dB. < 0 to leave unchanged. - \param reverse_twist Acceptable reverse twist, in dB. < 0 to leave unchanged. */ -void dtmf_rx_parms(dtmf_rx_state_t * s, int filter_dialtone, int twist, - int reverse_twist); - -/*! Process a block of received DTMF audio samples. - \brief Process a block of received DTMF audio samples. - \param s The DTMF receiver context. - \param amp The audio sample buffer. - \param samples The number of samples in the buffer. - \return The number of samples unprocessed. */ -int dtmf_rx(dtmf_rx_state_t * s, const int16_t amp[], int samples); - -/*! \brief Get a string of digits from a DTMF receiver's output buffer. - \param s The DTMF receiver context. - \param digits The buffer for the received digits. - \param max The maximum number of digits to be returned, - \return The number of digits actually returned. */ -size_t dtmf_rx_get(dtmf_rx_state_t * s, char *digits, int max); - -/*! \brief Initialise a DTMF receiver context. - \param s The DTMF receiver context. - \param callback An optional callback routine, used to report received digits. If - no callback routine is set, digits may be collected, using the dtmf_rx_get() - function. - \param user_data An opaque pointer which is associated with the context, - and supplied in callbacks. - \return A pointer to the DTMF receiver context. */ -dtmf_rx_state_t *dtmf_rx_init(dtmf_rx_state_t * s, dtmf_rx_callback_t callback, - void *user_data); - -/*- End of file ------------------------------------------------------------*/ - -#endif /* _CELLIAX_SPANDSP_H */ diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/chan_celliax.c b/src/mod/endpoints/mod_gsmopen/asterisk/chan_celliax.c deleted file mode 100644 index 32c6fef4b8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/chan_celliax.c +++ /dev/null @@ -1,3094 +0,0 @@ -//indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90 -#include "celliax.h" - -/* GLOBAL VARIABLES */ -char celliax_console_active_array[50] = ""; -char *celliax_console_active = celliax_console_active_array; -/*! \brief Count of active channels for this module */ -int celliax_usecnt = 0; -int celliax_debug = 0; -/*! \brief This is the thread for the monitor which checks for input on the channels - * which are not currently in use. */ -pthread_t celliax_monitor_thread = AST_PTHREADT_NULL; -pthread_t celliax_monitor_audio_thread = AST_PTHREADT_NULL; -int celliax_dir_entry_extension = 0; - -/* CONSTANTS */ -/*! \brief Name of configuration file for this module */ -const char celliax_config[] = "celliax.conf"; - -/*! \brief Textual description for this module */ -const char celliax_desc[] = "Celliax, Audio-Serial Driver"; -/*! \brief Textual type for this module */ -const char celliax_type[] = "Celliax"; - -/*! \brief Definition of this channel for PBX channel registration */ -const struct ast_channel_tech celliax_tech = { - .type = celliax_type, - .description = celliax_desc, - .capabilities = AST_FORMAT_SLINEAR, - .requester = celliax_request, - .hangup = celliax_hangup, - .answer = celliax_answer, - .read = celliax_read, - .call = celliax_call, - .write = celliax_write, - .indicate = celliax_indicate, - .fixup = celliax_fixup, - .devicestate = celliax_devicestate, -#ifdef ASTERISK_VERSION_1_4 - .send_digit_begin = celliax_senddigit_begin, - .send_digit_end = celliax_senddigit_end, -#else /* ASTERISK_VERSION_1_4 */ - .send_digit = celliax_senddigit, -#endif /* ASTERISK_VERSION_1_4 */ -}; - -#ifdef ASTERISK_VERSION_1_4 -#include "asterisk/abstract_jb.h" -/*! Global jitterbuffer configuration - by default, jb is disabled */ -static struct ast_jb_conf default_jbconf = { - .flags = 0, - .max_size = -1, - .resync_threshold = -1, - .impl = "" -}; -static struct ast_jb_conf global_jbconf; -#endif /* ASTERISK_VERSION_1_4 */ - - -#ifdef CELLIAX_ALSA -char celliax_console_alsa_period_usage[] = - "Usage: celliax_alsa_period [alsa_period_size, in bytes] [alsa_periods_in_buffer, how many]\n" - " Shows or set the values of the period and the buffer used by the ALSA subsistem. Standard values are 160 for alsa_period_size and 4 for alsa_periods_in_buffer. Without specifying a value, it just shows the current values. The values are for the \"current\" console (Celliax) channel.\n" - " Enter 'help console' on how to change the \"current\" console\n"; -#endif /* CELLIAX_ALSA */ - -char mandescr_celliax_sendsms[] = - "Description: Send an SMS through the designated Celliax interface.\n" "Variables: \n" - " Interface: The Celliax interface name you want to use.\n" - " Number: The recipient number you want to send the SMS to.\n" - " Text: The text of the SMS to be sent.\n" - " ActionID: The Action ID for this AMI transaction.\n"; - -char celliax_console_celliax_usage[] = - " \n" "chan_celliax commands info\n" " \n" - " chan_celliax adds to Asterisk the following CLI commands and DIALPLAN applications:\n" - " \n" " CLI COMMANDS:\n" " celliax_hangup\n" - " celliax_dial\n" " celliax_console\n" -#ifdef CELLIAX_DIR - " celliax_dir_import\n" " celliax_dir_export\n" -#endif /* CELLIAX_DIR */ - " celliax_playback_boost\n" " celliax_capture_boost\n" - " celliax_sendsms\n" " celliax_echo\n" " celliax_at\n" - " \n" " DIALPLAN APPLICATIONS:\n" " CelliaxSendsms\n" " \n" - " You can type 'help [command]' or 'show application [application]' to obtain more specific info on usage.\n" - " \n"; -char celliax_console_hangup_usage[] = - "Usage: celliax_hangup\n" - " Hangs up any call currently placed on the \"current\" celliax_console (Celliax) channel.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; -char celliax_console_playback_boost_usage[] = - "Usage: celliax_playback_boost [value]\n" - " Shows or set the value of boost applied to the outgoing sound (voice). Possible values are: 0 (no boost applied), -40 to 40 (negative to positive range, in db). Without specifying a value, it just shows the current value. The value is for the \"current\" celliax_console (Celliax) channel.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; -char celliax_console_capture_boost_usage[] = - "Usage: celliax_capture_boost [value]\n" - " Shows or set the value of boost applied to the incoming sound (voice). Possible values are: 0 (no boost applied), -40 to 40 (negative to positive range, in db). Without specifying a value, it just shows the current value. The value is for the \"current\" celliax_console (Celliax) channel.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; - -#ifdef CELLIAX_DIR -char celliax_console_celliax_dir_import_usage[] = - "Usage: celliax_dir_import [add | replace] fromcell\n" - " Write in the celliax_dir.conf config file all the entries found in the phonebook of the cellphone connected on the \"current\" celliax_console (Celliax) channel or in the 'Contacts' list of the Skype client.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; -char celliax_console_celliax_dir_export_usage[] = -#ifdef CELLIAX_LIBCSV - "Usage: celliax_dir_export tocell|tocsv celliax_cellphonenumber [csv_filename]\n" -#else /* CELLIAX_LIBCSV */ - "Usage: celliax_dir_export tocell celliax_cellphonenumber\n" -#endif /* CELLIAX_LIBCSV */ - " With 'tocell' modifier, write in the cellphone connected on the \"current\" celliax_console (Celliax) all the entries found in directoriax.conf, in the form: [celliax_cellphonenumber]wait_for_answer celliax_dir_prefix celliax_dir_entry. So, you can choose the new entry from the cellphone phonebook, dial it, and be directly connected to celliax_dir extension chosen, without having to pass through the voice menu.\n" -#ifdef CELLIAX_LIBCSV - " With 'tocsv' modifier, write in a file (Comma Separated Values, suitable to be imported by various software (eg Outlook) and smartphones) all the entries found in directoriax.conf, in the form: [celliax_cellphonenumber]wait_for_answer celliax_dir_prefix celliax_dir_entry. So, you can choose the new entry from the imported phonebook, dial it, and be directly connected to celliax_dir extension chosen, without having to pass through the voice menu.\n" -#endif /* CELLIAX_LIBCSV */ - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; - -#endif /* CELLIAX_DIR */ - -char celliax_console_dial_usage[] = - "Usage: celliax_dial [DTMFs]\n" - " Dials a given DTMF string in the call currently placed on the\n" - " \"current\" celliax_console (Celliax) channel.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; -char celliax_console_sendsms_usage[] = - "Usage: celliax_sendsms interfacename/number_to_send_sms_to SMS_TEXT\n" - " This CLI command will use the specified Celliax interface to send an SMS with content SMS_TEXT to the number_to_send_sms_to\n" - " Eg:\n" " celliax_sendsms nicephone/3472665618 \"ciao bello\"\n"; - -char celliax_console_celliax_console_usage[] = - "Usage: celliax_console [interface] | show\n" - " If used without a parameter, displays which interface is the \"current\"\n" - " celliax_console. If a device is specified, the \"current\" celliax_console is changed to\n" - " the interface specified.\n" - " If the parameter is \"show\", the available interfaces are listed\n"; -char *celliax_sendsmsapp = "CelliaxSendsms"; - -char *celliax_sendsmssynopsis = "CelliaxSendsms sends an SMS through the cellphone"; -char *celliax_sendsmsdescrip = - " CelliaxSendsms(interface_name / number_to_send_sms_to , SMS_TEXT):\n" - " This application will use the specified Celliax interface to send an SMS with content SMS_TEXT to the number_to_send_sms_to\n" - " Eg:\n" " CelliaxSendsms(nicephone/3472665618,\"ciao bello\")\n" " or\n" - " CelliaxSendsms(nicephone/3472665618,${DATETIME}\"ciao bello\")\n" "\n"; -char celliax_console_echo_usage[] = - "Usage: celliax_echo [0|1] [0|1]\n" - " Shows or set the values (0 meaning OFF and 1 meaning ON) of the echo suppression options: speexecho and speexpreprocess. Without specifying a value, it just shows the current values. The values are for the \"current\" celliax_console (Celliax) channel.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; -char celliax_console_at_usage[] = - "Usage: celliax_at [command string]\n" - " Send the 'command string' to the 'AT modem' (cellphone) connected to the \"current\" celliax_console (Celliax) channel.\n" - " Enter 'help celliax_console' on how to change the \"current\" celliax_console\n"; -/*! \brief fake celliax_pvt structure values, - * just for logging purposes */ -struct celliax_pvt celliax_log_struct = { - .name = "none", -}; - -/*! \brief Default celliax_pvt structure values, - * used by celliax_mkif to initialize the interfaces */ -struct celliax_pvt celliax_default = { - .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */ - .oss_write_dst = 0, /* start here on reads */ - .interface_state = AST_STATE_DOWN, - .phone_callflow = CALLFLOW_CALL_IDLE, - .dsp_silence_threshold = 512, - .context = "default", - .language = "en", - .exten = "s", - .controldevice_name = "none", - .controldevfd = 0, - .next = NULL, - .owner = NULL, - .dsp = NULL, - .fbus2_outgoing_list = NULL, - .seqnumfbus = FBUS2_SEQNUM_MAX, - .controldev_thread = AST_PTHREADT_NULL, - .arraycounter = 0, -#ifndef GIOVA48 - .celliax_sound_rate = 8000, -#else // GIOVA48 - .celliax_sound_rate = 48000, -#endif // GIOVA48 - .celliax_sound_capt_fd = -1, - .need_acoustic_ring = 0, - .celliax_serial_synced_timestamp = 0, - .celliax_serial_sync_period = 300, - .audio_play_reset_timestamp = 0, - .audio_capture_reset_timestamp = 0, - .controldevice_speed = B38400, - .capture_boost = 0, - .playback_boost = 0, - .stripmsd = 0, - .controldev_dead = 0, - .dtmf_inited = 0, - .at_dial_pre_number = "AT+CKPD=\"", - //.at_dial_post_number = "S\"", - .at_dial_post_number = ";", - .at_dial_expect = "OK", - .at_early_audio = 0, - .at_hangup = "AT+CKPD=\"E\"", - .at_hangup_expect = "OK", - .at_answer = "ATA", - .at_answer_expect = "OK", - .at_send_dtmf = "AT+CKPD", - .at_initial_pause = 0, - .at_preinit_1 = "", - .at_preinit_1_expect = "", - .at_preinit_2 = "", - .at_preinit_2_expect = "", - .at_preinit_3 = "", - .at_preinit_3_expect = "", - .at_preinit_4 = "", - .at_preinit_4_expect = "", - .at_preinit_5 = "", - .at_preinit_5_expect = "", - .at_after_preinit_pause = 0, - .at_postinit_1 = "", - .at_postinit_1_expect = "", - .at_postinit_2 = "", - .at_postinit_2_expect = "", - .at_postinit_3 = "", - .at_postinit_3_expect = "", - .at_postinit_4 = "", - .at_postinit_4_expect = "", - .at_postinit_5 = "", - .at_postinit_5_expect = "", - .at_query_battchg = "", - .at_query_battchg_expect = "", - .at_query_signal = "", - .at_query_signal_expect = "", - .at_call_idle = "", - .at_call_incoming = "", - .at_call_active = "", - .at_call_failed = "", - .at_call_calling = "", - .at_indicator_noservice_string = "CIEV: 2,0", - .at_indicator_nosignal_string = "CIEV: 5,0", - .at_indicator_lowsignal_string = "CIEV: 5,1", - .at_indicator_lowbattchg_string = "CIEV: 0,1", - .at_indicator_nobattchg_string = "CIEV: 0,0", - .at_indicator_callactive_string = "CIEV: 3,1", - .at_indicator_nocallactive_string = "CIEV: 3,0", - .at_indicator_nocallsetup_string = "CIEV: 6,0", - .at_indicator_callsetupincoming_string = "CIEV: 6,1", - .at_indicator_callsetupoutgoing_string = "CIEV: 6,2", - .at_indicator_callsetupremoteringing_string = "CIEV: 6,3", - .at_has_clcc = 0, - .at_has_ecam = 0, - - .skype = 0, - .celliax_dir_entry_extension_prefix = 5, - -#ifdef CELLIAX_CVM - .cvm_subsc_1_pin = "0000", - .cvm_subsc_2_pin = "0000", - .cvm_subsc_no = 1, - .cvm_lock_state = CVM_UNKNOWN_LOCK_STATE, - .cvm_register_state = CVM_UNKNOWN_REGISTER_STATE, - .cvm_busmail_outgoing_list = NULL, - .busmail_rxseq_cvm_last = 0xFF, /*!< \brief sequential number of BUSMAIL messages, (0-7) */ - .busmail_txseq_celliax_last = 0xFF, /*!< \brief sequential number of BUSMAIL messages, (0-7) */ - .cvm_volume_level = 5, - .cvm_celliax_serial_delay = 200, /* 200ms delay after sending down the wire, fix for a bug ? */ - .cvm_handset_no = 0, - .cvm_fp_is_cvm = 0, - .cvm_rssi = 0, - -#endif /* CELLIAX_CVM */ -#ifdef CELLIAX_LIBCSV - .csv_separator_is_semicolon = 0, //FIXME as option - .csv_complete_name_pos = 4, //FIXME as option was 4 for outlook express and some outlook, other outlook 2 - .csv_email_pos = 6, //FIXME as option for outlook express - .csv_home_phone_pos = 32, //FIXME as option was 12 for outlook express - .csv_mobile_phone_pos = 33, //FIXME as option was 14 for outlook express - .csv_business_phone_pos = 41, //FIXME as option was 22 for outlook express - .csv_first_row_is_title = 1, //FIXME as option -#endif /* CELLIAX_LIBCSV */ - - .audio_play_reset_period = 0, //do not reset - - .isInputInterleaved = 1, - .isOutputInterleaved = 1, - .numInputChannels = 1, - .numOutputChannels = 1, -#ifndef GIOVA48 - .framesPerCallback = 160, -#else // GIOVA48 - .framesPerCallback = 960, -#endif // GIOVA48 - .speexecho = 1, - .speexpreprocess = 1, - .portaudiocindex = -1, - .portaudiopindex = -1, -#ifdef CELLIAX_ALSA - .alsa_period_size = 160, - .alsa_periods_in_buffer = 4, - .alsac = NULL, - .alsap = NULL, - .alsawrite_filled = 0, -#endif /* CELLIAX_ALSA */ - -}; - -/*! - * \brief PVT structure for a celliax interface (channel), created by celliax_mkif - */ -struct celliax_pvt *celliax_iflist = NULL; - -#ifdef ASTERISK_VERSION_1_6_0 -struct ast_cli_entry myclis[] = { - AST_CLI_DEFINE(celliax_console_hangup, "Hangup a call on the console"), - //AST_CLI_DEFINE(celliax_console_dial, "Dial an extension on the console"), - //AST_CLI_DEFINE(celliax_console_playback_boost, "Sets/displays spk boost in dB"), - //AST_CLI_DEFINE(celliax_console_capture_boost, "Sets/displays mic boost in dB"), - //AST_CLI_DEFINE(celliax_console_set_active, "Sets/displays active console"), - //AST_CLI_DEFINE(celliax_console_at, "Sends an AT command"), - //AST_CLI_DEFINE(celliax_console_echo, "Echo suppression"), -#ifdef CELLIAX_DIR - //AST_CLI_DEFINE(celliax_console_celliax_dir_import, "imports entries from cellphone"), - //AST_CLI_DEFINE(celliax_console_celliax_dir_export, "exports entries to cellphone"), -#endif /* CELLIAX_DIR */ - //AST_CLI_DEFINE(celliax_console_celliax, "all things celliax"), - //AST_CLI_DEFINE(celliax_console_sendsms, "Send an SMS from a Celliax interface"), -}; -#else -struct ast_cli_entry myclis[] = { - {{"celliax_hangup", NULL}, celliax_console_hangup, - "Hangup a call on the celliax_console", - celliax_console_hangup_usage}, - {{"celliax_playback_boost", NULL}, celliax_console_playback_boost, "playback boost", - celliax_console_playback_boost_usage}, - {{"celliax_capture_boost", NULL}, celliax_console_capture_boost, "capture boost", - celliax_console_capture_boost_usage}, - {{"celliax_usage", NULL}, celliax_console_celliax, "chan_celliax commands info", - celliax_console_celliax_usage}, - - {{"celliax_at", NULL}, celliax_console_at, "AT command", - celliax_console_at_usage}, - {{"celliax_echo", NULL}, celliax_console_echo, "echo suppression", - celliax_console_echo_usage}, -#ifdef CELLIAX_DIR - {{"celliax_dir_import", NULL}, celliax_console_celliax_dir_import, - "Write the celliax_dir.conf file, used by celliax_dir app", - celliax_console_celliax_dir_import_usage}, - {{"celliax_dir_export", NULL}, celliax_console_celliax_dir_export, - "Write in the cellphone the contents of the celliax_dir.conf file, used by celliax_dir app", - celliax_console_celliax_dir_export_usage}, -#endif /* CELLIAX_DIR */ -#ifdef CELLIAX_ALSA - {{"celliax_alsa_period", NULL}, console_alsa_period, "alsa_period", - celliax_console_alsa_period_usage}, -#endif /* CELLIAX_ALSA */ - - {{"celliax_dial", NULL}, celliax_console_dial, - "Dial an extension on the celliax_console", - celliax_console_dial_usage}, - {{"celliax_sendsms", NULL}, celliax_console_sendsms, - "Send an SMS from a Celliax interface", - celliax_console_sendsms_usage}, - {{"celliax_console", NULL}, celliax_console_set_active, - "Sets/displays active celliax_console", - celliax_console_celliax_console_usage}, -}; -#endif /* ASTERISK_VERSION_1_6_0 */ - -/* IMPLEMENTATION */ - -#ifdef CELLIAX_ALSA -int console_alsa_period(int fd, int argc, char *argv[]) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - if (argc > 3 || argc == 2) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" console for alsa_period_size, please enter 'help console'\n"); - return RESULT_SUCCESS; - } - - if (argc == 1) { - ast_cli(fd, - "On the active console, that is [%s], alsa_period_size and alsa_periods_in_buffer are: %d and %d\n", - celliax_console_active, p->alsa_period_size, p->alsa_periods_in_buffer); - } else if (argc == 3) { - - if (p->owner) { - ast_cli(fd, - "CANNOT SET alsa_period_size and alsa_periods_in_buffer on the active console, that is [%s], because there is a call ongoing\n", - celliax_console_active); - return RESULT_SUCCESS; - } - sscanf(argv[1], "%d", &p->alsa_period_size); - sscanf(argv[2], "%d", &p->alsa_periods_in_buffer); - ast_cli(fd, - "alsa_period_size and alsa_periods_in_buffer on the active console, that is [%s], are now: %d and %d\n", - celliax_console_active, p->alsa_period_size, p->alsa_periods_in_buffer); - - if (celliax_monitor_audio_thread - && (celliax_monitor_audio_thread != AST_PTHREADT_NULL) - && (celliax_monitor_audio_thread != AST_PTHREADT_STOP)) { - - if (pthread_cancel(celliax_monitor_audio_thread)) { - ERRORA("pthread_cancel celliax_monitor_audio_thread failed, BAD\n", - CELLIAX_P_LOG); - } - if (pthread_kill(celliax_monitor_audio_thread, SIGURG)) { - DEBUGA_PBX("pthread_kill celliax_monitor_audio_thread failed, no problem\n", CELLIAX_P_LOG); //maybe it just died - } - - if (pthread_join(celliax_monitor_audio_thread, NULL)) { - ERRORA("pthread_join failed, BAD\n", CELLIAX_P_LOG); - } - } - - alsa_shutdown(p); - //sleep(5); - alsa_init(p); - - if (ast_pthread_create - (&celliax_monitor_audio_thread, NULL, celliax_do_audio_monitor, NULL) < 0) { - ERRORA("Unable to start audio_monitor thread.\n", CELLIAX_P_LOG); - return -1; - } - - ast_cli(fd, - "ACTIVATED alsa_period_size and alsa_periods_in_buffer on the active console\n"); - } - - return RESULT_SUCCESS; -} -#endif /* CELLIAX_ALSA */ - -void celliax_unlocka_log(void *x) -{ - ast_mutex_t *y; - y = x; - int i; - - for (i = 0; i < 5; i++) { //let's be generous - - ast_log(LOG_DEBUG, - CELLIAX_SVN_VERSION - "[%-7lx] I'm a dying thread, and I'm to go unlocking mutex %p for the %dth time\n", - (unsigned long int) pthread_self(), y, i); - - ast_mutex_unlock(y); - } - ast_log(LOG_DEBUG, - CELLIAX_SVN_VERSION - "[%-7lx] I'm a dying thread, I've finished unlocking mutex %p\n", - (unsigned long int) pthread_self(), y); -} - -int celliax_queue_control(struct ast_channel *c, int control) -{ - struct celliax_pvt *p = c->tech_pvt; - int times; - -/* queue the frame */ - if (p) - p->control_to_send = control; - else - return 0; - DEBUGA_PBX("Queued CONTROL FRAME %d\n", CELLIAX_P_LOG, control); - -/* wait for the frame to be sent */ - while (p->control_to_send){ - usleep(1000); - times++; - if(times == 1000){ - ERRORA("Queued CONTROL FRAME %d FAILED to be sent\n", CELLIAX_P_LOG, control); - p->control_to_send = 0; - break; - } - } - - return 0; -} - -int celliax_devicestate(void *data) -{ - struct celliax_pvt *p = NULL; - char *name = data; - int res = AST_DEVICE_INVALID; - - if (!data) { - ERRORA("Devicestate requested with no data\n", CELLIAX_P_LOG); - return res; - } - - /* lock the interfaces' list */ - LOKKA(&celliax_iflock); - /* make a pointer to the first interface in the interfaces list */ - p = celliax_iflist; - /* Search for the requested interface and verify if is unowned */ - while (p) { - size_t length = strlen(p->name); - /* is this the requested interface? */ - if (strncmp(name, p->name, length) == 0) { - /* is this interface unowned? */ - if (!p->owner) { - res = AST_DEVICE_NOT_INUSE; - DEBUGA_PBX("Interface is NOT OWNED by a channel\n", CELLIAX_P_LOG); - } else { - /* interface owned by a channel */ - res = AST_DEVICE_INUSE; - DEBUGA_PBX("Interface is OWNED by a channel\n", CELLIAX_P_LOG); - } - - /* we found the requested interface, bail out from the while loop */ - break; - } - /* not yet found, next please */ - p = p->next; - } - /* unlock the interfaces' list */ - UNLOCKA(&celliax_iflock); - - if (res == AST_DEVICE_INVALID) { - ERRORA("Checking device state for interface [%s] returning AST_DEVICE_INVALID\n", - CELLIAX_P_LOG, name); - } - return res; -} - -#ifndef ASTERISK_VERSION_1_4 -int celliax_indicate(struct ast_channel *c, int cond) -#else -int celliax_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen) -#endif -{ - struct celliax_pvt *p = c->tech_pvt; - int res = 0; - - switch (cond) { - case AST_CONTROL_BUSY: - case AST_CONTROL_CONGESTION: - case AST_CONTROL_RINGING: - case -1: - NOTICA("Let's INDICATE %d\n", CELLIAX_P_LOG, cond); - res = -1; /* Ask for inband indications */ - break; - case AST_CONTROL_PROGRESS: - case AST_CONTROL_PROCEEDING: - case AST_CONTROL_VIDUPDATE: - case AST_CONTROL_HOLD: - case AST_CONTROL_UNHOLD: -#ifdef ASTERISK_VERSION_1_4 - //FIXME case AST_CONTROL_SRCUPDATE: -#endif /* ASTERISK_VERSION_1_4 */ - NOTICA("Let's NOT INDICATE %d\n", CELLIAX_P_LOG, cond); - break; - default: - WARNINGA("Don't know how to display condition %d on %s\n", CELLIAX_P_LOG, cond, - c->name); - /* The core will play inband indications for us if appropriate */ - res = -1; - } - - return res; -} - -/*! \brief PBX interface function -build celliax pvt structure - * celliax calls initiated by the PBX arrive here */ -struct ast_channel *celliax_request(const char *type, int format, void *data, int *cause) -{ - struct celliax_pvt *p = NULL; - struct ast_channel *tmp = NULL; - char *name = data; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - - DEBUGA_PBX("Try to request type: %s, name: %s, cause: %d," " format: %d\n", - CELLIAX_P_LOG, type, name, *cause, format); - - if (!data) { - ERRORA("Channel requested with no data\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return NULL; - } - - /* lock the interfaces' list */ - LOKKA(&celliax_iflock); - /* make a pointer to the first interface in the interfaces list */ - p = celliax_iflist; - /* Search for the requested interface and verify if is unowned and format compatible */ - //TODO implement groups a la chan_zap - while (p) { - size_t length = strlen(p->name); - /* is this the requested interface? */ - if (strncmp(name, p->name, length) == 0) { - /* is the requested format supported by this interface? */ - if ((format & AST_FORMAT_SLINEAR) != 0) { - /* is this interface unowned? */ - if (!p->owner) { - DEBUGA_PBX("Requesting: %s, name: %s, format: %d\n", CELLIAX_P_LOG, type, name, - format); - /* create a new channel owning this interface */ - tmp = celliax_new(p, AST_STATE_DOWN, p->context); - if (!tmp) { - /* the channel was not created, probable memory allocation error */ - *cause = AST_CAUSE_SWITCH_CONGESTION; - } - } else { - /* interface owned by another channel */ - WARNINGA("owned by another channel\n", CELLIAX_P_LOG); - *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; - } - } else { - /* requested format not supported */ - WARNINGA("format %d not supported\n", CELLIAX_P_LOG, format); - *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; - } - /* we found the requested interface, bail out from the while loop */ - break; - } - /* not yet found, next please */ - p = p->next; - } - /* unlock the interfaces' list */ - UNLOCKA(&celliax_iflock); - /* restart the monitor so it will watch only the remaining unowned interfaces */ - celliax_restart_monitor(); - if (tmp == NULL) { - /* new channel was not created */ - WARNINGA("Unable to create new Celliax channel %s\n", CELLIAX_P_LOG, name); - } - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - /* return the newly created channel */ - return tmp; -} - -/*! \brief Hangup celliax call - * Part of PBX interface, called from ast_hangup */ - -int celliax_hangup(struct ast_channel *c) -{ - struct celliax_pvt *p; - int res; - - /* get our celliax pvt interface from channel */ - p = c->tech_pvt; - /* if there is not celliax pvt why we are here ? */ - if (!p) { - ERRORA("Asked to hangup channel not connected\n", CELLIAX_P_LOG); - return 0; - } - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - - p->phone_callflow = CALLFLOW_CALL_HANGUP_REQUESTED; - /* shutdown the serial monitoring thread */ - if (p->controldev_thread && (p->controldev_thread != AST_PTHREADT_NULL) - && (p->controldev_thread != AST_PTHREADT_STOP)) { - if (pthread_cancel(p->controldev_thread)) { - ERRORA("controldev_thread pthread_cancel failed, maybe he killed himself?\n", - CELLIAX_P_LOG); - } - /* push it, maybe is stuck in a select or so */ - if (pthread_kill(p->controldev_thread, SIGURG)) { - DEBUGA_SERIAL("controldev_thread pthread_kill failed, no problem\n", CELLIAX_P_LOG); - } -#ifndef __CYGWIN__ /* under cygwin, this seems to be not reliable, get stuck at times */ - /* wait for it to die */ - if (pthread_join(p->controldev_thread, NULL)) { - ERRORA("controldev_thread pthread_join failed, BAD\n", CELLIAX_P_LOG); - } -#else /* __CYGWIN__ */ -/* allow the serial thread to die */ - usleep(300000); //300msecs -#endif /* __CYGWIN__ */ - } - p->controldev_thread = AST_PTHREADT_NULL; - - if (p->controldevprotocol != PROTOCOL_NO_SERIAL) { - if (p->interface_state != AST_STATE_DOWN) { - /* actually hangup through the serial port */ - if (p->controldevprotocol != PROTOCOL_NO_SERIAL) { - res = celliax_serial_hangup(p); - if (res) { - ERRORA("celliax_serial_hangup error: %d\n", CELLIAX_P_LOG, res); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - } - - while (p->interface_state != AST_STATE_DOWN) { - usleep(10000); //10msec - } - if (p->interface_state != AST_STATE_DOWN) { - ERRORA("call hangup failed\n", CELLIAX_P_LOG); - return -1; - } else { - DEBUGA_SERIAL("call hungup\n", CELLIAX_P_LOG); - } - } - } else { - p->interface_state = AST_STATE_DOWN; - p->phone_callflow = CALLFLOW_CALL_IDLE; - } - /* if there is a dsp struct alloced, free it */ - if (p->dsp) { - ast_dsp_free(p->dsp); - p->dsp = NULL; - } -#ifndef __CYGWIN__ -#ifdef CELLIAX_ALSA -/* restart alsa */ - snd_pcm_drop(p->alsap); - snd_pcm_prepare(p->alsap); - - snd_pcm_prepare(p->alsac); - snd_pcm_start(p->alsac); - - /* shutdown the sound system, close sound fds, and if exist shutdown the sound managing threads */ - DEBUGA_SOUND("shutting down sound\n", CELLIAX_P_LOG); - res = celliax_sound_shutdown(p); - if (res == -1) { - ERRORA("Failed to shutdown sound\n", CELLIAX_P_LOG); - } - - -#endif /* CELLIAX_ALSA */ - -#endif /* __CYGWIN__ */ -#ifdef CELLIAX_PORTAUDIO - speex_echo_state_reset(p->stream->echo_state); -#endif // CELLIAX_PORTAUDIO - - /* re-init the serial port, be paranoid */ - if (p->controldevprotocol != PROTOCOL_NO_SERIAL) { - p->controldevfd = celliax_serial_init(p, p->controldevice_speed); - if (p->controldevfd < 1) { - ERRORA("bad, bad, bad\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - } -#ifndef ASTERISK_VERSION_1_4 - /* subtract one to the usage count of Celliax-type channels */ - LOKKA(&celliax_usecnt_lock); - celliax_usecnt--; - if (celliax_usecnt < 0) - ERRORA("Usecnt < 0???\n", CELLIAX_P_LOG); - UNLOCKA(&celliax_usecnt_lock); - ast_update_use_count(); -#else /* ASTERISK_VERSION_1_4 */ - ast_module_unref(ast_module_info->self); -#endif /* ASTERISK_VERSION_1_4 */ - - /* our celliax pvt interface is no more part of a channel */ - p->owner = NULL; - /* our channel has no more this celliax pvt interface to manage */ - c->tech_pvt = NULL; - /* set the channel state to DOWN, eg. available, not in active use */ - if (ast_setstate(c, AST_STATE_DOWN)) { - ERRORA("ast_setstate failed, BAD\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - - if (option_debug) - DEBUGA_PBX("Hanged Up\n", CELLIAX_P_LOG); - /* restart the monitor thread, so it can recheck which interfaces it have to watch during its loop (the interfaces that are not owned by channels) */ - if (celliax_restart_monitor()) { - ERRORA("celliax_restart_monitor failed, BAD\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return 0; -} - -/*! \brief Answer incoming call, - * Part of PBX interface */ -int celliax_answer(struct ast_channel *c) -{ - struct celliax_pvt *p = c->tech_pvt; - int res; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - /* do something to actually answer the call, if needed (eg. pick up the phone) */ - if (p->controldevprotocol != PROTOCOL_NO_SERIAL) { - if (celliax_serial_answer(p)) { - ERRORA("celliax_answer FAILED\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - } - p->interface_state = AST_STATE_UP; - p->phone_callflow = CALLFLOW_CALL_ACTIVE; - - while (p->interface_state == AST_STATE_RING) { - usleep(10000); //10msec - } - if (p->interface_state != AST_STATE_UP) { - ERRORA("call answering failed\n", CELLIAX_P_LOG); - res = -1; - } else { - if (option_debug) - DEBUGA_PBX("call answered\n", CELLIAX_P_LOG); - res = 0; -#ifdef CELLIAX_PORTAUDIO - speex_echo_state_reset(p->stream->echo_state); -#endif // CELLIAX_PORTAUDIO - - if (p->owner) { - DEBUGA_PBX("going to send AST_STATE_UP\n", CELLIAX_P_LOG); - ast_setstate(p->owner, AST_STATE_UP); - //ast_queue_control(p->owner, AST_CONTROL_ANSWER); - //celliax_queue_control(p->owner, AST_CONTROL_ANSWER); - DEBUGA_PBX("just sent AST_STATE_UP\n", CELLIAX_P_LOG); - } - } - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return res; -} - -#ifdef ASTERISK_VERSION_1_4 -int celliax_senddigit_begin(struct ast_channel *c, char digit) -{ - struct celliax_pvt *p = c->tech_pvt; - - DEBUGA_PBX("DIGIT BEGIN received: %c\n", CELLIAX_P_LOG, digit); - - return 0; -} - -int celliax_senddigit_end(struct ast_channel *c, char digit, unsigned int duration) -{ - struct celliax_pvt *p = c->tech_pvt; - - NOTICA("DIGIT END received: %c %d\n", CELLIAX_P_LOG, digit, duration); - - if (p->controldevprotocol == PROTOCOL_AT && p->at_send_dtmf[0]) { - int res = 0; - char at_command[256]; - - memset(at_command, '\0', 256); - sprintf(at_command, "%s=\"%c\"", p->at_send_dtmf, digit); - res = celliax_serial_write_AT_ack(p, at_command); - if (res) { - ERRORA("senddigit command failed, command used: '%s=\"%c\"', giving up\n", - CELLIAX_P_LOG, p->at_send_dtmf, digit); - } - } - return 0; -} -#else /* ASTERISK_VERSION_1_4 */ -int celliax_senddigit(struct ast_channel *c, char digit) -{ - struct celliax_pvt *p = c->tech_pvt; - - NOTICA("DIGIT received: %c\n", CELLIAX_P_LOG, digit); - - if (p->controldevprotocol == PROTOCOL_AT && p->at_send_dtmf[0]) { - int res = 0; - char at_command[256]; - - memset(at_command, '\0', 256); - sprintf(at_command, "%s=\"%c\"", p->at_send_dtmf, digit); - res = celliax_serial_write_AT_ack(p, at_command); - if (res) { - ERRORA("senddigit command failed, command used: '%s=\"%c\"', giving up\n", - CELLIAX_P_LOG, p->at_send_dtmf, digit); - } - } - return 0; -} - -#endif /* ASTERISK_VERSION_1_4 */ - -/*! \brief Read audio frames from channel */ -struct ast_frame *celliax_read(struct ast_channel *c) -{ - struct ast_frame *f; - struct celliax_pvt *p = c->tech_pvt; - int actual; - char buf[128 + 1]; - - if (p->dtmf_inited == 0) { - dtmf_rx_init(&p->dtmf_state, NULL, NULL); - p->dtmf_inited = 1; - dtmf_rx_parms(&p->dtmf_state, 0, 10, 10); - p->dtmf_timestamp.tv_sec=0; - p->dtmf_timestamp.tv_usec=0; - DEBUGA_SOUND("DTMF recognition inited\n", CELLIAX_P_LOG); - } - -/* if there are control frames queued to be sent by celliax_queue_control, send it the first */ -//FIXME maybe better a real queue? - if (p && p->owner && p->control_to_send) { - ast_queue_control(p->owner, p->control_to_send); - DEBUGA_PBX("Sent CONTROL FRAME %d\n", CELLIAX_P_LOG, p->control_to_send); - p->control_to_send = 0; - } - -#ifdef CELLIAX_PORTAUDIO -/* if the call is not active (ie: answered), do not send audio frames, they would pile up in a lag queue */ - if (!p->owner || p->owner->_state != AST_STATE_UP) -#else /* CELLIAX_PORTAUDIO */ - if (!p->owner ) -#endif /* CELLIAX_PORTAUDIO */ - { - static struct ast_frame f; -#ifdef CELLIAX_PORTAUDIO - char c; -#endif /* CELLIAX_PORTAUDIO */ - - f.frametype = AST_FRAME_NULL; - f.subclass = 0; - f.samples = 0; - f.datalen = 0; -#ifdef ASTERISK_VERSION_1_6_0_1 - f.data.ptr = NULL; -#else - f.data = NULL; -#endif /* ASTERISK_VERSION_1_6_0_1 */ - f.offset = 0; - f.src = celliax_type; - f.mallocd = 0; - f.delivery.tv_sec = 0; - f.delivery.tv_usec = 0; -/* read the char that was written by the audio thread in this pipe, this pipe is the fd monitored by asterisk, asterisk then has called the function we are inside) */ -#ifdef CELLIAX_PORTAUDIO - read(p->audiopipe[0], &c, 1); -#endif /* CELLIAX_PORTAUDIO */ - - return &f; - } - - /* read one asterisk frame of audio from sound interface */ - f = celliax_sound_read(p); - if (f) { - struct timeval now_timestamp; -#ifndef __CYGWIN__ -#ifdef CELLIAX_PORTAUDIO - char c[1000]; - int letti = 2; - - while (letti > 1) { - letti = read(p->audiopipe[0], &c, 1000); - if (letti > 0) - DEBUGA_SOUND("READ from audiopipe: %d\n", CELLIAX_P_LOG, letti); - //usleep(1); - } - //if(letti == -1) - //ERRORA("error: %s\n", CELLIAX_P_LOG, strerror(errno)); -#endif /* CELLIAX_PORTAUDIO */ -#endif /* __CYGWIN__ */ - - /* scale sound samples volume up or down */ - celliax_sound_boost(f, p->capture_boost); - - gettimeofday(&now_timestamp, NULL); - - if( (((now_timestamp.tv_sec - p->dtmf_timestamp.tv_sec) * 1000000) < 0) || ( ((now_timestamp.tv_sec - p->dtmf_timestamp.tv_sec) * 1000000) + (now_timestamp.tv_usec - p->dtmf_timestamp.tv_usec) ) > 300000) { // if more than 0.3 seconds from last DTMF, or never got DTMFs before - -#ifdef ASTERISK_VERSION_1_6_0_1 - dtmf_rx(&p->dtmf_state, f->data.ptr, f->samples); -#else - dtmf_rx(&p->dtmf_state, f->data, f->samples); -#endif /* ASTERISK_VERSION_1_6_0_1 */ - actual = dtmf_rx_get(&p->dtmf_state, buf, 128); - if (actual) { - //if (option_debug) - NOTICA("delta_usec=%ld, inband audio DTMF: %s\n", CELLIAX_P_LOG, ( (now_timestamp.tv_sec - p->dtmf_timestamp.tv_sec) * 1000000) + (now_timestamp.tv_usec - p->dtmf_timestamp.tv_usec), buf); - struct ast_frame f2 = { AST_FRAME_DTMF, buf[0], }; - ast_queue_frame(p->owner, &f2); - gettimeofday(&p->dtmf_timestamp, NULL); - } - } - return f; - } - return NULL; -} - -/*! \brief Initiate celliax call from PBX - * used from the dial() application - */ -int celliax_call(struct ast_channel *c, char *idest, int timeout) -{ - struct celliax_pvt *p = NULL; - p = c->tech_pvt; - char rdest[80], *where, dstr[100] = ""; - char *stringp = NULL; - int status; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - if ((c->_state != AST_STATE_DOWN) - && (c->_state != AST_STATE_RESERVED)) { - ERRORA("celliax_call called on %s, neither down nor reserved\n", CELLIAX_P_LOG, - c->name); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - - if (option_debug > 1) - DEBUGA_PBX("celliax_call to call idest: %s, timeout: %d!\n", CELLIAX_P_LOG, idest, - timeout); - - strncpy(rdest, idest, sizeof(rdest) - 1); - // try '/' as separator - stringp = rdest; - strsep(&stringp, "/"); - where = strsep(&stringp, "/"); - - if (!where) { - ERRORA - ("Destination %s is not recognized. Chan_celliax requires a standard destination with slashes (Celliax/device/destination, eg: 'Celliax/nicephone/3472665618')\n", - CELLIAX_P_LOG, idest); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - - strncpy(dstr, where + p->stripmsd, sizeof(dstr) - 1); - if (option_debug > 1) - DEBUGA_PBX("celliax_call dialing idest: %s, timeout: %d, dstr: %s!\n", CELLIAX_P_LOG, - idest, timeout, dstr); - - if (p->controldev_dead) { - WARNINGA("celliax_call: device is dead, cannot call!\n", CELLIAX_P_LOG); - status = -1; - } else { - ast_setstate(c, AST_STATE_DIALING); - status = celliax_serial_call(p, dstr); - } - - if (status) { - WARNINGA("celliax_call dialing failed: %d!\n", CELLIAX_P_LOG, status); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } else { - if (option_debug) - DEBUGA_PBX("call ongoing\n", CELLIAX_P_LOG); - ast_queue_control(p->owner, AST_CONTROL_RINGING); - } - - if (option_debug > 1) - DEBUGA_PBX("celliax_call dialed idest: %s, timeout: %d, dstr: %s!\n", CELLIAX_P_LOG, - idest, timeout, dstr); - - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } -#ifdef CELLIAX_PORTAUDIO - speex_echo_state_reset(p->stream->echo_state); -#endif // CELLIAX_PORTAUDIO - return 0; -} - -/*! \brief Send audio frame to channel */ -int celliax_write(struct ast_channel *c, struct ast_frame *f) -{ - struct celliax_pvt *p = c->tech_pvt; - if (p->owner && p->owner->_state != AST_STATE_UP) { - return 0; - } - - celliax_sound_boost(f, p->playback_boost); - - return celliax_sound_write(p, f); -} - -/*! \brief Fix up a channel: If a channel is consumed, this is called. - * Basically update any ->owner links */ -int celliax_fixup(struct ast_channel *oldchan, struct ast_channel *newchan) -{ - struct celliax_pvt *p = newchan->tech_pvt; - - if (!p) { - ERRORA("No pvt after masquerade. Strange things may happen\n", CELLIAX_P_LOG); - return -1; - } - - if (p->owner != oldchan) { - ERRORA("old channel wasn't %p but was %p\n", CELLIAX_P_LOG, oldchan, p->owner); - return -1; - } - - p->owner = newchan; - return 0; -} - -int celliax_sound_boost(struct ast_frame *f, double boost) -{ -/* LUIGI RIZZO's magic */ - if (boost != 0) { /* scale and clip values */ - int i, x; - -#ifdef ASTERISK_VERSION_1_6_0_1 - int16_t *ptr = (int16_t *) f->data.ptr; -#else - int16_t *ptr = (int16_t *) f->data; -#endif /* ASTERISK_VERSION_1_6_0_1 */ - for (i = 0; i < f->samples; i++) { - x = (ptr[i] * boost) / BOOST_SCALE; - if (x > 32767) { - x = 32767; - } else if (x < -32768) { - x = -32768; - } - ptr[i] = x; - } - } - return 0; -} - -struct ast_channel *celliax_new(struct celliax_pvt *p, int state, char *context) -{ - struct ast_channel *tmp; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - /* alloc a generic channel struct */ -#ifndef ASTERISK_VERSION_1_4 - tmp = ast_channel_alloc(1); -#else - //tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, ""); - tmp = - ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "Celliax/%s", p->name); - -#endif /* ASTERISK_VERSION_1_4 */ - if (tmp) { -int res; - -/* initialize the soundcard channels (input and output) used by this interface (a multichannel soundcard can be used by multiple interfaces), optionally starting the sound managing threads */ - res = celliax_sound_init(p); - if (res == -1) { - ERRORA("Failed initializing sound device\n", CELLIAX_P_LOG); - /* we failed, free the PVT */ - if (tmp) - free(tmp); - return NULL; - } - - /* give a name to the newly created channel */ -#ifndef ASTERISK_VERSION_1_4 - snprintf(tmp->name, sizeof(tmp->name), "Celliax/%s", p->name); - tmp->type = celliax_type; -#else /* ASTERISK_VERSION_1_4 */ - ast_string_field_build(tmp, name, "Celliax/%s", p->name); -#endif /* ASTERISK_VERSION_1_4 */ - - DEBUGA_PBX("new channel: name=%s requested_state=%d\n", CELLIAX_P_LOG, tmp->name, - state); - - /* fd for the channel to poll for incoming audio */ - tmp->fds[0] = p->celliax_sound_capt_fd; - - /* audio formats managed */ - tmp->nativeformats = AST_FORMAT_SLINEAR; - tmp->readformat = AST_FORMAT_SLINEAR; - tmp->writeformat = AST_FORMAT_SLINEAR; - /* the technology description (eg. the interface type) of the newly created channel is the Celliax's one */ - tmp->tech = &celliax_tech; - /* the technology pvt (eg. the interface) of the newly created channel is this interface pvt */ - tmp->tech_pvt = p; - - /* copy this interface default context, extension, language to the newly created channel */ - if (strlen(p->context)) - strncpy(tmp->context, p->context, sizeof(tmp->context) - 1); - if (strlen(p->exten)) - strncpy(tmp->exten, p->exten, sizeof(tmp->exten) - 1); -#ifndef ASTERISK_VERSION_1_4 - if (strlen(p->language)) - strncpy(tmp->language, p->language, sizeof(tmp->language) - 1); -#else - if (strlen(p->language)) - ast_string_field_set(tmp, language, p->language); -#endif /* ASTERISK_VERSION_1_4 */ - /* copy the requested context (not necessarily the interface default) to the newly created channel */ - if (strlen(context)) - strncpy(tmp->context, context, sizeof(tmp->context) - 1); - - /* copy this interface default callerid in the newly created channel */ - ast_set_callerid(tmp, !ast_strlen_zero(p->callid_number) ? p->callid_number : NULL, - !ast_strlen_zero(p->callid_name) ? p->callid_name : NULL, - !ast_strlen_zero(p->callid_number) ? p->callid_number : NULL); - - /* the owner of this interface pvt is the newly created channel */ - p->owner = tmp; - /* if this interface pvt has an initialized dsp struct, free it */ - if (p->dsp) { - DEBUGA_SOUND("freeing dsp\n", CELLIAX_P_LOG); - ast_dsp_free(p->dsp); - p->dsp = NULL; - } -#ifndef ASTERISK_VERSION_1_4 - /* set the newly created channel state to the requested state */ - if (ast_setstate(tmp, state)) { - ERRORA("ast_setstate failed, BAD\n", CELLIAX_P_LOG); - ast_dsp_free(p->dsp); - ast_channel_free(tmp); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return NULL; - } -#endif /* ASTERISK_VERSION_1_4 */ - -#ifdef AST_VERION_1_4 - ast_module_ref(ast_module_info->self); - ast_jb_configure(tmp, &global_jbconf); -#endif /* AST_VERION_1_4 */ - - /* if the requested state is different from DOWN, let the pbx manage this interface (now part of the newly created channel) */ - if (state != AST_STATE_DOWN) { - DEBUGA_PBX("Try to start PBX on %s, state=%d\n", CELLIAX_P_LOG, tmp->name, state); - if (ast_pbx_start(tmp)) { - ERRORA("Unable to start PBX on %s\n", CELLIAX_P_LOG, tmp->name); - ast_dsp_free(p->dsp); - ast_channel_free(tmp); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return NULL; - } - } - /* let's start the serial monitoring thread too, so we can have serial signaling */ - if (ast_pthread_create(&p->controldev_thread, NULL, celliax_do_controldev_thread, p) < - 0) { - ERRORA("Unable to start controldev thread.\n", CELLIAX_P_LOG); - ast_dsp_free(p->dsp); - ast_channel_free(tmp); - tmp = NULL; - } - DEBUGA_SERIAL("STARTED controldev_thread=%lu STOP=%lu NULL=%lu\n", CELLIAX_P_LOG, - (unsigned long) p->controldev_thread, (unsigned long) AST_PTHREADT_STOP, - (unsigned long) AST_PTHREADT_NULL); - -#ifndef ASTERISK_VERSION_1_4 - /* add one to the usage count of Celliax-type channels */ - LOKKA(&celliax_usecnt_lock); - celliax_usecnt++; - UNLOCKA(&celliax_usecnt_lock); - ast_update_use_count(); -#endif /* ASTERISK_VERSION_1_4 */ - - /* return the newly created channel */ - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return tmp; - } - ERRORA("failed memory allocation for Celliax channel\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return NULL; -} - -/*! - * \brief Load the module into Asterisk and start its threads - * - * This function register the module into Asterisk, - * create the interfaces for the channels, - * start the auxiliary threads for the interfaces, - * then start a monitor thread. The monitor thread - * will signal Asterisk when an interface receive a call. - * - * - * \return zero on success, -1 on error. - */ -int load_module(void) -{ - int i; - struct ast_config *cfg; - struct celliax_pvt *tmp; - struct celliax_pvt *p = NULL; -#ifdef ASTERISK_VERSION_1_6_0 - struct ast_flags config_flags = { 0 }; -#endif /* ASTERISK_VERSION_1_6_0 */ - - - -#ifdef ASTERISK_VERSION_1_4 - /* Copy the default jb config over global_jbconf */ - memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); -#endif /* ASTERISK_VERSION_1_4 */ - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - ast_register_application(celliax_sendsmsapp, celliax_sendsms, celliax_sendsmssynopsis, - celliax_sendsmsdescrip); - - ast_manager_register2("CELLIAXsendsms", EVENT_FLAG_SYSTEM, celliax_manager_sendsms, - "Send an SMS", mandescr_celliax_sendsms); - /* make sure we can register our channel type with Asterisk */ - i = ast_channel_register(&celliax_tech); - if (i < 0) { - ERRORA("Unable to register channel type '%s'\n", CELLIAX_P_LOG, celliax_type); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - /* load celliax.conf config file */ -#ifdef ASTERISK_VERSION_1_6_0 - cfg = ast_config_load(celliax_config, config_flags); -#else - cfg = ast_config_load(celliax_config); -#endif /* ASTERISK_VERSION_1_6_0 */ - if (cfg != NULL) { - char *ctg = NULL; - int is_first_category = 1; - while ((ctg = ast_category_browse(cfg, ctg)) != NULL) { - /* create one interface for each category in celliax.conf config file, first one set the defaults */ - tmp = celliax_mkif(cfg, ctg, is_first_category); - if (tmp) { - NOTICA("Created channel Celliax: celliax.conf category '[%s]', channel name '%s'" - " control_device_name '%s'\n", CELLIAX_P_LOG, ctg, tmp->name, - tmp->controldevice_name); - /* add interface to celliax_iflist */ - tmp->next = celliax_iflist; - celliax_iflist = tmp; - /* next one will not be the first ;) */ - if (is_first_category == 1) { - is_first_category = 0; - celliax_console_active = tmp->name; - } - } else { - ERRORA("Unable to create channel Celliax from celliax.conf category '[%s]'\n", - CELLIAX_P_LOG, ctg); - /* if error, unload config from memory and return */ - ast_config_destroy(cfg); - ast_channel_unregister(&celliax_tech); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - /* do it for each category described in config */ - } - - /* we finished, unload config from memory */ - ast_config_destroy(cfg); - } else { - ERRORA("Unable to load celliax_config celliax.conf\n", CELLIAX_P_LOG); - ast_channel_unregister(&celliax_tech); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } -#ifndef ASTERISK_VERSION_1_6_0 - ast_cli_register_multiple(myclis, sizeof(myclis) / sizeof(struct ast_cli_entry)); -#endif /* ASTERISK_VERSION_1_6_0 */ - /* start to monitor the interfaces (celliax_iflist) for the first time */ - if (celliax_restart_monitor()) { - ERRORA("celliax_restart_monitor failed, BAD\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } -#ifdef CELLIAX_DIR - //celliax_dir_create_extensions(); -#endif /* CELLIAX_DIR */ - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return 0; -} - -/*! - * \brief Unload the module from Asterisk and shutdown its threads - * - * This function unregister the module from Asterisk, - * destroy the interfaces for the channels, - * shutdown the auxiliary threads for the interfaces, - * then shutdown its monitor thread. - * - * \return zero on success, -1 on error. - */ -int unload_module(void) -{ - struct celliax_pvt *p = NULL, *p2 = NULL; - int res; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", CELLIAX_P_LOG); - } - - /* unregister our channel type with Asterisk */ - ast_channel_unregister(&celliax_tech); - ast_cli_unregister_multiple(myclis, sizeof(myclis) / sizeof(struct ast_cli_entry)); - - ast_unregister_application(celliax_sendsmsapp); - - /* lock the celliax_monlock, kill the monitor thread, unlock the celliax_monlock */ - LOKKA(&celliax_monlock); - if (celliax_monitor_thread && (celliax_monitor_thread != AST_PTHREADT_NULL) - && (celliax_monitor_thread != AST_PTHREADT_STOP)) { - if (pthread_cancel(celliax_monitor_thread)) { - ERRORA("pthread_cancel failed, BAD\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } - if (pthread_kill(celliax_monitor_thread, SIGURG)) { - DEBUGA_PBX("pthread_kill failed\n", CELLIAX_P_LOG); //maybe it just died - } -#ifndef __CYGWIN__ /* under cygwin, this seems to be not reliable, get stuck at times */ - if (pthread_join(celliax_monitor_thread, NULL)) { - ERRORA("pthread_join failed, BAD\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return -1; - } -#endif /* __CYGWIN__ */ - } - celliax_monitor_thread = AST_PTHREADT_STOP; - UNLOCKA(&celliax_monlock); - - if (celliax_monitor_audio_thread && (celliax_monitor_audio_thread != AST_PTHREADT_NULL) - && (celliax_monitor_audio_thread != AST_PTHREADT_STOP)) { - - if (pthread_cancel(celliax_monitor_audio_thread)) { - ERRORA("pthread_cancel celliax_monitor_audio_thread failed, BAD\n", CELLIAX_P_LOG); - } - if (pthread_kill(celliax_monitor_audio_thread, SIGURG)) { - DEBUGA_PBX("pthread_kill celliax_monitor_audio_thread failed, no problem\n", CELLIAX_P_LOG); //maybe it just died - } - - if (pthread_join(celliax_monitor_audio_thread, NULL)) { - ERRORA("pthread_join failed, BAD\n", CELLIAX_P_LOG); - } - } - /* lock the celliax_iflock, and go through the interfaces list (celliax_iflist) */ - LOKKA(&celliax_iflock); - p = celliax_iflist; - while (p) { - /* for each interface in list */ - p2 = p->next; - /* shutdown the sound system, close sound fds, and if exist shutdown the sound managing threads */ - DEBUGA_SOUND("shutting down sound\n", CELLIAX_P_LOG); - res = celliax_sound_shutdown(p); - if (res == -1) { - ERRORA("Failed to shutdown sound\n", CELLIAX_P_LOG); - } - - /* if a serial port has been opened, close it */ - if (p->controldevprotocol != PROTOCOL_NO_SERIAL) - if (p->controldevfd) - close(p->controldevfd); - - /* if a dsp struct has been allocated, free it */ - if (p->dsp) { - ast_dsp_free(p->dsp); - p->dsp = NULL; - } - DEBUGA_PBX("freeing PVT\n", CELLIAX_P_LOG); - /* free the pvt allocated memory */ - free(p); - /* next one, please */ - p = p2; - } - /* finished with the interfaces list, unlock the celliax_iflock */ - UNLOCKA(&celliax_iflock); - -#ifdef __CYGWIN__ - NOTICA("Sleping 5 secs, please wait...\n", CELLIAX_P_LOG); - sleep(5); /* without this pause, for some unknown (to me) reason it crashes on cygwin */ -#endif /* __CYGWIN__ */ - NOTICA("Unloaded Celliax Module\n", CELLIAX_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", CELLIAX_P_LOG); - } - return 0; -} - -/*! - * \brief Return the count of active channels for this module - * - * \return the count of active channels for this module - */ -int usecount() -{ - int res; - static struct celliax_pvt *p = &celliax_log_struct; -/* lock the celliax_usecnt lock */ - LOKKA(&celliax_usecnt_lock); - /* retrieve the celliax_usecnt */ - res = celliax_usecnt; -/* unlock the celliax_usecnt lock */ - UNLOCKA(&celliax_usecnt_lock); - /* return the celliax_usecnt */ - return res; -} - -/*! - * \brief Return the textual description of the module - * - * \return the textual description of the module - */ -char *description() -{ - return (char *) celliax_desc; -} - -/*! - * \brief Return the ASTERISK_GPL_KEY - * - * \return the ASTERISK_GPL_KEY - */ -char *key() -{ - struct celliax_pvt *p = NULL; - - if (option_debug) - NOTICA("Returning Key\n", CELLIAX_P_LOG); - - return ASTERISK_GPL_KEY; -} - -/*! - * \brief Create and initialize one interface for the module - * \param cfg pointer to configuration data from celliax.conf - * \param ctg pointer to a category name to be found in cfg - * \param is_first_category is this the first category in cfg - * - * This function create and initialize one interface for the module - * - * \return a pointer to the PVT structure of interface on success, NULL on error. - */ -struct celliax_pvt *celliax_mkif(struct ast_config *cfg, char *ctg, int is_first_category) -{ - struct celliax_pvt *tmp; - struct ast_variable *v; - int res; - - int debug_all = 0; - int debug_at = 0; - int debug_fbus2 = 0; - int debug_serial = 0; - int debug_sound = 0; - int debug_pbx = 0; - int debug_skype = 0; - int debug_call = 0; - int debug_locks = 0; - int debug_monitorlocks = 0; -#ifdef CELLIAX_CVM - int debug_cvm = 0; -#endif /* CELLIAX_CVM */ - - /* alloc memory for PVT */ - tmp = malloc(sizeof(struct celliax_pvt)); - if (tmp == NULL) /* fail */ - return NULL; - /* clear memory for PVT */ - memset(tmp, 0, sizeof(struct celliax_pvt)); - - //NOTICA("malloced %d bytes\n", CELLIAX_TMP_LOG, sizeof(struct celliax_pvt)); - - /* if we are reading the "first" category of the config file, take SELECTED values as defaults, overriding the values in celliax_default */ - if (is_first_category == 1) { - /* for each variable in category, copy it in the celliax_default struct */ - for (v = ast_variable_browse(cfg, ctg); v; v = v->next) { - M_START(v->name, v->value); - - M_STR("control_device_protocol", celliax_default.controldevprotocolname) - M_STR("context", celliax_default.context) - M_STR("language", celliax_default.language) - M_STR("extension", celliax_default.exten) - M_UINT("dsp_silence_threshold", celliax_default.dsp_silence_threshold) - M_UINT("audio_play_reset_period", celliax_default.audio_play_reset_period) -#ifdef CELLIAX_ALSA - M_UINT("alsa_period_size", celliax_default.alsa_period_size) - M_UINT("alsa_periods_in_buffer", celliax_default.alsa_periods_in_buffer) -#endif /* CELLIAX_ALSA */ - M_F("playback_boost", - celliax_store_boost(v->value, &celliax_default.playback_boost)) - M_F("capture_boost", - celliax_store_boost(v->value, &celliax_default.capture_boost)) - M_UINT("celliax_dir_entry_extension_prefix", - celliax_default.celliax_dir_entry_extension_prefix) - M_UINT("celliax_dir_prefix", celliax_default.celliax_dir_prefix) - M_STR("sms_receiving_program", tmp->sms_receiving_program) - M_END(; - ); - } - } - - /* initialize the newly created PVT from the celliax_default values */ - *tmp = celliax_default; - - /* initialize the mutexes */ - ast_mutex_init(&tmp->controldev_lock); - ast_mutex_init(&tmp->fbus2_outgoing_list_lock); -#ifdef CELLIAX_CVM - ast_mutex_init(&tmp->cvm_busmail_outgoing_list_lock); -#endif /* CELLIAX_CVM */ - - /* the category name becomes the interface name */ - tmp->name = strdup(ctg); - - /* for each category in config file, "first" included, read in ALL the values */ - for (v = ast_variable_browse(cfg, ctg); v; v = v->next) { - M_START(v->name, v->value); - - M_BOOL("debug_all", debug_all) - M_BOOL("debug_at", debug_at) - M_BOOL("debug_fbus2", debug_fbus2) - M_BOOL("debug_serial", debug_serial) - M_BOOL("debug_sound", debug_sound) - M_BOOL("debug_pbx", debug_pbx) - M_BOOL("debug_skype", debug_skype) - M_BOOL("debug_call", debug_call) - M_BOOL("debug_locks", debug_locks) - M_BOOL("debug_monitorlocks", debug_monitorlocks) -#ifdef CELLIAX_CVM - M_BOOL("debug_cvm", debug_cvm) - M_STR("cvm_subscription_1_pin", tmp->cvm_subsc_1_pin) - M_STR("cvm_subscription_2_pin", tmp->cvm_subsc_2_pin) - M_UINT("cvm_subscription_no", tmp->cvm_subsc_no) - M_UINT("cvm_volume_level", tmp->cvm_volume_level) - M_UINT("cvm_celliax_serial_delay", tmp->cvm_celliax_serial_delay) -#endif /* CELLIAX_CVM */ - M_BOOL("skype", tmp->skype) - M_BOOL("need_acoustic_ring", tmp->need_acoustic_ring) - M_STR("control_device_name", tmp->controldevice_name) - M_UINT("control_device_speed", tmp->controldevice_speed) - M_STR("control_device_protocol", tmp->controldevprotocolname) - M_STR("context", tmp->context) - M_STR("language", tmp->language) - M_STR("extension", tmp->exten) - M_UINT("dsp_silence_threshold", tmp->dsp_silence_threshold) - M_UINT("audio_play_reset_period", tmp->audio_play_reset_period) - M_UINT("portaudio_capture_device_id", tmp->portaudiocindex) - M_UINT("portaudio_playback_device_id", tmp->portaudiopindex) - M_F("playback_boost", celliax_store_boost(v->value, &tmp->playback_boost)) - M_F("capture_boost", celliax_store_boost(v->value, &tmp->capture_boost)) -#ifdef CELLIAX_ALSA - M_STR("alsa_capture_device_name", tmp->alsacname) - M_STR("alsa_playback_device_name", tmp->alsapname) - M_UINT("alsa_period_size", tmp->alsa_period_size) - M_UINT("alsa_periods_in_buffer", tmp->alsa_periods_in_buffer) -#endif /* CELLIAX_WINMM */ - M_STR("at_dial_pre_number", tmp->at_dial_pre_number) - M_STR("at_dial_post_number", tmp->at_dial_post_number) - - M_STR("at_dial_expect", tmp->at_dial_expect) - M_UINT("at_early_audio", tmp->at_early_audio) - M_STR("at_hangup", tmp->at_hangup) - M_STR("at_hangup_expect", tmp->at_hangup_expect) - M_STR("at_answer", tmp->at_answer) - M_STR("at_answer_expect", tmp->at_answer_expect) - M_STR("at_send_dtmf", tmp->at_send_dtmf) - - M_UINT("at_initial_pause", tmp->at_initial_pause) - M_STR("at_preinit_1", tmp->at_preinit_1) - M_STR("at_preinit_1_expect", tmp->at_preinit_1_expect) - M_STR("at_preinit_2", tmp->at_preinit_2) - M_STR("at_preinit_2_expect", tmp->at_preinit_2_expect) - M_STR("at_preinit_3", tmp->at_preinit_3) - M_STR("at_preinit_3_expect", tmp->at_preinit_3_expect) - M_STR("at_preinit_4", tmp->at_preinit_4) - M_STR("at_preinit_4_expect", tmp->at_preinit_4_expect) - M_STR("at_preinit_5", tmp->at_preinit_5) - M_STR("at_preinit_5_expect", tmp->at_preinit_5_expect) - M_UINT("at_after_preinit_pause", tmp->at_after_preinit_pause) - - M_STR("at_postinit_1", tmp->at_postinit_1) - M_STR("at_postinit_1_expect", tmp->at_postinit_1_expect) - M_STR("at_postinit_2", tmp->at_postinit_2) - M_STR("at_postinit_2_expect", tmp->at_postinit_2_expect) - M_STR("at_postinit_3", tmp->at_postinit_3) - M_STR("at_postinit_3_expect", tmp->at_postinit_3_expect) - M_STR("at_postinit_4", tmp->at_postinit_4) - M_STR("at_postinit_4_expect", tmp->at_postinit_4_expect) - M_STR("at_postinit_5", tmp->at_postinit_5) - M_STR("at_postinit_5_expect", tmp->at_postinit_5_expect) - - M_STR("at_query_battchg", tmp->at_query_battchg) - M_STR("at_query_battchg_expect", tmp->at_query_battchg_expect) - M_STR("at_query_signal", tmp->at_query_signal) - M_STR("at_query_signal_expect", tmp->at_query_signal_expect) - M_STR("at_call_idle", tmp->at_call_idle) - M_STR("at_call_incoming", tmp->at_call_incoming) - M_STR("at_call_active", tmp->at_call_active) - M_STR("at_call_failed", tmp->at_call_failed) - M_STR("at_call_calling", tmp->at_call_calling) - M_STR("at_indicator_noservice_string", tmp->at_indicator_noservice_string) - M_STR("at_indicator_nosignal_string", tmp->at_indicator_nosignal_string) - M_STR("at_indicator_lowsignal_string", tmp->at_indicator_lowsignal_string) - M_STR("at_indicator_lowbattchg_string", tmp->at_indicator_lowbattchg_string) - M_STR("at_indicator_nobattchg_string", tmp->at_indicator_nobattchg_string) - M_STR("at_indicator_callactive_string", tmp->at_indicator_callactive_string) - M_STR("at_indicator_nocallactive_string", tmp->at_indicator_nocallactive_string) - M_STR("at_indicator_nocallsetup_string", tmp->at_indicator_nocallsetup_string) - M_STR("at_indicator_callsetupincoming_string", - tmp->at_indicator_callsetupincoming_string) - M_STR("at_indicator_callsetupoutgoing_string", - tmp->at_indicator_callsetupoutgoing_string) - M_STR("at_indicator_callsetupremoteringing_string", - tmp->at_indicator_callsetupremoteringing_string) - M_UINT("celliax_dir_entry_extension_prefix", - tmp->celliax_dir_entry_extension_prefix) - M_UINT("celliax_dir_prefix", tmp->celliax_dir_prefix) -#ifdef CELLIAX_LIBCSV - M_UINT("csv_separator_is_semicolon", tmp->csv_separator_is_semicolon) - M_UINT("csv_complete_name_pos", tmp->csv_complete_name_pos) - M_UINT("csv_email_pos", tmp->csv_email_pos) - M_UINT("csv_home_phone_pos", tmp->csv_home_phone_pos) - M_UINT("csv_mobile_phone_pos", tmp->csv_mobile_phone_pos) - M_UINT("csv_business_phone_pos", tmp->csv_business_phone_pos) - M_UINT("csv_first_row_is_title", tmp->csv_first_row_is_title) -#endif /* CELLIAX_LIBCSV */ - M_STR("sms_receiving_program", tmp->sms_receiving_program) - M_BOOL("speexecho", tmp->speexecho) - M_BOOL("speexpreprocess", tmp->speexpreprocess) - M_END(; - ); - } - - if (debug_all) { - celliax_debug = celliax_debug | DEBUG_ALL; - if (!option_debug) { - WARNINGA - ("DEBUG_ALL activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_ALL debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_ALL activated. \n", CELLIAX_TMP_LOG); - } - } - if (debug_at) { - celliax_debug = celliax_debug | DEBUG_AT; - if (!option_debug) { - WARNINGA - ("DEBUG_AT activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_AT debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_AT activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_fbus2) { - celliax_debug = celliax_debug | DEBUG_FBUS2; - if (!option_debug) { - WARNINGA - ("DEBUG_FBUS2 activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_FBUS2 debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_FBUS2 activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_serial) { - celliax_debug = celliax_debug | DEBUG_SERIAL; - if (!option_debug) { - WARNINGA - ("DEBUG_SERIAL activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_SERIAL debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_SERIAL activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_sound) { - celliax_debug = celliax_debug | DEBUG_SOUND; - if (!option_debug) { - WARNINGA - ("DEBUG_SOUND activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_SOUND debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_SOUND activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_pbx) { - celliax_debug = celliax_debug | DEBUG_PBX; - if (!option_debug) { - WARNINGA - ("DEBUG_PBX activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_PBX debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_PBX activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_call) { - celliax_debug = celliax_debug | DEBUG_CALL; - if (!option_debug) { - WARNINGA - ("DEBUG_CALL activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_CALL debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_CALL activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_locks) { - celliax_debug = celliax_debug | DEBUG_LOCKS; - if (!option_debug) { - WARNINGA - ("DEBUG_LOCKS activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_LOCKS debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_LOCKS activated. \n", CELLIAX_TMP_LOG); - } - } - - if (debug_monitorlocks) { - celliax_debug = celliax_debug | DEBUG_MONITORLOCKS; - if (!option_debug) { - WARNINGA - ("DEBUG_MONITORLOCKS activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_MONITORLOCKS debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_MONITORLOCKS activated. \n", CELLIAX_TMP_LOG); - } - } -#ifdef CELLIAX_CVM - if (debug_cvm) { - celliax_debug = celliax_debug | DEBUG_CVM; - if (!option_debug) { - WARNINGA - ("DEBUG_CVM activated, but option_debug is 0. You have to set debug level higher than zero to see some debugging output. Please use the command \"set debug 10\" or start Asterisk with \"-dddddddddd\" option for full DEBUG_CVM debugging output.\n", - CELLIAX_TMP_LOG); - } else { - NOTICA("DEBUG_CVM activated. \n", CELLIAX_TMP_LOG); - } - } -#endif /* CELLIAX_CVM */ - - if (option_debug > 1) { - DEBUGA_SOUND("playback_boost is %f\n", CELLIAX_TMP_LOG, tmp->playback_boost); - DEBUGA_SOUND("capture_boost is %f\n", CELLIAX_TMP_LOG, tmp->capture_boost); - } - - /* serial protocols are named in config with a string, but as int in this software */ - if (strcasecmp(tmp->controldevprotocolname, "fbus2") == 0) - tmp->controldevprotocol = PROTOCOL_FBUS2; - else if (strcasecmp(tmp->controldevprotocolname, "at") == 0) - tmp->controldevprotocol = PROTOCOL_AT; - else if (strcasecmp(tmp->controldevprotocolname, "no_serial") == 0) - tmp->controldevprotocol = PROTOCOL_NO_SERIAL; - else if (strcasecmp(tmp->controldevprotocolname, "alsa_voicemodem") == 0) - tmp->controldevprotocol = PROTOCOL_ALSA_VOICEMODEM; -#ifdef CELLIAX_CVM - else if (strcasecmp(tmp->controldevprotocolname, "cvm_busmail") == 0) - tmp->controldevprotocol = PROTOCOL_CVM_BUSMAIL; -#endif /* CELLIAX_CVM */ - else { -#ifndef CELLIAX_CVM - ERRORA - ("control_device_protocol in celliax.conf MUST be = fbus2|at|no_serial|alsa_voicemodem, but is = '%s'\n", - CELLIAX_TMP_LOG, - tmp->controldevprotocolname ? tmp->controldevprotocolname : "NULL"); -#else - ERRORA - ("control_device_protocol in celliax.conf MUST be = fbus2|at|no_serial|alsa_voicemodem|cvm_busmail, but is = '%s'\n", - CELLIAX_TMP_LOG, - tmp->controldevprotocolname ? tmp->controldevprotocolname : "NULL"); -#endif /* CELLIAX_CVM */ - - /* we failed, free the PVT */ - free(tmp); - return NULL; - } - - if (tmp->controldevice_speed != celliax_default.controldevice_speed) { - /* serial speeds are numbers in config file, but we needs definitions in this software */ - if (tmp->controldevice_speed == 9600) - tmp->controldevice_speed = B9600; - else if (tmp->controldevice_speed == 19200) - tmp->controldevice_speed = B19200; - else if (tmp->controldevice_speed == 38400) - tmp->controldevice_speed = B38400; - else if (tmp->controldevice_speed == 57600) - tmp->controldevice_speed = B57600; - else if (tmp->controldevice_speed == 115200) - tmp->controldevice_speed = B115200; - else { - ERRORA - ("controldevice_speed has to be given one of the following values: 9600|19200|38400|57600|115200. In the config file, was given: %d\n", - CELLIAX_TMP_LOG, tmp->controldevice_speed); - free(tmp); - return NULL; - } - } - -/* CVM PP DECT modules supports registration to two DECT FPs (bases), but CVM can be only connected to one DECT FP at the time, so we need two PINs (for registration) and info to which DECT FP connect*/ -#ifdef CELLIAX_CVM - if (tmp->cvm_subsc_no != celliax_default.cvm_subsc_no) { - if ((tmp->cvm_subsc_no != 1) && (tmp->cvm_subsc_no != 2)) { - ERRORA - ("cvm_subscription_no has to be given one of the following values: 1|2. In the config file, was given: %d\n", - CELLIAX_TMP_LOG, tmp->cvm_subsc_no); - free(tmp); - return NULL; - } - } - - if (tmp->cvm_subsc_1_pin != celliax_default.cvm_subsc_1_pin) { - if (4 != strlen(tmp->cvm_subsc_1_pin)) { - ERRORA - ("cvm_subscription_1_pin has to be 4 digits long. In the config file, was given: %s\n", - CELLIAX_TMP_LOG, tmp->cvm_subsc_1_pin); - free(tmp); - return NULL; - } - } - - if (tmp->cvm_subsc_2_pin != celliax_default.cvm_subsc_2_pin) { - if (4 != strlen(tmp->cvm_subsc_2_pin)) { - ERRORA - ("cvm_subscription_2_pin has to be 4 digits long. In the config file, was given: %s\n", - CELLIAX_TMP_LOG, tmp->cvm_subsc_2_pin); - free(tmp); - return NULL; - } - } - - if (tmp->cvm_volume_level != celliax_default.cvm_volume_level) { - if ((0 > tmp->cvm_volume_level) && (9 < tmp->cvm_volume_level)) { - ERRORA("cvm_volume_level has to be 0-9. In the config file, was given: %d\n", - CELLIAX_TMP_LOG, tmp->cvm_volume_level); - free(tmp); - return NULL; - } - } - - if (tmp->cvm_celliax_serial_delay != celliax_default.cvm_celliax_serial_delay) { - if ((0 > tmp->cvm_celliax_serial_delay) && (65535 < tmp->cvm_celliax_serial_delay)) { - ERRORA - ("cvm_celliax_serial_dealy has to be 0-65535. In the config file, was given: %d\n", - CELLIAX_TMP_LOG, tmp->cvm_celliax_serial_delay); - free(tmp); - return NULL; - } - } -#endif /* CELLIAX_CVM */ - if (tmp->need_acoustic_ring) { - /* alloc and initialize a new dsp struct for this interface pvt, WITH silence suppression */ - if (celliax_sound_dsp_set(tmp, tmp->dsp_silence_threshold, 1)) { - ERRORA("celliax_sound_dsp_set failed\n", CELLIAX_TMP_LOG); - celliax_sound_shutdown(tmp); - if (tmp) - free(tmp); - return NULL; - } - -/* initialize the soundcard channels (input and output) used by this interface (a multichannel soundcard can be used by multiple interfaces), optionally starting the sound managing threads */ - res = celliax_sound_init(tmp); - if (res == -1) { - ERRORA("Failed initializing sound device\n", CELLIAX_TMP_LOG); - /* we failed, free the PVT */ - if (tmp) - free(tmp); - return NULL; - } - - } - - /* init the serial port */ - if (tmp->controldevprotocol != PROTOCOL_NO_SERIAL) { - tmp->controldevfd = celliax_serial_init(tmp, tmp->controldevice_speed); - if (tmp->controldevfd < 1) { - ERRORA("celliax_serial_init failed\n", CELLIAX_TMP_LOG); - celliax_sound_shutdown(tmp); - if (tmp) - free(tmp); - return NULL; - } - } - - /* config the phone/modem on the serial port */ - if (tmp->controldevprotocol != PROTOCOL_NO_SERIAL) { - //int res; - res = celliax_serial_config(tmp); - if (res) { - ERRORA("celliax_serial_config failed\n", CELLIAX_TMP_LOG); - celliax_sound_shutdown(tmp); - if (tmp) - free(tmp); - return NULL; - } - } - - /* return the newly created celliax_pvt */ - return tmp; -} - -/*! \brief (Re)Start the module main monitor thread, watching for incoming calls on the interfaces */ -int celliax_restart_monitor(void) -{ - static struct celliax_pvt *p = &celliax_log_struct; - /* If we're supposed to be stopped -- stay stopped */ - if (celliax_monitor_thread == AST_PTHREADT_STOP) - return 0; - LOKKA(&celliax_monlock); - /* Do not seems possible to me that this function can be called by the very same monitor thread, but let's be paranoid */ - if (celliax_monitor_thread == pthread_self()) { - UNLOCKA(&celliax_monlock); - ERRORA("Cannot kill myself\n", CELLIAX_P_LOG); - return -1; - } - /* if the monitor thread exists */ - if (celliax_monitor_thread != AST_PTHREADT_NULL) { - /* Wake up the thread, it can be stuck waiting in a select or so */ - pthread_kill(celliax_monitor_thread, SIGURG); - pthread_kill(celliax_monitor_audio_thread, SIGURG); - } else { - /* the monitor thread does not exists, start a new monitor */ - if (ast_pthread_create(&celliax_monitor_thread, NULL, celliax_do_monitor, NULL) < 0) { - UNLOCKA(&celliax_monlock); - ERRORA("Unable to start monitor thread.\n", CELLIAX_P_LOG); - return -1; - } - - if (ast_pthread_create - (&celliax_monitor_audio_thread, NULL, celliax_do_audio_monitor, NULL) < 0) { - ERRORA("Unable to start audio_monitor thread.\n", CELLIAX_P_LOG); - return -1; - } - - } - UNLOCKA(&celliax_monlock); - return 0; -} - -/*! \brief The celliax monitoring thread - * \note This thread monitors all the celliax interfaces that are not in a call - * (and thus do not have a separate thread) indefinitely - * */ -void *celliax_do_monitor(void *data) -{ - fd_set rfds; - int res; - struct celliax_pvt *p = NULL; - int max = -1; - struct timeval to; - time_t now_timestamp; - - if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { - ERRORA("Unable to set cancel type to deferred\n", CELLIAX_P_LOG); - return NULL; - } - - for (;;) { - pthread_testcancel(); - /* Don't let anybody kill us right away. Nobody should lock the interface list - and wait for the monitor list, but the other way around is okay. */ - PUSHA_UNLOCKA(&celliax_monlock); - MONITORLOKKA(&celliax_monlock); - /* Lock the interface list */ - PUSHA_UNLOCKA(&celliax_iflock); - MONITORLOKKA(&celliax_iflock); - /* Build the stuff we're going to select on, that is the celliax_serial_fd of every - celliax_pvt that does not have an associated owner channel. In the case of FBUS2 3310 - and in the case of PROTOCOL_NO_SERIAL we add the audio_fd as well, because there is not serial signaling of incoming calls */ - FD_ZERO(&rfds); - - time(&now_timestamp); - p = celliax_iflist; - while (p) { - if (!p->owner) { - /* This interface needs to be watched, as it lacks an owner */ - - if (p->controldevprotocol != PROTOCOL_NO_SERIAL && !p->controldev_dead) { - /* This interface needs its serial connection to be watched, nokia 3310 and compatibles needs sounds as well */ - if (FD_ISSET(p->controldevfd, &rfds)) { - ERRORA("Bizarre! Descriptor %d (controldevfd) appears twice ?\n", - CELLIAX_P_LOG, p->controldevfd); - } - if (p->controldevfd > 0) { - - //time(&now_timestamp); - if ((now_timestamp - p->celliax_serial_synced_timestamp) > p->celliax_serial_sync_period) { //TODO find a sensible period. 5min? in config? - int rt; - if (option_debug > 1) - DEBUGA_SERIAL("Syncing Serial\n", CELLIAX_P_LOG); - rt = celliax_serial_sync(p); - if (rt) { - p->controldev_dead = 1; - close(p->controldevfd); - ERRORA("serial sync failed, declaring %s dead\n", CELLIAX_P_LOG, - p->controldevice_name); - } - rt = celliax_serial_getstatus(p); - if (rt) { - p->controldev_dead = 1; - close(p->controldevfd); - ERRORA("serial getstatus failed, declaring %s dead\n", CELLIAX_P_LOG, - p->controldevice_name); - } - - } - - if (!p->controldev_dead) { - /* add this file descriptor to the set watched by the select */ - FD_SET(p->controldevfd, &rfds); - if (p->controldevfd > max) { - /* adjust the maximum file descriptor value the select has to watch for */ - max = p->controldevfd; - } - } - } - } - - } - /* next interface, please */ - p = p->next; - } - /* Okay, now that we know what to do, release the interface lock */ - MONITORUNLOCKA(&celliax_iflock); - POPPA_UNLOCKA(&celliax_iflock); - /* And from now on, we're okay to be killed, so release the monitor lock as well */ - MONITORUNLOCKA(&celliax_monlock); - POPPA_UNLOCKA(&celliax_monlock); - - /* you want me to die? */ - pthread_testcancel(); - - /* Wait for something to happen */ - to.tv_sec = 0; - to.tv_usec = 500000; /* we select with this timeout because under cygwin we avoid the signal usage, so there is no way to end the thread if it is stuck waiting for select */ - res = ast_select(max + 1, &rfds, NULL, NULL, &to); - - /* you want me to die? */ - pthread_testcancel(); - - /* Okay, select has finished. Let's see what happened. */ - - /* If there are errors... */ - if (res < 0) { - if (errno == EINTR) /* EINTR is just the select - being interrupted by a SIGURG, or so */ - continue; - else { - ERRORA("select returned %d: %s\n", CELLIAX_P_LOG, res, strerror(errno)); -//FIXME what to do here? is the interface that failed signaled? which interface we have to disable? - return NULL; - } - } - - /* must not be killed while celliax_iflist is locked */ - PUSHA_UNLOCKA(&celliax_monlock); - MONITORLOKKA(&celliax_monlock); - /* Alright, lock the interface list again, and let's look and see what has - happened */ - PUSHA_UNLOCKA(&celliax_iflock); - MONITORLOKKA(&celliax_iflock); - - p = celliax_iflist; - for (; p; p = p->next) { - - if (p->controldevprotocol != PROTOCOL_NO_SERIAL && !p->controldev_dead) { - if (!p->owner) { //give all the serial channels that have no owner a read, so we can have the timers clicking - - if (!p->celliax_serial_monitoring) { - p->celliax_serial_monitoring = 1; - res = celliax_serial_monitor(p); - if (res == -1) { //manage the graceful interface shutdown - p->controldev_dead = 1; - close(p->controldevfd); - ERRORA("celliax_serial_monitor failed, declaring %s dead\n", CELLIAX_P_LOG, - p->controldevice_name); - } else if (!p->need_acoustic_ring - && p->controldevprotocol != PROTOCOL_NO_SERIAL - && p->interface_state == AST_STATE_RING) { - if (option_debug) - DEBUGA_PBX("INCOMING RING\n", CELLIAX_P_LOG); - if (!celliax_new(p, AST_STATE_RING, p->context)) { - //FIXME what to do here? - ERRORA("celliax_new failed! BAD BAD BAD\n", CELLIAX_P_LOG); - } - } - p->celliax_serial_monitoring = 0; - } - } - } - - if (p->controldevprotocol != PROTOCOL_NO_SERIAL && p->controldev_dead) { - - /* init the serial port */ - p->controldevfd = celliax_serial_init(p, p->controldevice_speed); - if (p->controldevfd < 1) { - DEBUGA_SERIAL("celliax_serial_init failed\n", CELLIAX_P_LOG); - } else { - - /* config the phone/modem on the serial port */ - res = celliax_serial_config(p); - if (res) { - DEBUGA_SERIAL("celliax_serial_config failed\n", CELLIAX_P_LOG); - close(p->controldevfd); - } else { - - NOTICA("Wow, the serial port has come back! Let's see if it will work\n", - CELLIAX_P_LOG); - p->controldev_dead = 0; - } - - } - - } - - } - MONITORUNLOCKA(&celliax_iflock); - POPPA_UNLOCKA(&celliax_iflock); - MONITORUNLOCKA(&celliax_monlock); - POPPA_UNLOCKA(&celliax_monlock); - pthread_testcancel(); - } -/* Never reached */ - return NULL; - -} - -void *celliax_do_audio_monitor(void *data) -{ - fd_set rfds; - int res; - struct celliax_pvt *p = NULL; - int max = -1; - struct timeval to; - - if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { - ERRORA("Unable to set cancel type to deferred\n", CELLIAX_P_LOG); - return NULL; - } - - for (;;) { - pthread_testcancel(); - /* Lock the interface list */ - PUSHA_UNLOCKA(&celliax_iflock); - MONITORLOKKA(&celliax_iflock); - - FD_ZERO(&rfds); - - p = celliax_iflist; - while (p) { - if (!p->owner) { - /* This interface needs to be watched, as it lacks an owner */ - - if (p->controldevprotocol == PROTOCOL_NO_SERIAL || p->need_acoustic_ring) { - /* This interface needs its incoming sound to be watched, because it cannot signal incoming ring from serial (eg nokia 3310 and compatibles) */ - if (p->celliax_sound_capt_fd > 0) { - /* if fd exist */ - if (FD_ISSET(p->celliax_sound_capt_fd, &rfds)) { - ERRORA("Bizarre! Descriptor %d (celliax_sound_capt_fd) appears twice ?\n", - CELLIAX_P_LOG, p->celliax_sound_capt_fd); - } - /* add this file descriptor to the set watched by the select */ - FD_SET(p->celliax_sound_capt_fd, &rfds); - if (p->celliax_sound_capt_fd > max) { - /* adjust the maximum file descriptor value the select has to watch for */ - max = p->celliax_sound_capt_fd; - } - } - } - - } - /* next interface, please */ - p = p->next; - } - /* Okay, now that we know what to do, release the interface lock */ - - MONITORUNLOCKA(&celliax_iflock); - POPPA_UNLOCKA(&celliax_iflock); - /* you want me to die? */ - pthread_testcancel(); - - /* Wait for something to happen */ - to.tv_sec = 0; - to.tv_usec = 500000; /* we select with this timeout because under cygwin we avoid the signal usage, so there is no way to end the thread if it is stuck waiting for select */ - res = ast_select(max + 1, &rfds, NULL, NULL, &to); - - /* you want me to die? */ - pthread_testcancel(); - - /* Okay, select has finished. Let's see what happened. */ - - /* If there are errors... */ - if (res < 0) { - if (errno == EINTR) { /* EINTR is just the select - being interrupted by a SIGURG, or so */ - usleep(100); - continue; - } else { - ERRORA("select returned %d: %s\n", CELLIAX_P_LOG, res, strerror(errno)); -//FIXME what to do here? is the interface that failed signaled? which interface we have to disable? - return NULL; - } - } - /* If there are no file descriptors changed, just continue */ - - if (res == 0) { - usleep(100); //let's breath - continue; - } -//usleep(10); //let's breath - - /* Lock the interface list */ - PUSHA_UNLOCKA(&celliax_iflock); - MONITORLOKKA(&celliax_iflock); - - p = celliax_iflist; - for (; p; p = p->next) { - - if (FD_ISSET(p->celliax_sound_capt_fd, &rfds)) { - res = celliax_sound_monitor(p); - if (res < 0) { - ERRORA("celliax_sound_monitor ERROR %d\n", CELLIAX_P_LOG, res); - } else if (res == CALLFLOW_INCOMING_RING) { - p->phone_callflow = CALLFLOW_INCOMING_RING; - p->interface_state = AST_STATE_RING; - if (option_debug) - DEBUGA_PBX("INCOMING RING\n", CELLIAX_P_LOG); - if (!celliax_new(p, AST_STATE_RING, p->context)) - ERRORA("celliax_new failed! BAD BAD BAD\n", CELLIAX_P_LOG); - } else { - } - - } - - } -/* Okay, now that we know what to do, release the interface lock */ - - MONITORUNLOCKA(&celliax_iflock); - POPPA_UNLOCKA(&celliax_iflock); - - pthread_testcancel(); - } -/* Never reached */ - return NULL; -} - -/*! - * \brief Initialize the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the celliax_pvt of the interface - * - * This function initialize the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces). It simply pass its parameters to the right function for the sound system for which has been compiled, eg. alsa_init for ALSA, oss_init for OSS, winmm_init for Windows Multimedia, etc and return the result - * - * \return zero on success, -1 on error. - */ - -int celliax_sound_init(struct celliax_pvt *p) -{ -#ifdef CELLIAX_ALSA - return alsa_init(p); -#endif /* CELLIAX_ALSA */ -#ifdef CELLIAX_PORTAUDIO - return celliax_portaudio_init(p); -#endif /* CELLIAX_PORTAUDIO */ - - return -1; -} - -/*! - * \brief Shutdown the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces) - * \param p the celliax_pvt of the interface - * - * This function shutdown the soundcard channels (input and output) used by one interface (a multichannel soundcard can be used by multiple interfaces). It simply pass its parameters to the right function for the sound system for which has been compiled, eg. alsa_shutdown for ALSA, oss_shutdown for OSS, winmm_shutdown for Windows Multimedia, etc and return the result - * - * \return zero on success, -1 on error. - */ - -int celliax_sound_shutdown(struct celliax_pvt *p) -{ - -#ifdef CELLIAX_ALSA - return alsa_shutdown(p); -#endif /* CELLIAX_ALSA */ -#ifdef CELLIAX_PORTAUDIO - return celliax_portaudio_shutdown(p); -#endif /* CELLIAX_PORTAUDIO */ - - return -1; -} - -/*! \brief returns an asterisk frame categorized by dsp algorithms */ -struct ast_frame *celliax_sound_dsp_analize(struct celliax_pvt *p, struct ast_frame *f, - int dsp_silence_threshold) -{ - if (!p->dsp) { - DEBUGA_SOUND("no dsp, initializing it \n", CELLIAX_P_LOG); - if (celliax_sound_dsp_set(p, dsp_silence_threshold, 1)) { - ERRORA("celliax_sound_dsp_set failed\n", CELLIAX_P_LOG); - return NULL; - } - } - - /* process with dsp */ - if (p->dsp) { - if (f->frametype == AST_FRAME_VOICE) { - f = ast_dsp_process(p->owner, p->dsp, f); - } else { - //WARNINGA("not a VOICE frame ! \n", CELLIAX_P_LOG); - } - } - return f; -} - -/*! \brief initialize the dsp algorithms and structures */ -int celliax_sound_dsp_set(struct celliax_pvt *p, int dsp_silence_threshold, - int silence_suppression) -{ - -/* let asterisk dsp algorithms detect dtmf */ - if (p->dsp) { - return 0; - } - if (option_debug > 1) - DEBUGA_SOUND("alloc dsp \n", CELLIAX_P_LOG); - p->dsp = ast_dsp_new(); - if (p->dsp) { - if (silence_suppression) { - ast_dsp_set_threshold(p->dsp, dsp_silence_threshold); - DEBUGA_SOUND("set dsp_silence_threshold=%d\n", CELLIAX_P_LOG, - dsp_silence_threshold); - if (option_debug > 1) - DEBUGA_SOUND("Detecting silence, I mean, voice\n", CELLIAX_P_LOG); - ast_dsp_set_features(p->dsp, 0 | DSP_FEATURE_SILENCE_SUPPRESS); - } else { - if (option_debug > 1) - DEBUGA_SOUND("WITHOUT SILENCE_SUPPRESS, Detecting inband dtmf with sw DSP\n", - CELLIAX_P_LOG); - -#ifdef ASTERISK_VERSION_1_6_0_1 - ast_dsp_set_features(p->dsp, 0 | DSP_FEATURE_DIGIT_DETECT); -#else - ast_dsp_set_features(p->dsp, 0 | DSP_FEATURE_DTMF_DETECT); -#endif /* ASTERISK_VERSION_1_6_0_1 */ - } - - /* - if (ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF)) { - ERRORA("ast_dsp_digitmode failed\n", CELLIAX_P_LOG); - return -1; - } - */ - } else { - ERRORA("ast_dsp_new failed\n", CELLIAX_P_LOG); - return -1; - } - return 0; -} - -/*! \brief Read audio frames from interface */ -struct ast_frame *celliax_sound_read(struct celliax_pvt *p) -{ - struct ast_frame *f = NULL; -#ifdef CELLIAX_ALSA - f = alsa_read(p); -#endif /* CELLIAX_ALSA */ -#ifdef CELLIAX_PORTAUDIO - f = celliax_portaudio_read(p); -#endif /* CELLIAX_PORTAUDIO */ - - return f; -} - -/*! \brief Send audio frame to interface */ -int celliax_sound_write(struct celliax_pvt *p, struct ast_frame *f) -{ - int ret = -1; - -#ifdef CELLIAX_ALSA - ret = alsa_write(p, f); -#endif /* CELLIAX_ALSA */ -#ifdef CELLIAX_PORTAUDIO - ret = celliax_portaudio_write(p, f); -#endif /* CELLIAX_PORTAUDIO */ - - return ret; -} - -/*! \brief read an audio frame and tell if is "voice" (interpreted as incoming RING) */ -int celliax_sound_monitor(struct celliax_pvt *p) -{ - struct ast_frame *f; - f = celliax_sound_read(p); - if (f) { - f = celliax_sound_dsp_analize(p, f, p->dsp_silence_threshold); - if (f) { - if (f->frametype == AST_FRAME_VOICE) { - DEBUGA_SOUND("VOICE\n", CELLIAX_P_LOG); - return CALLFLOW_INCOMING_RING; - } else { - return AST_STATE_DOWN; - } - } - } - return -1; -} - -/*! - * \brief This thread runs during a call, and monitor the interface serial port for signaling, like hangup, caller id, etc - * - */ -void *celliax_do_controldev_thread(void *data) -{ - struct celliax_pvt *p = data; - int res; - - DEBUGA_SERIAL("In celliax_do_controldev_thread: started, p=%p\n", CELLIAX_P_LOG, p); - - if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { - ERRORA("Unable to set cancel type to deferred\n", CELLIAX_P_LOG); - return NULL; - } - - while (1) { - int rt; - time_t now_timestamp; - - if (p->controldevprotocol == PROTOCOL_NO_SERIAL) { - while (1) { - usleep(10000); - pthread_testcancel(); - } - } -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) { - usleep(p->cvm_celliax_serial_delay * 1000); //to get msecs - } else { - usleep(1000); - } - -#else - usleep(1000); -#endif /* CELLIAX_CVM */ - - pthread_testcancel(); - /* do not read from a dead controldev */ - if (p->controldev_dead) { - DEBUGA_SERIAL("celliax_do_controldev_thread: device %s is dead\n", CELLIAX_P_LOG, - p->controldevice_name); - if (p->owner) - celliax_queue_control(p->owner, AST_CONTROL_HANGUP); - return NULL; - } else { - pthread_testcancel(); - res = celliax_serial_read(p); - pthread_testcancel(); - if (res == -1) { - p->controldev_dead = 1; - close(p->controldevfd); - ERRORA("serial read failed, declaring %s dead\n", CELLIAX_P_LOG, - p->controldevice_name); - } - } - - pthread_testcancel(); - time(&now_timestamp); - if ((now_timestamp - p->celliax_serial_synced_timestamp) > p->celliax_serial_synced_timestamp && !p->controldev_dead) { //TODO find a sensible period. 5min? in config? - DEBUGA_SERIAL("Syncing Serial\n", CELLIAX_P_LOG); - pthread_testcancel(); - rt = celliax_serial_sync(p); - pthread_testcancel(); - if (rt) { - p->controldev_dead = 1; - close(p->controldevfd); - ERRORA("serial sync failed, declaring %s dead\n", CELLIAX_P_LOG, - p->controldevice_name); - } - pthread_testcancel(); - rt = celliax_serial_getstatus(p); - pthread_testcancel(); - if (rt) { - p->controldev_dead = 1; - close(p->controldevfd); - ERRORA("serial getstatus failed, declaring %s dead\n", CELLIAX_P_LOG, - p->controldevice_name); - } - - } - pthread_testcancel(); - } - return NULL; - -} - -int celliax_serial_init(struct celliax_pvt *p, speed_t controldevice_speed) -{ - int fd; - int rt; - struct termios tp; - -/* if there is a file descriptor, close it. But it is probably just an old value, so don't check for close success*/ - fd = p->controldevfd; - if (fd) { - close(fd); - } -/* open the serial port */ -#ifdef __CYGWIN__ - fd = open(p->controldevice_name, O_RDWR | O_NOCTTY | O_NONBLOCK); - sleep(1); - close(fd); -#endif /* __CYGWIN__ */ - fd = open(p->controldevice_name, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (fd == -1) { - DEBUGA_SERIAL("serial error: %s\n", CELLIAX_P_LOG, strerror(errno)); - p->controldevfd = fd; - return -1; - } -/* flush it */ - rt = tcflush(fd, TCIFLUSH); - if (rt == -1) { - ERRORA("serial error: %s", CELLIAX_P_LOG, strerror(errno)); - } -/* attributes */ - tp.c_cflag = B0 | CS8 | CLOCAL | CREAD | HUPCL; - tp.c_iflag = IGNPAR; - tp.c_cflag &= ~CRTSCTS; - tp.c_oflag = 0; - tp.c_lflag = 0; - tp.c_cc[VMIN] = 1; - tp.c_cc[VTIME] = 0; -/* set controldevice_speed */ - rt = cfsetispeed(&tp, p->controldevice_speed); - if (rt == -1) { - ERRORA("serial error: %s", CELLIAX_P_LOG, strerror(errno)); - } - rt = cfsetospeed(&tp, p->controldevice_speed); - if (rt == -1) { - ERRORA("serial error: %s", CELLIAX_P_LOG, strerror(errno)); - } -/* set port attributes */ - if (tcsetattr(fd, TCSADRAIN, &tp) == -1) { - ERRORA("serial error: %s", CELLIAX_P_LOG, strerror(errno)); - } - rt = tcsetattr(fd, TCSANOW, &tp); - if (rt == -1) { - ERRORA("serial error: %s", CELLIAX_P_LOG, strerror(errno)); - } - unsigned int status = 0; -#ifndef __CYGWIN__ - ioctl(fd, TIOCMGET, &status); - status |= TIOCM_DTR; /* Set DTR high */ - status &= ~TIOCM_RTS; /* Set RTS low */ - ioctl(fd, TIOCMSET, &status); - ioctl(fd, TIOCMGET, &status); - unsigned int flags = TIOCM_DTR; - ioctl(fd, TIOCMBIS, &flags); - flags = TIOCM_RTS; - ioctl(fd, TIOCMBIC, &flags); - ioctl(fd, TIOCMGET, &status); -#else /* __CYGWIN__ */ - ioctl(fd, TIOCMGET, &status); - status |= TIOCM_DTR; /* Set DTR high */ - status &= ~TIOCM_RTS; /* Set RTS low */ - ioctl(fd, TIOCMSET, &status); -#endif /* __CYGWIN__ */ - p->controldevfd = fd; - DEBUGA_SERIAL("Syncing Serial\n", CELLIAX_P_LOG); - rt = celliax_serial_sync(p); - if (rt == -1) { - ERRORA("Serial init error\n", CELLIAX_P_LOG); - return -1; - } - return (fd); -} - -int celliax_serial_sync(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_sync_AT(p); -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_sync_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_sync_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - - return -1; -} - -int celliax_serial_getstatus(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_getstatus_AT(p); -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_getstatus_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ - -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_getstatus_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - return -1; -} - -int celliax_serial_read(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_read_AT(p, 0, 100000, 0, NULL, 1); // a 10th of a second timeout -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_read_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_read_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - return -1; -} - -int celliax_serial_hangup(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_hangup_AT(p); -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_hangup_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_hangup_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - return -1; -} - -int celliax_serial_answer(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_answer_AT(p); -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_answer_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_answer_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - return -1; -} - -int celliax_serial_config(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_config_AT(p); -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_config_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_config_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - return -1; -} - -int celliax_serial_monitor(struct celliax_pvt *p) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_read_AT(p, 0, 100000, 0, NULL, 1); // a 10th of a second timeout -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_read_FBUS2(p); -#endif /* CELLIAX_FBUS2 */ -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_read_CVM_BUSMAIL(p); -#endif /* CELLIAX_CVM */ - return -1; -} - -/************************************************/ - -/* LUIGI RIZZO's magic */ -/* - * store the boost factor - */ -#ifdef ASTERISK_VERSION_1_6_0 -void celliax_store_boost(const char *s, double *boost) -#else -void celliax_store_boost(char *s, double *boost) -#endif /* ASTERISK_VERSION_1_6_0 */ -{ - struct celliax_pvt *p = NULL; - - if (sscanf(s, "%lf", boost) != 1) { - ERRORA("invalid boost <%s>\n", CELLIAX_P_LOG, s); - return; - } - if (*boost < -BOOST_MAX) { - WARNINGA("boost %s too small, using %d\n", CELLIAX_P_LOG, s, -BOOST_MAX); - *boost = -BOOST_MAX; - } else if (*boost > BOOST_MAX) { - WARNINGA("boost %s too large, using %d\n", CELLIAX_P_LOG, s, BOOST_MAX); - *boost = BOOST_MAX; - } - *boost = exp(log(10) * *boost / 20) * BOOST_SCALE; - if (option_debug > 1) - DEBUGA_SOUND("setting boost %s to %f\n", CELLIAX_P_LOG, s, *boost); -} - -int celliax_serial_call(struct celliax_pvt *p, char *dstr) -{ - if (p->controldevprotocol == PROTOCOL_AT) - return celliax_serial_call_AT(p, dstr); -#ifdef CELLIAX_FBUS2 - if (p->controldevprotocol == PROTOCOL_FBUS2) - return celliax_serial_call_FBUS2(p, dstr); -#endif /* CELLIAX_FBUS2 */ - if (p->controldevprotocol == PROTOCOL_NO_SERIAL) - return 0; -#ifdef CELLIAX_CVM - if (p->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return celliax_serial_call_CVM_BUSMAIL(p, dstr); -#endif /* CELLIAX_CVM */ - return -1; -} - -/* - * returns a pointer to the descriptor with the given name - */ -struct celliax_pvt *celliax_console_find_desc(char *dev) -{ - struct celliax_pvt *p; - - for (p = celliax_iflist; p && strcmp(p->name, dev) != 0; p = p->next); - if (p == NULL) - WARNINGA("could not find <%s>\n", CELLIAX_P_LOG, dev); - - return p; -} - -int celliax_console_playback_boost(int fd, int argc, char *argv[]) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - if (argc > 2) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" celliax_console for playback_boost, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - - if (argc == 1) { - ast_cli(fd, "playback_boost on the active celliax_console, that is [%s], is: %5.1f\n", - celliax_console_active, - 20 * log10(((double) p->playback_boost / (double) BOOST_SCALE))); - } else if (argc == 2) { - celliax_store_boost(argv[1], &p->playback_boost); - - ast_cli(fd, - "playback_boost on the active celliax_console, that is [%s], is now: %5.1f\n", - celliax_console_active, - 20 * log10(((double) p->playback_boost / (double) BOOST_SCALE))); - } - - return RESULT_SUCCESS; -} - -int celliax_console_capture_boost(int fd, int argc, char *argv[]) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - if (argc > 2) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" celliax_console for capture_boost, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - - if (argc == 1) { - ast_cli(fd, "capture_boost on the active celliax_console, that is [%s], is: %5.1f\n", - celliax_console_active, - 20 * log10(((double) p->capture_boost / (double) BOOST_SCALE))); - } else if (argc == 2) { - celliax_store_boost(argv[1], &p->capture_boost); - - ast_cli(fd, - "capture_boost on the active celliax_console, that is [%s], is now: %5.1f\n", - celliax_console_active, - 20 * log10(((double) p->capture_boost / (double) BOOST_SCALE))); - } - - return RESULT_SUCCESS; -} - -int celliax_console_echo(int fd, int argc, char *argv[]) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - if (argc != 3 && argc != 1) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" celliax_console for celliax_echo, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - - if (argc == 1) { - ast_cli(fd, - "On the active celliax_console, that is [%s], speexecho and speexpreprocess are: %d and %d\n", - celliax_console_active, p->speexecho, p->speexpreprocess); - } else if (argc == 3) { - sscanf(argv[1], "%d", &p->speexecho); - sscanf(argv[2], "%d", &p->speexpreprocess); - ast_cli(fd, - "On the active celliax_console, that is [%s], speexecho and speexpreprocess are NOW: %d and %d\n", - celliax_console_active, p->speexecho, p->speexpreprocess); - } - - return RESULT_SUCCESS; -} - -#ifndef ASTERISK_VERSION_1_6_0 -int celliax_console_hangup(int fd, int argc, char *argv[]) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - if (argc != 1) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" celliax_console for hanging up, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - if (!p->owner) { - ast_cli(fd, "No call to hangup on the active celliax_console, that is [%s]\n", - celliax_console_active); - return RESULT_FAILURE; - } - if (p->owner) - ast_queue_hangup(p->owner); - return RESULT_SUCCESS; -} -#else /* ASTERISK_VERSION_1_6_0 */ -char *celliax_console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) -{ - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - - switch (cmd) { - case CLI_INIT: - e->command = "celliax hangup"; - e->usage = - "Usage: celliax hangup\n" - " Hangup a call on the celliax channel.\n"; - - return NULL; - case CLI_GENERATE: - return NULL; - } - - if (a->argc != 2) - return CLI_SHOWUSAGE; - if (!p) { - ast_cli(a->fd, - "No \"current\" celliax_console for hanging up, please enter 'help celliax_console'\n"); - return CLI_SUCCESS; - } - if (!p->owner) { - ast_cli(a->fd, "No call to hangup on the active celliax_console, that is [%s]\n", - celliax_console_active); - return CLI_FAILURE; - } - if (p->owner) - ast_queue_hangup(p->owner); - return CLI_SUCCESS; -} - -#endif /* ASTERISK_VERSION_1_6_0 */ -int celliax_console_sendsms(int fd, int argc, char *argv[]) -{ - char *s = NULL; - char *s1 = NULL; - char command[512]; - - if (argc != 3) - return RESULT_SHOWUSAGE; - - s = argv[1]; - s1 = argv[2]; - - memset(command, 0, sizeof(command)); - - sprintf(command, "%s|%s|", s, s1); - - celliax_sendsms(NULL, (void *) &command); - - return RESULT_SUCCESS; -} - -int celliax_console_dial(int fd, int argc, char *argv[]) -{ - char *s = NULL; - struct celliax_pvt *p = celliax_console_find_desc(celliax_console_active); - - if (argc != 2) - return RESULT_SHOWUSAGE; - if (!p) { - ast_cli(fd, - "No \"current\" celliax_console for dialing, please enter 'help celliax_console'\n"); - return RESULT_SUCCESS; - } - - if (p->owner) { /* already in a call */ - int i; - struct ast_frame f = { AST_FRAME_DTMF, 0 }; - - s = argv[1]; - /* send the string one char at a time */ - for (i = 0; i < strlen(s); i++) { - f.subclass = s[i]; - ast_queue_frame(p->owner, &f); - } - return RESULT_SUCCESS; - } else - ast_cli(fd, - "No call in which to dial on the \"current\" celliax_console, that is [%s]\n", - celliax_console_active); - if (s) - free(s); - return RESULT_SUCCESS; -} - -int celliax_console_set_active(int fd, int argc, char *argv[]) -{ - if (argc == 1) - ast_cli(fd, - "\"current\" celliax_console is [%s]\n Enter 'celliax_console show' to see the available interfaces.\n Enter 'celliax_console interfacename' to change the \"current\" celliax_console.\n", - celliax_console_active); - else if (argc != 2) - return RESULT_SHOWUSAGE; - else { - struct celliax_pvt *p; - if (strcmp(argv[1], "show") == 0) { - ast_cli(fd, "Available interfaces:\n"); - for (p = celliax_iflist; p; p = p->next) - ast_cli(fd, " [%s]\n", p->name); - return RESULT_SUCCESS; - } - p = celliax_console_find_desc(argv[1]); - if (p == NULL) - ast_cli(fd, "Interface [%s] do not exists!\n", argv[1]); - else { - celliax_console_active = p->name; - ast_cli(fd, "\"current\" celliax_console is now: [%s]\n", argv[1]); - } - } - return RESULT_SUCCESS; -} - -int celliax_console_celliax(int fd, int argc, char *argv[]) -{ - return RESULT_SHOWUSAGE; -} - -#ifdef ASTERISK_VERSION_1_4 -#ifndef AST_MODULE -#define AST_MODULE "chan_celliax" -#endif -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Celliax, Audio-Serial Driver"); -#endif /* ASTERISK_VERSION_1_4 */ diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/ciapalo b/src/mod/endpoints/mod_gsmopen/asterisk/ciapalo deleted file mode 100755 index aa9ea7f4dd..0000000000 --- a/src/mod/endpoints/mod_gsmopen/asterisk/ciapalo +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/perl -open(FILEOUT, ">> /tmp/smses_received"); -while(<>){ - print FILEOUT $_ ; - printf FILEOUT "\n" ; -} -close(FILEOUT); - diff --git a/src/mod/endpoints/mod_gsmopen/configs/gsmopen.conf.xml b/src/mod/endpoints/mod_gsmopen/configs/gsmopen.conf.xml deleted file mode 100644 index 0647f53168..0000000000 --- a/src/mod/endpoints/mod_gsmopen/configs/gsmopen.conf.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/Makefile b/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/Makefile deleted file mode 100644 index f87fe778f5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Comment/uncomment the following line to disable/enable debugging -#DEBUG = y -#LDDINC= - -# Add your debugging flag (or not) to CFLAGS -ifeq ($(DEBUG),y) - DEBFLAGS = -O -g -DSKYPOPEN_DEBUG # "-O" is needed to expand inlines -else - DEBFLAGS = -O2 -Wall -endif - -EXTRA_CFLAGS += $(DEBFLAGS) -EXTRA_CFLAGS += -I$(LDDINC) - -ifneq ($(KERNELRELEASE),) -# call from kernel build system - -option-objs := main.o - -obj-m := option.o - -else - -KERNELDIR ?= /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) - -modules: - $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules - -endif - - - -clean: - rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers - -depend .depend dep: - $(CC) $(EXTRA_CFLAGS) -M *.c > .depend - - -ifeq (.depend,$(wildcard .depend)) -include .depend -endif diff --git a/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/README b/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/README deleted file mode 100644 index c89411760d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/README +++ /dev/null @@ -1,9 +0,0 @@ -On kernels < 2.6.34 the option modem driver, needed by your dongle, is unstable. - -In this directory you can build an option.ko module for kernels 2.6.32.* (eg: Proxmox, OpenVZ) and 2.6.34.* - -To install it: - -make clean ; make -cp /lib/modules/$(uname -r)/kernel/drivers/usb/serial/option.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/option.ko-backup -cp option.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ diff --git a/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/main.c b/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/main.c deleted file mode 100644 index c626fdaeec..0000000000 --- a/src/mod/endpoints/mod_gsmopen/driver_usb_dongle/main.c +++ /dev/null @@ -1,1817 +0,0 @@ -/* - USB Driver for GSM modems - - Copyright (C) 2005 Matthias Urlichs - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions copied from the Keyspan driver by Hugh Blemings - - History: see the git log. - - Work sponsored by: Sigos GmbH, Germany - - This driver exists because the "normal" serial driver doesn't work too well - with GSM modems. Issues: - - data loss -- one single Receive URB is not nearly enough - - nonstandard flow (Option devices) control - - controlling the baud rate doesn't make sense - - This driver is named "option" because the most common device it's - used for is a PC-Card (with an internal OHCI-USB interface, behind - which the GSM interface sits), made by Option Inc. - - Some of the "one port" devices actually exhibit multiple USB instances - on the USB bus. This is not a bug, these ports are used for different - device features. -*/ - -#define DRIVER_VERSION "v0.7.2" -#define DRIVER_AUTHOR "Matthias Urlichs " -#define DRIVER_DESC "USB Driver for GSM modems" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Function prototypes */ -static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id); -static int option_open(struct tty_struct *tty, struct usb_serial_port *port); -static void option_close(struct usb_serial_port *port); -static void option_dtr_rts(struct usb_serial_port *port, int on); - -static int option_startup(struct usb_serial *serial); -static void option_disconnect(struct usb_serial *serial); -static void option_release(struct usb_serial *serial); -static int option_write_room(struct tty_struct *tty); - -static void option_instat_callback(struct urb *urb); - -static int option_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static int option_chars_in_buffer(struct tty_struct *tty); -static void option_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static int option_tiocmget(struct tty_struct *tty, struct file *file); -static int option_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); -static int option_send_setup(struct usb_serial_port *port); -#ifdef CONFIG_PM -static int option_suspend(struct usb_serial *serial, pm_message_t message); -static int option_resume(struct usb_serial *serial); -#endif - -/* Vendor and product IDs */ -#define OPTION_VENDOR_ID 0x0AF0 -#define OPTION_PRODUCT_COLT 0x5000 -#define OPTION_PRODUCT_RICOLA 0x6000 -#define OPTION_PRODUCT_RICOLA_LIGHT 0x6100 -#define OPTION_PRODUCT_RICOLA_QUAD 0x6200 -#define OPTION_PRODUCT_RICOLA_QUAD_LIGHT 0x6300 -#define OPTION_PRODUCT_RICOLA_NDIS 0x6050 -#define OPTION_PRODUCT_RICOLA_NDIS_LIGHT 0x6150 -#define OPTION_PRODUCT_RICOLA_NDIS_QUAD 0x6250 -#define OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT 0x6350 -#define OPTION_PRODUCT_COBRA 0x6500 -#define OPTION_PRODUCT_COBRA_BUS 0x6501 -#define OPTION_PRODUCT_VIPER 0x6600 -#define OPTION_PRODUCT_VIPER_BUS 0x6601 -#define OPTION_PRODUCT_GT_MAX_READY 0x6701 -#define OPTION_PRODUCT_FUJI_MODEM_LIGHT 0x6721 -#define OPTION_PRODUCT_FUJI_MODEM_GT 0x6741 -#define OPTION_PRODUCT_FUJI_MODEM_EX 0x6761 -#define OPTION_PRODUCT_KOI_MODEM 0x6800 -#define OPTION_PRODUCT_SCORPION_MODEM 0x6901 -#define OPTION_PRODUCT_ETNA_MODEM 0x7001 -#define OPTION_PRODUCT_ETNA_MODEM_LITE 0x7021 -#define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 -#define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 -#define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 -#define OPTION_PRODUCT_GTM380_MODEM 0x7201 - -#define HUAWEI_VENDOR_ID 0x12D1 -#define HUAWEI_PRODUCT_E600 0x1001 -#define HUAWEI_PRODUCT_E220 0x1003 -#define HUAWEI_PRODUCT_E220BIS 0x1004 -#define HUAWEI_PRODUCT_E1401 0x1401 -#define HUAWEI_PRODUCT_E1402 0x1402 -#define HUAWEI_PRODUCT_E1403 0x1403 -#define HUAWEI_PRODUCT_E1404 0x1404 -#define HUAWEI_PRODUCT_E1405 0x1405 -#define HUAWEI_PRODUCT_E1406 0x1406 -#define HUAWEI_PRODUCT_E1407 0x1407 -#define HUAWEI_PRODUCT_E1408 0x1408 -#define HUAWEI_PRODUCT_E1409 0x1409 -#define HUAWEI_PRODUCT_E140A 0x140A -#define HUAWEI_PRODUCT_E140B 0x140B -#define HUAWEI_PRODUCT_E140C 0x140C -#define HUAWEI_PRODUCT_E140D 0x140D -#define HUAWEI_PRODUCT_E140E 0x140E -#define HUAWEI_PRODUCT_E140F 0x140F -#define HUAWEI_PRODUCT_E1410 0x1410 -#define HUAWEI_PRODUCT_E1411 0x1411 -#define HUAWEI_PRODUCT_E1412 0x1412 -#define HUAWEI_PRODUCT_E1413 0x1413 -#define HUAWEI_PRODUCT_E1414 0x1414 -#define HUAWEI_PRODUCT_E1415 0x1415 -#define HUAWEI_PRODUCT_E1416 0x1416 -#define HUAWEI_PRODUCT_E1417 0x1417 -#define HUAWEI_PRODUCT_E1418 0x1418 -#define HUAWEI_PRODUCT_E1419 0x1419 -#define HUAWEI_PRODUCT_E141A 0x141A -#define HUAWEI_PRODUCT_E141B 0x141B -#define HUAWEI_PRODUCT_E141C 0x141C -#define HUAWEI_PRODUCT_E141D 0x141D -#define HUAWEI_PRODUCT_E141E 0x141E -#define HUAWEI_PRODUCT_E141F 0x141F -#define HUAWEI_PRODUCT_E1420 0x1420 -#define HUAWEI_PRODUCT_E1421 0x1421 -#define HUAWEI_PRODUCT_E1422 0x1422 -#define HUAWEI_PRODUCT_E1423 0x1423 -#define HUAWEI_PRODUCT_E1424 0x1424 -#define HUAWEI_PRODUCT_E1425 0x1425 -#define HUAWEI_PRODUCT_E1426 0x1426 -#define HUAWEI_PRODUCT_E1427 0x1427 -#define HUAWEI_PRODUCT_E1428 0x1428 -#define HUAWEI_PRODUCT_E1429 0x1429 -#define HUAWEI_PRODUCT_E142A 0x142A -#define HUAWEI_PRODUCT_E142B 0x142B -#define HUAWEI_PRODUCT_E142C 0x142C -#define HUAWEI_PRODUCT_E142D 0x142D -#define HUAWEI_PRODUCT_E142E 0x142E -#define HUAWEI_PRODUCT_E142F 0x142F -#define HUAWEI_PRODUCT_E1430 0x1430 -#define HUAWEI_PRODUCT_E1431 0x1431 -#define HUAWEI_PRODUCT_E1432 0x1432 -#define HUAWEI_PRODUCT_E1433 0x1433 -#define HUAWEI_PRODUCT_E1434 0x1434 -#define HUAWEI_PRODUCT_E1435 0x1435 -#define HUAWEI_PRODUCT_E1436 0x1436 -#define HUAWEI_PRODUCT_E1437 0x1437 -#define HUAWEI_PRODUCT_E1438 0x1438 -#define HUAWEI_PRODUCT_E1439 0x1439 -#define HUAWEI_PRODUCT_E143A 0x143A -#define HUAWEI_PRODUCT_E143B 0x143B -#define HUAWEI_PRODUCT_E143C 0x143C -#define HUAWEI_PRODUCT_E143D 0x143D -#define HUAWEI_PRODUCT_E143E 0x143E -#define HUAWEI_PRODUCT_E143F 0x143F -#define HUAWEI_PRODUCT_K4505 0x1464 -#define HUAWEI_PRODUCT_K3765 0x1465 -#define HUAWEI_PRODUCT_E14AC 0x14AC -#define HUAWEI_PRODUCT_ETS1220 0x1803 - -#define QUANTA_VENDOR_ID 0x0408 -#define QUANTA_PRODUCT_Q101 0xEA02 -#define QUANTA_PRODUCT_Q111 0xEA03 -#define QUANTA_PRODUCT_GLX 0xEA04 -#define QUANTA_PRODUCT_GKE 0xEA05 -#define QUANTA_PRODUCT_GLE 0xEA06 - -#define NOVATELWIRELESS_VENDOR_ID 0x1410 - -/* YISO PRODUCTS */ - -#define YISO_VENDOR_ID 0x0EAB -#define YISO_PRODUCT_U893 0xC893 - -/* MERLIN EVDO PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_V640 0x1100 -#define NOVATELWIRELESS_PRODUCT_V620 0x1110 -#define NOVATELWIRELESS_PRODUCT_V740 0x1120 -#define NOVATELWIRELESS_PRODUCT_V720 0x1130 - -/* MERLIN HSDPA/HSPA PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_U730 0x1400 -#define NOVATELWIRELESS_PRODUCT_U740 0x1410 -#define NOVATELWIRELESS_PRODUCT_U870 0x1420 -#define NOVATELWIRELESS_PRODUCT_XU870 0x1430 -#define NOVATELWIRELESS_PRODUCT_X950D 0x1450 - -/* EXPEDITE PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_EV620 0x2100 -#define NOVATELWIRELESS_PRODUCT_ES720 0x2110 -#define NOVATELWIRELESS_PRODUCT_E725 0x2120 -#define NOVATELWIRELESS_PRODUCT_ES620 0x2130 -#define NOVATELWIRELESS_PRODUCT_EU730 0x2400 -#define NOVATELWIRELESS_PRODUCT_EU740 0x2410 -#define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 - -/* OVATION PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_MC727 0x4100 -#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 -#define NOVATELWIRELESS_PRODUCT_U727 0x5010 -#define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 -#define NOVATELWIRELESS_PRODUCT_MC760 0x6000 -#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 - -/* FUTURE NOVATEL PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 -#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 -#define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 - -/* AMOI PRODUCTS */ -#define AMOI_VENDOR_ID 0x1614 -#define AMOI_PRODUCT_H01 0x0800 -#define AMOI_PRODUCT_H01A 0x7002 -#define AMOI_PRODUCT_H02 0x0802 -#define AMOI_PRODUCT_SKYPEPHONE_S2 0x0407 - -#define DELL_VENDOR_ID 0x413C - -/* Dell modems */ -#define DELL_PRODUCT_5700_MINICARD 0x8114 -#define DELL_PRODUCT_5500_MINICARD 0x8115 -#define DELL_PRODUCT_5505_MINICARD 0x8116 -#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 -#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 - -#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 -#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 - -#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 -#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 -#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 -#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 - -#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 -#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 -#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 - -#define KYOCERA_VENDOR_ID 0x0c88 -#define KYOCERA_PRODUCT_KPC650 0x17da -#define KYOCERA_PRODUCT_KPC680 0x180a - -#define ANYDATA_VENDOR_ID 0x16d5 -#define ANYDATA_PRODUCT_ADU_620UW 0x6202 -#define ANYDATA_PRODUCT_ADU_E100A 0x6501 -#define ANYDATA_PRODUCT_ADU_500A 0x6502 - -#define AXESSTEL_VENDOR_ID 0x1726 -#define AXESSTEL_PRODUCT_MV110H 0x1000 - -#define BANDRICH_VENDOR_ID 0x1A8D -#define BANDRICH_PRODUCT_C100_1 0x1002 -#define BANDRICH_PRODUCT_C100_2 0x1003 -#define BANDRICH_PRODUCT_1004 0x1004 -#define BANDRICH_PRODUCT_1005 0x1005 -#define BANDRICH_PRODUCT_1006 0x1006 -#define BANDRICH_PRODUCT_1007 0x1007 -#define BANDRICH_PRODUCT_1008 0x1008 -#define BANDRICH_PRODUCT_1009 0x1009 -#define BANDRICH_PRODUCT_100A 0x100a - -#define BANDRICH_PRODUCT_100B 0x100b -#define BANDRICH_PRODUCT_100C 0x100c -#define BANDRICH_PRODUCT_100D 0x100d -#define BANDRICH_PRODUCT_100E 0x100e - -#define BANDRICH_PRODUCT_100F 0x100f -#define BANDRICH_PRODUCT_1010 0x1010 -#define BANDRICH_PRODUCT_1011 0x1011 -#define BANDRICH_PRODUCT_1012 0x1012 - -#define AMOI_VENDOR_ID 0x1614 -#define AMOI_PRODUCT_9508 0x0800 - -#define QUALCOMM_VENDOR_ID 0x05C6 - -#define CMOTECH_VENDOR_ID 0x16d8 -#define CMOTECH_PRODUCT_6008 0x6008 -#define CMOTECH_PRODUCT_6280 0x6280 - -#define TELIT_VENDOR_ID 0x1bc7 -#define TELIT_PRODUCT_UC864E 0x1003 -#define TELIT_PRODUCT_UC864G 0x1004 - -/* ZTE PRODUCTS */ -#define ZTE_VENDOR_ID 0x19d2 -#define ZTE_PRODUCT_MF622 0x0001 -#define ZTE_PRODUCT_MF628 0x0015 -#define ZTE_PRODUCT_MF626 0x0031 -#define ZTE_PRODUCT_CDMA_TECH 0xfffe -#define ZTE_PRODUCT_AC8710 0xfff1 -#define ZTE_PRODUCT_AC2726 0xfff5 -#define ZTE_PRODUCT_AC8710T 0xffff - -/* ZTE PRODUCTS -- alternate vendor ID */ -#define ZTE_VENDOR_ID2 0x1d6b -#define ZTE_PRODUCT_MF_330 0x0002 - -#define BENQ_VENDOR_ID 0x04a5 -#define BENQ_PRODUCT_H10 0x4068 - -#define DLINK_VENDOR_ID 0x1186 -#define DLINK_PRODUCT_DWM_652 0x3e04 -#define DLINK_PRODUCT_DWM_652_U5 0xce16 -#define DLINK_PRODUCT_DWM_652_U5A 0xce1e - -#define QISDA_VENDOR_ID 0x1da5 -#define QISDA_PRODUCT_H21_4512 0x4512 -#define QISDA_PRODUCT_H21_4523 0x4523 -#define QISDA_PRODUCT_H20_4515 0x4515 -#define QISDA_PRODUCT_H20_4518 0x4518 -#define QISDA_PRODUCT_H20_4519 0x4519 - -/* TLAYTECH PRODUCTS */ -#define TLAYTECH_VENDOR_ID 0x20B9 -#define TLAYTECH_PRODUCT_TEU800 0x1682 - -/* TOSHIBA PRODUCTS */ -#define TOSHIBA_VENDOR_ID 0x0930 -#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 -#define TOSHIBA_PRODUCT_G450 0x0d45 - -#define ALINK_VENDOR_ID 0x1e0e -#define ALINK_PRODUCT_3GU 0x9200 - -/* ALCATEL PRODUCTS */ -#define ALCATEL_VENDOR_ID 0x1bbb -#define ALCATEL_PRODUCT_X060S 0x0000 - -#define PIRELLI_VENDOR_ID 0x1266 -#define PIRELLI_PRODUCT_C100_1 0x1002 -#define PIRELLI_PRODUCT_C100_2 0x1003 -#define PIRELLI_PRODUCT_1004 0x1004 -#define PIRELLI_PRODUCT_1005 0x1005 -#define PIRELLI_PRODUCT_1006 0x1006 -#define PIRELLI_PRODUCT_1007 0x1007 -#define PIRELLI_PRODUCT_1008 0x1008 -#define PIRELLI_PRODUCT_1009 0x1009 -#define PIRELLI_PRODUCT_100A 0x100a -#define PIRELLI_PRODUCT_100B 0x100b -#define PIRELLI_PRODUCT_100C 0x100c -#define PIRELLI_PRODUCT_100D 0x100d -#define PIRELLI_PRODUCT_100E 0x100e -#define PIRELLI_PRODUCT_100F 0x100f -#define PIRELLI_PRODUCT_1011 0x1011 -#define PIRELLI_PRODUCT_1012 0x1012 - -/* Airplus products */ -#define AIRPLUS_VENDOR_ID 0x1011 -#define AIRPLUS_PRODUCT_MCD650 0x3198 - -/* Longcheer/Longsung vendor ID; makes whitelabel devices that - * many other vendors like 4G Systems, Alcatel, ChinaBird, - * Mobidata, etc sell under their own brand names. - */ -#define LONGCHEER_VENDOR_ID 0x1c9e - -/* 4G Systems products */ -/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick * - * It seems to contain a Qualcomm QSC6240/6290 chipset */ -#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 - -/* Haier products */ -#define HAIER_VENDOR_ID 0x201e -#define HAIER_PRODUCT_CE100 0x2009 - -/* Cinterion (formerly Siemens) products */ -#define SIEMENS_VENDOR_ID 0x0681 -#define CINTERION_VENDOR_ID 0x1e2d -#define CINTERION_PRODUCT_HC25_MDM 0x0047 -#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 -#define CINTERION_PRODUCT_HC28_MDM 0x004C -#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ -#define CINTERION_PRODUCT_EU3_E 0x0051 -#define CINTERION_PRODUCT_EU3_P 0x0052 -#define CINTERION_PRODUCT_PH8 0x0053 - -/* Olivetti products */ -#define OLIVETTI_VENDOR_ID 0x0b3c -#define OLIVETTI_PRODUCT_OLICARD100 0xc000 - -/* Celot products */ -#define CELOT_VENDOR_ID 0x211f -#define CELOT_PRODUCT_CT680M 0x6801 - -/* ONDA Communication vendor id */ -#define ONDA_VENDOR_ID 0x1ee8 - -/* ONDA MT825UP HSDPA 14.2 modem */ -#define ONDA_MT825UP 0x000b - -/* Samsung products */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_GT_B3730 0x6889 - -/* some devices interfaces need special handling due to a number of reasons */ -enum option_blacklist_reason { - OPTION_BLACKLIST_NONE = 0, - OPTION_BLACKLIST_SENDSETUP = 1, - OPTION_BLACKLIST_RESERVED_IF = 2 -}; - -struct option_blacklist_info { - const u32 infolen; /* number of interface numbers on blacklist */ - const u8 *ifaceinfo; /* pointer to the array holding the numbers */ - enum option_blacklist_reason reason; -}; - -static const u8 four_g_w14_no_sendsetup[] = { 0, 1 }; -static const struct option_blacklist_info four_g_w14_blacklist = { - .infolen = ARRAY_SIZE(four_g_w14_no_sendsetup), - .ifaceinfo = four_g_w14_no_sendsetup, - .reason = OPTION_BLACKLIST_SENDSETUP -}; - -static const struct usb_device_id option_ids[] = { - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA_BUS) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, /* Novatel Merlin V720/S720/PC720 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, /* Novatel U730/U740 (VF version) */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, /* Novatel U740 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, /* Novatel U870 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, /* Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, /* Novatel X950D */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, /* Novatel Merlin ES620 SM Bus */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727_NEW) }, /* Novatel MC727/U727/USB727 refresh */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ - - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_SKYPEPHONE_S2) }, - - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, - { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, - { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) }, - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0006, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0007, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0008, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0009, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000a, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000b, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000c, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000d, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000e, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) }, - /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) }, - /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0079, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0082, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1060, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1061, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1062, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1063, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1064, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1065, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1066, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1067, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1068, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1069, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1070, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1071, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1072, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1073, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1074, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1075, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1076, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1077, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1078, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1079, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1080, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1081, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1082, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1083, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1084, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1085, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1086, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1087, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1088, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1089, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1090, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1091, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1092, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1093, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1095, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1096, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1097, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1098, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1099, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1100, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1101, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1102, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1103, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1104, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1105, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1106, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1107, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1108, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1109, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1110, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1111, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1112, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1113, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1114, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1115, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1116, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1118, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1119, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1120, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1121, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1123, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1124, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1125, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1126, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1127, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1128, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1129, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1130, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1131, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1132, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1133, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1134, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1135, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1136, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1137, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1138, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1139, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1140, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1141, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1142, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1143, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1144, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1145, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1146, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1147, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1148, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1149, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1150, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1151, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1153, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1154, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1155, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1156, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1157, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1158, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1159, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1160, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1161, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1162, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1163, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1164, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1165, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1166, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1167, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1168, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1260, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1261, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1262, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1263, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1264, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1265, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1266, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1274, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1275, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1276, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1277, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1278, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1279, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1280, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1281, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1282, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1283, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1284, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1285, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1286, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1287, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1288, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1289, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1290, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1291, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1292, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1293, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1294, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1295, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1296, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1297, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, - { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) }, - { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, - { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, - { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ - { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4518) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, - { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, - { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ - { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, - { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, - { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, - { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, - { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), - .driver_info = (kernel_ulong_t)&four_g_w14_blacklist - }, - { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, - /* Pirelli */ - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, - /* Cinterion */ - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - - { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, - { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ - { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ - { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730/GT-B3710 LTE USB modem.*/ - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, option_ids); - -static struct usb_driver option_driver = { - .name = "option", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, -#ifdef CONFIG_PM - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .supports_autosuspend = 1, -#endif - .id_table = option_ids, - .no_dynamic_id = 1, -}; - -/* The card has three separate interfaces, which the serial driver - * recognizes separately, thus num_port=1. - */ - -static struct usb_serial_driver option_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "option1", - }, - .description = "GSM modem (1-port)", - .usb_driver = &option_driver, - .id_table = option_ids, - .num_ports = 1, - .probe = option_probe, - .open = option_open, - .close = option_close, - .dtr_rts = option_dtr_rts, - .write = option_write, - .write_room = option_write_room, - .chars_in_buffer = option_chars_in_buffer, - .set_termios = option_set_termios, - .tiocmget = option_tiocmget, - .tiocmset = option_tiocmset, - .attach = option_startup, - .disconnect = option_disconnect, - .release = option_release, - .read_int_callback = option_instat_callback, -#ifdef CONFIG_PM - .suspend = option_suspend, - .resume = option_resume, -#endif -}; - -static int debug; - -/* per port private data */ - -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 -#define OUT_BUFLEN 4096 - -struct option_intf_private { - spinlock_t susp_lock; - unsigned int suspended:1; - int in_flight; - struct option_blacklist_info *blacklist_info; -}; - -struct option_port_private { - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[N_IN_URB]; - u8 *in_buffer[N_IN_URB]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[N_OUT_URB]; - u8 *out_buffer[N_OUT_URB]; - unsigned long out_busy; /* Bit vector of URBs in use */ - int opened; - struct usb_anchor delayed; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - - unsigned long tx_start_time[N_OUT_URB]; -}; - -/* Functions used by new usb-serial code. */ -static int __init option_init(void) -{ - int retval; - retval = usb_serial_register(&option_1port_device); - if (retval) - goto failed_1port_device_register; - retval = usb_register(&option_driver); - if (retval) - goto failed_driver_register; - - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - - return 0; - -failed_driver_register: - usb_serial_deregister(&option_1port_device); -failed_1port_device_register: - return retval; -} - -static void __exit option_exit(void) -{ - usb_deregister(&option_driver); - usb_serial_deregister(&option_1port_device); -} - -module_init(option_init); -module_exit(option_exit); - -static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct option_intf_private *data; - - /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ - if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && - serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && - serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) - return -ENODEV; - - /* Bandrich modem and AT command interface is 0xff */ - if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || - serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && - serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) - return -ENODEV; - - /* Don't bind network interfaces on Huawei K3765 & K4505 */ - if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && - (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || - serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) && - serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) - return -ENODEV; - - data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; - spin_lock_init(&data->susp_lock); - data->blacklist_info = (struct option_blacklist_info*) id->driver_info; - return 0; -} - -static enum option_blacklist_reason is_blacklisted(const u8 ifnum, - const struct option_blacklist_info *blacklist) -{ - const u8 *info; - int i; - - if (blacklist) { - info = blacklist->ifaceinfo; - - for (i = 0; i < blacklist->infolen; i++) { - if (info[i] == ifnum) - return blacklist->reason; - } - } - return OPTION_BLACKLIST_NONE; -} - -static void option_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - dbg("%s", __func__); - /* Doesn't support option setting */ - tty_termios_copy_hw(tty->termios, old_termios); - option_send_setup(port); -} - -static int option_tiocmget(struct tty_struct *tty, struct file *file) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int value; - struct option_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} - -static int option_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct option_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - /* FIXME: what locks portdata fields ? */ - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return option_send_setup(port); -} - -/* Write */ -static int option_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct option_port_private *portdata; - struct option_intf_private *intfdata; - int i; - int left, todo; - struct urb *this_urb = NULL; /* spurious */ - int err; - unsigned long flags; - - portdata = usb_get_serial_port_data(port); - intfdata = port->serial->private; - - dbg("%s: write (%d chars)", __func__, count); - - i = 0; - left = count; - for (i = 0; left > 0 && i < N_OUT_URB; i++) { - todo = left; - if (todo > OUT_BUFLEN) - todo = OUT_BUFLEN; - - this_urb = portdata->out_urbs[i]; - if (test_and_set_bit(i, &portdata->out_busy)) { - if (time_before(jiffies, - portdata->tx_start_time[i] + 10 * HZ)) - continue; - usb_unlink_urb(this_urb); - continue; - } - dbg("%s: endpoint %d buf %d", __func__, - usb_pipeendpoint(this_urb->pipe), i); - - err = usb_autopm_get_interface_async(port->serial->interface); - if (err < 0) - break; - - /* send the data */ - memcpy(this_urb->transfer_buffer, buf, todo); - this_urb->transfer_buffer_length = todo; - - spin_lock_irqsave(&intfdata->susp_lock, flags); - if (intfdata->suspended) { - usb_anchor_urb(this_urb, &portdata->delayed); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - } else { - intfdata->in_flight++; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err) { - dbg("usb_submit_urb %p (write bulk) failed " - "(%d)", this_urb, err); - clear_bit(i, &portdata->out_busy); - spin_lock_irqsave(&intfdata->susp_lock, flags); - intfdata->in_flight--; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - continue; - } - } - - portdata->tx_start_time[i] = jiffies; - buf += todo; - left -= todo; - } - - count -= left; - dbg("%s: wrote (did %d)", __func__, count); - return count; -} - -static void option_indat_callback(struct urb *urb) -{ - int err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s: %p", __func__, urb); - - endpoint = usb_pipeendpoint(urb->pipe); - port = urb->context; - - if (status) { - dbg("%s: nonzero status: %d on endpoint %02x.", - __func__, status, endpoint); - } else { - tty = tty_port_tty_get(&port->port); - if (urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } else - dbg("%s: empty read urb received", __func__); - tty_kref_put(tty); - - /* Resubmit urb so we continue receiving */ - if (status != -ESHUTDOWN) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -EPERM) - printk(KERN_ERR "%s: resubmit read urb failed. " - "(%d)", __func__, err); - else - usb_mark_last_busy(port->serial->dev); - } - - } - return; -} - -static void option_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct option_port_private *portdata; - struct option_intf_private *intfdata; - int i; - - dbg("%s", __func__); - - port = urb->context; - intfdata = port->serial->private; - - usb_serial_port_softint(port); - usb_autopm_put_interface_async(port->serial->interface); - portdata = usb_get_serial_port_data(port); - spin_lock(&intfdata->susp_lock); - intfdata->in_flight--; - spin_unlock(&intfdata->susp_lock); - - for (i = 0; i < N_OUT_URB; ++i) { - if (portdata->out_urbs[i] == urb) { - smp_mb__before_clear_bit(); - clear_bit(i, &portdata->out_busy); - break; - } - } -} - -static void option_instat_callback(struct urb *urb) -{ - int err; - int status = urb->status; - struct usb_serial_port *port = urb->context; - struct option_port_private *portdata = usb_get_serial_port_data(port); - - dbg("%s", __func__); - dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); - - if (status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - if (!req_pkt) { - dbg("%s: NULL req_pkt", __func__); - return; - } - if ((req_pkt->bRequestType == 0xA1) && - (req_pkt->bRequest == 0x20)) { - int old_dcd_state; - unsigned char signals = *((unsigned char *) - urb->transfer_buffer + - sizeof(struct usb_ctrlrequest)); - - dbg("%s: signal x%x", __func__, signals); - - old_dcd_state = portdata->dcd_state; - portdata->cts_state = 1; - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - if (old_dcd_state && !portdata->dcd_state) { - struct tty_struct *tty = - tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - } else { - dbg("%s: type %x req %x", __func__, - req_pkt->bRequestType, req_pkt->bRequest); - } - } else - err("%s: error %d", __func__, status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (status != -ESHUTDOWN && status != -ENOENT) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - dbg("%s: resubmit intr urb failed. (%d)", - __func__, err); - } -} - -static int option_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct option_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i = 0; i < N_OUT_URB; i++) { - this_urb = portdata->out_urbs[i]; - if (this_urb && !test_bit(i, &portdata->out_busy)) - data_len += OUT_BUFLEN; - } - - dbg("%s: %d", __func__, data_len); - return data_len; -} - -static int option_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct option_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i = 0; i < N_OUT_URB; i++) { - this_urb = portdata->out_urbs[i]; - /* FIXME: This locking is insufficient as this_urb may - go unused during the test */ - if (this_urb && test_bit(i, &portdata->out_busy)) - data_len += this_urb->transfer_buffer_length; - } - dbg("%s: %d", __func__, data_len); - return data_len; -} - -static int option_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct option_port_private *portdata; - struct option_intf_private *intfdata; - struct usb_serial *serial = port->serial; - int i, err; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - intfdata = serial->private; - - dbg("%s", __func__); - - /* Start reading from the IN endpoint */ - for (i = 0; i < N_IN_URB; i++) { - urb = portdata->in_urbs[i]; - if (!urb) - continue; - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - dbg("%s: submit urb %d failed (%d) %d", - __func__, i, err, - urb->transfer_buffer_length); - } - } - - option_send_setup(port); - - serial->interface->needs_remote_wakeup = 1; - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 1; - spin_unlock_irq(&intfdata->susp_lock); - usb_autopm_put_interface(serial->interface); - - return 0; -} - -static void option_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_serial *serial = port->serial; - struct option_port_private *portdata; - - dbg("%s", __func__); - portdata = usb_get_serial_port_data(port); - mutex_lock(&serial->disc_mutex); - portdata->rts_state = on; - portdata->dtr_state = on; - if (serial->dev) - option_send_setup(port); - mutex_unlock(&serial->disc_mutex); -} - - -static void option_close(struct usb_serial_port *port) -{ - int i; - struct usb_serial *serial = port->serial; - struct option_port_private *portdata; - struct option_intf_private *intfdata = port->serial->private; - - dbg("%s", __func__); - portdata = usb_get_serial_port_data(port); - - if (serial->dev) { - /* Stop reading/writing urbs */ - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 0; - spin_unlock_irq(&intfdata->susp_lock); - - for (i = 0; i < N_IN_URB; i++) - usb_kill_urb(portdata->in_urbs[i]); - for (i = 0; i < N_OUT_URB; i++) - usb_kill_urb(portdata->out_urbs[i]); - usb_autopm_get_interface(serial->interface); - serial->interface->needs_remote_wakeup = 0; - } -} - -/* Helper functions used by option_setup_urbs */ -static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, char *buf, int len, - void (*callback)(struct urb *)) -{ - struct urb *urb; - - if (endpoint == -1) - return NULL; /* endpoint not needed */ - - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ - if (urb == NULL) { - dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); - return NULL; - } - - /* Fill URB using supplied data. */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - return urb; -} - -/* Setup urbs */ -static void option_setup_urbs(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct option_port_private *portdata; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* Do indat endpoints first */ - for (j = 0; j < N_IN_URB; ++j) { - portdata->in_urbs[j] = option_setup_urb(serial, - port->bulk_in_endpointAddress, - USB_DIR_IN, port, - portdata->in_buffer[j], - IN_BUFLEN, option_indat_callback); - } - - /* outdat endpoints */ - for (j = 0; j < N_OUT_URB; ++j) { - portdata->out_urbs[j] = option_setup_urb(serial, - port->bulk_out_endpointAddress, - USB_DIR_OUT, port, - portdata->out_buffer[j], - OUT_BUFLEN, option_outdat_callback); - } - } -} - - -/** send RTS/DTR state to the port. - * - * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN - * CDC. -*/ -static int option_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct option_intf_private *intfdata = - (struct option_intf_private *) serial->private; - struct option_port_private *portdata; - int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - int val = 0; - dbg("%s", __func__); - - if (is_blacklisted(ifNum, intfdata->blacklist_info) == - OPTION_BLACKLIST_SENDSETUP) { - dbg("No send_setup on blacklisted interface #%d\n", ifNum); - return -EIO; - } - - portdata = usb_get_serial_port_data(port); - - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - -static int option_startup(struct usb_serial *serial) -{ - int i, j, err; - struct usb_serial_port *port; - struct option_port_private *portdata; - u8 *buffer; - - dbg("%s", __func__); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) { - dbg("%s: kmalloc for option_port_private (%d) failed!.", - __func__, i); - return 1; - } - init_usb_anchor(&portdata->delayed); - - for (j = 0; j < N_IN_URB; j++) { - buffer = (u8 *)__get_free_page(GFP_KERNEL); - if (!buffer) - goto bail_out_error; - portdata->in_buffer[j] = buffer; - } - - for (j = 0; j < N_OUT_URB; j++) { - buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); - if (!buffer) - goto bail_out_error2; - portdata->out_buffer[j] = buffer; - } - - usb_set_serial_port_data(port, portdata); - - if (!port->interrupt_in_urb) - continue; - err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (err) - dbg("%s: submit irq_in urb failed %d", - __func__, err); - } - option_setup_urbs(serial); - return 0; - -bail_out_error2: - for (j = 0; j < N_OUT_URB; j++) - kfree(portdata->out_buffer[j]); -bail_out_error: - for (j = 0; j < N_IN_URB; j++) - if (portdata->in_buffer[j]) - free_page((unsigned long)portdata->in_buffer[j]); - kfree(portdata); - return 1; -} - -static void stop_read_write_urbs(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct option_port_private *portdata; - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < N_IN_URB; j++) - usb_kill_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) - usb_kill_urb(portdata->out_urbs[j]); - } -} - -static void option_disconnect(struct usb_serial *serial) -{ - dbg("%s", __func__); - - stop_read_write_urbs(serial); -} - -static void option_release(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct option_port_private *portdata; - - dbg("%s", __func__); - - /* Now free them */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - for (j = 0; j < N_IN_URB; j++) { - if (portdata->in_urbs[j]) { - usb_free_urb(portdata->in_urbs[j]); - free_page((unsigned long) - portdata->in_buffer[j]); - portdata->in_urbs[j] = NULL; - } - } - for (j = 0; j < N_OUT_URB; j++) { - if (portdata->out_urbs[j]) { - usb_free_urb(portdata->out_urbs[j]); - kfree(portdata->out_buffer[j]); - portdata->out_urbs[j] = NULL; - } - } - } - - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - kfree(usb_get_serial_port_data(port)); - } -} - -#ifdef CONFIG_PM -static int option_suspend(struct usb_serial *serial, pm_message_t message) -{ - struct option_intf_private *intfdata = serial->private; - int b; - - dbg("%s entered", __func__); - - if (message.event & PM_EVENT_AUTO) { - spin_lock_irq(&intfdata->susp_lock); - b = intfdata->in_flight; - spin_unlock_irq(&intfdata->susp_lock); - - if (b) - return -EBUSY; - } - - spin_lock_irq(&intfdata->susp_lock); - intfdata->suspended = 1; - spin_unlock_irq(&intfdata->susp_lock); - stop_read_write_urbs(serial); - - return 0; -} - -static void play_delayed(struct usb_serial_port *port) -{ - struct option_intf_private *data; - struct option_port_private *portdata; - struct urb *urb; - int err; - - portdata = usb_get_serial_port_data(port); - data = port->serial->private; - while ((urb = usb_get_from_anchor(&portdata->delayed))) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (!err) - data->in_flight++; - } -} - -static int option_resume(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct option_intf_private *intfdata = serial->private; - struct option_port_private *portdata; - struct urb *urb; - int err = 0; - - dbg("%s entered", __func__); - /* get the interrupt URBs resubmitted unconditionally */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - if (!port->interrupt_in_urb) { - dbg("%s: No interrupt URB for port %d", __func__, i); - continue; - } - err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); - dbg("Submitted interrupt URB for port %d (result %d)", i, err); - if (err < 0) { - err("%s: Error %d for interrupt URB of port%d", - __func__, err, i); - goto err_out; - } - } - - for (i = 0; i < serial->num_ports; i++) { - /* walk all ports */ - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* skip closed ports */ - spin_lock_irq(&intfdata->susp_lock); - if (!portdata->opened) { - spin_unlock_irq(&intfdata->susp_lock); - continue; - } - - for (j = 0; j < N_IN_URB; j++) { - urb = portdata->in_urbs[j]; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - err("%s: Error %d for bulk URB %d", - __func__, err, i); - spin_unlock_irq(&intfdata->susp_lock); - goto err_out; - } - } - play_delayed(port); - spin_unlock_irq(&intfdata->susp_lock); - } - spin_lock_irq(&intfdata->susp_lock); - intfdata->suspended = 0; - spin_unlock_irq(&intfdata->susp_lock); -err_out: - return err; -} -#endif - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/README b/src/mod/endpoints/mod_gsmopen/gsmlib/README deleted file mode 100644 index 9dbb65daa8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/README +++ /dev/null @@ -1,8 +0,0 @@ -For Linux distros without gsmlib (eg: CentOS): - -In the directory gsmlib-1.10-patched-13ubuntu is the source for gsmlib -as patched by Ubuntu for modern compilers: - - ./configure - make - make install diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ABOUT-NLS b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ABOUT-NLS deleted file mode 100644 index 28d38c76fd..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ABOUT-NLS +++ /dev/null @@ -1,226 +0,0 @@ -Notes on the Free Translation Project -************************************* - - Free software is going international! The Free Translation Project -is a way to get maintainers of free software, translators, and users all -together, so that will gradually become able to speak many languages. -A few packages already provide translations for their messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do *not* -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work at translations should contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -One advise in advance -===================== - - If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias or message inheritance) as the -implementation here. It is also not possible to offer this additional -functionality on top of a `catgets' implementation. Future versions of -GNU `gettext' will very likely convey even more functionality. So it -might be a good idea to change to GNU `gettext' as soon as possible. - - So you need not provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -INSTALL Matters -=============== - - Some packages are "localizable" when properly installed; the -programs they contain can be made to speak your own native language. -Most such packages use GNU `gettext'. Other packages have their own -ways to internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system provides -usable `catgets' (if using this is selected by the installer) or -`gettext' functions. If neither is available, the GNU `gettext' own -library will be used. This library is wholly contained within this -package, usually in the `intl/' subdirectory, so prior installation of -the GNU `gettext' package is *not* required. Installers may use -special options at configuration time for changing the default -behaviour. The commands: - - ./configure --with-included-gettext - ./configure --with-catgets - ./configure --disable-nls - -will respectively bypass any pre-existing `catgets' or `gettext' to use -the internationalizing routines provided within this package, enable -the use of the `catgets' functions (if found on the locale system), or -else, *totally* disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might be not what is desirable. You -should use the more recent version of the GNU `gettext' library. I.e. -if the file `intl/VERSION' shows that the library which comes with this -package is more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - By default the configuration process will not test for the `catgets' -function and therefore they will not be used. The reasons are already -given above: the emulation on top of `catgets' cannot provide all the -extensions provided by the GNU `gettext' library. If you nevertheless -want to use the `catgets' functions use - - ./configure --with-catgets - -to enable the test for `catgets' (this causes no harm if `catgets' is -not available on your system). If you really select this option we -would like to hear about the reasons because we cannot think of any -good one ourself. - - Internationalized packages have usually many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -Using This Package -================== - - As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -ISO 639 `LL' two-letter code prior to using the programs in the -package. For example, let's suppose that you speak German. At the -shell prompt, merely execute `setenv LANG de' (in `csh'), -`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This -can be done from your `.login' or `.profile' file, once and for all. - - An operating system might already offer message localization for -many of its programs, while other programs have been installed locally -with the full capabilities of GNU `gettext'. Just using `gettext' -extended syntax for `LANG' would break proper localization of already -available operating system programs. In this case, users should set -both `LANGUAGE' and `LANG' variables in their environment, as programs -using GNU `gettext' give preference to `LANGUAGE'. For example, some -Swedish users would rather read translations in German than English for -when Swedish is not available. This is easily accomplished by setting -`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'. - -Translating Teams -================= - - For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list, courtesy of Linux -International. You may reach your translation team at the address -`LL@li.org', replacing LL by the two-letter ISO 639 code for your -language. Language codes are *not* the same as the country codes given -in ISO 3166. The following translation teams exist, as of December -1997: - - Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en', - Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian - `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja', - Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish - `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es', - Swedish `sv', and Turkish `tr'. - -For example, you may reach the Chinese translation team by writing to -`zh@li.org'. - - If you'd like to volunteer to *work* at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is *not* the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -*actively* in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skill are praised more than -programming skill, here. - -Available Packages -================== - - Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of December -1997. The matrix shows, in regard of each package, for which languages -PO files have been submitted to translation coordination. - - Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv - .----------------------------------------------------. - bash | [] [] [] | 3 - bison | [] [] [] | 3 - clisp | [] [] [] [] | 4 - cpio | [] [] [] [] [] [] | 6 - diffutils | [] [] [] [] [] | 5 - enscript | [] [] [] [] [] [] | 6 - fileutils | [] [] [] [] [] [] [] [] [] [] | 10 - findutils | [] [] [] [] [] [] [] [] [] | 9 - flex | [] [] [] [] | 4 - gcal | [] [] [] [] [] | 5 - gettext | [] [] [] [] [] [] [] [] [] [] [] | 12 - grep | [] [] [] [] [] [] [] [] [] [] | 10 - hello | [] [] [] [] [] [] [] [] [] [] [] | 11 - id-utils | [] [] [] | 3 - indent | [] [] [] [] [] | 5 - libc | [] [] [] [] [] [] [] | 7 - m4 | [] [] [] [] [] [] | 6 - make | [] [] [] [] [] [] | 6 - music | [] [] | 2 - ptx | [] [] [] [] [] [] [] [] | 8 - recode | [] [] [] [] [] [] [] [] [] | 9 - sh-utils | [] [] [] [] [] [] [] [] | 8 - sharutils | [] [] [] [] [] [] | 6 - tar | [] [] [] [] [] [] [] [] [] [] [] | 11 - texinfo | [] [] [] | 3 - textutils | [] [] [] [] [] [] [] [] [] | 9 - wdiff | [] [] [] [] [] [] [] [] | 8 - `----------------------------------------------------' - 17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv - 27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If December 1997 seems to be old, you may fetch a more recent copy -of this `ABOUT-NLS' file on most GNU archive sites. - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/AUTHORS b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/AUTHORS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/COPYING b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/COPYING deleted file mode 100644 index bf50f20de6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/COPYING +++ /dev/null @@ -1,482 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307 USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ChangeLog b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ChangeLog deleted file mode 100644 index bdd64ab61c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ChangeLog +++ /dev/null @@ -1,386 +0,0 @@ -gsmlib-1.10 - - reactivated code in gsm_at to retry sending PDU after - unsolicited result code - - - added description of unicode handling to FAQ - - - compilation fixes for gcc-3.0.4 - - - added quick exit for ATZ in UnixSerialPort constructor - if phone gives ERROR - - - added fix for phones that return +CLIP: "Number not available." - instead of giving caller ID - - - added get/setCLIRPresentation() functions to MeTa (contribution by - ivan) - - - added "NO CARRIER" event to the event mechanism (contribution by - clock) - - - added Win32 port of gsmsmsd (thanks to Konstantin Forostyan) - - - further extented Win32 port of gsmsmsd to handle outgoing messages - - - fixed problem with Ericsson T39m SMS sending (zero bytes in handshake) - - - added capability to send concatenated SMSs in gsmsmsd and gsmsendsms - - - fixed unsigned/signed char problems in Unix/Win32 serial port - implementations - - - added capability to send multiple SMSs to gsmsendsms/gsmsmsd - -gsmlib-1.9 - - fixed decoding of alphanumeric addresses in gsm_sms_codec. - - - fixed bug in gsm_event when checking whether to send an - acknowledgment for a received SMS - - - More Siemens-specific patches, some extensions to the AT - command parser - - - New code to print PIN status and set the PIN in gsmctl, setPIN - function in MeTa class (Andreas Roedl ) - - - Missing virtual destructor in Port class caused destructors of - UnixSerialPort and Win32SerialPort not to be called - fixed - - - Added new code to set functionality level on or off (thanks to - David Woodhouse) - - - found bug in SMS store implementation that caused the now - obsolete _capacity member to be set to a too low value - - - Added changes contributed by Frediano Ziglio to enable compilation - on Windows - - - Added call waiting functions contributed by Ivan - -gsmlib-1.8 - - added workaround for Nokia Cellular Card Phone RPE-1 GSM900 - that reports a CDS event that actually is an CDSI and sends a spurious - CR when waiting for a PDU - - - SMS are stored without index in files now - - - tested compilation with gcc-3.0.2 - - - added workaround for gsmlib getting confused when receiving SMS - and echo cannot be switched off - echos of the AT command are - filtered out in chat() now - - - extended gsm_phonebook preload mechanism to batch-load phonebooks - where the index does not start with 1 - - - Added workaround for Motorola Timeport 260 to write back - deliver messages to the ME - - - added workaround for compilation with libstdc++-v2 - - - private members of MeTa made protected - - - new ext directory for phone-specific extensions - -gsmlib-1.7 - - fixed bug with calculation of userData length if userDataHeader - is present (octet count was subtracted, not septet count) - - - fixed problem with string erase() at end of PDU for Falcom A2-1 - - - -t/--charset option of gsmpb did not work due to missing parameter - of getopt_long, fixed - - - The SMS decoder/encoder can now handle alphanumeric addresses - in the GSM default alphabet - - - set only those SMS stores that are actually needed to perform - SMS store operation - - - Fixed signalling error 321 (Invalid memory index) when trying to - read from empty SMS store entry - - - Fixed parsing error when reading current network operator if no - network connection - - - Added capability to parse cell broadcast messages to gsmlib and - the gsmsmsd program - - - Added workaround for Motorola Timeport 260 bug that doesn't correctly - report the message status when retrieving SMS messages from the - store - - - Added workaround for Motorola Timeport 260 that allocates index - numbers to SMS messages linearly so that index number can be - be larger than capacity reported by AT command - -gsmlib-1.6 - - more fixes for the COPS=? return format - - - fixed putBack() behaviour in gsm_parser (don't put back if end-of- - stream is reached) - - - added toString() function to gsm_sms_codec's Address class - - - SMS dates and times are now output in a locale-specific manner - - - fixed bug in Parser::getEol() (_eos was accidentally set to true) - - - added gsm_win32_serial module, Win32 project (VC++), and - Option FirstFone changes contributed by Frediano Ziglio - - - - fix in COM port recognition for Win32 (gsm_util) - - - renamed library files libgsm.* to libgsmme.* (now starting with - version 1.0) because of conflict with another Debian package - - - in gsm_phonebook and gsm_store the caching of entries can now - be disabled - - - added facilities to use other character sets for phonebooks - - - fixed workaround for Ericcson SH888 (missing service centre address) - - - fixed bug in gsm_phonebook that prevented texts with the - character '@' to be written to to the phonebook - - - fixed nasty memory allocation bug in gsmpb/gsmsmsstore - (automatic MeTa variable went out of scope even though used - later) - - - fixed Y2K problem in timestamp printing - - - fixed "make dist" to include win32 files - - - added workarounds for Falcom A2-1 (autodetection and enabling by - "export GSMLIB_FALCOM_A2_1_FIX=1", zero after PDU) - - - fixed bug that caused gsmlib to abort with an assert if a malformed - PDU was read - -gsmlib-1.5 - - adapted MeTa::getCurrentOPInfo() and MeTa::getAvailableOPInfo() - to handle Nokia 8290 quirks - - - code to set line speed in gsm_unix_serial reinserted (it was - accidentally removed in previous version) - - - minor changes to initialization sequence in gsm_unix_serial - - - bugfix in gsm_unix_serial.cc: readByte() == 0 does not mean no - more bytes, but is legal value - - - additionally allowed characters "*#pwPW" and '+' at any - position in telephone numbers - - - added environment variable GSMLIB_SH888_FIX that (if set) - enables the gsmlib workaround for Ericsson SH888's broken SMS TPDUs - - - fixed command line parameter handling bug in gsmsmsstore - - - fixed %files section .spec file to correctly include manual pages - - - fixed some bugs in terminal line setup (gsm_unix_serial) regarding - software/hardware handshake - - - added new "--sca" option to SMS-related apps to set the SMS - service centre address on the command line (useful if default is not - set correctly in the phone) - - - removed tcflush() call in UnixSerialPort::putLine that broke - the event system needed for gsmsmsd - -gsmlib-1.4 - - more attempts to fix UNIX serial port access - - - allow custom backends for sorted phonebooks to be integrated - into gsmlib (eg. for RDBMS or LDAP storage). Introduced a new - module gsm_sorted_phonebook_base that contains the infrastructure for - this. - - - Now gsmlib needs at least gcc-2.95.2 to compile correctly. - - - Implemented option to open device with software handshaking (XON/XOFF). - The applications now have an -X option to turn this on. - - - gsmlib now contains a facility to interrupt ongoing activity in a - controlled way. gsm_unix_serial now blocks for one second - maximum until it checks whether it was interrupted. - - - various small bugfixes - - - added workaround for phones that omit ':' in AT command responses - - - all debugging output is now printed to stderr - - - gsm_unix_serial: new attempt to initialize modem in a more - robust way (contributed) - - - gsm_sms: fixed handling of user data header (contributed) - -gsmlib-1.3 - - fixed bug that caused gsmlib to hang if TAs don't respond - to AT inquiries for serial number etc. - - - fixed bug with handling of CB mode AT command construction in - gsm_me_ta.cc, setSMSRoutingToTA() - - - allow '+' as the first character of phonenumbers - - - implemented reading and writing from/to stdin/stdout in - gsm_sorted_[sms_store|phonebook] and gsmpb/gsmsmsstore - - - fixed (hopefully) the intermittent hangup problem in - gsm_unix_serial_port - - - Some mobile phones cannot report the status of some facility - locks. The gsmctl program now prints out "unknown" in the - corresponding result line from the FLSTAT - operation if this problem occurs (instead of terminating). - - - switched off non-blocking access to serial device - -gsmlib-1.2 - - gsmlib now also works with TAs that can not switch off echo - - - fixed bug that prevented gsmlib from copying SMS_DELIVER and - SMS_STATUS_REPORT back to the ME - - - introduced -I (--init) parameter to all command line apps to - allow for device-specific initialization - - - made SMS decoding routines more robust against bad SMS (especially - premature end of PDU) - - - New debugging feature: If compiled without NDEBUG, the - environment variable GSMLIB_DEBUG determines the verbosity of - debugging messages (0 = none, 1 = many, 2 = extreme) - -gsmlib-1.1 - - - Parse multiple COPS (operator info) lines returned by some phones - - - accept string as numeric value when interpreting COPS=? response - (Ericsson phone + GSM12 GSM module) - - - accept string as numeric value when interpreting COPS? response - (Ericsson phone + GSM12 GSM module) - - - retry when initializing TA (ATZ/ATE0 sequences) - - - Set SMS routing: - allow mode 3 (special in-band technique) when setting routing - to TA (gsmlib should not be active when phone is switched to data mode - anyway) - - - Set SMS routing: - handle buffer mode but only if it was reported by the +CNMI=? command - (the Ericsson GM12 GSM modem does not like it otherwise) - - - Determine CPMS number of parameters for CPMS command (better - compability with some mobile phones / GSM modems) - - - handle missing service centre address in incoming SMS for Ericsson - model 6050102 - - - add new RING event to gsm_event.h/.cc, gsmsmsd now handles RING - indications properly - - - defined default event handler mostly to handle unexpected RING - indications that might otherwise confuse gsmlib - - - gsmsmsd: can now be cleanly terminated using the SIGINT or SIGTERM - signals - - - gsmsmsd: now handles multiple incoming SMS messages cleanly, before - there was a chance that some SMS messages coming in rapid succession - might have been lost - - - gsmsmsd: flush option implemented that dispatches and erases - existing messages in SMS store - - - gsmsmsd: added sending of SMS messages. gsmsmsd now accepts a - spool directory options where it expects to find SMS message file in a - simple format, these are dispatched every 5 seconds - -gsmlib-1.0 - - - RPM support (spec file) - - - the "+" is at least for the Siemens S10 and S25 a valid char in - telephone numbers (inserts a pause of 3 seconds), therefore it is now - allowed as part of telephone numbers - - - fixed incorrect analysis of facility class parameters in gsmctl.cc - - - restricted call forward time to 0..30 seconds in gsm_me_ta.cc - -gsmlib-0.3 - - - implemented timeout for accessing the mobile phone in order - to avoid hangs - - - upgraded to BETA status - - - written glossary for abbreviations (gsminfo(7)) - - - implemented NLS support, added German translations - - - implemented preserving the index position of phonebook entries in - gsmpb.cc and gsm_sorted_phonebook - - - cleaned up manual pages (alphabetic ordering of options etc.) - - - gsmsmstore program and gsm_sorted_sms_store./.cc completed and - tested - - - gsmpb and gsmsmsstore now have --verbose (-V) options for detailed - progress reporting - - - now check for getopt_long in configure (can be compiled on non-GNU - systems) - - - removed asserts regarding lengths of numeric data types, put them - into configure script - - - sorted options in apps/*.cc alphabetically (--help option) - - - in gsm_sorted_sms_store compare telephone numbers more sensibly - - - introduced -v option to gsmpb and gsmsmsstore to report execution - statistics - - - tested new synchronization function in gsmpb program - - - implemented operations in the gsmctl program - - - rewrote test cases (compare output) - - - completed gsmsmsstore program - - - first changes for compilation with VC++ 6.0 on WIN32 - -gsmlib-0.2 - - - gsmsmstore program and gsm_sorted_sms_store./.cc mostly - completed but not yet much tested - - - Fixed problem with some mobiles/TAs not giving prefixes after - certain AT sequences (reported for SIEMENS S25/IrDA, Nokia - 8810/IrDA) - - - Fixed problem with Xircom REM56G.100/Nokia 6150 that give - "CABLE: GSM" instead of "OK" after ATZ - - - Mobiles that return nothing when empty phonebook entries are - requested are now handled correctly (reported for SIEMENS S25/IrDA) - - - optimizations in gsm_*_phonebook modules (less AT commands necessary) - - - new synchronization function in gsmpb program that is (hopefully) - more sensible (see man page for details) - -gsmlib-0.1 - - - Initial release diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/INSTALL b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/INSTALL deleted file mode 100644 index 6242d6f388..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/INSTALL +++ /dev/null @@ -1,198 +0,0 @@ -GSMLIB Installation -=================== - - This distribution uses autoconf/automake/libtool. See below - for generic installation instructions. The default commands would be: - - ./configure - make - make install - - See also the section INSTALLATION in the README file in this - directory. For questions regarding the internationalization of this - package refer to doc/README.NLS and ./ABOUT-NLS. - - Developers: See also the file doc/README.developers. - -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.am deleted file mode 100644 index daf1ea0047..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: Toplevel Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 21.5.1999 -# ************************************************************************* - -SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext - -EXTRA_DIST = gsmlib.spec - -if COMPILE_INTL -SUBDIRS = intl $(SUBDIRS_) # po - make automake happy -else -SUBDIRS = $(SUBDIRS_) # po intl - make automake happy -endif - -all: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.in deleted file mode 100644 index e9676cc981..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/Makefile.in +++ /dev/null @@ -1,423 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: Toplevel Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 21.5.1999 -# ************************************************************************* - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = . - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ -AR = @AR@ -AS = @AS@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -DATADIRNAME = @DATADIRNAME@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -GCJ = @GCJ@ -GCJFLAGS = @GCJFLAGS@ -GENCAT = @GENCAT@ -GLIBC2 = @GLIBC2@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_ASPRINTF = @HAVE_ASPRINTF@ -HAVE_LIB = @HAVE_LIB@ -HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ -HAVE_SNPRINTF = @HAVE_SNPRINTF@ -HAVE_WPRINTF = @HAVE_WPRINTF@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MAKEINFO = @MAKEINFO@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -RC = @RC@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ - -SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext - -EXTRA_DIST = gsmlib.spec -@COMPILE_INTL_TRUE@SUBDIRS = intl $(SUBDIRS_) # po - make automake happy -@COMPILE_INTL_FALSE@SUBDIRS = $(SUBDIRS_) # po intl - make automake happy -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = gsm_config.h -CONFIG_CLEAN_FILES = -DIST_COMMON = README ./stamp-h.in ABOUT-NLS AUTHORS COPYING ChangeLog \ -INSTALL Makefile.am Makefile.in NEWS TODO acconfig.h acinclude.m4 \ -aclocal.m4 configure configure.in gsm_config.h.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = tar -GZIP_ENV = --best -DIST_SUBDIRS = intl po gsmlib apps tests doc scripts win32 ext po \ -gsmlib apps tests doc scripts win32 ext -all: all-redirect -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status - -$(ACLOCAL_M4): configure.in acinclude.m4 - cd $(srcdir) && $(ACLOCAL) - -config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck -$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) - cd $(srcdir) && $(AUTOCONF) - -gsm_config.h: stamp-h - @if test ! -f $@; then \ - rm -f stamp-h; \ - $(MAKE) stamp-h; \ - else :; fi -stamp-h: $(srcdir)/gsm_config.h.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES= CONFIG_HEADERS=gsm_config.h \ - $(SHELL) ./config.status - @echo timestamp > stamp-h 2> /dev/null -$(srcdir)/gsm_config.h.in: $(srcdir)/stamp-h.in - @if test ! -f $@; then \ - rm -f $(srcdir)/stamp-h.in; \ - $(MAKE) $(srcdir)/stamp-h.in; \ - else :; fi -$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h - cd $(top_srcdir) && $(AUTOHEADER) - @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null - -mostlyclean-hdr: - -clean-hdr: - -distclean-hdr: - -rm -f gsm_config.h - -maintainer-clean-hdr: - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. - -@SET_MAKE@ - -all-recursive install-data-recursive install-exec-recursive \ -installdirs-recursive install-recursive uninstall-recursive \ -check-recursive installcheck-recursive info-recursive dvi-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ - rev="$$subdir $$rev"; \ - test "$$subdir" != "." || dot_seen=yes; \ - done; \ - test "$$dot_seen" = "no" && rev=". $$rev"; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: tags-recursive $(HEADERS) $(SOURCES) gsm_config.h.in $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)gsm_config.h.in$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags gsm_config.h.in $$unique $(LISP)) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - -rm -rf $(distdir) - GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz - mkdir $(distdir)/=build - mkdir $(distdir)/=inst - dc_install_base=`cd $(distdir)/=inst && pwd`; \ - cd $(distdir)/=build \ - && ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) dist - -rm -rf $(distdir) - @banner="$(distdir).tar.gz is ready for distribution"; \ - dashes=`echo "$$banner" | sed s/./=/g`; \ - echo "$$dashes"; \ - echo "$$banner"; \ - echo "$$dashes" -dist: distdir - -chmod -R a+r $(distdir) - GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) - -rm -rf $(distdir) -dist-all: distdir - -chmod -R a+r $(distdir) - GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) - -rm -rf $(distdir) -distdir: $(DISTFILES) - -rm -rf $(distdir) - mkdir $(distdir) - -chmod 777 $(distdir) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - for subdir in $(DIST_SUBDIRS); do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ - || exit 1; \ - fi; \ - done -info-am: -info: info-recursive -dvi-am: -dvi: dvi-recursive -check-am: all-am -check: check-recursive -installcheck-am: -installcheck: installcheck-recursive -all-recursive-am: gsm_config.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -install-exec-am: -install-exec: install-exec-recursive - -install-data-am: -install-data: install-data-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-recursive -uninstall-am: -uninstall: uninstall-recursive -all-am: Makefile gsm_config.h -all-redirect: all-recursive-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: installdirs-recursive -installdirs-am: - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic - -mostlyclean: mostlyclean-recursive - -clean-am: clean-hdr clean-tags clean-generic mostlyclean-am - -clean: clean-recursive - -distclean-am: distclean-hdr distclean-tags distclean-generic clean-am - -rm -f libtool - -distclean: distclean-recursive - -rm -f config.status - -maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ - maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-recursive - -rm -f config.status - -.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ -install-data-recursive uninstall-data-recursive install-exec-recursive \ -uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ -all-recursive check-recursive installcheck-recursive info-recursive \ -dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ -maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ -dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ -install-exec-am install-exec install-data-am install-data install-am \ -install uninstall-am uninstall all-redirect all-am all installdirs-am \ -installdirs mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -all: - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/NEWS b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/NEWS deleted file mode 100644 index 1efffa7d86..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/NEWS +++ /dev/null @@ -1,11 +0,0 @@ -NEWS - 9.1.2000 - - Version 1.0 - first release with RPM support and binary packages - -NEWS - 15.11.1999 - - BETA version (details see ChangeLog) - -NEWS - 16.7.1999 - - initial release diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/README b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/README deleted file mode 100644 index 2f5db9eb27..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/README +++ /dev/null @@ -1,166 +0,0 @@ -INTRODUCTION - - This distribution contains a library to access GSM mobile phones - through GSM modems or IrDA devices. Features include: - - * modification of phonebooks stored in the mobile phone or on the - SIM card - - * reading and writing of SMS messages stored in the mobile phone - - * sending and reception of SMS messages - - Additionally, some simple command line programs are provided to - use these functionalities. - - -REQUIREMENTS - - You need a mobile phone that conforms to the GSM - standards ETSI GSM 07.07, ETSI GSM 07.05, and others. - Non-GSM mobile phones will not work! Additionally, - to access the mobile phone from the computer you will probably need an - GSM modem (that would be a PC-CARD, usually). There might be some - mobile phones, however, that incorporate directly terminal - adapter (TA) functionality. Access via IrDA interfaces is also - reported to work. - - If you want to compile the library yourself please also read - doc/README.developers. - - -INSTALLATION - - This distribution uses autoconf/automake/libtool. See the file - INSTALL for generic installation instructions. The default - commands for installation under /usr/local would be: - - ./configure - make - make install - - If there are any problems you can generate a debug version. See - doc/README.developers for details. - - -AVAILABLE DOCUMENTATION - - For the command line tools UNIX manual pages are available in the - doc subdirectory of this distribution. These are installed by - default in the directories /usr/local/man1, man7, and man8. - - See also the files doc/README.developers, doc/README.NLS and doc/FAQ. - - -HARDWARE - - The following mobile phone/GSM modem combinations are reported to - be compatible in varying degrees with the current release: - - - Nokia 6150/Xircom REM56G.100 - - Nokia 6150/Options "GSM-Ready(R) Cellular-Only" modem - from Option International - - Nokia 6210/- (Linux IrDA serial device) - - Nokia 8810/- (Linux IrDA serial device) - - Siemens S10D/Dr Neuhaus Gipsy Card GSM - - Siemens S25/- (Linux IrDA serial device) - - Siemens S35i/- (Linux IrDA serial device) - - Siemens S45 - - Ericcson SH888/- (Linux IrDA serial device) - - Ericsson 6050102/GM 12 GSM module - - Ericsson T28s (firmware 000809 1106) - - Ericsson T20e (firmware R3A007) - - -/Siemens M20T (stand-alone GSM module) - - -/Wavecom WM02 GSM (stand-alone GSM module) - - Nokia 7110 (firware rev 4.80)/- (Linux IrDA serial device) - - Nokia 8290 (USA GSM 1900MHz)/- (Linux IrDA serial device) - - Falcom A2-1/- (stand-alone GSM module) - - Ericsson R320s/- (Linux IrDA serial device) - - Motorola Timeport 260/- (Serial cable and Linux IrDA serial device) - - Motorola Timeport 250/- (Linux IrDA serial device) - - Motorola Timeport P7389/- (Linux IrDA serial device) - - Nokia Cellular Card Phone RPE-1 GSM900 and - - Nokia Card Phone RPM-1 GSM900/1800 - - Nokia Cardphone/Compaq iPAQ - - Omnipoint technologies Redhawk 2000 GSM modem - - Ericsson T28 (but one firmware revision is reported to have problems) - - Ericcson T65 - - Ericcson T39m/Bluetooth - - Option International GlobeTrotter PCMCIA - - Note 1: Some of the mobile phones have an integrated GSM modem - that can be accessed via the Linux IrDA drivers. - - Note 2: Some of the abovementioned phones have still some glitches - with gsmlib (and I haven't tested them myself). - - For the following phones I receive a lot of errors reports: - - - Ericcson SH888: SMS function don't work with many firmware releases - - This list is not exhaustive, there are probably many other types of - phone or GSM modem that work with gsmlib. Just try it and report back - to me! - - -DISCLAIMER - - Even though care has been taken in the design and implementation - of this software it can not be excluded that this software could - destroy data in your mobile phone or may even render your mobile - phone useless (by erroneous PIN settings, for example). The - author will not be held responsible legally, financially, or in any - other form for any kind of damage that might occur from using - this software. - - This software is provided "as is" and without any expressed or implied - warranties, including, without limitation, the implied warranties of - merchantibility and fitness for any particular purpose. - - If you are not ready to accept these conditions please don't use - this software. - - -COPYING - - This software is available on the LGPL (GNU LIBRARY GENERAL - PUBLIC LICENSE), ie. it is allowed to link - the library to commercial programs. - - See the file COPYING for details on the license. - - -BUGS - - There still seem to be some problems with IrDA devices under - Linux. There have been reports of gsmlib-based applications - (eg. gsmctl) hanging upon startup after initializing the serial port - /dev/ircomm. I would be thankful for any input on this problem. - - If something does not work with your OS platform or the mobile/TA - combination please send a complete trace of the compilation or the - program execution that did fail. Make sure to compile with debugging - information enabled. Otherwise it will not be possible for me to do - much about the problem. Send bug reports to the mailing list or - to software@pxh.de. I promise not to publish telephone numbers or other - private information that might be contained in the execution traces - that you send me. - - -MAILING LISTS - - There are now two mailings lists available for announcements and - discussion of gsmlib-related issues (hosted on lists.over.net). - Refer to these pages for information on subscription procedures - and an archive of previous postings: - - http://lists.over.net/mailman/listinfo/gsmlib-announce/ - for announcements regarding GSMLIB - - http://lists.over.net/mailman/listinfo/gsmlib-devel/ - the GSMLIB development list - - -AUTHOR - - Peter Hofmann . diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/TODO b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/TODO deleted file mode 100644 index 3ea3aa3fd5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/TODO +++ /dev/null @@ -1,289 +0,0 @@ -This is my list of TODOs for development of this software (not -necessarily in order of importance): - -("+" = DONE) - -+ handle: - > --> AT+COPS=? - > <-- - > <-- +COPS: (1,"AMENA",,"21403"),(3,"MOVISTAR",,"21407"), - > <-- (3,"E VODAFONE",,"21401"),,(0,1),(2) - > <-- - > <-- OK - > gsmctl[ERROR]: expected comma (at position 45 of string '(1,"AMENA",,"21403"),(3,"MOVISTAR",,"21407"),') - -+ extend README and web site with names of working phones (Siemens S45,...) - -+ add workaround: - > Manufacturer: Nokia Mobile Phones - > Model: 8290 - > Revision: SW5.22 - > Serial Number: 010070303406434 - > Functionality Level: 1 - > gsmctl[ERROR]: expected number, got '(2)' - -- add fork to gsmsmsd - -+ document "on" and "off" operations of gsmctl - -- Just assume full functionality and issue AT+CGMF=0 if we haven't already - done so for this MeTa. - -+ make update po - -+ add find function - -+ specify exact location of manual files in /usr/man/man* in spec - file, so that erase does not try to delete these directories - -+ update PO - -+ add option to gsmsendsms/gsmsmsd to request delivery reports - -+ Fix CBM reception in gsmsmsd, see testcb.cc program - -+ fix gsmsmsd: - --> AT+CNMI=? - <-- - <-- +CNMI: (1),(1),(0),(0),(0) - <-- - <-- OK - --> AT+CNMI=1,0,0,0,0 - <-- - <-- +CME ERROR: 003 - ./gsmsmsd[ERROR]: ME/TA error 'operation not allowed' (code 003) - -+ Wenn ich den SMS-Speicher auslesen mchte, bricht gsmlib ab, weil der - Speicherplatz 1 auf der SIM-Karte nicht belegt ist. Das kann z.B. - passieren, wenn man Nachrichten im Handy lscht. Es kommt der Fehlercode - 321 (Invalid memory index). Wie wre es, in der Leseroutine alle - ungltigen Pltze zu ignorieren und solange zu lesen, bis die Anzahl der - vorhandenen Nachrichten im Speicher eingelesen ist? - -+ document --charset option of gsmpb - -+ Problems with PDUs with alphanumeric SCA, e.g.: - 07911497941902F00414D0E474989D769F5DE4320839001040122151820000 - -+ > 2. Ich kann mit meinem Nokia 6210 nicht den Telefon-SMS-Speicher - auslesen. Dies liegt an der Speicherwahl, die vor dem Auslesen - an das Telefon bermittelt wird. Von der gsmlib wird anscheinend - immer die Anzahl der Speicher aus dem "CPMS=?"-Befehl genommen - (z.B. "SM","SM","SM"). Notwendig ist es aber nur, die erste - Position (zum Lesen und Lschen) bzw. die ersten beiden - Positionen (zum Schreiben) zu benutzen. - Das Nokia 6210 untersttzt aber an der ritten Stelle nur "SM", - nicht "ME". So kann ich die SMS im Telefon leider nicht - auslesen :-( - -- add option to gsmpb/gsmssmstore deletion to delete ALL entries - -- recheck Solaris port - -+ cache character set settings in MeTa - -+ add documentation for new gsmctl and gsmpb charset parameters - -+ support characters sets other than GSM default alphabet for phone books - -+ create non-existent files (gsmpb and gsmsmsstore) - -+ rename libgsm to libgsmme, new major version 1 - -+ document sca/setsca operations/parameters in gsmctl - -+ document option to set SCA in SMS-related apps - -+ implement option to set SCA in SMS-related apps - -+ convert NDEBUG test output from cout to cerr - -+ test new gsm_unix_serial behaviour - -+ apply checks for telephone number in gsm_sorted_phonebook - -+ add interrupted() checks - -+ check for gcc-2.95.2 in configure - -- document custom backend options of gsmpb (and gsmsmsstore) - -- /var/lock/LCK..modem - -+ make gsmctl all continue even if there are some failures - -+ CPIN thing - -+ bring German translations up-to-date - -+ document -I parameter - -+ make chat routines robust against TAs that insist on echoing AT commands - -+ ericsson sh 888: - <-- AT+CLCK="P2",2,,1 - <-- - +CME ERROR: 4 - gsmctl[ERROR]: ME/TA error 'operation not supported' (code 4) - -+ put README etc. into gsmlib package (not only devel) - -+ make SMS decoding routines more robust against bad SMS (especially - premature end of PDU) - -+ stop gsm_sorted_sms_store.cc from copying back SMS that came from - the SC (SMS_DELIVER, SMS_STATUS_REPORT, SMS_SUBMIT_REPORT). Their - message type is ambiguous and the ME may misinterpret them. - -+ gsmsmsd: reinitialize modem every hour or so (signal termination implemented) - -+ implement store, flush and spool options of gsmsmsd, - document them in man pages - -+ test case for COPS answer numeric operator name in quotation marks - (testparser.cc) - -+ retry when initializing TA (ATZ/ATE0 sequences) - -+ correctly parse malformed SMS PDUs without SCA with Ericsson phone, - introduce Capability object for that. Ericsson ID: - Manufacturer: ERICSSON - Model: 6050102 - Revision: 990225 1852 CXC112143 - Serial Number: 520001690279310 - -+ Determine CPMS number of parameters for CPMS command (Ericsson - phone/GM12 GSM modem): - AT+CPMS? - +CPMS: "ME",0,10,"ME",0,10 - AT+CPMS=? - +CPMS: ("ME","SM"),("ME","SM") - -+ accept string as numeric value when interpreting COPS=? response - (Ericsson phone + GSM12 GSM module) - -+ accept string as numeric value when interpreting COPS? response - (Ericsson phone + GSM12 GSM module) - -+ It would be nice if it was possible to send sms:es - via gsmsmsd as well, via a spool directory or a socket (or stdin, in which - case one can put another program in front of this program and then - feed it with outgoing messages any way one wants). That way the program - could be the gateway between programs and the sms network. Now one has - to stop gsmsmsd to send an sms and that's not so elegant or write - ones own program. - -+ gsmsmsd geht davon aus, das ein platz frei ist und benutzt nur diesen.... - Wenn also eine SMS kommt, dann zieht es Sie raus, und lscht den - Speicherplatz. - Wenn aber die Karte voll ist, passiert gar nichts. Fr eine automatisierte - umgebung ist das schlecht. besser wre es, bei startup von gsmsmsd alle - Speicherpltze abzufrhstcken, und die Action aufzurufen. - -+ Ein RING bringt den gsmsmsd ziemlich heftig aus dem Tritt. Hab jetzt ne - Rufumleitung eingebaut. - -+ Links section in homepage - -+ AT+CNMI=? liefert bei mir folgendes zurck: - +CNMI: (0-3),(0-3),(0-2),0,(0-1) - Parameter 4 () liefert also keine Liste sondern nur ein Int zurck, du - versuchts aber ein ( zu parsen. - Was sagt die ETSI-spec. dazu ?? Ist das konform ?? - -+ give name of command at beginning of synopsis in man pages - -+ list combinations of mobiles phones/GSM modems in the README - -+ test ALARM in case of timeout when writing or reading to TA - -+ install headers in gsmlib subdirectory - -+ RPM spec file - -+ test index changes for sorted phonebook -> write second test case - -+ sort phone numbers the same way in gsm_sorted_sms_store and - gsm_sorted_phonebook - -+ write glossary for all these nice abbreviations (TA, ME, SC, SME, TE) - -+ HAVE_VSNPRINTF instead of HAVE_VPRINTF - -+ internationalization of messages with GNU gettext. Files: - +gsm_at.cc +gsm_parser.cc +gsm_sorted_phonebook.cc - +gsm_error.cc +gsm_phonebook.cc +gsm_sorted_sms_store.cc - +gsm_event.cc +gsm_sms.cc +gsm_unix_serial.cc - +gsm_me_ta.cc +gsm_sms_codec.cc +gsm_util.cc - +gsm_nls.cc +gsm_sms_store.cc - +gsmctl.cc +gsmpb.cc +gsmsendsms.cc - +gsmsmsd.cc +gsmsmsstore.cc - -+ implement indexed phonebook ops in gsmpb.cc - -+ describe phonebook file format in gsmpb.man - -+ update list of compatible hardware in README - -+ all #include must be enclosed in #ifdef's - -+ check for getopt_long in configure - -+ remove asserts regarding lengths of numeric data types, put them -into configure script -(string) - -+ sort options in apps/*.cc alphabetically - -+ in gsm_sorted_sms_store compare telephone numbers numerically - -+ introduce -v option to gsmpb and gsmsmsstore to report execution -statistics (gives a nicer feeling to users) - -+ test new synchronization function in gsmpb program - -+ implement equality operator for SMSSToreEntry - -+ test 'make install' - -+ implement operations in the gsmctl program - -+ test operations in the gsmctl program - -+ document operations in the gsmctl program - -+ rewrite test cases (compare output) - -+ write gsm_sorted_sms_store module (along the lines of gsm_sorted_phonebook) - -+ complete gsmsmsstore program (using abovementioned modules) - -TODO low priority: - -- implement SMS text mode - -- The action command of gsmsmsd would be easier to make, if the program - sent the values in environment variables instead (except the user data - which could be sent on stdin). - -+ Upgrade to latest autoheader, autoconf, libtool - -- provide German translations for manual pages - -- organize doc subdirectory for translated READMEs, manual pages - -+ Win32 port - -- test: optimization when accessing phonebooks: use size information -available via AT command to stop reading entries known to be empty (I -cannot test this with my hardware since CPBS? is not fully supported) - -- make apps accept stdin or stdout - -+ maybe strip leading and trailing whitespace from phonebook entries -when reading them from ME/TA or file? (not done, perhaps users want to -achieve special effects with white space) - -- support international character sets (8-bit, 16-bit) in phonebook -operations (I'd like to have input from users who need this) - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acconfig.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acconfig.h deleted file mode 100644 index 14ce58fbc3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acconfig.h +++ /dev/null @@ -1,33 +0,0 @@ -/* used by libtool*/ -#define PACKAGE 0 - -/* used by libtool*/ -#define VERSION 0 - -/* Define if getopt_long() available */ -#undef HAVE_GETOPT_LONG - -/* Define if alarm() available */ -#undef HAVE_ALARM - -/* Define if netinet/in.h header available */ -#undef HAVE_NETINET_IN_H - -/* Define if string.h header available */ -#undef HAVE_STRING_H - -/* Define for NLS */ -#undef ENABLE_NLS -#undef HAVE_CATGETS -#undef HAVE_GETTEXT -#undef HAVE_LC_MESSAGES -#undef HAVE_STPCPY - -/* Define LOCALEDIR */ -#define LOCALEDIR "/usr/share/locale" - -/* Define if libintl.h header available */ -#undef HAVE_LIBINTL_H - -/* Define if vsnprintf() function available */ -#undef HAVE_VSNPRINTF diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acinclude.m4 b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/acinclude.m4 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/aclocal.m4 b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/aclocal.m4 deleted file mode 100644 index 8d27d03353..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/aclocal.m4 +++ /dev/null @@ -1,9704 +0,0 @@ -# generated automatically by aclocal 1.9.6 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# codeset.m4 serial AM1 (gettext-0.10.40) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([AM_LANGINFO_CODESET], -[ - AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, - [AC_TRY_LINK([#include ], - [char* cs = nl_langinfo(CODESET);], - am_cv_langinfo_codeset=yes, - am_cv_langinfo_codeset=no) - ]) - if test $am_cv_langinfo_codeset = yes; then - AC_DEFINE(HAVE_LANGINFO_CODESET, 1, - [Define if you have and nl_langinfo(CODESET).]) - fi -]) - -# gettext.m4 serial 37 (gettext-0.14.4) -dnl Copyright (C) 1995-2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2003. - -dnl Macro to add for using GNU gettext. - -dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). -dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The -dnl default (if it is not specified or empty) is 'no-libtool'. -dnl INTLSYMBOL should be 'external' for packages with no intl directory, -dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. -dnl If INTLSYMBOL is 'use-libtool', then a libtool library -dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, -dnl depending on --{enable,disable}-{shared,static} and on the presence of -dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library -dnl $(top_builddir)/intl/libintl.a will be created. -dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext -dnl implementations (in libc or libintl) without the ngettext() function -dnl will be ignored. If NEEDSYMBOL is specified and is -dnl 'need-formatstring-macros', then GNU gettext implementations that don't -dnl support the ISO C 99 formatstring macros will be ignored. -dnl INTLDIR is used to find the intl libraries. If empty, -dnl the value `$(top_builddir)/intl/' is used. -dnl -dnl The result of the configuration is one of three cases: -dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled -dnl and used. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 2) GNU gettext has been found in the system's C library. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 3) No internationalization, always use English msgid. -dnl Catalog format: none -dnl Catalog extension: none -dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. -dnl The use of .gmo is historical (it was needed to avoid overwriting the -dnl GNU format catalogs when building on a platform with an X/Open gettext), -dnl but we keep it in order not to force irrelevant filename changes on the -dnl maintainers. -dnl -AC_DEFUN([AM_GNU_GETTEXT], -[ - dnl Argument checking. - ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , - [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT -])])])])]) - ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , - [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT -])])])]) - define([gt_included_intl], ifelse([$1], [external], [no], [yes])) - define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) - - AC_REQUIRE([AM_PO_SUBDIRS])dnl - ifelse(gt_included_intl, yes, [ - AC_REQUIRE([AM_INTL_SUBDIR])dnl - ]) - - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Sometimes libintl requires libiconv, so first search for libiconv. - dnl Ideally we would do this search only after the - dnl if test "$USE_NLS" = "yes"; then - dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT - dnl the configure script would need to contain the same shell code - dnl again, outside any 'if'. There are two solutions: - dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. - dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. - dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not - dnl documented, we avoid it. - ifelse(gt_included_intl, yes, , [ - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - ]) - - dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation. - gt_INTL_MACOSX - - dnl Set USE_NLS. - AM_NLS - - ifelse(gt_included_intl, yes, [ - BUILD_INCLUDED_LIBINTL=no - USE_INCLUDED_LIBINTL=no - ]) - LIBINTL= - LTLIBINTL= - POSUB= - - dnl If we use NLS figure out what method - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - ifelse(gt_included_intl, yes, [ - AC_MSG_CHECKING([whether included gettext is requested]) - AC_ARG_WITH(included-gettext, - [ --with-included-gettext use the GNU gettext library included here], - nls_cv_force_use_gnu_gettext=$withval, - nls_cv_force_use_gnu_gettext=no) - AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) - - nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" - if test "$nls_cv_force_use_gnu_gettext" != "yes"; then - ]) - dnl User does not insist on using GNU NLS library. Figure out what - dnl to use. If GNU gettext is available we use this. Else we have - dnl to fall back to GNU NLS library. - - dnl Add a version number to the cache macros. - define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) - define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) - define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) - - AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, - [AC_TRY_LINK([#include -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings;], - [bindtextdomain ("", ""); -return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], - gt_cv_func_gnugettext_libc=yes, - gt_cv_func_gnugettext_libc=no)]) - - if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl Sometimes libintl requires libiconv, so first search for libiconv. - ifelse(gt_included_intl, yes, , [ - AM_ICONV_LINK - ]) - dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL - dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) - dnl because that would add "-liconv" to LIBINTL and LTLIBINTL - dnl even if libiconv doesn't exist. - AC_LIB_LINKFLAGS_BODY([intl]) - AC_CACHE_CHECK([for GNU gettext in libintl], - gt_cv_func_gnugettext_libintl, - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - dnl Now see whether libintl exists and does not depend on libiconv. - AC_TRY_LINK([#include -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *);], - [bindtextdomain ("", ""); -return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias ("")], - gt_cv_func_gnugettext_libintl=yes, - gt_cv_func_gnugettext_libintl=no) - dnl Now see whether libintl exists and depends on libiconv. - if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *);], - [bindtextdomain ("", ""); -return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias ("")], - [LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - gt_cv_func_gnugettext_libintl=yes - ]) - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - fi - - dnl If an already present or preinstalled GNU gettext() is found, - dnl use it. But if this macro is used in GNU gettext, and GNU - dnl gettext is already preinstalled in libintl, we update this - dnl libintl. (Cf. the install rule in intl/Makefile.in.) - if test "$gt_cv_func_gnugettext_libc" = "yes" \ - || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ - && test "$PACKAGE" != gettext-runtime \ - && test "$PACKAGE" != gettext-tools; }; then - gt_use_preinstalled_gnugettext=yes - else - dnl Reset the values set by searching for libintl. - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - ifelse(gt_included_intl, yes, [ - if test "$gt_use_preinstalled_gnugettext" != "yes"; then - dnl GNU gettext is not found in the C library. - dnl Fall back on included GNU gettext library. - nls_cv_use_gnu_gettext=yes - fi - fi - - if test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions used to generate GNU NLS library. - BUILD_INCLUDED_LIBINTL=yes - USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" - LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` - fi - - CATOBJEXT= - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions to use GNU gettext tools. - CATOBJEXT=.gmo - fi - ]) - - if test -n "$INTL_MACOSX_LIBS"; then - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Some extra flags are needed during linking. - LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" - LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" - fi - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - AC_DEFINE(ENABLE_NLS, 1, - [Define to 1 if translation of program messages to the user's native language - is requested.]) - else - USE_NLS=no - fi - fi - - AC_MSG_CHECKING([whether to use NLS]) - AC_MSG_RESULT([$USE_NLS]) - if test "$USE_NLS" = "yes"; then - AC_MSG_CHECKING([where the gettext function comes from]) - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - gt_source="external libintl" - else - gt_source="libc" - fi - else - gt_source="included intl directory" - fi - AC_MSG_RESULT([$gt_source]) - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - AC_MSG_CHECKING([how to link with libintl]) - AC_MSG_RESULT([$LIBINTL]) - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) - fi - - dnl For backward compatibility. Some packages may be using this. - AC_DEFINE(HAVE_GETTEXT, 1, - [Define if the GNU gettext() function is already present or preinstalled.]) - AC_DEFINE(HAVE_DCGETTEXT, 1, - [Define if the GNU dcgettext() function is already present or preinstalled.]) - fi - - dnl We need to process the po/ directory. - POSUB=po - fi - - ifelse(gt_included_intl, yes, [ - dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL - dnl to 'yes' because some of the testsuite requires it. - if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then - BUILD_INCLUDED_LIBINTL=yes - fi - - dnl Make all variables we use known to autoconf. - AC_SUBST(BUILD_INCLUDED_LIBINTL) - AC_SUBST(USE_INCLUDED_LIBINTL) - AC_SUBST(CATOBJEXT) - - dnl For backward compatibility. Some configure.ins may be using this. - nls_cv_header_intl= - nls_cv_header_libgt= - - dnl For backward compatibility. Some Makefiles may be using this. - DATADIRNAME=share - AC_SUBST(DATADIRNAME) - - dnl For backward compatibility. Some Makefiles may be using this. - INSTOBJEXT=.mo - AC_SUBST(INSTOBJEXT) - - dnl For backward compatibility. Some Makefiles may be using this. - GENCAT=gencat - AC_SUBST(GENCAT) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLOBJS= - if test "$USE_INCLUDED_LIBINTL" = yes; then - INTLOBJS="\$(GETTOBJS)" - fi - AC_SUBST(INTLOBJS) - - dnl Enable libtool support if the surrounding package wishes it. - INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix - AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) - ]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLLIBS="$LIBINTL" - AC_SUBST(INTLLIBS) - - dnl Make all documented variables known to autoconf. - AC_SUBST(LIBINTL) - AC_SUBST(LTLIBINTL) - AC_SUBST(POSUB) -]) - - -dnl Checks for all prerequisites of the intl subdirectory, -dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, -dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. -AC_DEFUN([AM_INTL_SUBDIR], -[ - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - AC_REQUIRE([gt_GLIBC2])dnl - AC_REQUIRE([AC_PROG_RANLIB])dnl - AC_REQUIRE([AC_ISC_POSIX])dnl - AC_REQUIRE([AC_HEADER_STDC])dnl - AC_REQUIRE([AC_C_CONST])dnl - AC_REQUIRE([bh_C_SIGNED])dnl - AC_REQUIRE([AC_C_INLINE])dnl - AC_REQUIRE([AC_TYPE_OFF_T])dnl - AC_REQUIRE([AC_TYPE_SIZE_T])dnl - AC_REQUIRE([gl_AC_TYPE_LONG_LONG])dnl - AC_REQUIRE([gt_TYPE_LONGDOUBLE])dnl - AC_REQUIRE([gt_TYPE_WCHAR_T])dnl - AC_REQUIRE([gt_TYPE_WINT_T])dnl - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_REQUIRE([gt_TYPE_INTMAX_T]) - AC_REQUIRE([gt_PRINTF_POSIX]) - AC_REQUIRE([AC_FUNC_ALLOCA])dnl - AC_REQUIRE([AC_FUNC_MMAP])dnl - AC_REQUIRE([gl_GLIBC21])dnl - AC_REQUIRE([gt_INTDIV0])dnl - AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl - AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl - AC_REQUIRE([gt_INTTYPES_PRI])dnl - AC_REQUIRE([gl_XSIZE])dnl - AC_REQUIRE([gt_INTL_MACOSX])dnl - - AC_CHECK_TYPE([ptrdiff_t], , - [AC_DEFINE([ptrdiff_t], [long], - [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) - ]) - AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ -stdlib.h string.h unistd.h sys/param.h]) - AC_CHECK_FUNCS([asprintf fwprintf getcwd getegid geteuid getgid getuid \ -mempcpy munmap putenv setenv setlocale snprintf stpcpy strcasecmp strdup \ -strtoul tsearch wcslen __argz_count __argz_stringify __argz_next \ -__fsetlocking]) - - dnl Use the _snprintf function only if it is declared (because on NetBSD it - dnl is defined as a weak alias of snprintf; we prefer to use the latter). - gt_CHECK_DECL(_snprintf, [#include ]) - gt_CHECK_DECL(_snwprintf, [#include ]) - - dnl Use the *_unlocked functions only if they are declared. - dnl (because some of them were defined without being declared in Solaris - dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built - dnl on Solaris 2.5.1 to run on Solaris 2.6). - dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. - gt_CHECK_DECL(feof_unlocked, [#include ]) - gt_CHECK_DECL(fgets_unlocked, [#include ]) - gt_CHECK_DECL(getc_unlocked, [#include ]) - - case $gt_cv_func_printf_posix in - *yes) HAVE_POSIX_PRINTF=1 ;; - *) HAVE_POSIX_PRINTF=0 ;; - esac - AC_SUBST([HAVE_POSIX_PRINTF]) - if test "$ac_cv_func_asprintf" = yes; then - HAVE_ASPRINTF=1 - else - HAVE_ASPRINTF=0 - fi - AC_SUBST([HAVE_ASPRINTF]) - if test "$ac_cv_func_snprintf" = yes; then - HAVE_SNPRINTF=1 - else - HAVE_SNPRINTF=0 - fi - AC_SUBST([HAVE_SNPRINTF]) - if test "$ac_cv_func_wprintf" = yes; then - HAVE_WPRINTF=1 - else - HAVE_WPRINTF=0 - fi - AC_SUBST([HAVE_WPRINTF]) - - AM_ICONV - AM_LANGINFO_CODESET - if test $ac_cv_header_locale_h = yes; then - gt_LC_MESSAGES - fi - - if test -n "$INTL_MACOSX_LIBS"; then - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - fi - - dnl intl/plural.c is generated from intl/plural.y. It requires bison, - dnl because plural.y uses bison specific features. It requires at least - dnl bison-1.26 because earlier versions generate a plural.c that doesn't - dnl compile. - dnl bison is only needed for the maintainer (who touches plural.y). But in - dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put - dnl the rule in general Makefile. Now, some people carelessly touch the - dnl files or have a broken "make" program, hence the plural.c rule will - dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not - dnl present or too old. - AC_CHECK_PROGS([INTLBISON], [bison]) - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - dnl Found it, now check the version. - AC_MSG_CHECKING([version of bison]) -changequote(<<,>>)dnl - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) -changequote([,])dnl - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - AC_MSG_RESULT([$ac_prog_version]) - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi -]) - - -dnl Checks for special options needed on MacOS X. -dnl Defines INTL_MACOSX_LIBS. -AC_DEFUN([gt_INTL_MACOSX], -[ - dnl Check for API introduced in MacOS X 10.2. - AC_CACHE_CHECK([for CFPreferencesCopyAppValue], - gt_cv_func_CFPreferencesCopyAppValue, - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - gt_save_LIBS="$LIBS" - LIBS="$LIBS -framework CoreFoundation" - AC_TRY_LINK([#include ], - [CFPreferencesCopyAppValue(NULL, NULL)], - [gt_cv_func_CFPreferencesCopyAppValue=yes], - [gt_cv_func_CFPreferencesCopyAppValue=no]) - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then - AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1, - [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) - fi - dnl Check for API introduced in MacOS X 10.3. - AC_CACHE_CHECK([for CFLocaleCopyCurrent], gt_cv_func_CFLocaleCopyCurrent, - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - gt_save_LIBS="$LIBS" - LIBS="$LIBS -framework CoreFoundation" - AC_TRY_LINK([#include ], [CFLocaleCopyCurrent();], - [gt_cv_func_CFLocaleCopyCurrent=yes], - [gt_cv_func_CFLocaleCopyCurrent=no]) - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - if test $gt_cv_func_CFLocaleCopyCurrent = yes; then - AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1, - [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) - fi - INTL_MACOSX_LIBS= - if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then - INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" - fi - AC_SUBST([INTL_MACOSX_LIBS]) -]) - - -dnl gt_CHECK_DECL(FUNC, INCLUDES) -dnl Check whether a function is declared. -AC_DEFUN([gt_CHECK_DECL], -[ - AC_CACHE_CHECK([whether $1 is declared], ac_cv_have_decl_$1, - [AC_TRY_COMPILE([$2], [ -#ifndef $1 - char *p = (char *) $1; -#endif -], ac_cv_have_decl_$1=yes, ac_cv_have_decl_$1=no)]) - if test $ac_cv_have_decl_$1 = yes; then - gt_value=1 - else - gt_value=0 - fi - AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value], - [Define to 1 if you have the declaration of `$1', and to 0 if you don't.]) -]) - - -dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) -AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) - -# glibc2.m4 serial 1 -dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Test for the GNU C Library, version 2.0 or newer. -# From Bruno Haible. - -AC_DEFUN([gt_GLIBC2], - [ - AC_CACHE_CHECK(whether we are using the GNU C Library 2 or newer, - ac_cv_gnu_library_2, - [AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) - Lucky GNU user - #endif -#endif - ], - ac_cv_gnu_library_2=yes, - ac_cv_gnu_library_2=no) - ] - ) - AC_SUBST(GLIBC2) - GLIBC2="$ac_cv_gnu_library_2" - ] -) - -# glibc21.m4 serial 3 -dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Test for the GNU C Library, version 2.1 or newer. -# From Bruno Haible. - -AC_DEFUN([gl_GLIBC21], - [ - AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, - ac_cv_gnu_library_2_1, - [AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) - Lucky GNU user - #endif -#endif - ], - ac_cv_gnu_library_2_1=yes, - ac_cv_gnu_library_2_1=no) - ] - ) - AC_SUBST(GLIBC21) - GLIBC21="$ac_cv_gnu_library_2_1" - ] -) - -# iconv.m4 serial AM4 (gettext-0.11.3) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], -[ - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([iconv]) -]) - -AC_DEFUN([AM_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - - dnl Add $INCICONV to CPPFLAGS before performing the following checks, - dnl because if the user has installed libiconv and not disabled its use - dnl via --without-libiconv-prefix, he wants to use it. The first - dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. - am_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - - AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - AC_TRY_LINK([#include -#include ], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_func_iconv=yes) - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include -#include ], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_lib_iconv=yes - am_cv_func_iconv=yes) - LIBS="$am_save_LIBS" - fi - ]) - if test "$am_cv_func_iconv" = yes; then - AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) - fi - if test "$am_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([$LIBICONV]) - else - dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV - dnl either. - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - AC_SUBST(LIBICONV) - AC_SUBST(LTLIBICONV) -]) - -AC_DEFUN([AM_ICONV], -[ - AM_ICONV_LINK - if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL(am_cv_proto_iconv, [ - AC_TRY_COMPILE([ -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif -], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([$]{ac_t:- - }[$]am_cv_proto_iconv) - AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, - [Define as const if the declaration of iconv() needs const.]) - fi -]) - -# intdiv0.m4 serial 1 (gettext-0.11.3) -dnl Copyright (C) 2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([gt_INTDIV0], -[ - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - - AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], - gt_cv_int_divbyzero_sigfpe, - [ - AC_TRY_RUN([ -#include -#include - -static void -#ifdef __cplusplus -sigfpe_handler (int sig) -#else -sigfpe_handler (sig) int sig; -#endif -{ - /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ - exit (sig != SIGFPE); -} - -int x = 1; -int y = 0; -int z; -int nan; - -int main () -{ - signal (SIGFPE, sigfpe_handler); -/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ -#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) - signal (SIGTRAP, sigfpe_handler); -#endif -/* Linux/SPARC yields signal SIGILL. */ -#if defined (__sparc__) && defined (__linux__) - signal (SIGILL, sigfpe_handler); -#endif - - z = x / y; - nan = y / y; - exit (1); -} -], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, - [ - # Guess based on the CPU. - case "$host_cpu" in - alpha* | i[34567]86 | m68k | s390*) - gt_cv_int_divbyzero_sigfpe="guessing yes";; - *) - gt_cv_int_divbyzero_sigfpe="guessing no";; - esac - ]) - ]) - case "$gt_cv_int_divbyzero_sigfpe" in - *yes) value=1;; - *) value=0;; - esac - AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, - [Define if integer division by zero raises signal SIGFPE.]) -]) - -# intmax.m4 serial 2 (gettext-0.14.2) -dnl Copyright (C) 2002-2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether the system has the 'intmax_t' type, but don't attempt to -dnl find a replacement if it is lacking. - -AC_DEFUN([gt_TYPE_INTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, - [AC_TRY_COMPILE([ -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -#include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -#include -#endif -], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) - if test $gt_cv_c_intmax_t = yes; then - AC_DEFINE(HAVE_INTMAX_T, 1, - [Define if you have the 'intmax_t' type in or .]) - fi -]) - -# inttypes-pri.m4 serial 1 (gettext-0.11.4) -dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -# Define PRI_MACROS_BROKEN if exists and defines the PRI* -# macros to non-string values. This is the case on AIX 4.3.3. - -AC_DEFUN([gt_INTTYPES_PRI], -[ - AC_REQUIRE([gt_HEADER_INTTYPES_H]) - if test $gt_cv_header_inttypes_h = yes; then - AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], - gt_cv_inttypes_pri_broken, - [ - AC_TRY_COMPILE([#include -#ifdef PRId32 -char *p = PRId32; -#endif -], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) - ]) - fi - if test "$gt_cv_inttypes_pri_broken" = yes; then - AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, - [Define if exists and defines unusable PRI* macros.]) - fi -]) - -# inttypes.m4 serial 1 (gettext-0.11.4) -dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H if exists and doesn't clash with -# . - -AC_DEFUN([gt_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, - [ - AC_TRY_COMPILE( - [#include -#include ], - [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) - ]) - if test $gt_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, - [Define if exists and doesn't clash with .]) - fi -]) - -# inttypes_h.m4 serial 6 -dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, -# doesn't clash with , and declares uintmax_t. - -AC_DEFUN([gl_AC_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], gl_cv_header_inttypes_h, - [AC_TRY_COMPILE( - [#include -#include ], - [uintmax_t i = (uintmax_t) -1;], - gl_cv_header_inttypes_h=yes, - gl_cv_header_inttypes_h=no)]) - if test $gl_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, - [Define if exists, doesn't clash with , - and declares uintmax_t. ]) - fi -]) - -# lcmessage.m4 serial 4 (gettext-0.14.2) -dnl Copyright (C) 1995-2002, 2004-2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995. - -# Check whether LC_MESSAGES is available in . - -AC_DEFUN([gt_LC_MESSAGES], -[ - AC_CACHE_CHECK([for LC_MESSAGES], gt_cv_val_LC_MESSAGES, - [AC_TRY_LINK([#include ], [return LC_MESSAGES], - gt_cv_val_LC_MESSAGES=yes, gt_cv_val_LC_MESSAGES=no)]) - if test $gt_cv_val_LC_MESSAGES = yes; then - AC_DEFINE(HAVE_LC_MESSAGES, 1, - [Define if your file defines LC_MESSAGES.]) - fi -]) - -# lib-ld.m4 serial 3 (gettext-0.13) -dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Subroutines of libtool.m4, -dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision -dnl with libtool.m4. - -dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(acl_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break ;; - *) - test "$with_gnu_ld" != yes && break ;; - esac - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_LIB_PROG_LD_GNU -]) - -# lib-link.m4 serial 6 (gettext-0.14.3) -dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_PREREQ(2.50) - -dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and -dnl augments the CPPFLAGS variable. -AC_DEFUN([AC_LIB_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - ac_cv_lib[]Name[]_libs="$LIB[]NAME" - ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" - ac_cv_lib[]Name[]_cppflags="$INC[]NAME" - ]) - LIB[]NAME="$ac_cv_lib[]Name[]_libs" - LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" - INC[]NAME="$ac_cv_lib[]Name[]_cppflags" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the - dnl results of this search when this library appears as a dependency. - HAVE_LIB[]NAME=yes - undefine([Name]) - undefine([NAME]) -]) - -dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) -dnl searches for libname and the libraries corresponding to explicit and -dnl implicit dependencies, together with the specified include files and -dnl the ability to compile and link the specified testcode. If found, it -dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and -dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. -AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - - dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - - dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, - dnl because if the user has installed lib[]Name and not disabled its use - dnl via --without-lib[]Name-prefix, he wants to use it. - ac_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - - AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIB[]NAME" - AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) - LIBS="$ac_save_LIBS" - ]) - if test "$ac_cv_lib[]Name" = yes; then - HAVE_LIB[]NAME=yes - AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) - AC_MSG_CHECKING([how to link with lib[]$1]) - AC_MSG_RESULT([$LIB[]NAME]) - else - HAVE_LIB[]NAME=no - dnl If $LIB[]NAME didn't lead to a usable library, we don't need - dnl $INC[]NAME either. - CPPFLAGS="$ac_save_CPPFLAGS" - LIB[]NAME= - LTLIB[]NAME= - fi - AC_SUBST([HAVE_LIB]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - undefine([Name]) - undefine([NAME]) -]) - -dnl Determine the platform dependent parameters needed to use rpath: -dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, -dnl hardcode_direct, hardcode_minus_L. -AC_DEFUN([AC_LIB_RPATH], -[ - dnl Tell automake >= 1.10 to complain if config.rpath is missing. - m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - libext="$acl_cv_libext" - shlibext="$acl_cv_shlibext" - hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - hardcode_direct="$acl_cv_hardcode_direct" - hardcode_minus_L="$acl_cv_hardcode_minus_L" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE(rpath, - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) -]) - -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib$1-prefix], -[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib - --without-lib$1-prefix don't search for lib$1 in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi -]) - -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) - -# lib-prefix.m4 serial 4 (gettext-0.14.2) -dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi - fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi - fi - fi - fi -]) - -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" -]) - -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- - -# serial 47 Debian 1.5.20-2 AC_PROG_LIBTOOL - - -# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) -# ----------------------------------------------------------- -# If this macro is not defined by Autoconf, define it here. -m4_ifdef([AC_PROVIDE_IFELSE], - [], - [m4_define([AC_PROVIDE_IFELSE], - [m4_ifdef([AC_PROVIDE_$1], - [$2], [$3])])]) - - -# AC_PROG_LIBTOOL -# --------------- -AC_DEFUN([AC_PROG_LIBTOOL], -[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl -dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX -dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. - AC_PROVIDE_IFELSE([AC_PROG_CXX], - [AC_LIBTOOL_CXX], - [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX - ])]) -dnl And a similar setup for Fortran 77 support - AC_PROVIDE_IFELSE([AC_PROG_F77], - [AC_LIBTOOL_F77], - [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 -])]) - -dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. -dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run -dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. - AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [ifdef([AC_PROG_GCJ], - [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) - ifdef([A][M_PROG_GCJ], - [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) - ifdef([LT_AC_PROG_GCJ], - [define([LT_AC_PROG_GCJ], - defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) -])])# AC_PROG_LIBTOOL - - -# _AC_PROG_LIBTOOL -# ---------------- -AC_DEFUN([_AC_PROG_LIBTOOL], -[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl -AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl -AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl -AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -# Prevent multiple expansion -define([AC_PROG_LIBTOOL], []) -])# _AC_PROG_LIBTOOL - - -# AC_LIBTOOL_SETUP -# ---------------- -AC_DEFUN([AC_LIBTOOL_SETUP], -[AC_PREREQ(2.50)dnl -AC_REQUIRE([AC_ENABLE_SHARED])dnl -AC_REQUIRE([AC_ENABLE_STATIC])dnl -AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_LD])dnl -AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl -AC_REQUIRE([AC_PROG_NM])dnl - -AC_REQUIRE([AC_PROG_LN_S])dnl -AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl -# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! -AC_REQUIRE([AC_OBJEXT])dnl -AC_REQUIRE([AC_EXEEXT])dnl -dnl - -AC_LIBTOOL_SYS_MAX_CMD_LEN -AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -AC_LIBTOOL_OBJDIR - -AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl -_LT_AC_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' -[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] - -# Same as above, but do not quote variable references. -[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" - -AC_CHECK_TOOL(AR, ar, false) -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_CHECK_TOOL(STRIP, strip, :) - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$SED" && SED=sed -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - AC_PATH_MAGIC - fi - ;; -esac - -AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) -AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], -enable_win32_dll=yes, enable_win32_dll=no) - -AC_ARG_ENABLE([libtool-lock], - [AC_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -AC_ARG_WITH([pic], - [AC_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) -test -z "$pic_mode" && pic_mode=default - -# Use C for the default configuration in the libtool script -tagname= -AC_LIBTOOL_LANG_C_CONFIG -_LT_AC_TAGCONFIG -])# AC_LIBTOOL_SETUP - - -# _LT_AC_SYS_COMPILER -# ------------------- -AC_DEFUN([_LT_AC_SYS_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_AC_SYS_COMPILER - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -AC_DEFUN([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` -]) - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -AC_DEFUN([_LT_COMPILER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -AC_DEFUN([_LT_LINKER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* -])# _LT_LINKER_BOILERPLATE - - -# _LT_AC_SYS_LIBPATH_AIX -# ---------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], -[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_AC_SYS_LIBPATH_AIX - - -# _LT_AC_SHELL_INIT(ARG) -# ---------------------- -AC_DEFUN([_LT_AC_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_AC_SHELL_INIT - - -# _LT_AC_PROG_ECHO_BACKSLASH -# -------------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], -[_LT_AC_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -echo=${ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null 2>&1 && unset CDPATH - -if test -z "$ECHO"; then -if test "X${echo_test_string+set}" != Xset; then -# find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string=`eval $cmd`) 2>/dev/null && - echo_test_string=`eval $cmd` && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(ECHO) -])])# _LT_AC_PROG_ECHO_BACKSLASH - - -# _LT_AC_LOCK -# ----------- -AC_DEFUN([_LT_AC_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AC_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], -[*-*-cygwin* | *-*-mingw* | *-*-pw32*) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; - ]) -esac - -need_locks="$enable_libtool_lock" - -])# _LT_AC_LOCK - - -# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], -[AC_REQUIRE([LT_AC_PROG_SED]) -AC_CACHE_CHECK([$1], [$2], - [$2=no - ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $rm conftest* -]) - -if test x"[$]$2" = xyes; then - ifelse([$5], , :, [$5]) -else - ifelse([$6], , :, [$6]) -fi -])# AC_LIBTOOL_COMPILER_OPTION - - -# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ------------------------------------------------------------ -# Check whether the given compiler option works -AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], -[AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - ifelse([$4], , :, [$4]) -else - ifelse([$5], , :, [$5]) -fi -])# AC_LIBTOOL_LINKER_OPTION - - -# AC_LIBTOOL_SYS_MAX_CMD_LEN -# -------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], -[# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ - = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -])# AC_LIBTOOL_SYS_MAX_CMD_LEN - - -# _LT_AC_CHECK_DLFCN -# -------------------- -AC_DEFUN([_LT_AC_CHECK_DLFCN], -[AC_CHECK_HEADERS(dlfcn.h)dnl -])# _LT_AC_CHECK_DLFCN - - -# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ -AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], -[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -}] -EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_AC_TRY_DLOPEN_SELF - - -# AC_LIBTOOL_DLOPEN_SELF -# ------------------- -AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], -[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -])# AC_LIBTOOL_DLOPEN_SELF - - -# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) -# --------------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler -AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* -]) -])# AC_LIBTOOL_PROG_CC_C_O - - -# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) -# ----------------------------------------- -# Check to see if we can do hard links to lock some files if needed -AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], -[AC_REQUIRE([_LT_AC_LOCK])dnl - -hard_links="nottested" -if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS - - -# AC_LIBTOOL_OBJDIR -# ----------------- -AC_DEFUN([AC_LIBTOOL_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -])# AC_LIBTOOL_OBJDIR - - -# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) -# ---------------------------------------------- -# Check hardcoding attributes. -AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_AC_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ - test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ - test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existant directories. - if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_AC_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_AC_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_AC_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH - - -# AC_LIBTOOL_SYS_LIB_STRIP -# ------------------------ -AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], -[striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) -fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -])# AC_LIBTOOL_SYS_LIB_STRIP - - -# AC_LIBTOOL_SYS_DYNAMIC_LINKER -# ----------------------------- -# PORTME Fill in your ld.so characteristics -AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], -[AC_MSG_CHECKING([dynamic linker characteristics]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no -])# AC_LIBTOOL_SYS_DYNAMIC_LINKER - - -# _LT_AC_TAGCONFIG -# ---------------- -AC_DEFUN([_LT_AC_TAGCONFIG], -[AC_ARG_WITH([tags], - [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], - [include additional configurations @<:@automatic@:>@])], - [tagnames="$withval"]) - -if test -f "$ltmain" && test -n "$tagnames"; then - if test ! -f "${ofile}"; then - AC_MSG_WARN([output file `$ofile' does not exist]) - fi - - if test -z "$LTCC"; then - eval "`$SHELL ${ofile} --config | grep '^LTCC='`" - if test -z "$LTCC"; then - AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) - else - AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) - fi - fi - - # Extract list of available tagged configurations in $ofile. - # Note that this assumes the entire list is on one line. - available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` - - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for tagname in $tagnames; do - IFS="$lt_save_ifs" - # Check whether tagname contains only valid characters - case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in - "") ;; - *) AC_MSG_ERROR([invalid tag name: $tagname]) - ;; - esac - - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null - then - AC_MSG_ERROR([tag name \"$tagname\" already exists]) - fi - - # Update the list of available tags. - if test -n "$tagname"; then - echo appending configuration tag \"$tagname\" to $ofile - - case $tagname in - CXX) - if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_LIBTOOL_LANG_CXX_CONFIG - else - tagname="" - fi - ;; - - F77) - if test -n "$F77" && test "X$F77" != "Xno"; then - AC_LIBTOOL_LANG_F77_CONFIG - else - tagname="" - fi - ;; - - GCJ) - if test -n "$GCJ" && test "X$GCJ" != "Xno"; then - AC_LIBTOOL_LANG_GCJ_CONFIG - else - tagname="" - fi - ;; - - RC) - AC_LIBTOOL_LANG_RC_CONFIG - ;; - - *) - AC_MSG_ERROR([Unsupported tag name: $tagname]) - ;; - esac - - # Append the new tag name to the list of available tags. - if test -n "$tagname" ; then - available_tags="$available_tags $tagname" - fi - fi - done - IFS="$lt_save_ifs" - - # Now substitute the updated list of available tags. - if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then - mv "${ofile}T" "$ofile" - chmod +x "$ofile" - else - rm -f "${ofile}T" - AC_MSG_ERROR([unable to update list of available tagged configurations.]) - fi -fi -])# _LT_AC_TAGCONFIG - - -# AC_LIBTOOL_DLOPEN -# ----------------- -# enable checks for dlopen support -AC_DEFUN([AC_LIBTOOL_DLOPEN], - [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) -])# AC_LIBTOOL_DLOPEN - - -# AC_LIBTOOL_WIN32_DLL -# -------------------- -# declare package support for building win32 DLLs -AC_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) -])# AC_LIBTOOL_WIN32_DLL - - -# AC_ENABLE_SHARED([DEFAULT]) -# --------------------------- -# implement the --enable-shared flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_SHARED], -[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([shared], - [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]AC_ENABLE_SHARED_DEFAULT) -])# AC_ENABLE_SHARED - - -# AC_DISABLE_SHARED -# ----------------- -#- set the default shared flag to --disable-shared -AC_DEFUN([AC_DISABLE_SHARED], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_SHARED(no) -])# AC_DISABLE_SHARED - - -# AC_ENABLE_STATIC([DEFAULT]) -# --------------------------- -# implement the --enable-static flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_STATIC], -[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([static], - [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]AC_ENABLE_STATIC_DEFAULT) -])# AC_ENABLE_STATIC - - -# AC_DISABLE_STATIC -# ----------------- -# set the default static flag to --disable-static -AC_DEFUN([AC_DISABLE_STATIC], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_STATIC(no) -])# AC_DISABLE_STATIC - - -# AC_ENABLE_FAST_INSTALL([DEFAULT]) -# --------------------------------- -# implement the --enable-fast-install flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_FAST_INSTALL], -[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([fast-install], - [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) -])# AC_ENABLE_FAST_INSTALL - - -# AC_DISABLE_FAST_INSTALL -# ----------------------- -# set the default to --disable-fast-install -AC_DEFUN([AC_DISABLE_FAST_INSTALL], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_FAST_INSTALL(no) -])# AC_DISABLE_FAST_INSTALL - - -# AC_LIBTOOL_PICMODE([MODE]) -# -------------------------- -# implement the --with-pic flag -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -AC_DEFUN([AC_LIBTOOL_PICMODE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -pic_mode=ifelse($#,1,$1,default) -])# AC_LIBTOOL_PICMODE - - -# AC_PROG_EGREP -# ------------- -# This is predefined starting with Autoconf 2.54, so this conditional -# definition can be removed once we require Autoconf 2.54 or later. -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], -[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], - [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi]) - EGREP=$ac_cv_prog_egrep - AC_SUBST([EGREP]) -])]) - - -# AC_PATH_TOOL_PREFIX -# ------------------- -# find a file program which can recognise shared library -AC_DEFUN([AC_PATH_TOOL_PREFIX], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="ifelse([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -])# AC_PATH_TOOL_PREFIX - - -# AC_PATH_MAGIC -# ------------- -# find a file program which can recognise a shared library -AC_DEFUN([AC_PATH_MAGIC], -[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# AC_PATH_MAGIC - - -# AC_PROG_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([AC_PROG_LD], -[AC_ARG_WITH([gnu-ld], - [AC_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no]) -AC_REQUIRE([LT_AC_PROG_SED])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -nto-qnx*) - lt_cv_deplibs_check_method=unknown - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown -])# AC_DEPLIBS_CHECK_METHOD - - -# AC_PROG_NM -# ---------- -# find the pathname to a BSD-compatible name lister -AC_DEFUN([AC_PROG_NM], -[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - esac - fi - done - IFS="$lt_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi]) -NM="$lt_cv_path_NM" -])# AC_PROG_NM - - -# AC_CHECK_LIBM -# ------------- -# check for math library -AC_DEFUN([AC_CHECK_LIBM], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -])# AC_CHECK_LIBM - - -# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) -# ----------------------------------- -# sets LIBLTDL to the link flags for the libltdl convenience library and -# LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-convenience to the configure arguments. Note that -# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, -# it is assumed to be `libltdl'. LIBLTDL will be prefixed with -# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' -# (note the single quotes!). If your package is not flat and you're not -# using automake, define top_builddir and top_srcdir appropriately in -# the Makefiles. -AC_DEFUN([AC_LIBLTDL_CONVENIENCE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - case $enable_ltdl_convenience in - no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; - "") enable_ltdl_convenience=yes - ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; - esac - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -])# AC_LIBLTDL_CONVENIENCE - - -# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) -# ----------------------------------- -# sets LIBLTDL to the link flags for the libltdl installable library and -# LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-install to the configure arguments. Note that -# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, -# and an installed libltdl is not found, it is assumed to be `libltdl'. -# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and top_srcdir -# appropriately in the Makefiles. -# In the future, this macro may have to be called after AC_PROG_LIBTOOL. -AC_DEFUN([AC_LIBLTDL_INSTALLABLE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - AC_CHECK_LIB(ltdl, lt_dlinit, - [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], - [if test x"$enable_ltdl_install" = xno; then - AC_MSG_WARN([libltdl not installed, but installation disabled]) - else - enable_ltdl_install=yes - fi - ]) - if test x"$enable_ltdl_install" = x"yes"; then - ac_configure_args="$ac_configure_args --enable-ltdl-install" - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - else - ac_configure_args="$ac_configure_args --enable-ltdl-install=no" - LIBLTDL="-lltdl" - LTDLINCL= - fi - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -])# AC_LIBLTDL_INSTALLABLE - - -# AC_LIBTOOL_CXX -# -------------- -# enable support for C++ libraries -AC_DEFUN([AC_LIBTOOL_CXX], -[AC_REQUIRE([_LT_AC_LANG_CXX]) -])# AC_LIBTOOL_CXX - - -# _LT_AC_LANG_CXX -# --------------- -AC_DEFUN([_LT_AC_LANG_CXX], -[AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([_LT_AC_PROG_CXXCPP]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) -])# _LT_AC_LANG_CXX - -# _LT_AC_PROG_CXXCPP -# --------------- -AC_DEFUN([_LT_AC_PROG_CXXCPP], -[ -AC_REQUIRE([AC_PROG_CXX]) -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -fi -])# _LT_AC_PROG_CXXCPP - -# AC_LIBTOOL_F77 -# -------------- -# enable support for Fortran 77 libraries -AC_DEFUN([AC_LIBTOOL_F77], -[AC_REQUIRE([_LT_AC_LANG_F77]) -])# AC_LIBTOOL_F77 - - -# _LT_AC_LANG_F77 -# --------------- -AC_DEFUN([_LT_AC_LANG_F77], -[AC_REQUIRE([AC_PROG_F77]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) -])# _LT_AC_LANG_F77 - - -# AC_LIBTOOL_GCJ -# -------------- -# enable support for GCJ libraries -AC_DEFUN([AC_LIBTOOL_GCJ], -[AC_REQUIRE([_LT_AC_LANG_GCJ]) -])# AC_LIBTOOL_GCJ - - -# _LT_AC_LANG_GCJ -# --------------- -AC_DEFUN([_LT_AC_LANG_GCJ], -[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], - [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], - [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], - [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], - [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) -])# _LT_AC_LANG_GCJ - - -# AC_LIBTOOL_RC -# -------------- -# enable support for Windows resource files -AC_DEFUN([AC_LIBTOOL_RC], -[AC_REQUIRE([LT_AC_PROG_RC]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) -])# AC_LIBTOOL_RC - - -# AC_LIBTOOL_LANG_C_CONFIG -# ------------------------ -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) -AC_DEFUN([_LT_AC_LANG_C_CONFIG], -[lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' - -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# -# Check for any special shared library compilation flags. -# -_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' - ;; - esac -fi -if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then - AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : - else - AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) - _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), - $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), - [], - [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) - - -AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -# Report which librarie types wil actually be built -AC_MSG_CHECKING([if libtool supports shared libraries]) -AC_MSG_RESULT([$can_build_shared]) - -AC_MSG_CHECKING([whether to build shared libraries]) -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case $host_os in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4* | aix5*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -AC_MSG_RESULT([$enable_shared]) - -AC_MSG_CHECKING([whether to build static libraries]) -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -AC_MSG_RESULT([$enable_static]) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC="$lt_save_CC" -])# AC_LIBTOOL_LANG_C_CONFIG - - -# AC_LIBTOOL_LANG_CXX_CONFIG -# -------------------------- -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) -AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], -[AC_LANG_PUSH(C++) -AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([_LT_AC_PROG_CXXCPP]) - -_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_AC_TAGVAR(allow_undefined_flag, $1)= -_LT_AC_TAGVAR(always_export_symbols, $1)=no -_LT_AC_TAGVAR(archive_expsym_cmds, $1)= -_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_direct, $1)=no -_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= -_LT_AC_TAGVAR(hardcode_minus_L, $1)=no -_LT_AC_TAGVAR(hardcode_automatic, $1)=no -_LT_AC_TAGVAR(module_cmds, $1)= -_LT_AC_TAGVAR(module_expsym_cmds, $1)= -_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown -_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_AC_TAGVAR(no_undefined_flag, $1)= -_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= -_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Dependencies to place before and after the object being linked: -_LT_AC_TAGVAR(predep_objects, $1)= -_LT_AC_TAGVAR(postdep_objects, $1)= -_LT_AC_TAGVAR(predeps, $1)= -_LT_AC_TAGVAR(postdeps, $1)= -_LT_AC_TAGVAR(compiler_lib_search_path, $1)= - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_LD=$LD -lt_save_GCC=$GCC -GCC=$GXX -lt_save_with_gnu_ld=$with_gnu_ld -lt_save_path_LD=$lt_cv_path_LD -if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx -else - unset lt_cv_prog_gnu_ld -fi -if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX -else - unset lt_cv_path_LD -fi -test -z "${LDCXX+set}" || LD=$LDCXX -CC=${CXX-"c++"} -compiler=$CC -_LT_AC_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) - -# We don't want -fno-exception wen compiling C++ code, so set the -# no_builtin_flag separately -if test "$GXX" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' -else - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -fi - -if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - AC_PROG_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ - grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - -else - GXX=no - with_gnu_ld=no - wlarc= -fi - -# PORTME: fill in a description of your system's C++ link characteristics -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -_LT_AC_TAGVAR(ld_shlibs, $1)=yes -case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_AC_TAGVAR(archive_cmds, $1)='' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - else - # We have old collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes ; then - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before switch to ELF - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - freebsd-elf*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - ;; - gnu*) - ;; - hpux9*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - ;; - *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - *) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - ia64*|hppa*64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' - fi - fi - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - linux*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc*) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC*) - # Portland Group C++ compiler - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - esac - ;; - lynxos*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - m88k*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - openbsd2*) - # C++ shared libraries are fairly broken - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd='echo' - ;; - osf3*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ - $rm $lib.exp' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - psos*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - sco*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. We must also pass each convience library through - # to the system linker between allextract/defaultextract. - # The C++ compiler will combine linker options so we - # cannot just pass the convience library names through - # without $wl. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' - ;; - esac - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | grep -v '^2\.7' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - fi - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - fi - ;; - esac - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - vxworks*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; -esac -AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_AC_TAGVAR(GCC, $1)="$GXX" -_LT_AC_TAGVAR(LD, $1)="$LD" - -AC_LIBTOOL_POSTDEP_PREDEP($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC=$lt_save_CC -LDCXX=$LD -LD=$lt_save_LD -GCC=$lt_save_GCC -with_gnu_ldcxx=$with_gnu_ld -with_gnu_ld=$lt_save_with_gnu_ld -lt_cv_path_LDCXX=$lt_cv_path_LD -lt_cv_path_LD=$lt_save_path_LD -lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld -lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -])# AC_LIBTOOL_LANG_CXX_CONFIG - -# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) -# ------------------------ -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" -ifelse([$1], [], -[#! $SHELL - -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e 1s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# The names of the tagged configurations supported by this script. -available_tags= - -# ### BEGIN LIBTOOL CONFIG], -[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) - -# Is the compiler the GNU C compiler? -with_gcc=$_LT_AC_TAGVAR(GCC, $1) - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_[]_LT_AC_TAGVAR(LD, $1) - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) - -# Commands used to build and install a shared archive. -archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) -archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) -module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" - -# Set to yes if exported symbols are required. -always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) - -# The commands to list exported symbols. -export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) - -# Symbols that must always be exported. -include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) - -ifelse([$1],[], -[# ### END LIBTOOL CONFIG], -[# ### END LIBTOOL TAG CONFIG: $tagname]) - -__EOF__ - -ifelse([$1],[], [ - case $host_os in - aix3*) - cat <<\EOF >> "$cfgfile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || \ - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -]) -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi -])# AC_LIBTOOL_CONFIG - - -# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------------------- -AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl - -_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI - - -# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -# --------------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], -[AC_REQUIRE([AC_CANONICAL_HOST]) -AC_REQUIRE([AC_PROG_NM]) -AC_REQUIRE([AC_OBJEXT]) -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) # Its linker distinguishes data from code symbols - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -linux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDGIRSTW]]' - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris* | sysv5*) - symcode='[[BDRT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if grep ' nm_test_var$' "$nlist" >/dev/null; then - if grep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[[]] = -{ -EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi -]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE - - -# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) -# --------------------------------------- -AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], -[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) - ifelse([$1],[CXX],[ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | os2* | pw32*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix4* | aix5*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - if test "$host_cpu" != ia64; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - icpc* | ecpc*) - # Intel C++ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC*) - # Portland Group C++ compiler. - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - sco*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - *) - ;; - esac - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - unixware*) - ;; - vxworks*) - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - esac - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - newsos6) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - linux*) - case $cc_basename in - icc* | ecc*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' - ;; - - solaris*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - unicos*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then - AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), - [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" - ;; -esac -]) - - -# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) -# ------------------------------------ -# See if the linker supports building shared libraries. -AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], -[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -ifelse([$1],[CXX],[ - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix4* | aix5*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - else - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' - ;; - linux*) - _LT_AC_TAGVAR(link_all_deplibs, $1)=no - ;; - *) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -],[ - runpath_var= - _LT_AC_TAGVAR(allow_undefined_flag, $1)= - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)= - _LT_AC_TAGVAR(archive_expsym_cmds, $1)= - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= - _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown - _LT_AC_TAGVAR(hardcode_automatic, $1)=no - _LT_AC_TAGVAR(module_cmds, $1)= - _LT_AC_TAGVAR(module_expsym_cmds, $1)= - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_AC_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - # Just being paranoid about ensuring that cc_basename is set. - _LT_CC_BASENAME([$compiler]) - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_AC_TAGVAR(ld_shlibs, $1)=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_addflag= - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - esac - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test $supports_anon_versioning = yes; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - _LT_AC_TAGVAR(link_all_deplibs, $1)=no - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - _LT_AC_TAGVAR(ld_shlibs, $1)=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sunos4*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - else - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_AC_TAGVAR(archive_cmds, $1)='' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - else - # We have old collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - # see comment about different semantics on the GNU ld section - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - bsdi[[45]]*) - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' - _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - if test "$GCC" = yes ; then - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi - ;; - - dgux*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - ;; - *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - sco3.2v5*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - wlarc='' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. - # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; - *) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; - esac - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4.2uw2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv5*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi -]) -AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_AC_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) - _LT_AC_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) - then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac -])# AC_LIBTOOL_PROG_LD_SHLIBS - - -# _LT_AC_FILE_LTDLL_C -# ------------------- -# Be careful that the start marker always follows a newline. -AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include -# #undef WIN32_LEAN_AND_MEAN -# #include -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ -])# _LT_AC_FILE_LTDLL_C - - -# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) -# --------------------------------- -AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) - - -# old names -AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) -AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) -AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) -AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) -AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) - -# This is just to silence aclocal about the macro not being used -ifelse([AC_DISABLE_FAST_INSTALL]) - -AC_DEFUN([LT_AC_PROG_GCJ], -[AC_CHECK_TOOL(GCJ, gcj, no) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS) -]) - -AC_DEFUN([LT_AC_PROG_RC], -[AC_CHECK_TOOL(RC, windres, no) -]) - -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -# LT_AC_PROG_SED -# -------------- -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -AC_DEFUN([LT_AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_MSG_RESULT([$SED]) -]) - -# longdouble.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether the compiler supports the 'long double' type. -dnl Prerequisite: AC_PROG_CC - -AC_DEFUN([gt_TYPE_LONGDOUBLE], -[ - AC_CACHE_CHECK([for long double], gt_cv_c_long_double, - [if test "$GCC" = yes; then - gt_cv_c_long_double=yes - else - AC_TRY_COMPILE([ - /* The Stardent Vistra knows sizeof(long double), but does not support it. */ - long double foo = 0.0; - /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ - int array [2*(sizeof(long double) >= sizeof(double)) - 1]; - ], , - gt_cv_c_long_double=yes, gt_cv_c_long_double=no) - fi]) - if test $gt_cv_c_long_double = yes; then - AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) - fi -]) - -# longlong.m4 serial 5 -dnl Copyright (C) 1999-2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_LONG_LONG if 'long long' works. - -AC_DEFUN([gl_AC_TYPE_LONG_LONG], -[ - AC_CACHE_CHECK([for long long], ac_cv_type_long_long, - [AC_TRY_LINK([long long ll = 1LL; int i = 63;], - [long long llmax = (long long) -1; - return ll << i | ll >> i | llmax / ll | llmax % ll;], - ac_cv_type_long_long=yes, - ac_cv_type_long_long=no)]) - if test $ac_cv_type_long_long = yes; then - AC_DEFINE(HAVE_LONG_LONG, 1, - [Define if you have the 'long long' type.]) - fi -]) - -# nls.m4 serial 2 (gettext-0.14.3) -dnl Copyright (C) 1995-2003, 2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2003. - -AC_PREREQ(2.50) - -AC_DEFUN([AM_NLS], -[ - AC_MSG_CHECKING([whether NLS is requested]) - dnl Default is enabled NLS - AC_ARG_ENABLE(nls, - [ --disable-nls do not use Native Language Support], - USE_NLS=$enableval, USE_NLS=yes) - AC_MSG_RESULT($USE_NLS) - AC_SUBST(USE_NLS) -]) - -AC_DEFUN([AM_MKINSTALLDIRS], -[ - dnl Tell automake >= 1.10 to complain if mkinstalldirs is missing. - m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([mkinstalldirs])]) - dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly - dnl find the mkinstalldirs script in another subdir but $(top_srcdir). - dnl Try to locate it. - MKINSTALLDIRS= - if test -n "$ac_aux_dir"; then - case "$ac_aux_dir" in - /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; - *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; - esac - fi - if test -z "$MKINSTALLDIRS"; then - MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" - fi - AC_SUBST(MKINSTALLDIRS) -]) - -# po.m4 serial 7 (gettext-0.14.3) -dnl Copyright (C) 1995-2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2003. - -AC_PREREQ(2.50) - -dnl Checks for all prerequisites of the po subdirectory. -AC_DEFUN([AM_PO_SUBDIRS], -[ - AC_REQUIRE([AC_PROG_MAKE_SET])dnl - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AM_NLS])dnl - - dnl Perform the following tests also if --disable-nls has been given, - dnl because they are needed for "make dist" to work. - - dnl Search for GNU msgfmt in the PATH. - dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. - dnl The second test excludes FreeBSD msgfmt. - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - - dnl Search for GNU xgettext 0.12 or newer in the PATH. - dnl The first test excludes Solaris xgettext and early GNU xgettext versions. - dnl The second test excludes FreeBSD xgettext. - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - - dnl Search for GNU msgmerge 0.11 or newer in the PATH. - AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, - [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU msgfmt. - if test "$GMSGFMT" != ":"; then - dnl If it is no GNU msgfmt we define it as : so that the - dnl Makefiles still can work. - if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && - (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` - AC_MSG_RESULT( - [found $GMSGFMT program is not GNU msgfmt; ignore it]) - GMSGFMT=":" - fi - fi - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU xgettext. - if test "$XGETTEXT" != ":"; then - dnl If it is no GNU xgettext we define it as : so that the - dnl Makefiles still can work. - if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && - (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - AC_MSG_RESULT( - [found xgettext program is not GNU xgettext; ignore it]) - XGETTEXT=":" - fi - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - fi - - AC_OUTPUT_COMMANDS([ - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - # Treat a directory as a PO directory if and only if it has a - # POTFILES.in file. This allows packages to have multiple PO - # directories under different names or in different locations. - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assigment from automake. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - # Compute POFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) - # Compute UPDATEPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) - # Compute DUMMYPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) - # Compute GMOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - UPDATEPOFILES= - DUMMYPOFILES= - GMOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done], - [# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it - # from automake. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - ]) -]) - -dnl Postprocesses a Makefile in a directory containing PO files. -AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], -[ - # When this code is run, in config.status, two variables have already been - # set: - # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, - # - LINGUAS is the value of the environment variable LINGUAS at configure - # time. - -changequote(,)dnl - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - # Find a way to echo strings without interpreting backslash. - if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then - gt_echo='echo' - else - if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then - gt_echo='printf %s\n' - else - echo_func () { - cat < "$ac_file.tmp" - if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then - # Add dependencies that cannot be formulated as a simple suffix rule. - for lang in $ALL_LINGUAS; do - frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` - cat >> "$ac_file.tmp" < /dev/null; then - # Add dependencies that cannot be formulated as a simple suffix rule. - for lang in $ALL_LINGUAS; do - frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` - cat >> "$ac_file.tmp" <> "$ac_file.tmp" < -#include -/* The string "%2$d %1$d", with dollar characters protected from the shell's - dollar expansion (possibly an autoconf bug). */ -static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; -static char buf[100]; -int main () -{ - sprintf (buf, format, 33, 55); - return (strcmp (buf, "55 33") != 0); -}], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no, - [ - AC_EGREP_CPP(notposix, [ -#if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ - notposix -#endif - ], gt_cv_func_printf_posix="guessing no", - gt_cv_func_printf_posix="guessing yes") - ]) - ]) - case $gt_cv_func_printf_posix in - *yes) - AC_DEFINE(HAVE_POSIX_PRINTF, 1, - [Define if your printf() function supports format strings with positions.]) - ;; - esac -]) - -# progtest.m4 serial 4 (gettext-0.14.2) -dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1996. - -AC_PREREQ(2.50) - -# Search path for a program which passes the given test. - -dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -AC_DEFUN([AM_PATH_PROG_WITH_TEST], -[ -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "$2", so it can be a program name with args. -set dummy $2; ac_word=[$]2 -AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL(ac_cv_path_$1, -[case "[$]$1" in - [[\\/]]* | ?:[[\\/]]*) - ac_cv_path_$1="[$]$1" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in ifelse([$5], , $PATH, [$5]); do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD - if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" -dnl If no 4th arg is given, leave the cache variable unset, -dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -])dnl - ;; -esac])dnl -$1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$]$1) -else - AC_MSG_RESULT(no) -fi -AC_SUBST($1)dnl -]) - -# signed.m4 serial 1 (gettext-0.10.40) -dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([bh_C_SIGNED], -[ - AC_CACHE_CHECK([for signed], bh_cv_c_signed, - [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)]) - if test $bh_cv_c_signed = no; then - AC_DEFINE(signed, , - [Define to empty if the C compiler doesn't support this keyword.]) - fi -]) - -# size_max.m4 serial 2 -dnl Copyright (C) 2003 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([gl_SIZE_MAX], -[ - AC_CHECK_HEADERS(stdint.h) - dnl First test whether the system already has SIZE_MAX. - AC_MSG_CHECKING([for SIZE_MAX]) - result= - AC_EGREP_CPP([Found it], [ -#include -#if HAVE_STDINT_H -#include -#endif -#ifdef SIZE_MAX -Found it -#endif -], result=yes) - if test -z "$result"; then - dnl Define it ourselves. Here we assume that the type 'size_t' is not wider - dnl than the type 'unsigned long'. - dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr', - dnl which is guaranteed to work from LONG_MIN to LONG_MAX. - _AC_COMPUTE_INT([~(size_t)0 / 10], res_hi, - [#include ], result=?) - _AC_COMPUTE_INT([~(size_t)0 % 10], res_lo, - [#include ], result=?) - _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint, - [#include ], result=?) - if test "$fits_in_uint" = 1; then - dnl Even though SIZE_MAX fits in an unsigned int, it must be of type - dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. - AC_TRY_COMPILE([#include - extern size_t foo; - extern unsigned long foo; - ], [], fits_in_uint=0) - fi - if test -z "$result"; then - if test "$fits_in_uint" = 1; then - result="$res_hi$res_lo"U - else - result="$res_hi$res_lo"UL - fi - else - dnl Shouldn't happen, but who knows... - result='~(size_t)0' - fi - fi - AC_MSG_RESULT([$result]) - if test "$result" != yes; then - AC_DEFINE_UNQUOTED([SIZE_MAX], [$result], - [Define as the maximum value of type 'size_t', if the system doesn't define it.]) - fi -]) - -# stdint_h.m4 serial 5 -dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_STDINT_H_WITH_UINTMAX if exists, -# doesn't clash with , and declares uintmax_t. - -AC_DEFUN([gl_AC_HEADER_STDINT_H], -[ - AC_CACHE_CHECK([for stdint.h], gl_cv_header_stdint_h, - [AC_TRY_COMPILE( - [#include -#include ], - [uintmax_t i = (uintmax_t) -1;], - gl_cv_header_stdint_h=yes, - gl_cv_header_stdint_h=no)]) - if test $gl_cv_header_stdint_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, - [Define if exists, doesn't clash with , - and declares uintmax_t. ]) - fi -]) - -# uintmax_t.m4 serial 9 -dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -AC_PREREQ(2.13) - -# Define uintmax_t to 'unsigned long' or 'unsigned long long' -# if it is not already defined in or . - -AC_DEFUN([gl_AC_TYPE_UINTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then - AC_REQUIRE([gl_AC_TYPE_UNSIGNED_LONG_LONG]) - test $ac_cv_type_unsigned_long_long = yes \ - && ac_type='unsigned long long' \ - || ac_type='unsigned long' - AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, - [Define to unsigned long or unsigned long long - if and don't define.]) - else - AC_DEFINE(HAVE_UINTMAX_T, 1, - [Define if you have the 'uintmax_t' type in or .]) - fi -]) - -# ulonglong.m4 serial 4 -dnl Copyright (C) 1999-2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_UNSIGNED_LONG_LONG if 'unsigned long long' works. - -AC_DEFUN([gl_AC_TYPE_UNSIGNED_LONG_LONG], -[ - AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, - [AC_TRY_LINK([unsigned long long ull = 1ULL; int i = 63;], - [unsigned long long ullmax = (unsigned long long) -1; - return ull << i | ull >> i | ullmax / ull | ullmax % ull;], - ac_cv_type_unsigned_long_long=yes, - ac_cv_type_unsigned_long_long=no)]) - if test $ac_cv_type_unsigned_long_long = yes; then - AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, - [Define if you have the 'unsigned long long' type.]) - fi -]) - -# wchar_t.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether has the 'wchar_t' type. -dnl Prerequisite: AC_PROG_CC - -AC_DEFUN([gt_TYPE_WCHAR_T], -[ - AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t, - [AC_TRY_COMPILE([#include - wchar_t foo = (wchar_t)'\0';], , - gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)]) - if test $gt_cv_c_wchar_t = yes; then - AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.]) - fi -]) - -# wint_t.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 2003 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether has the 'wint_t' type. -dnl Prerequisite: AC_PROG_CC - -AC_DEFUN([gt_TYPE_WINT_T], -[ - AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t, - [AC_TRY_COMPILE([#include - wint_t foo = (wchar_t)'\0';], , - gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)]) - if test $gt_cv_c_wint_t = yes; then - AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.]) - fi -]) - -# xsize.m4 serial 3 -dnl Copyright (C) 2003-2004 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_XSIZE], -[ - dnl Prerequisites of lib/xsize.h. - AC_REQUIRE([gl_SIZE_MAX]) - AC_REQUIRE([AC_C_INLINE]) - AC_CHECK_HEADERS(stdint.h) -]) - -# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION so it can be traced. -# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.6])]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 7 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE]) -AC_SUBST([$1_FALSE]) -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH]) -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -#serial 3 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. -AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 12 - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.58])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AM_PROG_INSTALL_SH -AM_PROG_INSTALL_STRIP -AC_REQUIRE([AM_PROG_MKDIR_P])dnl -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -]) -]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $1 | $1:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"$am_aux_dir/install-sh"} -AC_SUBST(install_sh)]) - -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_MKDIR_P -# --------------- -# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. -# -# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories -# created by `make install' are always world readable, even if the -# installer happens to have an overly restrictive umask (e.g. 077). -# This was a mistake. There are at least two reasons why we must not -# use `-m 0755': -# - it causes special bits like SGID to be ignored, -# - it may be too restrictive (some setups expect 775 directories). -# -# Do not use -m 0755 and let people choose whatever they expect by -# setting umask. -# -# We cannot accept any implementation of `mkdir' that recognizes `-p'. -# Some implementations (such as Solaris 8's) are not thread-safe: if a -# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' -# concurrently, both version can detect that a/ is missing, but only -# one can create it and the other will error out. Consequently we -# restrict ourselves to GNU make (using the --version option ensures -# this.) -AC_DEFUN([AM_PROG_MKDIR_P], -[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in - # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' -else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - for d in ./-p ./--version; - do - test -d $d && rmdir $d - done - # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. - if test -f "$ac_aux_dir/mkinstalldirs"; then - mkdir_p='$(mkinstalldirs)' - else - mkdir_p='$(install_sh) -d' - fi -fi -AC_SUBST([mkdir_p])]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([acinclude.m4]) diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.am deleted file mode 100644 index eff2f893fc..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: apps Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 5.6.1999 -# ************************************************************************* - -INCLUDES = -I.. - -bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms - -# build gsmsmsd from gsmsmsd.cc and libgsmme.la -gsmsmsd_SOURCES = gsmsmsd.cc -gsmsmsd_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmpb from gsmpb.cc and libgsmme.la -gsmpb_SOURCES = gsmpb.cc -gsmpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmctl from gsmctl.cc and libgsmme.la -gsmctl_SOURCES = gsmctl.cc -gsmctl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmsendsms from gsmsendsms.cc and libgsmme.la -gsmsendsms_SOURCES = gsmsendsms.cc -gsmsendsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmsmsstore from gsmsmsstore.cc and libgsmme.la -gsmsmsstore_SOURCES = gsmsmsstore.cc -gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.in deleted file mode 100644 index c18e2df06b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/Makefile.in +++ /dev/null @@ -1,442 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: apps Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 5.6.1999 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -INCLUDES = -I.. - -bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms - -# build gsmsmsd from gsmsmsd.cc and libgsmme.la -gsmsmsd_SOURCES = gsmsmsd.cc -gsmsmsd_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmpb from gsmpb.cc and libgsmme.la -gsmpb_SOURCES = gsmpb.cc -gsmpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmctl from gsmctl.cc and libgsmme.la -gsmctl_SOURCES = gsmctl.cc -gsmctl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmsendsms from gsmsendsms.cc and libgsmme.la -gsmsendsms_SOURCES = gsmsendsms.cc -gsmsendsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build gsmsmsstore from gsmsmsstore.cc and libgsmme.la -gsmsmsstore_SOURCES = gsmsmsstore.cc -gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) -subdir = apps -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -bin_PROGRAMS = gsmsmsstore$(EXEEXT) gsmctl$(EXEEXT) gsmsmsd$(EXEEXT) \ - gsmpb$(EXEEXT) gsmsendsms$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) - -am_gsmctl_OBJECTS = gsmctl.$(OBJEXT) -gsmctl_OBJECTS = $(am_gsmctl_OBJECTS) -gsmctl_DEPENDENCIES = ../gsmlib/libgsmme.la -gsmctl_LDFLAGS = -am_gsmpb_OBJECTS = gsmpb.$(OBJEXT) -gsmpb_OBJECTS = $(am_gsmpb_OBJECTS) -gsmpb_DEPENDENCIES = ../gsmlib/libgsmme.la -gsmpb_LDFLAGS = -am_gsmsendsms_OBJECTS = gsmsendsms.$(OBJEXT) -gsmsendsms_OBJECTS = $(am_gsmsendsms_OBJECTS) -gsmsendsms_DEPENDENCIES = ../gsmlib/libgsmme.la -gsmsendsms_LDFLAGS = -am_gsmsmsd_OBJECTS = gsmsmsd.$(OBJEXT) -gsmsmsd_OBJECTS = $(am_gsmsmsd_OBJECTS) -gsmsmsd_DEPENDENCIES = ../gsmlib/libgsmme.la -gsmsmsd_LDFLAGS = -am_gsmsmsstore_OBJECTS = gsmsmsstore.$(OBJEXT) -gsmsmsstore_OBJECTS = $(am_gsmsmsstore_OBJECTS) -gsmsmsstore_DEPENDENCIES = ../gsmlib/libgsmme.la -gsmsmsstore_LDFLAGS = - -DEFS = @DEFS@ -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp -am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsmctl.Po ./$(DEPDIR)/gsmpb.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsmsendsms.Po ./$(DEPDIR)/gsmsmsd.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsmsmsstore.Po -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CXXFLAGS = @CXXFLAGS@ -DIST_SOURCES = $(gsmctl_SOURCES) $(gsmpb_SOURCES) $(gsmsendsms_SOURCES) \ - $(gsmsmsd_SOURCES) $(gsmsmsstore_SOURCES) -DIST_COMMON = Makefile.am Makefile.in -SOURCES = $(gsmctl_SOURCES) $(gsmpb_SOURCES) $(gsmsendsms_SOURCES) $(gsmsmsd_SOURCES) $(gsmsmsstore_SOURCES) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .cc .lo .o .obj -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu apps/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - || test -f $$p1 \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ - rm -f $(DESTDIR)$(bindir)/$$f; \ - done - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -gsmctl$(EXEEXT): $(gsmctl_OBJECTS) $(gsmctl_DEPENDENCIES) - @rm -f gsmctl$(EXEEXT) - $(CXXLINK) $(gsmctl_LDFLAGS) $(gsmctl_OBJECTS) $(gsmctl_LDADD) $(LIBS) -gsmpb$(EXEEXT): $(gsmpb_OBJECTS) $(gsmpb_DEPENDENCIES) - @rm -f gsmpb$(EXEEXT) - $(CXXLINK) $(gsmpb_LDFLAGS) $(gsmpb_OBJECTS) $(gsmpb_LDADD) $(LIBS) -gsmsendsms$(EXEEXT): $(gsmsendsms_OBJECTS) $(gsmsendsms_DEPENDENCIES) - @rm -f gsmsendsms$(EXEEXT) - $(CXXLINK) $(gsmsendsms_LDFLAGS) $(gsmsendsms_OBJECTS) $(gsmsendsms_LDADD) $(LIBS) -gsmsmsd$(EXEEXT): $(gsmsmsd_OBJECTS) $(gsmsmsd_DEPENDENCIES) - @rm -f gsmsmsd$(EXEEXT) - $(CXXLINK) $(gsmsmsd_LDFLAGS) $(gsmsmsd_OBJECTS) $(gsmsmsd_LDADD) $(LIBS) -gsmsmsstore$(EXEEXT): $(gsmsmsstore_OBJECTS) $(gsmsmsstore_DEPENDENCIES) - @rm -f gsmsmsstore$(EXEEXT) - $(CXXLINK) $(gsmsmsstore_LDFLAGS) $(gsmsmsstore_OBJECTS) $(gsmsmsstore_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmctl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmpb.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsendsms.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsmsd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsmsstore.Po@am__quote@ - -distclean-depend: - -rm -rf ./$(DEPDIR) - -.cc.o: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -.cc.obj: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `cygpath -w $<` - -.cc.lo: -@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -CXXDEPMODE = @CXXDEPMODE@ - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ETAGS = etags -ETAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-compile distclean-depend \ - distclean-generic distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: install-binPROGRAMS - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -uninstall-am: uninstall-binPROGRAMS uninstall-info-am - -.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool distclean distclean-compile \ - distclean-depend distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am info info-am install \ - install-am install-binPROGRAMS install-data install-data-am \ - install-exec install-exec-am install-info install-info-am \ - install-man install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool tags uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmctl.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmctl.cc deleted file mode 100644 index df6fd28e1d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmctl.cc +++ /dev/null @@ -1,635 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmctl.cc -// * -// * Purpose: GSM mobile phone control program -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 11.7.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#include - -using namespace std; -using namespace gsmlib; - -// my ME - -static MeTa *m; - -// information parameters - -enum InfoParameter {AllInfo, // print all info - MeInfo, // MeInfo must be first! - FunctionalityInfo, - OperatorInfo, - CurrentOperatorInfo, - FacilityLockStateInfo, - FacilityLockCapabilityInfo, - PasswordInfo, - PINInfo, - CLIPInfo, - CallForwardingInfo, - BatteryInfo, - BitErrorInfo, - SCAInfo, - CharSetInfo, - SignalInfo}; // SignalInfo must be last! - -// operation parameters - -// FIXME operations not implemented yet - -// options - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"operation", required_argument, (int*)NULL, 'o'}, - {"device", required_argument, (int*)NULL, 'd'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -// helper function, prints forwarding info - -void printForwardReason(string s, ForwardInfo &info) -{ - cout << s << " " - << (info._active ? _("active ") : _("inactive ")) - << _("number: ") << info._number - << _(" subaddr: ") << info._subAddr - << _(" time: ") << info._time << endl; -} - -// print information - -static void printInfo(InfoParameter ip) -{ - switch (ip) - { - case MeInfo: - { - MEInfo mei = m->getMEInfo(); - cout << _(" Manufacturer: ") << mei._manufacturer << endl - << _(" Model: ") << mei._model << endl - << _(" Revision: ") << mei._revision << endl - << _(" Serial Number: ") << mei._serialNumber << endl; - break; - } - case FunctionalityInfo: - { - try { - int fun; - fun = m->getFunctionalityLevel(); - cout << _(" Functionality Level: ") << fun << endl; - } catch (GsmException &x) { - cout << _(" Functionality Level: ") << _("unsupported") << endl; - } - break; - } - case OperatorInfo: - { - int count = 0; - vector opis = m->getAvailableOPInfo(); - for (vector::iterator i = opis.begin(); i != opis.end(); ++i) - { - cout << " Status: "); - switch (i->_status) - { - case UnknownOPStatus: cout << _("unknown"); break; - case CurrentOPStatus: cout << _("current"); break; - case AvailableOPStatus: cout << _("available"); break; - case ForbiddenOPStatus: cout << _("forbidden"); break; - } - cout << _(" Long name: '") << i->_longName << "' " - << _(" Short name: '") << i->_shortName << "' " - << _(" Numeric name: ") << i->_numericName << endl; - ++count; - } - break; - } - case CurrentOperatorInfo: - { - OPInfo opi = m->getCurrentOPInfo(); - cout << "" - << _(" Long name: '") << opi._longName << "' " - << _(" Short name: '") << opi._shortName << "' " - << _(" Numeric name: ") << opi._numericName - << _(" Mode: "); - switch (opi._mode) - { - case AutomaticOPMode: cout << _("automatic"); break; - case ManualOPMode: cout << _("manual"); break; - case DeregisterOPMode: cout << _("deregister"); break; - case ManualAutomaticOPMode: cout << _("manual/automatic"); break; - } - cout << endl; - break; - } - case FacilityLockStateInfo: - { - int count = 0; - vector fclc = m->getFacilityLockCapabilities(); - for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) - if (*i != "AB" && *i != "AG" && *i != "AC") - { - cout << " '" << *i << "'"; - try - { - if (m->getFacilityLockStatus(*i, VoiceFacility)) - cout << _(" Voice"); - } - catch (GsmException &e) - { - cout << _(" unknown"); - } - try - { - if (m->getFacilityLockStatus(*i, DataFacility)) - cout << _(" Data"); - } - catch (GsmException &e) - { - cout << _(" unknown"); - } - try - { - if (m->getFacilityLockStatus(*i, FaxFacility)) - cout << _(" Fax"); - } - catch (GsmException &e) - { - cout << _(" unknown"); - } - cout << endl; - ++count; - } - break; - } - case FacilityLockCapabilityInfo: - { - cout << " "; - vector fclc = m->getFacilityLockCapabilities(); - for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) - cout << "'" << *i << "' "; - cout << endl; - break; - } - case PasswordInfo: - { - vector pwi = m->getPasswords(); - int count = 0; - for (vector::iterator i = pwi.begin(); i != pwi.end(); ++i) - { - cout << " '" - << i->_facility << "' " << i->_maxPasswdLen << endl; - ++count; - } - break; - } - case PINInfo: - { - cout << " " << m->getPINStatus() << endl; - break; - } - case CLIPInfo: - { - cout << " " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl; - break; - } - case CallForwardingInfo: - { - for (int r = 0; r < 4; ++r) - { - string text; - switch (r) - { - case 0: text = _("UnconditionalReason"); break; - case 1: text = _("MobileBusyReason"); break; - case 2: text = _("NoReplyReason"); break; - case 3: text = _("NotReachableReason"); break; - } - ForwardInfo voice, fax, data; - m->getCallForwardInfo((ForwardReason)r, voice, fax, data); - cout << " " + text + _(" Voice"), voice); - cout << " " + text + _(" Data"), data); - cout << " " + text + _(" Fax"), fax); - } - break; - } - case BatteryInfo: - { - cout << " "; - int bcs = m->getBatteryChargeStatus(); - switch (bcs) - { - case 0: cout << _("0 ME is powered by the battery") << endl; break; - case 1: cout << _("1 ME has a battery connected, but is not powered by it") - << endl; break; - case 2: cout << _("2 ME does not have a battery connected") << endl; break; - case 3: - cout << _("3 Recognized power fault, calls inhibited") << endl; - break; - } - cout << " " << m->getBatteryCharge() << endl; - break; - } - case BitErrorInfo: - { - cout << " " << m->getBitErrorRate() << endl; - break; - } - case SCAInfo: - { - cout << " " << m->getServiceCentreAddress() << endl; - break; - } - case CharSetInfo: - { - cout << " "; - vector cs = m->getSupportedCharSets(); - for (vector::iterator i = cs.begin(); i != cs.end(); ++i) - cout << "'" << *i << "' "; - cout << endl; - cout << " '" << m->getCurrentCharSet() << "'" << endl; - break; - } - case SignalInfo: - { - cout << " " << m->getSignalStrength() << endl; - break; - } - default: - assert(0); - break; - } -} - -// convert facility class string of the form "", "all", or any combination -// of "v" (voice), "d" (data), or "f" (fax) to numeric form - -FacilityClass strToFacilityClass(string facilityClassS) -{ - facilityClassS = lowercase(facilityClassS); - FacilityClass facilityClass = (FacilityClass)0; - if (facilityClassS == "all" || facilityClassS == "") - return (FacilityClass)ALL_FACILITIES; - - // OR in facility class bits - for (unsigned int i = 0; i < facilityClassS.length(); ++i) - if (facilityClassS[i] == 'v') - facilityClass = (FacilityClass)(facilityClass | VoiceFacility); - else if (facilityClassS[i] == 'd') - facilityClass = (FacilityClass)(facilityClass | DataFacility); - else if (facilityClassS[i] == 'f') - facilityClass = (FacilityClass)(facilityClass | FaxFacility); - else - throw GsmException( - stringPrintf(_("unknown facility class parameter '%c'"), - facilityClassS[i]), ParameterError); - - return facilityClass; -} - -// check if argc - optind is in range min..max -// throw exception otherwise - -void checkParamCount(int optind, int argc, int min, int max) -{ - int paramCount = argc - optind; - if (paramCount < min) - throw GsmException(stringPrintf(_("not enough parameters, minimum number " - "of parameters is %d"), min), - ParameterError); - else if (paramCount > max) - throw GsmException(stringPrintf(_("too many parameters, maximum number " - "of parameters is %d"), max), - ParameterError); -} - -// *** main program - -int main(int argc, char *argv[]) -{ - try - { - // handle command line options - string device = "/dev/mobilephone"; - string operation; - string baudrate; - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy)) - != -1) - switch (opt) - { - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 'd': - device = optarg; - break; - case 'o': - operation = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-b baudrate][-d device][-h]" - "[-I init string][-o operation]\n" - " [-v][-X]{parameters}") << endl - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -d, --device sets the destination device to " - "connect to") << endl - << _(" -h, --help prints this message") << endl - << _(" -I, --init device AT init sequence") << endl - << _(" -o, --operation operation to perform on the mobile \n" - " phone with the specified parameters") - << endl - << _(" -v, --version prints version and exits") << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << endl - << _(" parameters parameters to use for the operation\n" - " (if an operation is given) or\n" - " a specification which kind of\n" - " information to read from the mobile " - "phone") - << endl << endl - << _("Refer to gsmctl(1) for details on the available parameters" - " and operations.") - << endl << endl; - exit(0); - break; - case '?': - throw GsmException(_("unknown option"), ParameterError); - break; - } - - // open the port and ME/TA - m = new MeTa(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (device, - baudrate == "" ? - DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), - initString, swHandshake)); - - if (operation == "") - { // process info parameters - for (int i = optind; i < argc; ++i) - { - string param = lowercase(argv[i]); - if (param == "all") - for (int ip = MeInfo; ip <= SignalInfo; ++ip) - printInfo((InfoParameter)ip); - else if (param == "me") - printInfo(MeInfo); - else if (param == "fun") - printInfo(FunctionalityInfo); - else if (param == "op") - printInfo(OperatorInfo); - else if (param == "currop") - printInfo(CurrentOperatorInfo); - else if (param == "flstat") - printInfo(FacilityLockStateInfo); - else if (param == "flcap") - printInfo(FacilityLockCapabilityInfo); - else if (param == "pw") - printInfo(PasswordInfo); - else if (param == "pin") - printInfo(PINInfo); - else if (param == "clip") - printInfo(CLIPInfo); - else if (param == "forw") - printInfo(CallForwardingInfo); - else if (param == "batt") - printInfo(BatteryInfo); - else if (param == "biterr") - printInfo(BitErrorInfo); - else if (param == "sig") - printInfo(SignalInfo); - else if (param == "sca") - printInfo(SCAInfo); - else if (param == "cset") - printInfo(CharSetInfo); - else - throw GsmException( - stringPrintf(_("unknown information parameter '%s'"), - param.c_str()), - ParameterError); - } - } - else - { // process operation - operation = lowercase(operation); - if (operation == "dial") - { - // dial: number - checkParamCount(optind, argc, 1, 1); - - m->dial(argv[optind]); - - // wait for keypress from stdin - char c; - read(1, &c, 1); - } - else if (operation == "on") - { - m->setFunctionalityLevel(1); - } - else if (operation == "off") - { - m->setFunctionalityLevel(0); - } - else if (operation == "pin") - { - // pin: PIN - checkParamCount(optind, argc, 1, 1); - - m->setPIN(argv[optind]); - } - else if (operation == "setop") - { - // setop: opmode numeric FIXME allow long and numeric too - checkParamCount(optind, argc, 2, 2); - string opmodeS = lowercase(argv[optind]); - OPModes opmode; - if (opmodeS == "automatic") - opmode = AutomaticOPMode; - else if (opmodeS == "manual") - opmode = ManualOPMode; - else if (opmodeS == "deregister") - opmode = DeregisterOPMode; - else if (opmodeS == "manualautomatic") - opmode = ManualAutomaticOPMode; - else - throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"), - opmodeS.c_str()), ParameterError); - - m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1])); - } - else if (operation == "lock") - { - // lock: facility [facilityclass] [passwd] - checkParamCount(optind, argc, 1, 3); - string passwd = (argc - optind == 3) ? - (string)argv[optind + 2] : (string)""; - - m->lockFacility(argv[optind], - (argc - optind >= 2) ? - strToFacilityClass(argv[optind + 1]) : - (FacilityClass)ALL_FACILITIES, - passwd); - } - else if (operation == "unlock") - { - // unlock: facility [facilityclass] [passwd] - checkParamCount(optind, argc, 1, 3); - string passwd = argc - optind == 3 ? argv[optind + 2] : ""; - - m->unlockFacility(argv[optind], - (argc - optind >= 2) ? - strToFacilityClass(argv[optind + 1]) : - (FacilityClass)ALL_FACILITIES, - passwd); - } - else if (operation == "setpw") - { - // set password: facility oldpasswd newpasswd - checkParamCount(optind, argc, 1, 3); - string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : ""; - string newPasswd = argc - optind == 3 ? argv[optind + 2] : ""; - - m->setPassword(argv[optind], oldPasswd, newPasswd); - } - else if (operation == "forw") - { - // call forwarding: mode reason number [facilityclass] [forwardtime] - checkParamCount(optind, argc, 2, 5); - - // get optional parameters facility class and forwardtime - int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) : - NOT_SET; - FacilityClass facilityClass = - argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) : - (FacilityClass)ALL_FACILITIES; - - // get forward reason - string reasonS = lowercase(argv[optind + 1]); - ForwardReason reason; - if (reasonS == "unconditional") - reason = UnconditionalReason; - else if (reasonS == "mobilebusy") - reason = MobileBusyReason; - else if (reasonS == "noreply") - reason = NoReplyReason; - else if (reasonS == "notreachable") - reason = NotReachableReason; - else if (reasonS == "all") - reason = AllReasons; - else if (reasonS == "allconditional") - reason = AllConditionalReasons; - else - throw GsmException( - stringPrintf(_("unknown forward reason parameter '%s'"), - reasonS.c_str()), ParameterError); - - // get mode - string modeS = lowercase(argv[optind]); - ForwardMode mode; - if (modeS == "disable") - mode = DisableMode; - else if (modeS == "enable") - mode = EnableMode; - else if (modeS == "register") - mode = RegistrationMode; - else if (modeS == "erase") - mode = ErasureMode; - else - throw GsmException( - stringPrintf(_("unknown forward mode parameter '%s'"), - modeS.c_str()), ParameterError); - - m->setCallForwarding(reason, mode, - (argc - optind >= 3) ? argv[optind + 2] : "", - "", // subaddr - facilityClass, forwardTime); - } - else if (operation == "setsca") - { - // set sca: number - checkParamCount(optind, argc, 1, 1); - m->setServiceCentreAddress(argv[optind]); - } - else if (operation == "cset") - { - // set charset: string - checkParamCount(optind, argc, 1, 1); - m->setCharSet(argv[optind]); - } - else - throw GsmException(stringPrintf(_("unknown operation '%s'"), - operation.c_str()), ParameterError); - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmpb.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmpb.cc deleted file mode 100644 index 6196b717c2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmpb.cc +++ /dev/null @@ -1,507 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmpb.cc -// * -// * Purpose: phonebook management program -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 24.6.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"phonebook", required_argument, (int*)NULL, 'p'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"destination", required_argument, (int*)NULL, 'd'}, - {"source", required_argument, (int*)NULL, 's'}, - {"destination-backend", required_argument, (int*)NULL, 'D'}, - {"source-backend", required_argument, (int*)NULL, 'S'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"charset", required_argument, (int*)NULL, 't'}, - {"copy", no_argument, (int*)NULL, 'c'}, - {"synchronize", no_argument, (int*)NULL, 'y'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {"verbose", no_argument, (int*)NULL, 'V'}, - {"indexed", no_argument, (int*)NULL, 'i'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -// insert those entries from sourcePhonebook into destPhonebook -// that are not already present in destPhonebook - -void insertNotPresent(SortedPhonebookRef sourcePhonebook, - SortedPhonebookRef destPhonebook, - bool indexed, bool verbose) -{ - for (SortedPhonebookBase::iterator i = sourcePhonebook->begin(); - i != sourcePhonebook->end(); ++i) - { - pair range; - if (indexed) - { - int index = i->index(); - range = destPhonebook->equal_range(index); - } - else - { - string text = i->text(); - range = destPhonebook->equal_range(text); - } - - // do nothing if the entry is already present in the destination - bool alreadyPresent = false; - for (SortedPhonebookBase::iterator j = range.first; - j != range.second; ++j) - { - i->setUseIndex(indexed); - if (i->telephone() == j->telephone()) - { - alreadyPresent = true; - break; - } - } - // ... else insert it - if (! alreadyPresent) - { - if (verbose) - { - cout << stringPrintf(_("inserting '%s' tel# %s"), - i->text().c_str(), i->telephone().c_str()); - if (indexed) - cout << stringPrintf(_(" (index #%d)"), i->index()); - cout << endl; - } - i->setUseIndex(indexed); - destPhonebook->insert(*i); // insert - } - } -} - -// update those entries in destPhonebook, that -// - have the same name as one entry in destPhonebook -// - but have a different telephone number -// this is only done if the name in question is unique in the destPhonebook -// the case of several entries having the same in the sourcePhonebook -// is handled - only the first is considered for updating - -void updateEntries(SortedPhonebookRef sourcePhonebook, - SortedPhonebookRef destPhonebook, - bool verbose) -{ - bool firstLoop = true; - string lastText; - - for (SortedPhonebookBase::iterator i = sourcePhonebook->begin(); - i != sourcePhonebook->end(); ++i) - { - string text = i->text(); - if (! firstLoop && text != lastText) - { - pair range = - destPhonebook->equal_range(text); - - SortedPhonebookBase::iterator first = range.first; - if (first != destPhonebook->end() && range.second == ++first) - { // just one text in the destPhonebook - if (! (*range.first == *i)) // overwrite if different in destination - { - if (verbose) - cout << stringPrintf(_("updating '%s' tel# %s to new tel# %s"), - range.first->text().c_str(), - range.first->telephone().c_str(), - i->telephone().c_str()) - << endl; - - *range.first = *i; - } - } - lastText = text; - } - firstLoop = false; - } -} - -// the same but for indexed phonebooks - -void updateEntriesIndexed(SortedPhonebookRef sourcePhonebook, - SortedPhonebookRef destPhonebook, - bool verbose) -{ - for (SortedPhonebookBase::iterator i = sourcePhonebook->begin(); - i != sourcePhonebook->end(); ++i) - { - int index = i->index(); - - SortedPhonebookBase::iterator j = destPhonebook->find(index); - - if (j != destPhonebook->end()) - { // index present in the destPhonebook - if (! (*j == *i)) // overwrite if different in destination - { - if (verbose) - cout << stringPrintf(_("updating '%s' tel# %s to new tel# %s" - "(index %d)"), - j->text().c_str(), - j->telephone().c_str(), - i->telephone().c_str(), i->index()) - << endl; - - *j = *i; - } - } - } -} - -// delete those entries from destPhonebook, that are not present -// in sourcePhonebook - -void deleteNotPresent(SortedPhonebookRef sourcePhonebook, - SortedPhonebookRef destPhonebook, - bool indexed, bool verbose) -{ - for (SortedPhonebookBase::iterator i = destPhonebook->begin(); - i != destPhonebook->end(); ++i) - { - pair range; - if (indexed) - { - int index = i->index(); - range = sourcePhonebook->equal_range(index); - } - else - { - string text = i->text(); - range = sourcePhonebook->equal_range(text); - } - - bool found = false; - for (SortedPhonebookBase::iterator j = range.first; - j != range.second; ++j) - { - i->setUseIndex(indexed); - if (j->telephone() == i->telephone()) - { - found = true; - break; - } - } - if (! found) - { - if (verbose) - { - cout << stringPrintf(_("deleting '%s' tel# %s"), - i->text().c_str(), i->telephone().c_str()); - if (indexed) - cout << stringPrintf(_(" (index #%d)"), i->index()); - cout << endl; - } - destPhonebook->erase(i); -#ifdef BUGGY_MAP_ERASE - deleteNotPresent(sourcePhonebook, destPhonebook, indexed, verbose); - return; -#endif - } - } -} - -// *** main program - -int main(int argc, char *argv[]) -{ - try - { - // handle command line options - string destination; - string source; - string destinationBackend; - string sourceBackend; - string baudrate; - bool doSynchronize = true; - string phonebook; - SortedPhonebookRef sourcePhonebook, destPhonebook; - bool verbose = false; - bool indexed = false; - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - string charSet; - Ref sourceMeTa, destMeTa; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "I:p:s:d:b:cyhvViD:S:Xt:", longOpts, - &dummy)) - != -1) - switch (opt) - { - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 'V': - verbose = true; - break; - case 'p': - phonebook = optarg; - break; - case 'd': - destination = optarg; - break; - case 's': - source = optarg; - break; - case 'D': - destinationBackend = optarg; - break; - case 'S': - sourceBackend = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 't': - charSet = optarg; - break; - case 'c': - doSynchronize = false; - break; - case 'i': - indexed = true; - break; - case 'y': - doSynchronize = true; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]" - "[-I init string]\n" - " [-p phonebook name][-s device or file]" - "[-t charset][-v]" - "[-V][-y][-X]") << endl - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -c, --copy copy source entries to destination") - << endl - << _(" -d, --destination sets the destination device to " - "connect \n" - " to, or the file to write") << endl - << _(" -D, --destination-backend sets the destination backend") - << endl - << _(" -h, --help prints this message") << endl - << _(" -i, --index takes index positions into account") - << endl - << _(" -I, --init device AT init sequence") << endl - << _(" -p, --phonebook name of phonebook to use") << endl - << _(" -s, --source sets the source device to connect to,\n" - " or the file to read") << endl - << _(" -t, --charset sets the character set to use for\n" - " phonebook entries") << endl - << _(" -S, --source-backend sets the source backend") - << endl - << _(" -v, --version prints version and exits") << endl - << _(" -V, --verbose print detailed progress messages") - << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << _(" -y, --synchronize synchronize destination with source\n" - " entries (destination is overwritten)\n" - " (see gsmpb(1) for details)") - << endl << endl; - exit(0); - break; - case '?': - throw GsmException(_("unknown option"), ParameterError); - break; - } - - // check if all parameters all present - if (destination == "" || source == "") - throw GsmException(_("both source and destination must be given"), - ParameterError); - - // start accessing source mobile phone or file - if (sourceBackend != "") - sourcePhonebook = - CustomPhonebookRegistry::createPhonebook(sourceBackend, source); - else if (source == "-") - sourcePhonebook = new SortedPhonebook(true, indexed); - else if (isFile(source)) - sourcePhonebook = new SortedPhonebook(source, indexed); - else - { - if (phonebook == "") - throw GsmException(_("phonebook name must be given"), ParameterError); - - sourceMeTa = new MeTa(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (source, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), initString, - swHandshake)); - if (charSet != "") - sourceMeTa->setCharSet(charSet); - sourcePhonebook = - new SortedPhonebook(sourceMeTa->getPhonebook(phonebook)); - } - - // make sure destination.c_str file exists - if (destination != "") - { - try - { - ofstream f(destination.c_str(), ios::out | ios::app); - } - catch (exception) - { - } - } - - // start accessing destination mobile phone or file - if (destinationBackend != "") - destPhonebook = - CustomPhonebookRegistry::createPhonebook(destinationBackend, - destination); - else if (destination == "-") - destPhonebook = new SortedPhonebook(false, indexed); - else if (isFile(destination)) - destPhonebook = new SortedPhonebook(destination, indexed); - else - { - if (phonebook == "") - throw GsmException(_("phonebook name must be given"), ParameterError); - - destMeTa = new MeTa(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (destination, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), initString, - swHandshake)); - if (charSet != "") - destMeTa->setCharSet(charSet); - PhonebookRef destPb = destMeTa->getPhonebook(phonebook); - - // check maximum lengths of source text and phonenumber when writing to - // mobile phone - unsigned int maxTextLen = destPb->getMaxTextLen(); - unsigned int maxTelLen = destPb->getMaxTelephoneLen(); - - for (SortedPhonebookBase::iterator i = sourcePhonebook->begin(); - i != sourcePhonebook->end(); ++i) - if (i->text().length() > maxTextLen) - throw GsmException( - stringPrintf(_("text '%s' is too large to fit into destination " - "(maximum size %d characters)"), - i->text().c_str(), maxTextLen), - ParameterError); - else if (i->telephone().length() > maxTelLen) - throw GsmException( - stringPrintf(_("phone number '%s' is too large to fit into " - "destination (maximum size %d characters)"), - i->telephone().c_str(), maxTelLen), - ParameterError); - - // read phonebook - destPhonebook = new SortedPhonebook(destPb); - } - - // now do the actual work - if (doSynchronize) - { // synchronizing - if (indexed) - { - sourcePhonebook->setSortOrder(ByIndex); - destPhonebook->setSortOrder(ByIndex); - // for an explanation see below - updateEntriesIndexed(sourcePhonebook, destPhonebook, verbose); - deleteNotPresent(sourcePhonebook, destPhonebook, true, verbose); - insertNotPresent(sourcePhonebook, destPhonebook, true, verbose); - } - else - { - sourcePhonebook->setSortOrder(ByText); - destPhonebook->setSortOrder(ByText); - // the following is done to avoid superfluous writes to the TA - // (that takes time) and keep updated (ie. telephone number changed) - // entries at the same place - // 1. update entries in place where just the number changed - updateEntries(sourcePhonebook, destPhonebook, verbose); - // 2. delete those that are not present anymore - deleteNotPresent(sourcePhonebook, destPhonebook, false, verbose); - // 3. insert the new ones - insertNotPresent(sourcePhonebook, destPhonebook, false, verbose); - } - } - else - { // copying - destPhonebook->clear(); - for (SortedPhonebookBase::iterator i = sourcePhonebook->begin(); - i != sourcePhonebook->end(); ++i) - { - if (verbose) - { - cout << stringPrintf(_("inserting '%s' tel# %s"), - i->text().c_str(), i->telephone().c_str()); - if (indexed) - cout << stringPrintf(_(" (index #%d)"), i->index()); - cout << endl; - } - destPhonebook->insert(*i); - } - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsendsms.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsendsms.cc deleted file mode 100644 index f6418842ac..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsendsms.cc +++ /dev/null @@ -1,257 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmsendsms.cc -// * -// * Purpose: GSM sms send program -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 16.7.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// options - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"requeststat", no_argument, (int*)NULL, 'r'}, - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"sca", required_argument, (int*)NULL, 'C'}, - {"device", required_argument, (int*)NULL, 'd'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"concatenate", required_argument, (int*)NULL, 'c'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"test", no_argument, (int*)NULL, 't'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -// convert /r and /n to CR and LF - -static string unescapeString(char *line) -{ - string result; - bool escaped = false; - int index = 0; - - while (line[index] != 0 && - line[index] != CR && line[index] != LF) - { - if (escaped) - { - escaped = false; - if (line[index] == 'r') - result += CR; - else if (line[index] == 'n') - result += LF; - else if (line[index] == '\\') - result += '\\'; - else - result += line[index]; - } - else - if (line[index] == '\\') - escaped = true; - else - result += line[index]; - - ++index; - } - return result; -} - -// *** main program - -int main(int argc, char *argv[]) -{ - try - { - // handle command line options - string device = "/dev/mobilephone"; - bool test = false; - string baudrate; - Ref at; - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - bool requestStatusReport = false; - // service centre address (set on command line) - string serviceCentreAddress; - MeTa *m = NULL; - string concatenatedMessageIdStr; - int concatenatedMessageId = -1; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "c:C:I:d:b:thvXr", longOpts, &dummy)) - != -1) - switch (opt) - { - case 'c': - concatenatedMessageIdStr = optarg; - break; - case 'C': - serviceCentreAddress = optarg; - break; - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 'd': - device = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 't': - test = true; - break; - case 'r': - requestStatusReport = true; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-b baudrate][-c concatenatedID]" - "[-C sca][-d device][-h][-I init string]\n" - " [-t][-v][-X] phonenumber [text]") << endl - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -c, --concatenate ID for concatenated SMS messages") - << endl - << _(" -C, --sca SMS service centre address") << endl - << _(" -d, --device sets the destination device to connect " - "to") << endl - << _(" -h, --help prints this message") << endl - << _(" -I, --init device AT init sequence") << endl - << _(" -r, --requeststat request SMS status report") << endl - << _(" -t, --test convert text to GSM alphabet and " - "vice\n" - " versa, no SMS message is sent") << endl - << _(" -v, --version prints version and exits") - << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << endl - << _(" phonenumber recipient's phone number") << endl - << _(" text optional text of the SMS message\n" - " if omitted: read from stdin") - << endl << endl; - exit(0); - break; - case '?': - throw GsmException(_("unknown option"), ParameterError); - break; - } - - if (! test) - { - // open the port and ME/TA - Ref port = new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (device, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), - initString, swHandshake); - // switch message service level to 1 - // this enables acknowledgement PDUs - m = new MeTa(port); - m->setMessageService(1); - - at = new GsmAt(*m); - } - - // check parameters - if (optind == argc) - throw GsmException(_("phone number and text missing"), ParameterError); - - if (optind + 2 < argc) - throw GsmException(_("more than two parameters given"), ParameterError); - - if (concatenatedMessageIdStr != "") - concatenatedMessageId = checkNumber(concatenatedMessageIdStr); - - // get phone number - string phoneNumber = argv[optind]; - - // get text - string text; - if (optind + 1 == argc) - { // read from stdin - char s[1000]; - cin.get(s, 1000); - text = unescapeString(s); - if (text.length() > 160) - throw GsmException(_("text is larger than 160 characters"), - ParameterError); - } - else - text = argv[optind + 1]; - - if (test) - cout << gsmToLatin1(latin1ToGsm(text)) << endl; - else - { - // send SMS - Ref submitSMS = new SMSSubmitMessage(); - // set service centre address in new submit PDU if requested by user - if (serviceCentreAddress != "") - { - Address sca(serviceCentreAddress); - submitSMS->setServiceCentreAddress(sca); - } - submitSMS->setStatusReportRequest(requestStatusReport); - Address destAddr(phoneNumber); - submitSMS->setDestinationAddress(destAddr); - if (concatenatedMessageId == -1) - m->sendSMSs(submitSMS, text, true); - else - m->sendSMSs(submitSMS, text, false, concatenatedMessageId); - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsd.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsd.cc deleted file mode 100644 index ffb2db0739..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsd.cc +++ /dev/null @@ -1,723 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmsmsd.cc -// * -// * Purpose: SMS receiver daemon -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 5.6.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include - -#ifdef WIN32 -#include -#include -#include -#define popen _popen -#define pclose _pclose -#else -#include -#include -#include -#include -#endif -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"requeststat", no_argument, (int*)NULL, 'r'}, - {"direct", no_argument, (int*)NULL, 'D'}, - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"store", required_argument, (int*)NULL, 't'}, - {"device", required_argument, (int*)NULL, 'd'}, - {"spool", required_argument, (int*)NULL, 's'}, - {"sent", required_argument, (int*)NULL, 'S'}, - {"failed", required_argument, (int*)NULL, 'F'}, - {"priorities", required_argument, (int*)NULL, 'P'}, -#ifndef WIN32 - {"syslog", no_argument, (int*)NULL, 'L'}, -#endif - {"sca", required_argument, (int*)NULL, 'C'}, - {"flush", no_argument, (int*)NULL, 'f'}, - {"concatenate", required_argument, (int*)NULL, 'c'}, - {"action", required_argument, (int*)NULL, 'a'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -// my ME - -static MeTa *me = NULL; -string receiveStoreName; // store name for received SMSs - -// service centre address (set on command line) - -static string serviceCentreAddress; - -// ID if concatenated messages should be sent - -static int concatenatedMessageId = -1; - -// signal handler for terminate signal - -bool terminateSent = false; - -void terminateHandler(int signum) -{ - terminateSent = true; -} - -// local class to handle SMS events - -struct IncomingMessage -{ - // used if new message is put into store - int _index; // -1 means message want send directly - string _storeName; - // used if SMS message was sent directly to TA - SMSMessageRef _newSMSMessage; - // used if CB message was sent directly to TA - CBMessageRef _newCBMessage; - // used in both cases - GsmEvent::SMSMessageType _messageType; - - IncomingMessage() : _index(-1) {} -}; - -vector newMessages; - -class EventHandler : public GsmEvent -{ -public: - // inherited from GsmEvent - void SMSReception(SMSMessageRef newMessage, - SMSMessageType messageType); - void CBReception(CBMessageRef newMessage); - void SMSReceptionIndication(string storeName, unsigned int index, - SMSMessageType messageType); - - virtual ~EventHandler() {} -}; - -void EventHandler::SMSReception(SMSMessageRef newMessage, - SMSMessageType messageType) -{ - IncomingMessage m; - m._messageType = messageType; - m._newSMSMessage = newMessage; - newMessages.push_back(m); -} - -void EventHandler::CBReception(CBMessageRef newMessage) -{ - IncomingMessage m; - m._messageType = GsmEvent::CellBroadcastSMS; - m._newCBMessage = newMessage; - newMessages.push_back(m); -} - -void EventHandler::SMSReceptionIndication(string storeName, unsigned int index, - SMSMessageType messageType) -{ - IncomingMessage m; - m._index = index; - - if (receiveStoreName != "" && ( storeName == "MT" || storeName == "mt")) - m._storeName = receiveStoreName; - else - m._storeName = storeName; - - m._messageType = messageType; - newMessages.push_back(m); -} - -// execute action on string - -void doAction(string action, string result) -{ - if (action != "") - { - FILE *fd = popen(action.c_str(), "w"); - if (fd == NULL) - throw GsmException(stringPrintf(_("could not execute '%s'"), - action.c_str()), OSError); - fputs(result.c_str(), fd); - if (ferror(fd)) - throw GsmException(stringPrintf(_("error writing to '%s'"), - action.c_str()), OSError); - pclose(fd); - } - else - // default if no action: output on stdout - cout << result << endl; -} - -// send all SMS messages in spool dir - -bool requestStatusReport = false; - -void sendSMS(string spoolDirBase, string sentDirBase, string failedDirBase, - unsigned int priority, bool enableSyslog, Ref at) -{ - string spoolDir = spoolDirBase; - string sentDir = sentDirBase; - string failedDir = failedDirBase; - if ( priority >= 1 ) - { - spoolDir = spoolDirBase + stringPrintf(_("%d"),priority); - sentDir = sentDirBase + stringPrintf(_("%d"),priority); - failedDir = failedDirBase + stringPrintf(_("%d"),priority); - } - if ( priority > 1 ) - sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at); - if (spoolDirBase != "") - { - // look into spoolDir for any outgoing SMS that should be sent -#ifdef WIN32 - struct _finddata_t fileInfo; - long fileHandle; - string pattern = spoolDir + "\\*"; - fileHandle = _findfirst(pattern.c_str(), &fileInfo); - bool moreFiles = fileHandle != -1L; -#else - DIR *dir = opendir(spoolDir.c_str()); - if (dir == (DIR*)NULL) - throw GsmException( - stringPrintf(_("error when calling opendir('%s')" - "(errno: %d/%s)"), - spoolDir.c_str(), errno, strerror(errno)), - OSError); -#endif - -#ifdef WIN32 - while (moreFiles) - { - if (strcmp(fileInfo.name, ".") != 0 && - strcmp(fileInfo.name, "..") != 0) -#else - struct dirent *entry; - while ((entry = readdir(dir)) != (struct dirent*)NULL) - if (strcmp(entry->d_name, ".") != 0 && - strcmp(entry->d_name, "..") != 0) -#endif - { - if ( priority > 1 ) - sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at); - // read in file - // the first line is interpreted as the phone number - // the rest is the message -#ifdef WIN32 - string filename = spoolDir + "\\" + fileInfo.name; -#else - string filename = spoolDir + "/" + entry->d_name; -#endif - ifstream ifs(filename.c_str()); - if (! ifs) -#ifndef WIN32 - if (enableSyslog) - { - syslog(LOG_WARNING, "Could not open SMS spool file %s", - filename.c_str()); - if (failedDirBase != "") { - string failedfilename = failedDir + "/" + entry->d_name; - rename(filename.c_str(),failedfilename.c_str()); - } - continue; - } - else -#endif - throw GsmException( - stringPrintf(_("count not open SMS spool file %s"), - filename.c_str()), ParameterError); - char phoneBuf[1001]; - ifs.getline(phoneBuf, 1000); - for(int i=0;i<1000;i++) - if(phoneBuf[i]=='\t' || phoneBuf[i]==0) - { // ignore everything after a in the phone number - phoneBuf[i]=0; - break; - } - string text; - while (! ifs.eof()) - { - char c; - ifs.get(c); - text += c; - } - ifs.close(); - - // remove trailing newline/linefeed - while (text[text.length() - 1] == '\n' || - text[text.length() - 1] == '\r') - text = text.substr(0, text.length() - 1); - - // send the message - string phoneNumber(phoneBuf); - Ref submitSMS = new SMSSubmitMessage(); - // set service centre address in new submit PDU if requested by user - if (serviceCentreAddress != "") - { - Address sca(serviceCentreAddress); - submitSMS->setServiceCentreAddress(sca); - } - submitSMS->setStatusReportRequest(requestStatusReport); - Address destAddr(phoneNumber); - submitSMS->setDestinationAddress(destAddr); - try - { - if (concatenatedMessageId == -1) - me->sendSMSs(submitSMS, text, true); - else - { - // maximum for concatenatedMessageId is 255 - if (concatenatedMessageId > 256) - concatenatedMessageId = 0; - me->sendSMSs(submitSMS, text, false, concatenatedMessageId++); - } -#ifndef WIN32 - if (enableSyslog) - syslog(LOG_NOTICE, "Sent SMS to %s from file %s", phoneBuf, filename.c_str()); -#endif - if (sentDirBase != "") { -#ifdef WIN32 - string sentfilename = sentDir + "\\" + fileInfo.name; -#else - string sentfilename = sentDir + "/" + entry->d_name; -#endif - rename(filename.c_str(),sentfilename.c_str()); - } else { - unlink(filename.c_str()); - } - } - catch (GsmException &me) - { -#ifndef WIN32 - if (enableSyslog) - syslog(LOG_WARNING, "Failed sending SMS to %s from file %s: %s", phoneBuf, - filename.c_str(), me.what()); - else -#endif - cerr << "Failed sending SMS to " << phoneBuf << " from " - << filename << ": " << me.what() << endl; - if (failedDirBase != "") { -#ifdef WIN32 - string failedfilename = failedDir + "\\" + fileInfo.name; -#else - string failedfilename = failedDir + "/" + entry->d_name; -#endif - rename(filename.c_str(),failedfilename.c_str()); - } - } -#ifdef WIN32 - } - moreFiles = _findnext(fileHandle, &fileInfo) == 0; -#endif - } -#ifdef WIN32 - _findclose(fileHandle); -#else - closedir(dir); -#endif - } -} - -#ifndef WIN32 -void syslogExit(int exitcode, int *dummy) -{ - syslog(LOG_NOTICE, "exited (exit %d)",exitcode); -} -#endif - -// *** main program - -int main(int argc, char *argv[]) -{ - bool enableSyslog = false; - try - { - string device = "/dev/mobilephone"; - string action; - string baudrate; - bool enableSMS = true; - bool enableCB = true; - bool enableStat = true; - bool flushSMS = false; - bool onlyReceptionIndication = true; - string spoolDir; - string sentDir = ""; - string failedDir = ""; - unsigned int priorities = 0; - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - string concatenatedMessageIdStr; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "c:C:I:t:fd:a:b:hvs:S:F:P:LXDr", - longOpts, &dummy)) != -1) - switch (opt) - { - case 'c': - concatenatedMessageIdStr = optarg; - break; - case 'r': - requestStatusReport = true; - break; - case 'D': - onlyReceptionIndication = false; - break; - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 't': - receiveStoreName = optarg; - break; - case 'd': - device = optarg; - break; - case 'C': - serviceCentreAddress = optarg; - break; - case 's': - spoolDir = optarg; - break; - case 'L': - enableSyslog = true; - break; - case 'S': - sentDir = optarg; - break; - case 'F': - failedDir = optarg; - break; - case 'P': - priorities = abs(atoi(optarg)); - break; - case 'f': - flushSMS = true; - break; - case 'a': - action = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-a action][-b baudrate][-C sca][-d device]" - "[-f][-h][-I init string]\n" - " [-s spool dir][-t][-v]{sms_type}") - << endl << endl - << _(" -a, --action the action to execute when an SMS " - "arrives\n" - " (SMS is send to stdin of action)") - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -c, --concatenate start ID for concatenated SMS messages") - << endl - << _(" -C, --sca SMS service centre address") << endl - << _(" -d, --device sets the device to connect to") << endl - << _(" -D, --direct enable direct routing of SMSs") << endl - << _(" -f, --flush flush SMS from store") << endl - << _(" -F, --failed directory to move failed SMS to,") << endl - << _(" if unset, the SMS will be deleted") << endl - << _(" -h, --help prints this message") << endl - << _(" -I, --init device AT init sequence") << endl -#ifndef WIN32 - << _(" -L, --syslog log errors and information to syslog") - << endl -#endif - << _(" -P, --priorities number of priority levels to use,") << endl - << _(" (default: none)") << endl - << _(" -r, --requeststat request SMS status report") << endl - << _(" -s, --spool spool directory for outgoing SMS") - << endl - << _(" -S, --sent directory to move sent SMS to,") << endl - << _(" if unset, the SMS will be deleted") << endl - << _(" -t, --store name of SMS store to use for flush\n" - " and/or temporary SMS storage") << endl - << endl - << _(" -v, --version prints version and exits") << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << endl - << _(" sms_type may be any combination of") << endl << endl - << _(" sms, no_sms controls reception of normal SMS") - << endl - << _(" cb, no_cb controls reception of cell broadcast" - " messages") << endl - << _(" stat, no_stat controls reception of status reports") - << endl << endl - << _(" default is \"sms cb stat\"") << endl << endl - << _("If no action is given, the SMS is printed to stdout") - << endl << endl - << _("If -P is given, it activates the priority system and sets the") << endl - << _("number or levels to use. For every level, there must be directories") << endl - << _("named +.") << endl - << _("For example \"-P 2 -s queue -S send -F failed\" needs the following") <getSMSStore(receiveStoreName); - - for (SMSStore::iterator s = store->begin(); s != store->end(); ++s) - if (! s->empty()) - { - string result = _("Type of message: "); - switch (s->message()->messageType()) - { - case SMSMessage::SMS_DELIVER: - result += _("SMS message\n"); - break; - case SMSMessage::SMS_SUBMIT_REPORT: - result += _("submit report message\n"); - break; - case SMSMessage::SMS_STATUS_REPORT: - result += _("status report message\n"); - break; - } - result += s->message()->toString(); - doAction(action, result); - store->erase(s); - } - } - - // set default SMS store if -t option was given or - // read from ME otherwise - if (receiveStoreName == "") - { - string dummy1, dummy2; - me->getSMSStore(dummy1, dummy2, receiveStoreName ); - } - else - me->setSMSStore(receiveStoreName, 3); - - // switch message service level to 1 - // this enables SMS routing to TA - me->setMessageService(1); - - // switch on SMS routing - me->setSMSRoutingToTA(enableSMS, enableCB, enableStat, - onlyReceptionIndication); - - // register event handler to handle routed SMSs, CBMs, and status reports - me->setEventHandler(new EventHandler()); - - // wait for new messages - bool exitScheduled = false; - while (1) - { -#ifdef WIN32 - ::timeval timeoutVal; - timeoutVal.tv_sec = 5; - timeoutVal.tv_usec = 0; - me->waitEvent((gsmlib::timeval *)&timeoutVal); -#else - struct timeval timeoutVal; - timeoutVal.tv_sec = 5; - timeoutVal.tv_usec = 0; - me->waitEvent(&timeoutVal); -#endif - // if it returns, there was an event or a timeout - while (newMessages.size() > 0) - { - // get first new message and remove it from the vector - SMSMessageRef newSMSMessage = newMessages.begin()->_newSMSMessage; - CBMessageRef newCBMessage = newMessages.begin()->_newCBMessage; - GsmEvent::SMSMessageType messageType = - newMessages.begin()->_messageType; - int index = newMessages.begin()->_index; - string storeName = newMessages.begin()->_storeName; - newMessages.erase(newMessages.begin()); - - // process the new message - string result = _("Type of message: "); - switch (messageType) - { - case GsmEvent::NormalSMS: - result += _("SMS message\n"); - break; - case GsmEvent::CellBroadcastSMS: - result += _("cell broadcast message\n"); - break; - case GsmEvent::StatusReportSMS: - result += _("status report message\n"); - break; - } - if (! newSMSMessage.isnull()) - result += newSMSMessage->toString(); - else if (! newCBMessage.isnull()) - result += newCBMessage->toString(); - else - { - SMSStoreRef store = me->getSMSStore(storeName); - store->setCaching(false); - - if (messageType == GsmEvent::CellBroadcastSMS) - result += (*store.getptr())[index].cbMessage()->toString(); - else - result += (*store.getptr())[index].message()->toString(); - - store->erase(store->begin() + index); - } - - // call the action - doAction(action, result); - } - - // if no new SMS came in and program exit was scheduled, then exit - if (exitScheduled) - exit(0); - - // handle terminate signal - if (terminateSent) - { - exitScheduled = true; - // switch off SMS routing - try - { - me->setSMSRoutingToTA(false, false, false); - } - catch (GsmException &ge) - { - // some phones (e.g. Motorola Timeport 260) don't allow to switch - // off SMS routing which results in an error. Just ignore this. - } - // the AT sequences involved in switching of SMS routing - // may yield more SMS events, so go round the loop one more time - } - - // send spooled SMS - if (! terminateSent) - sendSMS(spoolDir, sentDir, failedDir, priorities, enableSyslog, me->getAt()); - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - if (ge.getErrorClass() == MeTaCapabilityError) - cerr << argv[0] << _("[ERROR]: ") - << _("(try setting sms_type, please refer to gsmsmsd manpage)") - << endl; - // switch off message routing, so that following invocations of gsmsmd - // are not swamped with message deliveries while they start up - if (me != NULL) - { - try - { - me->setSMSRoutingToTA(false, false, false); - } - catch (GsmException &ge) - { - // some phones (e.g. Motorola Timeport 260) don't allow to switch - // off SMS routing which results in an error. Just ignore this. - } - } - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsstore.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsstore.cc deleted file mode 100644 index 2bb50a0c76..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/apps/gsmsmsstore.cc +++ /dev/null @@ -1,434 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmsmsstore.cc -// * -// * Purpose: SMS store management program -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.8.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"store", required_argument, (int*)NULL, 't'}, - {"erase", no_argument, (int*)NULL, 'e'}, - {"add", no_argument, (int*)NULL, 'a'}, - {"list", no_argument, (int*)NULL, 'l'}, - {"destination", required_argument, (int*)NULL, 'd'}, - {"source", required_argument, (int*)NULL, 's'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"sca", required_argument, (int*)NULL, 'C'}, - {"copy", no_argument, (int*)NULL, 'c'}, - {"delete", no_argument, (int*)NULL, 'x'}, - {"backup", no_argument, (int*)NULL, 'k'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {"verbose", no_argument, (int*)NULL, 'V'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -bool verbose = false; // true if --verbose option given - -// type of operation to perform - -enum Operation {CopyOp = 'c', BackupOp = 'k', DeleteOp = 'x', - AddOp = 'a', ListOp = 'l', NoOp = 0}; - -// aux function, insert entry only if not already present in dest - -void backup(SortedSMSStoreRef destStore, SMSStoreEntry &entry) -{ - // the following only works because we know that the default sort order - // is by date - assert(destStore->sortOrder() == ByDate); - - Timestamp date = entry.message()->serviceCentreTimestamp(); - pair range = - destStore->equal_range(date); - - for (SortedSMSStore::iterator j = range.first; - j != range.second; ++j) - if (entry == *j) - // do nothing if the entry is already present in the destination - return; - - if (verbose) - cout << stringPrintf(_("inserting entry #%d from source into destination"), - entry.index()) << endl - << entry.message()->toString(); - destStore->insert(entry); // insert -} - -// aux function, throw exception if operation != NoOp - -void checkNoOp(Operation operation, int opt) -{ - if (operation != NoOp) - throw GsmException(stringPrintf(_("incompatible options '%c' and '%c'"), - (char)operation, (char)opt), - ParameterError); -} - -// *** main program - -int main(int argc, char *argv[]) -{ - try - { - // handle command line options - string destination; - string source; - string baudrate; - string storeName; - char operation = NoOp; - SortedSMSStoreRef sourceStore, destStore; - bool useIndices = false; // use indices in delete, copy, backup op - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - // service centre address (set on command line) - string serviceCentreAddress; - Ref sourceMeTa, destMeTa; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "I:t:s:d:b:cxlakhvVXC:", - longOpts, &dummy)) - != -1) - switch (opt) - { - case 'C': - serviceCentreAddress = optarg; - break; - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 'V': - verbose = true; - break; - case 't': - storeName = optarg; - break; - case 'd': - destination = optarg; - break; - case 's': - source = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 'c': - checkNoOp((Operation)operation, opt); - operation = CopyOp; - break; - case 'x': - checkNoOp((Operation)operation, opt); - operation = DeleteOp; - break; - case 'l': - checkNoOp((Operation)operation, opt); - operation = ListOp; - break; - case 'a': - checkNoOp((Operation)operation, opt); - operation = AddOp; - break; - case 'k': - checkNoOp((Operation)operation, opt); - operation = BackupOp; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-a][-b baudrate][-c][-C sca]" - "[-d device or file]\n" - " [-h][-I init string][-k][-l]" - "[-s device or file]" - "[-t SMS store name]\n [-v][-V][-x][-X]" - "{indices}|[phonenumber text]") << endl - << endl - << _(" -a, --add add new SMS submit message\n" - " (phonenumber and text) to destination") - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -c, --copy copy source entries to destination\n" - " (if indices are given, " - "copy only these entries)") << endl - << _(" -C, --sca SMS service centre address") << endl - << _(" -d, --destination sets the destination device to\n" - " connect to, or the file to write to") - << endl - << _(" -h, --help prints this message") << endl - << _(" -I, --init device AT init sequence") << endl - << _(" -k, --backup backup new entries to destination\n" - " (if indices are given, " - "copy only these entries)") << endl - << _(" -l, --list list source to stdout") << endl - << _(" -s, --source sets the source device to connect to,\n" - " or the file to read") << endl - << _(" -t, --store name of SMS store to use") << endl - << _(" -v, --version prints version and exits") << endl - << _(" -V, --verbose print detailed progress messages") - << endl - << _(" -x, --delete delete entries denoted by indices") - << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << endl; - exit(0); - break; - case '?': - throw GsmException(_("unknown option"), ParameterError); - break; - } - - // check if parameters are complete - if (operation == NoOp) - throw GsmException(_("no operation option given"), ParameterError); - if (operation == BackupOp || operation == CopyOp) - if (destination.length() == 0 || source.length() == 0) - throw GsmException(_("both source and destination required"), - ParameterError); - if (operation == ListOp) - { - if (destination.length() != 0) - throw GsmException(_("destination must not be given"), ParameterError); - if (source.length() == 0) - throw GsmException(_("source required"), ParameterError); - } - if (operation == AddOp || operation == DeleteOp) - { - if (source.length() != 0) - throw GsmException(_("source must not be given"), ParameterError); - if (destination.length() == 0) - throw GsmException(_("destination required"), ParameterError); - } - if (operation == CopyOp || operation == DeleteOp || operation == BackupOp) - { - // check if all indices are numbers - for (int i = optind; i < argc; ++i) - for (char *pp = argv[i]; *pp != 0; ++pp) - if (! isdigit(*pp)) - throw GsmException(stringPrintf(_("expected number, got '%s'"), - argv[i]), ParameterError); - useIndices = optind != argc; - } - else if (operation == AddOp) - { - if (optind + 2 < argc) - throw GsmException(_("more than two parameters given"), - ParameterError); - if (optind + 2 > argc) - throw GsmException(_("not enough parameters given"), - ParameterError); - } - else - if (optind != argc) - throw GsmException(_("unexpected parameters"), ParameterError); - - // start accessing source store or file if required by operation - if (operation == CopyOp || operation == BackupOp || operation == ListOp) - if (source == "-") - sourceStore = new SortedSMSStore(true); - else if (isFile(source)) - sourceStore = new SortedSMSStore(source); - else - { - if (storeName == "") - throw GsmException(_("store name must be given"), ParameterError); - - sourceMeTa = new MeTa(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (source, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), initString, - swHandshake)); - sourceStore = new SortedSMSStore(sourceMeTa->getSMSStore(storeName)); - } - - // make sure destination file exists if specified - // Use isFile() for its exception-throwing properties, and discard - // return value cos we don't care (yet) whether it's a device or a - // regular file. - if (destination != "") - isFile(destination); - - // start accessing destination store or file - if (operation == CopyOp || operation == BackupOp || operation == AddOp || - operation == DeleteOp) - if (destination == "-") - destStore = new SortedSMSStore(false); - else if (isFile(destination)) - destStore = new SortedSMSStore(destination); - else - { - if (storeName == "") - throw GsmException(_("store name must be given"), ParameterError); - - destMeTa = new MeTa(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (destination, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), initString, - swHandshake)); - destStore = new SortedSMSStore(destMeTa->getSMSStore(storeName)); - } - - // now do the actual work - switch (operation) - { - case BackupOp: - { - sourceStore->setSortOrder(ByIndex); // needed in loop - - if (useIndices) - for (int i = optind; i < argc; ++i) - { - SortedSMSStore::iterator j = sourceStore->find(atoi(argv[i])); - if (j == sourceStore->end()) - throw GsmException(stringPrintf(_("no index '%s' in source"), - argv[i]), ParameterError); - backup(destStore, *j); - } - else - for (SortedSMSStore::iterator i = sourceStore->begin(); - i != sourceStore->end(); ++i) - backup(destStore, *i); - break; - } - case CopyOp: - { - destStore->clear(); - if (! useIndices) // copy all entries - { - for (SortedSMSStore::iterator i = sourceStore->begin(); - i != sourceStore->end(); ++i) - { - if (verbose) - cout << stringPrintf(_("inserting entry #%d from source " - "into destination"), i->index()) << endl - << i->message()->toString(); - destStore->insert(*i); - } - } - else // copy indexed entries - { - sourceStore->setSortOrder(ByIndex); // needed in loop - - for (int i = optind; i < argc; ++i) - { - SortedSMSStore::iterator j = sourceStore->find(atoi(argv[i])); - if (j == sourceStore->end()) - throw GsmException(stringPrintf(_("no index '%s' in source"), - argv[i]), ParameterError); - if (verbose) - cout << stringPrintf(_("inserting entry #%d from source into " - "destination"), j->index()) << endl - << j->message()->toString(); - destStore->insert(*j); - } - } - break; - } - case ListOp: - { - for (SortedSMSStore::iterator i = sourceStore->begin(); - i != sourceStore->end(); ++i) - cout << stringPrintf(_("index #%d"), i->index()) << endl - << i->message()->toString(); - break; - } - case AddOp: - { - SMSMessageRef sms = new SMSSubmitMessage(argv[optind + 1], argv[optind]); - // set service centre address in new submit PDU if requested by user - if (serviceCentreAddress != "") - { - Address sca(serviceCentreAddress); - sms->setServiceCentreAddress(sca); - } - if (verbose) - cout << _("inserting new entry into destination") << endl - << sms->toString(); - destStore->insert(sms); - break; - } - case DeleteOp: - { - destStore->setSortOrder(ByIndex); - for (int i = optind; i < argc; ++i) - { - int index = atoi(argv[i]); - if (verbose) - { - SortedSMSStore::iterator e = destStore->find(index); - if (e != destStore->end()) - cout << stringPrintf(_("deleting entry #%d from destination"), - index) << endl - << e->message()->toString(); - } - if (destStore->erase(index) != 1) - throw GsmException(stringPrintf(_("no index '%s' in destination"), - argv[i]), ParameterError); - } - break; - } - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure deleted file mode 100755 index 5918af81fb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure +++ /dev/null @@ -1,30623 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59. -# -# Copyright (C) 2003 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - - - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` - ;; -esac - -echo=${ECHO-echo} -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null 2>&1 && unset CDPATH - -if test -z "$ECHO"; then -if test "X${echo_test_string+set}" != Xset; then -# find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string=`eval $cmd`) 2>/dev/null && - echo_test_string=`eval $cmd` && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL $0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" -fi - - - - -tagnames=${tagnames+${tagnames},}CXX - -tagnames=${tagnames+${tagnames},}F77 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_config_libobj_dir=. -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="gsmlib/gsm_error.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_STAT_H -# include -#endif -#if STDC_HEADERS -# include -# include -#else -# if HAVE_STDLIB_H -# include -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include -#endif -#if HAVE_STRINGS_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#else -# if HAVE_STDINT_H -# include -# endif -#endif -#if HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL ALLOCA GSM_VERSION MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE GLIBC2 GLIBC21 INTL_MACOSX_LIBS HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB COMPILE_INTL_TRUE COMPILE_INTL_FALSE LIBOBJS LTLIBOBJS' -ac_subst_files='' - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -ac_prev= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP -ac_env_CXX_set=${CXX+set} -ac_env_CXX_value=$CXX -ac_cv_env_CXX_set=${CXX+set} -ac_cv_env_CXX_value=$CXX -ac_env_CXXFLAGS_set=${CXXFLAGS+set} -ac_env_CXXFLAGS_value=$CXXFLAGS -ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} -ac_cv_env_CXXFLAGS_value=$CXXFLAGS -ac_env_CXXCPP_set=${CXXCPP+set} -ac_env_CXXCPP_value=$CXXCPP -ac_cv_env_CXXCPP_set=${CXXCPP+set} -ac_cv_env_CXXCPP_value=$CXXCPP -ac_env_F77_set=${F77+set} -ac_env_F77_value=$F77 -ac_cv_env_F77_set=${F77+set} -ac_cv_env_F77_value=$F77 -ac_env_FFLAGS_set=${FFLAGS+set} -ac_env_FFLAGS_value=$FFLAGS -ac_cv_env_FFLAGS_set=${FFLAGS+set} -ac_cv_env_FFLAGS_value=$FFLAGS - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -_ACEOF - - cat <<_ACEOF -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --enable-shared[=PKGS] - build shared libraries [default=yes] - --enable-static[=PKGS] - build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - --disable-nls do not use Native Language Support - --disable-rpath do not hardcode runtime library paths - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-pic try to use only PIC/non-PIC objects [default=use - both] - --with-tags[=TAGS] - include additional configurations [automatic] - --with-gnu-ld assume the C compiler uses GNU ld default=no - --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib - --without-libiconv-prefix don't search for libiconv in includedir and libdir - --with-included-gettext use the GNU gettext library included here - --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib - --without-libintl-prefix don't search for libintl in includedir and libdir - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory - CPP C preprocessor - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CXXCPP C++ preprocessor - F77 Fortran 77 compiler command - FFLAGS Fortran 77 compiler flags - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd "$ac_popdir" - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF - -Copyright (C) 2003 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_sep= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h | sort - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - - -ac_aux_dir= -for ac_dir in scripts $srcdir/scripts; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f $ac_dir/shtool; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in scripts $srcdir/scripts" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in scripts $srcdir/scripts" >&2;} - { (exit 1); exit 1; }; } -fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL=$ac_install_sh - fi -fi -echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; - * ) - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cc_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_stdc=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext -done -rm -f conftest.$ac_ext conftest.$ac_objext -CC=$ac_save_CC - -fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; - *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; -esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -echo "$as_me:$LINENO: checking for textdomain in -lintl" >&5 -echo $ECHO_N "checking for textdomain in -lintl... $ECHO_C" >&6 -if test "${ac_cv_lib_intl_textdomain+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lintl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char textdomain (); -int -main () -{ -textdomain (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_intl_textdomain=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_intl_textdomain=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_intl_textdomain" >&5 -echo "${ECHO_T}$ac_cv_lib_intl_textdomain" >&6 -if test $ac_cv_lib_intl_textdomain = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBINTL 1 -_ACEOF - - LIBS="-lintl $LIBS" - -fi - - - ac_config_headers="$ac_config_headers gsm_config.h" - - -am__api_version="1.9" -echo "$as_me:$LINENO: checking whether build environment is sane" >&5 -echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&5 -echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&2;} - { (exit 1); exit 1; }; } - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! -Check your system clock" >&5 -echo "$as_me: error: newly created file is older than distributed files! -Check your system clock" >&2;} - { (exit 1); exit 1; }; } -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -test "$program_prefix" != NONE && - program_transform_name="s,^,$program_prefix,;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s,\$,$program_suffix,;$program_transform_name" -# Double any \ or $. echo might interpret backslashes. -# By default was `s,x,x', remove it if useless. -cat <<\_ACEOF >conftest.sed -s/[\\$]/&&/g;s/;s,x,x,$// -_ACEOF -program_transform_name=`echo $program_transform_name | sed -f conftest.sed` -rm conftest.sed - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 -echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in - # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' -else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - for d in ./-p ./--version; - do - test -d $d && rmdir $d - done - # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. - if test -f "$ac_aux_dir/mkinstalldirs"; then - mkdir_p='$(mkinstalldirs)' - else - mkdir_p='$(install_sh) -d' - fi -fi - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AWK+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - echo "$as_me:$LINENO: result: $AWK" >&5 -echo "${ECHO_T}$AWK" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$AWK" && break -done - -echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.make <<\_ACEOF -all: - @echo 'ac_maketemp="$(MAKE)"' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi -rm -f conftest.make -fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - SET_MAKE= -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -DEPDIR="${am__leading_dot}deps" - - ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 -echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi - - -echo "$as_me:$LINENO: result: $_am_result" >&5 -echo "${ECHO_T}$_am_result" >&6 -rm -f confinc confmf - -# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then - enableval="$enable_dependency_tracking" - -fi; -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - - -if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 -echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} - { (exit 1); exit 1; }; } -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE=gsmlib - VERSION=1.10 - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -install_sh=${install_sh-"$am_aux_dir/install-sh"} - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - STRIP=$ac_ct_STRIP -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - - - -depcc="$CC" am_compiler_list= - -echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 -echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - - -if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - - -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=yes -fi; - - -if test "$CXXFLAGS" = ""; then - CXXFLAGS="-O2" -fi - - - -if test x"`egrep _REENTRANT /usr/include/features.h`" != x; then - CXXFLAGS="-D_REENTRANT $CXXFLAGS" - CFLAGS="-D_REENTRANT $CFLAGS" -fi - -CXXFLAGS="-Wall $CXXFLAGS" - -# Check whether --enable-static or --disable-static was given. -if test "${enable_static+set}" = set; then - enableval="$enable_static" - p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi; - -# Check whether --enable-fast-install or --disable-fast-install was given. -if test "${enable_fast_install+set}" = set; then - enableval="$enable_fast_install" - p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi; - -# Make sure we can run config.sub. -$ac_config_sub sun4 >/dev/null 2>&1 || - { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 -echo "$as_me: error: cannot run $ac_config_sub" >&2;} - { (exit 1); exit 1; }; } - -echo "$as_me:$LINENO: checking build system type" >&5 -echo $ECHO_N "checking build system type... $ECHO_C" >&6 -if test "${ac_cv_build+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_build_alias=$build_alias -test -z "$ac_cv_build_alias" && - ac_cv_build_alias=`$ac_config_guess` -test -z "$ac_cv_build_alias" && - { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 -echo "$as_me: error: cannot guess build type; you must specify one" >&2;} - { (exit 1); exit 1; }; } -ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_build" >&5 -echo "${ECHO_T}$ac_cv_build" >&6 -build=$ac_cv_build -build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - -echo "$as_me:$LINENO: checking host system type" >&5 -echo $ECHO_N "checking host system type... $ECHO_C" >&6 -if test "${ac_cv_host+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_host_alias=$host_alias -test -z "$ac_cv_host_alias" && - ac_cv_host_alias=$ac_cv_build_alias -ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_host" >&5 -echo "${ECHO_T}$ac_cv_host" >&6 -host=$ac_cv_host -host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - -echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 -echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 -if test "${lt_cv_path_SED+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done - -fi - -SED=$lt_cv_path_SED -echo "$as_me:$LINENO: result: $SED" >&5 -echo "${ECHO_T}$SED" >&6 - -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep - - - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi; -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo "$as_me:$LINENO: checking for ld used by $CC" >&5 -echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - echo "$as_me:$LINENO: checking for GNU ld" >&5 -echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 -else - echo "$as_me:$LINENO: checking for non-GNU ld" >&5 -echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 -fi -if test "${lt_cv_path_LD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -echo "${ECHO_T}$LD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 -echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} - { (exit 1); exit 1; }; } -echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 -echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 -if test "${lt_cv_prog_gnu_ld+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 -with_gnu_ld=$lt_cv_prog_gnu_ld - - -echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 -echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 -if test "${lt_cv_ld_reload_flag+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_ld_reload_flag='-r' -fi -echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 -echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - darwin*) - if test "$GCC" = yes; then - reload_cmds='$CC -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - -echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 -echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 -if test "${lt_cv_path_NM+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - esac - fi - done - IFS="$lt_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi -fi -echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 -echo "${ECHO_T}$lt_cv_path_NM" >&6 -NM="$lt_cv_path_NM" - -echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6 -fi - -echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 -echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 -if test "${lt_cv_deplibs_check_method+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix4* | aix5*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump'. - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | kfreebsd*-gnu | dragonfly*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -nto-qnx*) - lt_cv_deplibs_check_method=unknown - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 -echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Check whether --enable-libtool-lock or --disable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then - enableval="$enable_libtool_lock" - -fi; -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line 3740 "configure"' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 -echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 -if test "${lt_cv_cc_needs_belf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - lt_cv_cc_needs_belf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -lt_cv_cc_needs_belf=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 -echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; - -esac - -need_locks="$enable_libtool_lock" - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdc=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_Header=no" -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_header in dlfcn.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - echo "$as_me:$LINENO: result: $CXX" >&5 -echo "${ECHO_T}$CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -echo "${ECHO_T}$ac_ct_CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CXX" && break -done -test -n "$ac_ct_CXX" || ac_ct_CXX="g++" - - CXX=$ac_ct_CXX -fi - - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C++ compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 -GXX=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cxx_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cxx_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -depcc="$CXX" am_compiler_list= - -echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 -if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 -echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - - -if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - - - -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 -echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 -if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -echo "$as_me:$LINENO: result: $CXXCPP" >&5 -echo "${ECHO_T}$CXXCPP" >&6 -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -fi - - -ac_ext=f -ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' -ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_f77_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$F77"; then - ac_cv_prog_F77="$F77" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_F77="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -F77=$ac_cv_prog_F77 -if test -n "$F77"; then - echo "$as_me:$LINENO: result: $F77" >&5 -echo "${ECHO_T}$F77" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$F77" && break - done -fi -if test -z "$F77"; then - ac_ct_F77=$F77 - for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_F77"; then - ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_F77="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_F77=$ac_cv_prog_ac_ct_F77 -if test -n "$ac_ct_F77"; then - echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 -echo "${ECHO_T}$ac_ct_F77" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_F77" && break -done - - F77=$ac_ct_F77 -fi - - -# Provide some information about the compiler. -echo "$as_me:5311:" \ - "checking for Fortran 77 compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -rm -f a.out - -# If we don't use `.F' as extension, the preprocessor is not run on the -# input file. (Note that this only needs to work for GNU compilers.) -ac_save_ext=$ac_ext -ac_ext=F -echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 -if test "${ac_cv_f77_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF - program main -#ifndef __GNUC__ - choke me -#endif - - end -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_f77_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 -ac_ext=$ac_save_ext -ac_test_FFLAGS=${FFLAGS+set} -ac_save_FFLAGS=$FFLAGS -FFLAGS= -echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 -echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_f77_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - FFLAGS=-g -cat >conftest.$ac_ext <<_ACEOF - program main - - end -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_f77_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_f77_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 -echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 -if test "$ac_test_FFLAGS" = set; then - FFLAGS=$ac_save_FFLAGS -elif test $ac_cv_prog_f77_g = yes; then - if test "x$ac_cv_f77_compiler_gnu" = xyes; then - FFLAGS="-g -O2" - else - FFLAGS="-g" - fi -else - if test "x$ac_cv_f77_compiler_gnu" = xyes; then - FFLAGS="-O2" - else - FFLAGS= - fi -fi - -G77=`test $ac_compiler_gnu = yes && echo yes` -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! - -# find the maximum length of command line arguments -echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 -echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 -if test "${lt_cv_sys_max_cmd_len+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ - = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 -echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 -else - echo "$as_me:$LINENO: result: none" >&5 -echo "${ECHO_T}none" >&6 -fi - - - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 -echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 -if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32*) - symcode='[ABCDGISTW]' - ;; -hpux*) # Its linker distinguishes data from code symbols - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -linux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDGIRSTW]' - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris* | sysv5*) - symcode='[BDRT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 - (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if grep ' nm_test_var$' "$nlist" >/dev/null; then - if grep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[] = -{ -EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - echo "$as_me:$LINENO: result: failed" >&5 -echo "${ECHO_T}failed" >&6 -else - echo "$as_me:$LINENO: result: ok" >&5 -echo "${ECHO_T}ok" >&6 -fi - -echo "$as_me:$LINENO: checking for objdir" >&5 -echo $ECHO_N "checking for objdir... $ECHO_C" >&6 -if test "${lt_cv_objdir+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 -echo "${ECHO_T}$lt_cv_objdir" >&6 -objdir=$lt_cv_objdir - - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' -sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 -echo "${ECHO_T}$ac_ct_AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - AR=$ac_ct_AR -else - AR="$ac_cv_prog_AR" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - STRIP=$ac_ct_STRIP -else - STRIP="$ac_cv_prog_STRIP" -fi - - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$SED" && SED=sed -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 -echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 -echo "${ECHO_T}$MAGIC_CMD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - echo "$as_me:$LINENO: checking for file" >&5 -echo $ECHO_N "checking for file... $ECHO_C" >&6 -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 -echo "${ECHO_T}$MAGIC_CMD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -enable_dlopen=no -enable_win32_dll=no - -# Check whether --enable-libtool-lock or --disable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then - enableval="$enable_libtool_lock" - -fi; -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - - -# Check whether --with-pic or --without-pic was given. -if test "${with_pic+set}" = set; then - withval="$with_pic" - pic_mode="$withval" -else - pic_mode=default -fi; -test -z "$pic_mode" && pic_mode=default - -# Use C for the default configuration in the libtool script -tagname= -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* - -ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* - - -# -# Check for any special shared library compilation flags. -# -lt_prog_cc_shlib= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - lt_prog_cc_shlib='-belf' - ;; - esac -fi -if test -n "$lt_prog_cc_shlib"; then - { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5 -echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;} - if echo "$old_CC $old_CFLAGS " | grep "[ ]$lt_prog_cc_shlib[ ]" >/dev/null; then : - else - { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 -echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} - lt_cv_prog_cc_can_build_shared=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5 -echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6 -if test "${lt_prog_compiler_static_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_prog_compiler_static" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_static_works=yes - fi - else - lt_prog_compiler_static_works=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 - -if test x"$lt_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - lt_prog_compiler_no_builtin_flag=' -fno-builtin' - - -echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6407: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:6411: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - -lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - lt_prog_compiler_pic='-qnocommon' - lt_prog_compiler_wl='-Wl,' - ;; - esac - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - linux*) - case $cc_basename in - icc* | ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - sco3.2v5*) - lt_prog_compiler_pic='-Kpic' - lt_prog_compiler_static='-dn' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6669: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:6673: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 - -if test x"$lt_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6731: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:6735: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - runpath_var= - allow_undefined_flag= - enable_shared_with_static_runtimes=no - archive_cmds= - archive_expsym_cmds= - old_archive_From_new_cmds= - old_archive_from_expsyms_cmds= - export_dynamic_flag_spec= - whole_archive_flag_spec= - thread_safe_flag_spec= - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= - hardcode_libdir_separator= - hardcode_direct=no - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - link_all_deplibs=unknown - hardcode_automatic=no - module_cmds= - module_expsym_cmds= - always_export_symbols=no - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - # Just being paranoid about ensuring that cc_basename is set. - for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs=no - fi - ;; - - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_addflag= - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - esac - archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test $supports_anon_versioning = yes; then - archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - link_all_deplibs=no - else - ld_shlibs=no - fi - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec=' ' - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_From_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes=yes - ;; - - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[012]) - allow_undefined_flag='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='' - link_all_deplibs=yes - if test "$GCC" = yes ; then - output_verbose_link_cmd='echo' - archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - ld_shlibs=no - ;; - esac - fi - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*|ia64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*|ia64*) - archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=no - hardcode_shlibpath_var=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_ld='-rpath $libdir' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - link_all_deplibs=yes - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - openbsd*) - hardcode_direct=yes - hardcode_shlibpath_var=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag=' -z text' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. - # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - *) - whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $ld_shlibs" >&5 -echo "${ECHO_T}$ld_shlibs" >&6 -test "$ld_shlibs" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc=no - else - archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 -echo "${ECHO_T}$archive_cmds_need_lc" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var" || \ - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action" >&5 -echo "${ECHO_T}$hardcode_action" >&6 - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -# Report which librarie types wil actually be built -echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 -echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $can_build_shared" >&5 -echo "${ECHO_T}$can_build_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 -echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case $host_os in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4* | aix5*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -echo "$as_me:$LINENO: result: $enable_shared" >&5 -echo "${ECHO_T}$enable_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build static libraries" >&5 -echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -echo "$as_me:$LINENO: result: $enable_static" >&5 -echo "${ECHO_T}$enable_static" >&6 - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler \ - CC \ - LD \ - lt_prog_compiler_wl \ - lt_prog_compiler_pic \ - lt_prog_compiler_static \ - lt_prog_compiler_no_builtin_flag \ - export_dynamic_flag_spec \ - thread_safe_flag_spec \ - whole_archive_flag_spec \ - enable_shared_with_static_runtimes \ - old_archive_cmds \ - old_archive_from_new_cmds \ - predep_objects \ - postdep_objects \ - predeps \ - postdeps \ - compiler_lib_search_path \ - archive_cmds \ - archive_expsym_cmds \ - postinstall_cmds \ - postuninstall_cmds \ - old_archive_from_expsyms_cmds \ - allow_undefined_flag \ - no_undefined_flag \ - export_symbols_cmds \ - hardcode_libdir_flag_spec \ - hardcode_libdir_flag_spec_ld \ - hardcode_libdir_separator \ - hardcode_automatic \ - module_cmds \ - module_expsym_cmds \ - lt_cv_prog_compiler_c_o \ - exclude_expsyms \ - include_expsyms; do - - case $var in - old_archive_cmds | \ - old_archive_from_new_cmds | \ - archive_cmds | \ - archive_expsym_cmds | \ - module_cmds | \ - module_expsym_cmds | \ - old_archive_from_expsyms_cmds | \ - export_symbols_cmds | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="${ofile}T" - trap "$rm \"$cfgfile\"; exit 1" 1 2 15 - $rm -f "$cfgfile" - { echo "$as_me:$LINENO: creating $ofile" >&5 -echo "$as_me: creating $ofile" >&6;} - - cat <<__EOF__ >> "$cfgfile" -#! $SHELL - -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e 1s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# The names of the tagged configurations supported by this script. -available_tags= - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU C compiler? -with_gcc=$GCC - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# ### END LIBTOOL CONFIG - -__EOF__ - - - case $host_os in - aix3*) - cat <<\EOF >> "$cfgfile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || \ - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - -# Check whether --with-tags or --without-tags was given. -if test "${with_tags+set}" = set; then - withval="$with_tags" - tagnames="$withval" -fi; - -if test -f "$ltmain" && test -n "$tagnames"; then - if test ! -f "${ofile}"; then - { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 -echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} - fi - - if test -z "$LTCC"; then - eval "`$SHELL ${ofile} --config | grep '^LTCC='`" - if test -z "$LTCC"; then - { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 -echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} - else - { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 -echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} - fi - fi - - # Extract list of available tagged configurations in $ofile. - # Note that this assumes the entire list is on one line. - available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` - - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for tagname in $tagnames; do - IFS="$lt_save_ifs" - # Check whether tagname contains only valid characters - case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in - "") ;; - *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 -echo "$as_me: error: invalid tag name: $tagname" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null - then - { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 -echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} - { (exit 1); exit 1; }; } - fi - - # Update the list of available tags. - if test -n "$tagname"; then - echo appending configuration tag \"$tagname\" to $ofile - - case $tagname in - CXX) - if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - -archive_cmds_need_lc_CXX=no -allow_undefined_flag_CXX= -always_export_symbols_CXX=no -archive_expsym_cmds_CXX= -export_dynamic_flag_spec_CXX= -hardcode_direct_CXX=no -hardcode_libdir_flag_spec_CXX= -hardcode_libdir_flag_spec_ld_CXX= -hardcode_libdir_separator_CXX= -hardcode_minus_L_CXX=no -hardcode_automatic_CXX=no -module_cmds_CXX= -module_expsym_cmds_CXX= -link_all_deplibs_CXX=unknown -old_archive_cmds_CXX=$old_archive_cmds -no_undefined_flag_CXX= -whole_archive_flag_spec_CXX= -enable_shared_with_static_runtimes_CXX=no - -# Dependencies to place before and after the object being linked: -predep_objects_CXX= -postdep_objects_CXX= -predeps_CXX= -postdeps_CXX= -compiler_lib_search_path_CXX= - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -objext_CXX=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *) { return(0); }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* - -ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* - - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_LD=$LD -lt_save_GCC=$GCC -GCC=$GXX -lt_save_with_gnu_ld=$with_gnu_ld -lt_save_path_LD=$lt_cv_path_LD -if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx -else - unset lt_cv_prog_gnu_ld -fi -if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX -else - unset lt_cv_path_LD -fi -test -z "${LDCXX+set}" || LD=$LDCXX -CC=${CXX-"c++"} -compiler=$CC -compiler_CXX=$CC -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - -# We don't want -fno-exception wen compiling C++ code, so set the -# no_builtin_flag separately -if test "$GXX" = yes; then - lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' -else - lt_prog_compiler_no_builtin_flag_CXX= -fi - -if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi; -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo "$as_me:$LINENO: checking for ld used by $CC" >&5 -echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - echo "$as_me:$LINENO: checking for GNU ld" >&5 -echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 -else - echo "$as_me:$LINENO: checking for non-GNU ld" >&5 -echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 -fi -if test "${lt_cv_path_LD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -echo "${ECHO_T}$LD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 -echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} - { (exit 1); exit 1; }; } -echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 -echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 -if test "${lt_cv_prog_gnu_ld+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ - grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_CXX= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - -else - GXX=no - with_gnu_ld=no - wlarc= -fi - -# PORTME: fill in a description of your system's C++ link characteristics -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 -ld_shlibs_CXX=yes -case $host_os in - aix3*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_CXX='' - hardcode_direct_CXX=yes - hardcode_libdir_separator_CXX=':' - link_all_deplibs_CXX=yes - - if test "$GXX" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct_CXX=yes - else - # We have old collect2 - hardcode_direct_CXX=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_CXX=yes - hardcode_libdir_flag_spec_CXX='-L$libdir' - hardcode_libdir_separator_CXX= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols_CXX=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_CXX='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - - archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_CXX=' ${wl}-bernotok' - allow_undefined_flag_CXX=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_CXX=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_CXX=' ' - archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_CXX='-L$libdir' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=no - enable_shared_with_static_runtimes_CXX=yes - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs_CXX=no - fi - ;; - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[012]) - allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes - hardcode_shlibpath_var_CXX=unsupported - whole_archive_flag_spec_CXX='' - link_all_deplibs_CXX=yes - - if test "$GXX" = yes ; then - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - ld_shlibs_CXX=no - ;; - esac - fi - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - freebsd[12]*) - # C++ shared libraries reported to be fairly broken before switch to ELF - ld_shlibs_CXX=no - ;; - freebsd-elf*) - archive_cmds_need_lc_CXX=no - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - ld_shlibs_CXX=yes - ;; - gnu*) - ;; - hpux9*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' - hardcode_direct_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC*) - archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_CXX='+b $libdir' - hardcode_libdir_separator_CXX=: - ;; - ia64*) - hardcode_libdir_flag_spec_CXX='-L$libdir' - ;; - *) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - ;; - ia64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - *) - hardcode_direct_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC*) - case $host_cpu in - hppa*64*|ia64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - ia64*|hppa*64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' - fi - fi - link_all_deplibs_CXX=yes - ;; - esac - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - ;; - linux*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc*) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - archive_cmds_need_lc_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC*) - # Portland Group C++ compiler - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - esac - ;; - lynxos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - m88k*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - openbsd2*) - # C++ shared libraries are fairly broken - ld_shlibs_CXX=no - ;; - openbsd*) - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - export_dynamic_flag_spec_CXX='${wl}-E' - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd='echo' - ;; - osf3*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - hardcode_libdir_separator_CXX=: - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' - - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - cxx*) - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - hardcode_libdir_separator_CXX=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - cxx*) - allow_undefined_flag_CXX=' -expect_unresolved \*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ - $rm $lib.exp' - - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - psos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - sco*) - archive_cmds_need_lc_CXX=no - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - archive_cmds_need_lc_CXX=yes - no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_shlibpath_var_CXX=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. We must also pass each convience library through - # to the system linker between allextract/defaultextract. - # The C++ compiler will combine linker options so we - # cannot just pass the convience library names through - # without $wl. - # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' - ;; - esac - link_all_deplibs_CXX=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - no_undefined_flag_CXX=' ${wl}-z ${wl}defs' - if $CC --version | grep -v '^2\.7' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - fi - - hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' - fi - ;; - esac - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - archive_cmds_need_lc_CXX=no - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - vxworks*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; -esac -echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 -echo "${ECHO_T}$ld_shlibs_CXX" >&6 -test "$ld_shlibs_CXX" = no && can_build_shared=no - -GCC_CXX="$GXX" -LD_CXX="$LD" - - -cat > conftest.$ac_ext <&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - # The `*' in the case matches for architectures that use `case' in - # $output_verbose_cmd can trigger glob expansion during the loop - # eval without this substitution. - output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` - - for p in `eval $output_verbose_link_cmd`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" \ - || test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$compiler_lib_search_path_CXX"; then - compiler_lib_search_path_CXX="${prev}${p}" - else - compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$postdeps_CXX"; then - postdeps_CXX="${prev}${p}" - else - postdeps_CXX="${postdeps_CXX} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$predep_objects_CXX"; then - predep_objects_CXX="$p" - else - predep_objects_CXX="$predep_objects_CXX $p" - fi - else - if test -z "$postdep_objects_CXX"; then - postdep_objects_CXX="$p" - else - postdep_objects_CXX="$postdep_objects_CXX $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling CXX test program" -fi - -$rm -f confest.$objext - -# PORTME: override above test on systems where it is broken -case $host_os in -solaris*) - case $cc_basename in - CC*) - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - postdeps_CXX='-lCstd -lCrun' - ;; - esac -esac - - -case " $postdeps_CXX " in -*" -lc "*) archive_cmds_need_lc_CXX=no ;; -esac - -lt_prog_compiler_wl_CXX= -lt_prog_compiler_pic_CXX= -lt_prog_compiler_static_CXX= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - fi - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | os2* | pw32*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_CXX='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_CXX='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - lt_prog_compiler_pic_CXX= - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_CXX=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - else - case $host_os in - aix4* | aix5*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - else - lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - lt_prog_compiler_pic_CXX='-qnocommon' - lt_prog_compiler_wl_CXX='-Wl,' - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - lt_prog_compiler_pic_CXX='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - if test "$host_cpu" != ia64; then - lt_prog_compiler_pic_CXX='+Z' - fi - ;; - aCC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_CXX='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - lt_prog_compiler_wl_CXX='--backend -Wl,' - lt_prog_compiler_pic_CXX='-fPIC' - ;; - icpc* | ecpc*) - # Intel C++ - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-static' - ;; - pgCC*) - # Portland Group C++ compiler. - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-fpic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - *) - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - lt_prog_compiler_pic_CXX='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - lt_prog_compiler_wl_CXX='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - lt_prog_compiler_pic_CXX='-pic' - ;; - cxx*) - # Digital/Compaq C++ - lt_prog_compiler_wl_CXX='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - sco*) - case $cc_basename in - CC*) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - *) - ;; - esac - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - lt_prog_compiler_wl_CXX='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - lt_prog_compiler_pic_CXX='-pic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - lcc*) - # Lucid - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - lt_prog_compiler_pic_CXX='-KPIC' - ;; - *) - ;; - esac - ;; - unixware*) - ;; - vxworks*) - ;; - *) - lt_prog_compiler_can_build_shared_CXX=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_CXX"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works_CXX=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11334: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:11338: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works_CXX=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 - -if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then - case $lt_prog_compiler_pic_CXX in - "" | " "*) ;; - *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; - esac -else - lt_prog_compiler_pic_CXX= - lt_prog_compiler_can_build_shared_CXX=no -fi - -fi -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_CXX= - ;; - *) - lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o_CXX=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11396: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:11400: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_CXX=yes - fi - fi - chmod u+w . 2>&5 - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix4* | aix5*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - export_symbols_cmds_CXX="$ltdll_cmds" - ;; - cygwin* | mingw*) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - ;; - linux*) - link_all_deplibs_CXX=no - ;; - *) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - -echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 -echo "${ECHO_T}$ld_shlibs_CXX" >&6 -test "$ld_shlibs_CXX" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_CXX" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_CXX=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_CXX in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_CXX - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_CXX - allow_undefined_flag_CXX= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc_CXX=no - else - archive_cmds_need_lc_CXX=yes - fi - allow_undefined_flag_CXX=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 -echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action_CXX= -if test -n "$hardcode_libdir_flag_spec_CXX" || \ - test -n "$runpath_var_CXX" || \ - test "X$hardcode_automatic_CXX" = "Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct_CXX" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && - test "$hardcode_minus_L_CXX" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_CXX=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_CXX=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_CXX=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 -echo "${ECHO_T}$hardcode_action_CXX" >&6 - -if test "$hardcode_action_CXX" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_CXX \ - CC_CXX \ - LD_CXX \ - lt_prog_compiler_wl_CXX \ - lt_prog_compiler_pic_CXX \ - lt_prog_compiler_static_CXX \ - lt_prog_compiler_no_builtin_flag_CXX \ - export_dynamic_flag_spec_CXX \ - thread_safe_flag_spec_CXX \ - whole_archive_flag_spec_CXX \ - enable_shared_with_static_runtimes_CXX \ - old_archive_cmds_CXX \ - old_archive_from_new_cmds_CXX \ - predep_objects_CXX \ - postdep_objects_CXX \ - predeps_CXX \ - postdeps_CXX \ - compiler_lib_search_path_CXX \ - archive_cmds_CXX \ - archive_expsym_cmds_CXX \ - postinstall_cmds_CXX \ - postuninstall_cmds_CXX \ - old_archive_from_expsyms_cmds_CXX \ - allow_undefined_flag_CXX \ - no_undefined_flag_CXX \ - export_symbols_cmds_CXX \ - hardcode_libdir_flag_spec_CXX \ - hardcode_libdir_flag_spec_ld_CXX \ - hardcode_libdir_separator_CXX \ - hardcode_automatic_CXX \ - module_cmds_CXX \ - module_expsym_cmds_CXX \ - lt_cv_prog_compiler_c_o_CXX \ - exclude_expsyms_CXX \ - include_expsyms_CXX; do - - case $var in - old_archive_cmds_CXX | \ - old_archive_from_new_cmds_CXX | \ - archive_cmds_CXX | \ - archive_expsym_cmds_CXX | \ - module_cmds_CXX | \ - module_expsym_cmds_CXX | \ - old_archive_from_expsyms_cmds_CXX | \ - export_symbols_cmds_CXX | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_CXX - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_CXX - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_CXX - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_CXX - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_CXX - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_CXX -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_CXX - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_CXX -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_CXX -archive_expsym_cmds=$lt_archive_expsym_cmds_CXX -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_CXX -module_expsym_cmds=$lt_module_expsym_cmds_CXX - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_CXX - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_CXX - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_CXX - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_CXX - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_CXX - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_CXX - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_CXX - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_CXX - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_CXX - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_CXX - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_CXX - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_CXX - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_CXX" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_CXX - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_CXX - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_CXX - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_CXX - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC=$lt_save_CC -LDCXX=$LD -LD=$lt_save_LD -GCC=$lt_save_GCC -with_gnu_ldcxx=$with_gnu_ld -with_gnu_ld=$lt_save_with_gnu_ld -lt_cv_path_LDCXX=$lt_cv_path_LD -lt_cv_path_LD=$lt_save_path_LD -lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld -lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld - - else - tagname="" - fi - ;; - - F77) - if test -n "$F77" && test "X$F77" != "Xno"; then - -ac_ext=f -ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' -ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_f77_compiler_gnu - - -archive_cmds_need_lc_F77=no -allow_undefined_flag_F77= -always_export_symbols_F77=no -archive_expsym_cmds_F77= -export_dynamic_flag_spec_F77= -hardcode_direct_F77=no -hardcode_libdir_flag_spec_F77= -hardcode_libdir_flag_spec_ld_F77= -hardcode_libdir_separator_F77= -hardcode_minus_L_F77=no -hardcode_automatic_F77=no -module_cmds_F77= -module_expsym_cmds_F77= -link_all_deplibs_F77=unknown -old_archive_cmds_F77=$old_archive_cmds -no_undefined_flag_F77= -whole_archive_flag_spec_F77= -enable_shared_with_static_runtimes_F77=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -objext_F77=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code=" subroutine t\n return\n end\n" - -# Code to be used in simple link tests -lt_simple_link_test_code=" program t\n end\n" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* - -ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* - - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${F77-"f77"} -compiler=$CC -compiler_F77=$CC -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - -echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 -echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $can_build_shared" >&5 -echo "${ECHO_T}$can_build_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 -echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case $host_os in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; -aix4* | aix5*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -echo "$as_me:$LINENO: result: $enable_shared" >&5 -echo "${ECHO_T}$enable_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build static libraries" >&5 -echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -echo "$as_me:$LINENO: result: $enable_static" >&5 -echo "${ECHO_T}$enable_static" >&6 - -test "$ld_shlibs_F77" = no && can_build_shared=no - -GCC_F77="$G77" -LD_F77="$LD" - -lt_prog_compiler_wl_F77= -lt_prog_compiler_pic_F77= -lt_prog_compiler_static_F77= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - if test "$GCC" = yes; then - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_static_F77='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_F77='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_F77='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_F77='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared_F77=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_F77=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_F77='-fPIC' - ;; - esac - ;; - - *) - lt_prog_compiler_pic_F77='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl_F77='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_F77='-Bstatic' - else - lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' - fi - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - lt_prog_compiler_pic_F77='-qnocommon' - lt_prog_compiler_wl_F77='-Wl,' - ;; - esac - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_F77='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl_F77='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_F77='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static_F77='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl_F77='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static_F77='-non_shared' - ;; - - newsos6) - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - linux*) - case $cc_basename in - icc* | ecc*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-fpic' - lt_prog_compiler_static_F77='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl_F77='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static_F77='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl_F77='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static_F77='-non_shared' - ;; - - sco3.2v5*) - lt_prog_compiler_pic_F77='-Kpic' - lt_prog_compiler_static_F77='-dn' - ;; - - solaris*) - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - lt_prog_compiler_wl_F77='-Qoption ld ';; - *) - lt_prog_compiler_wl_F77='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl_F77='-Qoption ld ' - lt_prog_compiler_pic_F77='-PIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic_F77='-Kconform_pic' - lt_prog_compiler_static_F77='-Bstatic' - fi - ;; - - unicos*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_can_build_shared_F77=no - ;; - - uts4*) - lt_prog_compiler_pic_F77='-pic' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared_F77=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_F77"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works_F77=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_F77" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13764: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:13768: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works_F77=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 - -if test x"$lt_prog_compiler_pic_works_F77" = xyes; then - case $lt_prog_compiler_pic_F77 in - "" | " "*) ;; - *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; - esac -else - lt_prog_compiler_pic_F77= - lt_prog_compiler_can_build_shared_F77=no -fi - -fi -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_F77= - ;; - *) - lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o_F77=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13826: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:13830: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_F77=yes - fi - fi - chmod u+w . 2>&5 - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - runpath_var= - allow_undefined_flag_F77= - enable_shared_with_static_runtimes_F77=no - archive_cmds_F77= - archive_expsym_cmds_F77= - old_archive_From_new_cmds_F77= - old_archive_from_expsyms_cmds_F77= - export_dynamic_flag_spec_F77= - whole_archive_flag_spec_F77= - thread_safe_flag_spec_F77= - hardcode_libdir_flag_spec_F77= - hardcode_libdir_flag_spec_ld_F77= - hardcode_libdir_separator_F77= - hardcode_direct_F77=no - hardcode_minus_L_F77=no - hardcode_shlibpath_var_F77=unsupported - link_all_deplibs_F77=unknown - hardcode_automatic_F77=no - module_cmds_F77= - module_expsym_cmds_F77= - always_export_symbols_F77=no - export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms_F77= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - # Just being paranoid about ensuring that cc_basename is set. - for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs_F77=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_F77='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_F77= - fi - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs_F77=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_minus_L_F77=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - ld_shlibs_F77=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag_F77=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs_F77=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_F77='-L$libdir' - allow_undefined_flag_F77=unsupported - always_export_symbols_F77=no - enable_shared_with_static_runtimes_F77=yes - export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs_F77=no - fi - ;; - - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_addflag= - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - esac - archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test $supports_anon_versioning = yes; then - archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - link_all_deplibs_F77=no - else - ld_shlibs_F77=no - fi - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs_F77=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_F77=no - fi - ;; - - sunos4*) - archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_F77=no - fi - ;; - esac - - if test "$ld_shlibs_F77" = no; then - runpath_var= - hardcode_libdir_flag_spec_F77= - export_dynamic_flag_spec_F77= - whole_archive_flag_spec_F77= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag_F77=unsupported - always_export_symbols_F77=yes - archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L_F77=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct_F77=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_F77='' - hardcode_direct_F77=yes - hardcode_libdir_separator_F77=':' - link_all_deplibs_F77=yes - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct_F77=yes - else - # We have old collect2 - hardcode_direct_F77=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_F77=yes - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_libdir_separator_F77= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols_F77=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_F77='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF - program main - - end -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_F77="-z nodefs" - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF - program main - - end -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_F77=' ${wl}-bernotok' - allow_undefined_flag_F77=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_F77=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_F77=' ' - archive_cmds_need_lc_F77=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_minus_L_F77=yes - # see comment about different semantics on the GNU ld section - ld_shlibs_F77=no - ;; - - bsdi[45]*) - export_dynamic_flag_spec_F77=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec_F77=' ' - allow_undefined_flag_F77=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_From_new_cmds_F77='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path_F77='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes_F77=yes - ;; - - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[012]) - allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - archive_cmds_need_lc_F77=no - hardcode_direct_F77=no - hardcode_automatic_F77=yes - hardcode_shlibpath_var_F77=unsupported - whole_archive_flag_spec_F77='' - link_all_deplibs_F77=yes - if test "$GCC" = yes ; then - output_verbose_link_cmd='echo' - archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - ld_shlibs_F77=no - ;; - esac - fi - ;; - - dgux*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_shlibpath_var_F77=no - ;; - - freebsd1*) - ld_shlibs_F77=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_minus_L_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) - archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes - export_dynamic_flag_spec_F77='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*|ia64*) - archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*|ia64*) - archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_F77='+b $libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no - ;; - ia64*) - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes - ;; - *) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=yes - export_dynamic_flag_spec_F77='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' - fi - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_F77=: - link_all_deplibs_F77=yes - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - newsos6) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_F77=: - hardcode_shlibpath_var_F77=no - ;; - - openbsd*) - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' - export_dynamic_flag_spec_F77='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-R$libdir' - ;; - *) - archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_minus_L_F77=yes - allow_undefined_flag_F77=unsupported - archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag_F77=' -expect_unresolved \*' - archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_F77=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag_F77=' -expect_unresolved \*' - archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec_F77='-rpath $libdir' - fi - hardcode_libdir_separator_F77=: - ;; - - sco3.2v5*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - export_dynamic_flag_spec_F77='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag_F77=' -z text' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - wlarc='' - archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_shlibpath_var_F77=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. - # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; - *) - whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; - esac - link_all_deplibs_F77=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_direct_F77=yes - hardcode_minus_L_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds_F77='$CC -r -o $output$reload_objs' - hardcode_direct_F77=no - ;; - motorola) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_F77=no - ;; - - sysv4.3*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - export_dynamic_flag_spec_F77='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs_F77=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_minus_L_F77=no - hardcode_shlibpath_var_F77=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_F77='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_F77=no - ;; - - sysv5*) - no_undefined_flag_F77=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_F77= - hardcode_shlibpath_var_F77=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_shlibpath_var_F77=no - ;; - - *) - ld_shlibs_F77=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 -echo "${ECHO_T}$ld_shlibs_F77" >&6 -test "$ld_shlibs_F77" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_F77" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_F77=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_F77 in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_F77 - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_F77 - allow_undefined_flag_F77= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc_F77=no - else - archive_cmds_need_lc_F77=yes - fi - allow_undefined_flag_F77=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 -echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action_F77= -if test -n "$hardcode_libdir_flag_spec_F77" || \ - test -n "$runpath_var_F77" || \ - test "X$hardcode_automatic_F77" = "Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct_F77" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && - test "$hardcode_minus_L_F77" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_F77=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_F77=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_F77=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 -echo "${ECHO_T}$hardcode_action_F77" >&6 - -if test "$hardcode_action_F77" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - - - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_F77 \ - CC_F77 \ - LD_F77 \ - lt_prog_compiler_wl_F77 \ - lt_prog_compiler_pic_F77 \ - lt_prog_compiler_static_F77 \ - lt_prog_compiler_no_builtin_flag_F77 \ - export_dynamic_flag_spec_F77 \ - thread_safe_flag_spec_F77 \ - whole_archive_flag_spec_F77 \ - enable_shared_with_static_runtimes_F77 \ - old_archive_cmds_F77 \ - old_archive_from_new_cmds_F77 \ - predep_objects_F77 \ - postdep_objects_F77 \ - predeps_F77 \ - postdeps_F77 \ - compiler_lib_search_path_F77 \ - archive_cmds_F77 \ - archive_expsym_cmds_F77 \ - postinstall_cmds_F77 \ - postuninstall_cmds_F77 \ - old_archive_from_expsyms_cmds_F77 \ - allow_undefined_flag_F77 \ - no_undefined_flag_F77 \ - export_symbols_cmds_F77 \ - hardcode_libdir_flag_spec_F77 \ - hardcode_libdir_flag_spec_ld_F77 \ - hardcode_libdir_separator_F77 \ - hardcode_automatic_F77 \ - module_cmds_F77 \ - module_expsym_cmds_F77 \ - lt_cv_prog_compiler_c_o_F77 \ - exclude_expsyms_F77 \ - include_expsyms_F77; do - - case $var in - old_archive_cmds_F77 | \ - old_archive_from_new_cmds_F77 | \ - archive_cmds_F77 | \ - archive_expsym_cmds_F77 | \ - module_cmds_F77 | \ - module_expsym_cmds_F77 | \ - old_archive_from_expsyms_cmds_F77 | \ - export_symbols_cmds_F77 | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_F77 - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_F77 - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_F77 - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_F77 - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_F77 - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_F77 -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_F77 - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_F77 -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_F77 -archive_expsym_cmds=$lt_archive_expsym_cmds_F77 -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_F77 -module_expsym_cmds=$lt_module_expsym_cmds_F77 - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_F77 - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_F77 - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_F77 - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_F77 - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_F77 - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_F77 - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_F77 - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_F77 - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_F77 - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_F77 - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_F77 - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_F77 - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_F77" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_F77 - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_F77 - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_F77 - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_F77 - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - else - tagname="" - fi - ;; - - GCJ) - if test -n "$GCJ" && test "X$GCJ" != "Xno"; then - - - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -objext_GCJ=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* - -ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* - - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${GCJ-"gcj"} -compiler=$CC -compiler_GCJ=$CC -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -archive_cmds_need_lc_GCJ=no - -old_archive_cmds_GCJ=$old_archive_cmds - - -lt_prog_compiler_no_builtin_flag_GCJ= - -if test "$GCC" = yes; then - lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' - - -echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15967: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:15971: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" -else - : -fi - -fi - -lt_prog_compiler_wl_GCJ= -lt_prog_compiler_pic_GCJ= -lt_prog_compiler_static_GCJ= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - if test "$GCC" = yes; then - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_static_GCJ='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_GCJ='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_GCJ='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared_GCJ=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_GCJ=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_GCJ='-fPIC' - ;; - esac - ;; - - *) - lt_prog_compiler_pic_GCJ='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl_GCJ='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_GCJ='-Bstatic' - else - lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' - fi - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - lt_prog_compiler_pic_GCJ='-qnocommon' - lt_prog_compiler_wl_GCJ='-Wl,' - ;; - esac - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl_GCJ='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_GCJ='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl_GCJ='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static_GCJ='-non_shared' - ;; - - newsos6) - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - linux*) - case $cc_basename in - icc* | ecc*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-fpic' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl_GCJ='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static_GCJ='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl_GCJ='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static_GCJ='-non_shared' - ;; - - sco3.2v5*) - lt_prog_compiler_pic_GCJ='-Kpic' - lt_prog_compiler_static_GCJ='-dn' - ;; - - solaris*) - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - lt_prog_compiler_wl_GCJ='-Qoption ld ';; - *) - lt_prog_compiler_wl_GCJ='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl_GCJ='-Qoption ld ' - lt_prog_compiler_pic_GCJ='-PIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic_GCJ='-Kconform_pic' - lt_prog_compiler_static_GCJ='-Bstatic' - fi - ;; - - unicos*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_can_build_shared_GCJ=no - ;; - - uts4*) - lt_prog_compiler_pic_GCJ='-pic' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared_GCJ=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_GCJ"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works_GCJ=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_GCJ" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16229: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:16233: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works_GCJ=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 - -if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then - case $lt_prog_compiler_pic_GCJ in - "" | " "*) ;; - *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; - esac -else - lt_prog_compiler_pic_GCJ= - lt_prog_compiler_can_build_shared_GCJ=no -fi - -fi -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_GCJ= - ;; - *) - lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o_GCJ=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16291: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:16295: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_GCJ=yes - fi - fi - chmod u+w . 2>&5 - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - runpath_var= - allow_undefined_flag_GCJ= - enable_shared_with_static_runtimes_GCJ=no - archive_cmds_GCJ= - archive_expsym_cmds_GCJ= - old_archive_From_new_cmds_GCJ= - old_archive_from_expsyms_cmds_GCJ= - export_dynamic_flag_spec_GCJ= - whole_archive_flag_spec_GCJ= - thread_safe_flag_spec_GCJ= - hardcode_libdir_flag_spec_GCJ= - hardcode_libdir_flag_spec_ld_GCJ= - hardcode_libdir_separator_GCJ= - hardcode_direct_GCJ=no - hardcode_minus_L_GCJ=no - hardcode_shlibpath_var_GCJ=unsupported - link_all_deplibs_GCJ=unknown - hardcode_automatic_GCJ=no - module_cmds_GCJ= - module_expsym_cmds_GCJ= - always_export_symbols_GCJ=no - export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms_GCJ= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - # Just being paranoid about ensuring that cc_basename is set. - for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs_GCJ=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_GCJ= - fi - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs_GCJ=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_minus_L_GCJ=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - ld_shlibs_GCJ=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag_GCJ=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs_GCJ=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_GCJ='-L$libdir' - allow_undefined_flag_GCJ=unsupported - always_export_symbols_GCJ=no - enable_shared_with_static_runtimes_GCJ=yes - export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs_GCJ=no - fi - ;; - - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_addflag= - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - esac - archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test $supports_anon_versioning = yes; then - archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - link_all_deplibs_GCJ=no - else - ld_shlibs_GCJ=no - fi - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs_GCJ=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_GCJ=no - fi - ;; - - sunos4*) - archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_GCJ=no - fi - ;; - esac - - if test "$ld_shlibs_GCJ" = no; then - runpath_var= - hardcode_libdir_flag_spec_GCJ= - export_dynamic_flag_spec_GCJ= - whole_archive_flag_spec_GCJ= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag_GCJ=unsupported - always_export_symbols_GCJ=yes - archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L_GCJ=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct_GCJ=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_GCJ='' - hardcode_direct_GCJ=yes - hardcode_libdir_separator_GCJ=':' - link_all_deplibs_GCJ=yes - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct_GCJ=yes - else - # We have old collect2 - hardcode_direct_GCJ=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_GCJ=yes - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_libdir_separator_GCJ= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols_GCJ=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_GCJ='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_GCJ="-z nodefs" - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_GCJ=' ${wl}-bernotok' - allow_undefined_flag_GCJ=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_GCJ=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_GCJ=' ' - archive_cmds_need_lc_GCJ=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_minus_L_GCJ=yes - # see comment about different semantics on the GNU ld section - ld_shlibs_GCJ=no - ;; - - bsdi[45]*) - export_dynamic_flag_spec_GCJ=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec_GCJ=' ' - allow_undefined_flag_GCJ=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_From_new_cmds_GCJ='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes_GCJ=yes - ;; - - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[012]) - allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - archive_cmds_need_lc_GCJ=no - hardcode_direct_GCJ=no - hardcode_automatic_GCJ=yes - hardcode_shlibpath_var_GCJ=unsupported - whole_archive_flag_spec_GCJ='' - link_all_deplibs_GCJ=yes - if test "$GCC" = yes ; then - output_verbose_link_cmd='echo' - archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - ld_shlibs_GCJ=no - ;; - esac - fi - ;; - - dgux*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_shlibpath_var_GCJ=no - ;; - - freebsd1*) - ld_shlibs_GCJ=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) - archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes - export_dynamic_flag_spec_GCJ='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*|ia64*) - archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*|ia64*) - archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no - ;; - ia64*) - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes - ;; - *) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=yes - export_dynamic_flag_spec_GCJ='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' - fi - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - link_all_deplibs_GCJ=yes - ;; - - netbsd* | netbsdelf*-gnu | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - newsos6) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - hardcode_shlibpath_var_GCJ=no - ;; - - openbsd*) - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' - export_dynamic_flag_spec_GCJ='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - ;; - *) - archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_minus_L_GCJ=yes - allow_undefined_flag_GCJ=unsupported - archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag_GCJ=' -expect_unresolved \*' - archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag_GCJ=' -expect_unresolved \*' - archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec_GCJ='-rpath $libdir' - fi - hardcode_libdir_separator_GCJ=: - ;; - - sco3.2v5*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - export_dynamic_flag_spec_GCJ='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag_GCJ=' -z text' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - wlarc='' - archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_shlibpath_var_GCJ=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. - # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; - *) - whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; - esac - link_all_deplibs_GCJ=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds_GCJ='$CC -r -o $output$reload_objs' - hardcode_direct_GCJ=no - ;; - motorola) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_GCJ=no - ;; - - sysv4.3*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - export_dynamic_flag_spec_GCJ='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs_GCJ=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=no - hardcode_shlibpath_var_GCJ=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_GCJ='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_GCJ=no - ;; - - sysv5*) - no_undefined_flag_GCJ=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_GCJ= - hardcode_shlibpath_var_GCJ=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_shlibpath_var_GCJ=no - ;; - - *) - ld_shlibs_GCJ=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 -echo "${ECHO_T}$ld_shlibs_GCJ" >&6 -test "$ld_shlibs_GCJ" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_GCJ" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_GCJ=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_GCJ in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_GCJ - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ - allow_undefined_flag_GCJ= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc_GCJ=no - else - archive_cmds_need_lc_GCJ=yes - fi - allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 -echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action_GCJ= -if test -n "$hardcode_libdir_flag_spec_GCJ" || \ - test -n "$runpath_var_GCJ" || \ - test "X$hardcode_automatic_GCJ" = "Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct_GCJ" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && - test "$hardcode_minus_L_GCJ" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_GCJ=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_GCJ=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_GCJ=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 -echo "${ECHO_T}$hardcode_action_GCJ" >&6 - -if test "$hardcode_action_GCJ" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_GCJ \ - CC_GCJ \ - LD_GCJ \ - lt_prog_compiler_wl_GCJ \ - lt_prog_compiler_pic_GCJ \ - lt_prog_compiler_static_GCJ \ - lt_prog_compiler_no_builtin_flag_GCJ \ - export_dynamic_flag_spec_GCJ \ - thread_safe_flag_spec_GCJ \ - whole_archive_flag_spec_GCJ \ - enable_shared_with_static_runtimes_GCJ \ - old_archive_cmds_GCJ \ - old_archive_from_new_cmds_GCJ \ - predep_objects_GCJ \ - postdep_objects_GCJ \ - predeps_GCJ \ - postdeps_GCJ \ - compiler_lib_search_path_GCJ \ - archive_cmds_GCJ \ - archive_expsym_cmds_GCJ \ - postinstall_cmds_GCJ \ - postuninstall_cmds_GCJ \ - old_archive_from_expsyms_cmds_GCJ \ - allow_undefined_flag_GCJ \ - no_undefined_flag_GCJ \ - export_symbols_cmds_GCJ \ - hardcode_libdir_flag_spec_GCJ \ - hardcode_libdir_flag_spec_ld_GCJ \ - hardcode_libdir_separator_GCJ \ - hardcode_automatic_GCJ \ - module_cmds_GCJ \ - module_expsym_cmds_GCJ \ - lt_cv_prog_compiler_c_o_GCJ \ - exclude_expsyms_GCJ \ - include_expsyms_GCJ; do - - case $var in - old_archive_cmds_GCJ | \ - old_archive_from_new_cmds_GCJ | \ - archive_cmds_GCJ | \ - archive_expsym_cmds_GCJ | \ - module_cmds_GCJ | \ - module_expsym_cmds_GCJ | \ - old_archive_from_expsyms_cmds_GCJ | \ - export_symbols_cmds_GCJ | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_GCJ - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_GCJ - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_GCJ - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_GCJ - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_GCJ - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_GCJ -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_GCJ - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_GCJ -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_GCJ -archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_GCJ -module_expsym_cmds=$lt_module_expsym_cmds_GCJ - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_GCJ - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_GCJ - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_GCJ - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_GCJ - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_GCJ - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_GCJ - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_GCJ - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_GCJ - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_GCJ - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_GCJ - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_GCJ - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_GCJ" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_GCJ - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_GCJ - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_GCJ - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_GCJ - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - else - tagname="" - fi - ;; - - RC) - - - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -objext_RC=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* - -ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* - - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${RC-"windres"} -compiler=$CC -compiler_RC=$CC -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - -lt_cv_prog_compiler_c_o_RC=yes - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_RC \ - CC_RC \ - LD_RC \ - lt_prog_compiler_wl_RC \ - lt_prog_compiler_pic_RC \ - lt_prog_compiler_static_RC \ - lt_prog_compiler_no_builtin_flag_RC \ - export_dynamic_flag_spec_RC \ - thread_safe_flag_spec_RC \ - whole_archive_flag_spec_RC \ - enable_shared_with_static_runtimes_RC \ - old_archive_cmds_RC \ - old_archive_from_new_cmds_RC \ - predep_objects_RC \ - postdep_objects_RC \ - predeps_RC \ - postdeps_RC \ - compiler_lib_search_path_RC \ - archive_cmds_RC \ - archive_expsym_cmds_RC \ - postinstall_cmds_RC \ - postuninstall_cmds_RC \ - old_archive_from_expsyms_cmds_RC \ - allow_undefined_flag_RC \ - no_undefined_flag_RC \ - export_symbols_cmds_RC \ - hardcode_libdir_flag_spec_RC \ - hardcode_libdir_flag_spec_ld_RC \ - hardcode_libdir_separator_RC \ - hardcode_automatic_RC \ - module_cmds_RC \ - module_expsym_cmds_RC \ - lt_cv_prog_compiler_c_o_RC \ - exclude_expsyms_RC \ - include_expsyms_RC; do - - case $var in - old_archive_cmds_RC | \ - old_archive_from_new_cmds_RC | \ - archive_cmds_RC | \ - archive_expsym_cmds_RC | \ - module_cmds_RC | \ - module_expsym_cmds_RC | \ - old_archive_from_expsyms_cmds_RC | \ - export_symbols_cmds_RC | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_RC - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_RC - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_RC - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_RC - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_RC - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_RC -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_RC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_RC -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_RC -archive_expsym_cmds=$lt_archive_expsym_cmds_RC -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_RC -module_expsym_cmds=$lt_module_expsym_cmds_RC - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_RC - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_RC - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_RC - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_RC - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_RC - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_RC - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_RC - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_RC - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_RC - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_RC - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_RC - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_RC - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_RC - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_RC" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_RC - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_RC - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_RC - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_RC - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - ;; - - *) - { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 -echo "$as_me: error: Unsupported tag name: $tagname" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - - # Append the new tag name to the list of available tags. - if test -n "$tagname" ; then - available_tags="$available_tags $tagname" - fi - fi - done - IFS="$lt_save_ifs" - - # Now substitute the updated list of available tags. - if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then - mv "${ofile}T" "$ofile" - chmod +x "$ofile" - else - rm -f "${ofile}T" - { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 -echo "$as_me: error: unable to update list of available tagged configurations." >&2;} - { (exit 1); exit 1; }; } - fi -fi - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - -# Prevent multiple expansion - - - - - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - echo "$as_me:$LINENO: result: $CXX" >&5 -echo "${ECHO_T}$CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -echo "${ECHO_T}$ac_ct_CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CXX" && break -done -test -n "$ac_ct_CXX" || ac_ct_CXX="g++" - - CXX=$ac_ct_CXX -fi - - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C++ compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 -GXX=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cxx_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cxx_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -depcc="$CXX" am_compiler_list= - -echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 -if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 -echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - - -if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - - -if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -main() -{ -#if defined(__GNUC__) && \ - ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)) - return 1; -#endif - return 0; -} - -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -echo "need at least gcc 2.95 to compile correctly" -exit 1 -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - -# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works -# for constant arguments. Useless! -echo "$as_me:$LINENO: checking for working alloca.h" >&5 -echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6 -if test "${ac_cv_working_alloca_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -char *p = (char *) alloca (2 * sizeof (int)); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_working_alloca_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_working_alloca_h=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 -echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 -if test $ac_cv_working_alloca_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ALLOCA_H 1 -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for alloca" >&5 -echo $ECHO_N "checking for alloca... $ECHO_C" >&6 -if test "${ac_cv_func_alloca_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# ifdef _MSC_VER -# include -# define alloca _alloca -# else -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -int -main () -{ -char *p = (char *) alloca (1); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_alloca_works=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_alloca_works=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 -echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 - -if test $ac_cv_func_alloca_works = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ALLOCA 1 -_ACEOF - -else - # The SVR3 libPW and SVR4 libucb both contain incompatible functions -# that cause trouble. Some versions do not even contain alloca or -# contain a buggy version. If you still want to use their alloca, -# use ar to extract alloca.o from them instead of compiling alloca.c. - -ALLOCA=alloca.$ac_objext - -cat >>confdefs.h <<\_ACEOF -#define C_ALLOCA 1 -_ACEOF - - -echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 -echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6 -if test "${ac_cv_os_cray+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#if defined(CRAY) && ! defined(CRAY2) -webecray -#else -wenotbecray -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "webecray" >/dev/null 2>&1; then - ac_cv_os_cray=yes -else - ac_cv_os_cray=no -fi -rm -f conftest* - -fi -echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 -echo "${ECHO_T}$ac_cv_os_cray" >&6 -if test $ac_cv_os_cray = yes; then - for ac_func in _getb67 GETB67 getb67; do - as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - -cat >>confdefs.h <<_ACEOF -#define CRAY_STACKSEG_END $ac_func -_ACEOF - - break -fi - - done -fi - -echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 -echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6 -if test "${ac_cv_c_stack_direction+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_c_stack_direction=0 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int -find_stack_direction () -{ - static char *addr = 0; - auto char dummy; - if (addr == 0) - { - addr = &dummy; - return find_stack_direction (); - } - else - return (&dummy > addr) ? 1 : -1; -} - -int -main () -{ - exit (find_stack_direction () < 0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_stack_direction=1 -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_c_stack_direction=-1 -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 -echo "${ECHO_T}$ac_cv_c_stack_direction" >&6 - -cat >>confdefs.h <<_ACEOF -#define STACK_DIRECTION $ac_cv_c_stack_direction -_ACEOF - - -fi - - -echo "$as_me:$LINENO: checking for getopt_long in -lc" >&5 -echo $ECHO_N "checking for getopt_long in -lc... $ECHO_C" >&6 -if test "${ac_cv_lib_c_getopt_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lc $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char getopt_long (); -int -main () -{ -getopt_long (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_c_getopt_long=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_c_getopt_long=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_c_getopt_long" >&5 -echo "${ECHO_T}$ac_cv_lib_c_getopt_long" >&6 -if test $ac_cv_lib_c_getopt_long = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_GETOPT_LONG 1 -_ACEOF - -fi - - -echo "$as_me:$LINENO: checking for alarm in -lc" >&5 -echo $ECHO_N "checking for alarm in -lc... $ECHO_C" >&6 -if test "${ac_cv_lib_c_alarm+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lc $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char alarm (); -int -main () -{ -alarm (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_c_alarm=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_c_alarm=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_c_alarm" >&5 -echo "${ECHO_T}$ac_cv_lib_c_alarm" >&6 -if test $ac_cv_lib_c_alarm = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_ALARM 1 -_ACEOF - -fi - - - -for ac_header in netinet/in.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_header in string.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_header in libintl.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 -if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset x; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - ccp = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - } -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_const=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_c_const=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6 -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const -_ACEOF - -fi - - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "vsnprintf" >/dev/null 2>&1; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_VSNPRINTF 1 -_ACEOF - -fi -rm -f conftest* - - -echo "$as_me:$LINENO: checking for unsigned short int" >&5 -echo $ECHO_N "checking for unsigned short int... $ECHO_C" >&6 -if test "${ac_cv_type_unsigned_short_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((unsigned short int *) 0) - return 0; -if (sizeof (unsigned short int)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_unsigned_short_int=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_unsigned_short_int=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_short_int" >&5 -echo "${ECHO_T}$ac_cv_type_unsigned_short_int" >&6 - -echo "$as_me:$LINENO: checking size of unsigned short int" >&5 -echo $ECHO_N "checking size of unsigned short int... $ECHO_C" >&6 -if test "${ac_cv_sizeof_unsigned_short_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_unsigned_short_int" = yes; then - # The cast to unsigned long works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned short int))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned short int))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned short int))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned short int))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo= ac_hi= -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned short int))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_unsigned_short_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned short int), 77 -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (unsigned short int), 77 -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 -echo "$as_me: error: internal error: not reached in cross-compile" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -long longval () { return (long) (sizeof (unsigned short int)); } -unsigned long ulongval () { return (long) (sizeof (unsigned short int)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if (((long) (sizeof (unsigned short int))) < 0) - { - long i = longval (); - if (i != ((long) (sizeof (unsigned short int)))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != ((long) (sizeof (unsigned short int)))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_unsigned_short_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned short int), 77 -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (unsigned short int), 77 -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - ac_cv_sizeof_unsigned_short_int=0 -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_short_int" >&5 -echo "${ECHO_T}$ac_cv_sizeof_unsigned_short_int" >&6 -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_SHORT_INT $ac_cv_sizeof_unsigned_short_int -_ACEOF - - -echo "$as_me:$LINENO: checking for unsigned long int" >&5 -echo $ECHO_N "checking for unsigned long int... $ECHO_C" >&6 -if test "${ac_cv_type_unsigned_long_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((unsigned long int *) 0) - return 0; -if (sizeof (unsigned long int)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_unsigned_long_int=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_unsigned_long_int=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_int" >&5 -echo "${ECHO_T}$ac_cv_type_unsigned_long_int" >&6 - -echo "$as_me:$LINENO: checking size of unsigned long int" >&5 -echo $ECHO_N "checking size of unsigned long int... $ECHO_C" >&6 -if test "${ac_cv_sizeof_unsigned_long_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_unsigned_long_int" = yes; then - # The cast to unsigned long works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long int))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long int))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long int))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long int))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo= ac_hi= -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long int))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_unsigned_long_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long int), 77 -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (unsigned long int), 77 -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 -echo "$as_me: error: internal error: not reached in cross-compile" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -long longval () { return (long) (sizeof (unsigned long int)); } -unsigned long ulongval () { return (long) (sizeof (unsigned long int)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if (((long) (sizeof (unsigned long int))) < 0) - { - long i = longval (); - if (i != ((long) (sizeof (unsigned long int)))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != ((long) (sizeof (unsigned long int)))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_unsigned_long_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long int), 77 -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (unsigned long int), 77 -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - ac_cv_sizeof_unsigned_long_int=0 -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long_int" >&5 -echo "${ECHO_T}$ac_cv_sizeof_unsigned_long_int" >&6 -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_LONG_INT $ac_cv_sizeof_unsigned_long_int -_ACEOF - - -echo "$as_me:$LINENO: checking for unsigned int" >&5 -echo $ECHO_N "checking for unsigned int... $ECHO_C" >&6 -if test "${ac_cv_type_unsigned_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((unsigned int *) 0) - return 0; -if (sizeof (unsigned int)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_unsigned_int=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_unsigned_int=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_int" >&5 -echo "${ECHO_T}$ac_cv_type_unsigned_int" >&6 - -echo "$as_me:$LINENO: checking size of unsigned int" >&5 -echo $ECHO_N "checking size of unsigned int... $ECHO_C" >&6 -if test "${ac_cv_sizeof_unsigned_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_unsigned_int" = yes; then - # The cast to unsigned long works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo= ac_hi= -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_unsigned_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned int), 77 -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (unsigned int), 77 -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 -echo "$as_me: error: internal error: not reached in cross-compile" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -long longval () { return (long) (sizeof (unsigned int)); } -unsigned long ulongval () { return (long) (sizeof (unsigned int)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if (((long) (sizeof (unsigned int))) < 0) - { - long i = longval (); - if (i != ((long) (sizeof (unsigned int)))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != ((long) (sizeof (unsigned int)))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_unsigned_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned int), 77 -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (unsigned int), 77 -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - ac_cv_sizeof_unsigned_int=0 -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_int" >&5 -echo "${ECHO_T}$ac_cv_sizeof_unsigned_int" >&6 -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int -_ACEOF - - - -GSM_VERSION="1:4:0" - - -LINGUAS="de" -ALL_LINGUAS=$LINGUAS - - - MKINSTALLDIRS= - if test -n "$ac_aux_dir"; then - case "$ac_aux_dir" in - /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; - *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; - esac - fi - if test -z "$MKINSTALLDIRS"; then - MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" - fi - - - - echo "$as_me:$LINENO: checking whether NLS is requested" >&5 -echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6 - # Check whether --enable-nls or --disable-nls was given. -if test "${enable_nls+set}" = set; then - enableval="$enable_nls" - USE_NLS=$enableval -else - USE_NLS=yes -fi; - echo "$as_me:$LINENO: result: $USE_NLS" >&5 -echo "${ECHO_T}$USE_NLS" >&6 - - - - - - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "msgfmt", so it can be a program name with args. -set dummy msgfmt; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_MSGFMT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case "$MSGFMT" in - [\\/]* | ?:[\\/]*) - ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&5 - if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" - test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" - ;; -esac -fi -MSGFMT="$ac_cv_path_MSGFMT" -if test "$MSGFMT" != ":"; then - echo "$as_me:$LINENO: result: $MSGFMT" >&5 -echo "${ECHO_T}$MSGFMT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - # Extract the first word of "gmsgfmt", so it can be a program name with args. -set dummy gmsgfmt; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_GMSGFMT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $GMSGFMT in - [\\/]* | ?:[\\/]*) - ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" - ;; -esac -fi -GMSGFMT=$ac_cv_path_GMSGFMT - -if test -n "$GMSGFMT"; then - echo "$as_me:$LINENO: result: $GMSGFMT" >&5 -echo "${ECHO_T}$GMSGFMT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "xgettext", so it can be a program name with args. -set dummy xgettext; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_XGETTEXT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case "$XGETTEXT" in - [\\/]* | ?:[\\/]*) - ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&5 - if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" - test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" - ;; -esac -fi -XGETTEXT="$ac_cv_path_XGETTEXT" -if test "$XGETTEXT" != ":"; then - echo "$as_me:$LINENO: result: $XGETTEXT" >&5 -echo "${ECHO_T}$XGETTEXT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - rm -f messages.po - - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "msgmerge", so it can be a program name with args. -set dummy msgmerge; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_MSGMERGE+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case "$MSGMERGE" in - [\\/]* | ?:[\\/]*) - ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&5 - if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then - ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" - test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" - ;; -esac -fi -MSGMERGE="$ac_cv_path_MSGMERGE" -if test "$MSGMERGE" != ":"; then - echo "$as_me:$LINENO: result: $MSGMERGE" >&5 -echo "${ECHO_T}$MSGMERGE" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - if test "$GMSGFMT" != ":"; then - if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && - (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` - echo "$as_me:$LINENO: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5 -echo "${ECHO_T}found $GMSGFMT program is not GNU msgfmt; ignore it" >&6 - GMSGFMT=":" - fi - fi - - if test "$XGETTEXT" != ":"; then - if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && - (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - echo "$as_me:$LINENO: result: found xgettext program is not GNU xgettext; ignore it" >&5 -echo "${ECHO_T}found xgettext program is not GNU xgettext; ignore it" >&6 - XGETTEXT=":" - fi - rm -f messages.po - fi - - ac_config_commands="$ac_config_commands default-1" - - - - echo "$as_me:$LINENO: checking whether we are using the GNU C Library 2 or newer" >&5 -echo $ECHO_N "checking whether we are using the GNU C Library 2 or newer... $ECHO_C" >&6 -if test "${ac_cv_gnu_library_2+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) - Lucky GNU user - #endif -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "Lucky GNU user" >/dev/null 2>&1; then - ac_cv_gnu_library_2=yes -else - ac_cv_gnu_library_2=no -fi -rm -f conftest* - - - -fi -echo "$as_me:$LINENO: result: $ac_cv_gnu_library_2" >&5 -echo "${ECHO_T}$ac_cv_gnu_library_2" >&6 - - GLIBC2="$ac_cv_gnu_library_2" - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -echo "$as_me:$LINENO: checking for library containing strerror" >&5 -echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6 -if test "${ac_cv_search_strerror+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_strerror=no -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strerror (); -int -main () -{ -strerror (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_strerror="none required" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_strerror" = no; then - for ac_lib in cposix; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strerror (); -int -main () -{ -strerror (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_strerror="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 -echo "${ECHO_T}$ac_cv_search_strerror" >&6 -if test "$ac_cv_search_strerror" != no; then - test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS" - -fi - - - echo "$as_me:$LINENO: checking for signed" >&5 -echo $ECHO_N "checking for signed... $ECHO_C" >&6 -if test "${bh_cv_c_signed+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -signed char x; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - bh_cv_c_signed=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -bh_cv_c_signed=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $bh_cv_c_signed" >&5 -echo "${ECHO_T}$bh_cv_c_signed" >&6 - if test $bh_cv_c_signed = no; then - -cat >>confdefs.h <<\_ACEOF -#define signed -_ACEOF - - fi - -echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6 -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6 - - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - -echo "$as_me:$LINENO: checking for off_t" >&5 -echo $ECHO_N "checking for off_t... $ECHO_C" >&6 -if test "${ac_cv_type_off_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((off_t *) 0) - return 0; -if (sizeof (off_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_off_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_off_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 -echo "${ECHO_T}$ac_cv_type_off_t" >&6 -if test $ac_cv_type_off_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define off_t long -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for size_t" >&5 -echo $ECHO_N "checking for size_t... $ECHO_C" >&6 -if test "${ac_cv_type_size_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((size_t *) 0) - return 0; -if (sizeof (size_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_size_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_size_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -echo "${ECHO_T}$ac_cv_type_size_t" >&6 -if test $ac_cv_type_size_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned -_ACEOF - -fi - - - echo "$as_me:$LINENO: checking for long long" >&5 -echo $ECHO_N "checking for long long... $ECHO_C" >&6 -if test "${ac_cv_type_long_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -long long ll = 1LL; int i = 63; -int -main () -{ -long long llmax = (long long) -1; - return ll << i | ll >> i | llmax / ll | llmax % ll; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_long_long=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_long_long=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5 -echo "${ECHO_T}$ac_cv_type_long_long" >&6 - if test $ac_cv_type_long_long = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LONG_LONG 1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for long double" >&5 -echo $ECHO_N "checking for long double... $ECHO_C" >&6 -if test "${gt_cv_c_long_double+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$GCC" = yes; then - gt_cv_c_long_double=yes - else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - /* The Stardent Vistra knows sizeof(long double), but does not support it. */ - long double foo = 0.0; - /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ - int array [2*(sizeof(long double) >= sizeof(double)) - 1]; - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_c_long_double=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_c_long_double=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - fi -fi -echo "$as_me:$LINENO: result: $gt_cv_c_long_double" >&5 -echo "${ECHO_T}$gt_cv_c_long_double" >&6 - if test $gt_cv_c_long_double = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LONG_DOUBLE 1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for wchar_t" >&5 -echo $ECHO_N "checking for wchar_t... $ECHO_C" >&6 -if test "${gt_cv_c_wchar_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - wchar_t foo = (wchar_t)'\0'; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_c_wchar_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_c_wchar_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gt_cv_c_wchar_t" >&5 -echo "${ECHO_T}$gt_cv_c_wchar_t" >&6 - if test $gt_cv_c_wchar_t = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WCHAR_T 1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for wint_t" >&5 -echo $ECHO_N "checking for wint_t... $ECHO_C" >&6 -if test "${gt_cv_c_wint_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - wint_t foo = (wchar_t)'\0'; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_c_wint_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_c_wint_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gt_cv_c_wint_t" >&5 -echo "${ECHO_T}$gt_cv_c_wint_t" >&6 - if test $gt_cv_c_wint_t = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WINT_T 1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for inttypes.h" >&5 -echo $ECHO_N "checking for inttypes.h... $ECHO_C" >&6 -if test "${gl_cv_header_inttypes_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -int -main () -{ -uintmax_t i = (uintmax_t) -1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gl_cv_header_inttypes_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gl_cv_header_inttypes_h=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gl_cv_header_inttypes_h" >&5 -echo "${ECHO_T}$gl_cv_header_inttypes_h" >&6 - if test $gl_cv_header_inttypes_h = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_INTTYPES_H_WITH_UINTMAX 1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for stdint.h" >&5 -echo $ECHO_N "checking for stdint.h... $ECHO_C" >&6 -if test "${gl_cv_header_stdint_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -int -main () -{ -uintmax_t i = (uintmax_t) -1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gl_cv_header_stdint_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gl_cv_header_stdint_h=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gl_cv_header_stdint_h" >&5 -echo "${ECHO_T}$gl_cv_header_stdint_h" >&6 - if test $gl_cv_header_stdint_h = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STDINT_H_WITH_UINTMAX 1 -_ACEOF - - fi - - - - - echo "$as_me:$LINENO: checking for intmax_t" >&5 -echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6 -if test "${gt_cv_c_intmax_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -#include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -#include -#endif - -int -main () -{ -intmax_t x = -1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_c_intmax_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_c_intmax_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gt_cv_c_intmax_t" >&5 -echo "${ECHO_T}$gt_cv_c_intmax_t" >&6 - if test $gt_cv_c_intmax_t = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_INTMAX_T 1 -_ACEOF - - fi - - - - echo "$as_me:$LINENO: checking whether printf() supports POSIX/XSI format strings" >&5 -echo $ECHO_N "checking whether printf() supports POSIX/XSI format strings... $ECHO_C" >&6 -if test "${gt_cv_func_printf_posix+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - if test "$cross_compiling" = yes; then - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ - notposix -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "notposix" >/dev/null 2>&1; then - gt_cv_func_printf_posix="guessing no" -else - gt_cv_func_printf_posix="guessing yes" -fi -rm -f conftest* - - -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include -/* The string "%2$d %1$d", with dollar characters protected from the shell's - dollar expansion (possibly an autoconf bug). */ -static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; -static char buf[100]; -int main () -{ - sprintf (buf, format, 33, 55); - return (strcmp (buf, "55 33") != 0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_printf_posix=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -gt_cv_func_printf_posix=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - -fi -echo "$as_me:$LINENO: result: $gt_cv_func_printf_posix" >&5 -echo "${ECHO_T}$gt_cv_func_printf_posix" >&6 - case $gt_cv_func_printf_posix in - *yes) - -cat >>confdefs.h <<\_ACEOF -#define HAVE_POSIX_PRINTF 1 -_ACEOF - - ;; - esac - - - -for ac_header in stdlib.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_func in getpagesize -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -echo "$as_me:$LINENO: checking for working mmap" >&5 -echo $ECHO_N "checking for working mmap... $ECHO_C" >&6 -if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_mmap_fixed_mapped=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -/* malloc might have been renamed as rpl_malloc. */ -#undef malloc - -/* Thanks to Mike Haertel and Jim Avera for this test. - Here is a matrix of mmap possibilities: - mmap private not fixed - mmap private fixed at somewhere currently unmapped - mmap private fixed at somewhere already mapped - mmap shared not fixed - mmap shared fixed at somewhere currently unmapped - mmap shared fixed at somewhere already mapped - For private mappings, we should verify that changes cannot be read() - back from the file, nor mmap's back from the file at a different - address. (There have been systems where private was not correctly - implemented like the infamous i386 svr4.0, and systems where the - VM page cache was not coherent with the file system buffer cache - like early versions of FreeBSD and possibly contemporary NetBSD.) - For shared mappings, we should conversely verify that changes get - propagated back to all the places they're supposed to be. - - Grep wants private fixed already mapped. - The main things grep needs to know about mmap are: - * does it exist and is it safe to write into the mmap'd area - * how to use it (BSD variants) */ - -#include -#include - -#if !STDC_HEADERS && !HAVE_STDLIB_H -char *malloc (); -#endif - -/* This mess was copied from the GNU getpagesize.h. */ -#if !HAVE_GETPAGESIZE -/* Assume that all systems that can run configure have sys/param.h. */ -# if !HAVE_SYS_PARAM_H -# define HAVE_SYS_PARAM_H 1 -# endif - -# ifdef _SC_PAGESIZE -# define getpagesize() sysconf(_SC_PAGESIZE) -# else /* no _SC_PAGESIZE */ -# if HAVE_SYS_PARAM_H -# include -# ifdef EXEC_PAGESIZE -# define getpagesize() EXEC_PAGESIZE -# else /* no EXEC_PAGESIZE */ -# ifdef NBPG -# define getpagesize() NBPG * CLSIZE -# ifndef CLSIZE -# define CLSIZE 1 -# endif /* no CLSIZE */ -# else /* no NBPG */ -# ifdef NBPC -# define getpagesize() NBPC -# else /* no NBPC */ -# ifdef PAGESIZE -# define getpagesize() PAGESIZE -# endif /* PAGESIZE */ -# endif /* no NBPC */ -# endif /* no NBPG */ -# endif /* no EXEC_PAGESIZE */ -# else /* no HAVE_SYS_PARAM_H */ -# define getpagesize() 8192 /* punt totally */ -# endif /* no HAVE_SYS_PARAM_H */ -# endif /* no _SC_PAGESIZE */ - -#endif /* no HAVE_GETPAGESIZE */ - -int -main () -{ - char *data, *data2, *data3; - int i, pagesize; - int fd; - - pagesize = getpagesize (); - - /* First, make a file with some known garbage in it. */ - data = (char *) malloc (pagesize); - if (!data) - exit (1); - for (i = 0; i < pagesize; ++i) - *(data + i) = rand (); - umask (0); - fd = creat ("conftest.mmap", 0600); - if (fd < 0) - exit (1); - if (write (fd, data, pagesize) != pagesize) - exit (1); - close (fd); - - /* Next, try to mmap the file at a fixed address which already has - something else allocated at it. If we can, also make sure that - we see the same garbage. */ - fd = open ("conftest.mmap", O_RDWR); - if (fd < 0) - exit (1); - data2 = (char *) malloc (2 * pagesize); - if (!data2) - exit (1); - data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1); - if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED, fd, 0L)) - exit (1); - for (i = 0; i < pagesize; ++i) - if (*(data + i) != *(data2 + i)) - exit (1); - - /* Finally, make sure that changes to the mapped area do not - percolate back to the file as seen by read(). (This is a bug on - some variants of i386 svr4.0.) */ - for (i = 0; i < pagesize; ++i) - *(data2 + i) = *(data2 + i) + 1; - data3 = (char *) malloc (pagesize); - if (!data3) - exit (1); - if (read (fd, data3, pagesize) != pagesize) - exit (1); - for (i = 0; i < pagesize; ++i) - if (*(data + i) != *(data3 + i)) - exit (1); - close (fd); - exit (0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_mmap_fixed_mapped=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_mmap_fixed_mapped=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 -echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6 -if test $ac_cv_func_mmap_fixed_mapped = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_MMAP 1 -_ACEOF - -fi -rm -f conftest.mmap - - - echo "$as_me:$LINENO: checking whether we are using the GNU C Library 2.1 or newer" >&5 -echo $ECHO_N "checking whether we are using the GNU C Library 2.1 or newer... $ECHO_C" >&6 -if test "${ac_cv_gnu_library_2_1+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) - Lucky GNU user - #endif -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "Lucky GNU user" >/dev/null 2>&1; then - ac_cv_gnu_library_2_1=yes -else - ac_cv_gnu_library_2_1=no -fi -rm -f conftest* - - - -fi -echo "$as_me:$LINENO: result: $ac_cv_gnu_library_2_1" >&5 -echo "${ECHO_T}$ac_cv_gnu_library_2_1" >&6 - - GLIBC21="$ac_cv_gnu_library_2_1" - - - - - echo "$as_me:$LINENO: checking whether integer division by zero raises SIGFPE" >&5 -echo $ECHO_N "checking whether integer division by zero raises SIGFPE... $ECHO_C" >&6 -if test "${gt_cv_int_divbyzero_sigfpe+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - if test "$cross_compiling" = yes; then - - # Guess based on the CPU. - case "$host_cpu" in - alpha* | i3456786 | m68k | s390*) - gt_cv_int_divbyzero_sigfpe="guessing yes";; - *) - gt_cv_int_divbyzero_sigfpe="guessing no";; - esac - -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include - -static void -#ifdef __cplusplus -sigfpe_handler (int sig) -#else -sigfpe_handler (sig) int sig; -#endif -{ - /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ - exit (sig != SIGFPE); -} - -int x = 1; -int y = 0; -int z; -int nan; - -int main () -{ - signal (SIGFPE, sigfpe_handler); -/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ -#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) - signal (SIGTRAP, sigfpe_handler); -#endif -/* Linux/SPARC yields signal SIGILL. */ -#if defined (__sparc__) && defined (__linux__) - signal (SIGILL, sigfpe_handler); -#endif - - z = x / y; - nan = y / y; - exit (1); -} - -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_int_divbyzero_sigfpe=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -gt_cv_int_divbyzero_sigfpe=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - -fi -echo "$as_me:$LINENO: result: $gt_cv_int_divbyzero_sigfpe" >&5 -echo "${ECHO_T}$gt_cv_int_divbyzero_sigfpe" >&6 - case "$gt_cv_int_divbyzero_sigfpe" in - *yes) value=1;; - *) value=0;; - esac - -cat >>confdefs.h <<_ACEOF -#define INTDIV0_RAISES_SIGFPE $value -_ACEOF - - - - echo "$as_me:$LINENO: checking for unsigned long long" >&5 -echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6 -if test "${ac_cv_type_unsigned_long_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -unsigned long long ull = 1ULL; int i = 63; -int -main () -{ -unsigned long long ullmax = (unsigned long long) -1; - return ull << i | ull >> i | ullmax / ull | ullmax % ull; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_unsigned_long_long=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_unsigned_long_long=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5 -echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6 - if test $ac_cv_type_unsigned_long_long = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_UNSIGNED_LONG_LONG 1 -_ACEOF - - fi - - - - - if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then - - test $ac_cv_type_unsigned_long_long = yes \ - && ac_type='unsigned long long' \ - || ac_type='unsigned long' - -cat >>confdefs.h <<_ACEOF -#define uintmax_t $ac_type -_ACEOF - - else - -cat >>confdefs.h <<\_ACEOF -#define HAVE_UINTMAX_T 1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for inttypes.h" >&5 -echo $ECHO_N "checking for inttypes.h... $ECHO_C" >&6 -if test "${gt_cv_header_inttypes_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_header_inttypes_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_header_inttypes_h=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $gt_cv_header_inttypes_h" >&5 -echo "${ECHO_T}$gt_cv_header_inttypes_h" >&6 - if test $gt_cv_header_inttypes_h = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_INTTYPES_H 1 -_ACEOF - - fi - - - - if test $gt_cv_header_inttypes_h = yes; then - echo "$as_me:$LINENO: checking whether the inttypes.h PRIxNN macros are broken" >&5 -echo $ECHO_N "checking whether the inttypes.h PRIxNN macros are broken... $ECHO_C" >&6 -if test "${gt_cv_inttypes_pri_broken+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#ifdef PRId32 -char *p = PRId32; -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_inttypes_pri_broken=no -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_inttypes_pri_broken=yes -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $gt_cv_inttypes_pri_broken" >&5 -echo "${ECHO_T}$gt_cv_inttypes_pri_broken" >&6 - fi - if test "$gt_cv_inttypes_pri_broken" = yes; then - -cat >>confdefs.h <<_ACEOF -#define PRI_MACROS_BROKEN 1 -_ACEOF - - fi - - - -for ac_header in stdint.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - echo "$as_me:$LINENO: checking for SIZE_MAX" >&5 -echo $ECHO_N "checking for SIZE_MAX... $ECHO_C" >&6 - result= - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#if HAVE_STDINT_H -#include -#endif -#ifdef SIZE_MAX -Found it -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "Found it" >/dev/null 2>&1; then - result=yes -fi -rm -f conftest* - - if test -z "$result"; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo= ac_hi= -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) res_hi=$ac_lo;; -'') result=? ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 -echo "$as_me: error: internal error: not reached in cross-compile" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -long longval () { return ~(size_t)0 / 10; } -unsigned long ulongval () { return ~(size_t)0 / 10; } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((~(size_t)0 / 10) < 0) - { - long i = longval (); - if (i != (~(size_t)0 / 10)) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (~(size_t)0 / 10)) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - res_hi=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -result=? -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo= ac_hi= -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) res_lo=$ac_lo;; -'') result=? ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 -echo "$as_me: error: internal error: not reached in cross-compile" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -long longval () { return ~(size_t)0 % 10; } -unsigned long ulongval () { return ~(size_t)0 % 10; } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((~(size_t)0 % 10) < 0) - { - long i = longval (); - if (i != (~(size_t)0 % 10)) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (~(size_t)0 % 10)) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - res_lo=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -result=? -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo= ac_hi= -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) fits_in_uint=$ac_lo;; -'') result=? ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 -echo "$as_me: error: internal error: not reached in cross-compile" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -long longval () { return sizeof (size_t) <= sizeof (unsigned int); } -unsigned long ulongval () { return sizeof (size_t) <= sizeof (unsigned int); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((sizeof (size_t) <= sizeof (unsigned int)) < 0) - { - long i = longval (); - if (i != (sizeof (size_t) <= sizeof (unsigned int))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (sizeof (size_t) <= sizeof (unsigned int))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - fits_in_uint=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -result=? -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val - if test "$fits_in_uint" = 1; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - extern size_t foo; - extern unsigned long foo; - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - fits_in_uint=0 -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$result"; then - if test "$fits_in_uint" = 1; then - result="$res_hi$res_lo"U - else - result="$res_hi$res_lo"UL - fi - else - result='~(size_t)0' - fi - fi - echo "$as_me:$LINENO: result: $result" >&5 -echo "${ECHO_T}$result" >&6 - if test "$result" != yes; then - -cat >>confdefs.h <<_ACEOF -#define SIZE_MAX $result -_ACEOF - - fi - - - - - -for ac_header in stdint.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - echo "$as_me:$LINENO: checking for CFPreferencesCopyAppValue" >&5 -echo $ECHO_N "checking for CFPreferencesCopyAppValue... $ECHO_C" >&6 -if test "${gt_cv_func_CFPreferencesCopyAppValue+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - gt_save_LIBS="$LIBS" - LIBS="$LIBS -framework CoreFoundation" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -CFPreferencesCopyAppValue(NULL, NULL) - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_CFPreferencesCopyAppValue=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_func_CFPreferencesCopyAppValue=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS" -fi -echo "$as_me:$LINENO: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 -echo "${ECHO_T}$gt_cv_func_CFPreferencesCopyAppValue" >&6 - if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CFPREFERENCESCOPYAPPVALUE 1 -_ACEOF - - fi - echo "$as_me:$LINENO: checking for CFLocaleCopyCurrent" >&5 -echo $ECHO_N "checking for CFLocaleCopyCurrent... $ECHO_C" >&6 -if test "${gt_cv_func_CFLocaleCopyCurrent+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - gt_save_LIBS="$LIBS" - LIBS="$LIBS -framework CoreFoundation" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -CFLocaleCopyCurrent(); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_CFLocaleCopyCurrent=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_func_CFLocaleCopyCurrent=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS" -fi -echo "$as_me:$LINENO: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 -echo "${ECHO_T}$gt_cv_func_CFLocaleCopyCurrent" >&6 - if test $gt_cv_func_CFLocaleCopyCurrent = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CFLOCALECOPYCURRENT 1 -_ACEOF - - fi - INTL_MACOSX_LIBS= - if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then - INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" - fi - - - - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" - - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi; -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo "$as_me:$LINENO: checking for ld used by GCC" >&5 -echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6 - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - echo "$as_me:$LINENO: checking for GNU ld" >&5 -echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 -else - echo "$as_me:$LINENO: checking for non-GNU ld" >&5 -echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 -fi -if test "${acl_cv_path_LD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break ;; - *) - test "$with_gnu_ld" != yes && break ;; - esac - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$acl_cv_path_LD" -if test -n "$LD"; then - echo "$as_me:$LINENO: result: $LD" >&5 -echo "${ECHO_T}$LD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 -echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} - { (exit 1); exit 1; }; } -echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 -echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 -if test "${acl_cv_prog_gnu_ld+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 &5 -echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6 -with_gnu_ld=$acl_cv_prog_gnu_ld - - - - - echo "$as_me:$LINENO: checking for shared library run path origin" >&5 -echo $ECHO_N "checking for shared library run path origin... $ECHO_C" >&6 -if test "${acl_cv_rpath+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - -fi -echo "$as_me:$LINENO: result: $acl_cv_rpath" >&5 -echo "${ECHO_T}$acl_cv_rpath" >&6 - wl="$acl_cv_wl" - libext="$acl_cv_libext" - shlibext="$acl_cv_shlibext" - hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - hardcode_direct="$acl_cv_hardcode_direct" - hardcode_minus_L="$acl_cv_hardcode_minus_L" - # Check whether --enable-rpath or --disable-rpath was given. -if test "${enable_rpath+set}" = set; then - enableval="$enable_rpath" - : -else - enable_rpath=yes -fi; - - - - - - - - use_additional=yes - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - -# Check whether --with-libiconv-prefix or --without-libiconv-prefix was given. -if test "${with_libiconv_prefix+set}" = set; then - withval="$with_libiconv_prefix" - - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi - -fi; - LIBICONV= - LTLIBICONV= - INCICONV= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='iconv ' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$hardcode_direct" = yes; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" - ;; - esac - done - fi - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" - done - fi - - - - - - - - - echo "$as_me:$LINENO: checking for ptrdiff_t" >&5 -echo $ECHO_N "checking for ptrdiff_t... $ECHO_C" >&6 -if test "${ac_cv_type_ptrdiff_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((ptrdiff_t *) 0) - return 0; -if (sizeof (ptrdiff_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_ptrdiff_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_ptrdiff_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_ptrdiff_t" >&5 -echo "${ECHO_T}$ac_cv_type_ptrdiff_t" >&6 -if test $ac_cv_type_ptrdiff_t = yes; then - : -else - -cat >>confdefs.h <<\_ACEOF -#define ptrdiff_t long -_ACEOF - - -fi - - - - - - - - - - - -for ac_header in argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ -stdlib.h string.h unistd.h sys/param.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - - - - - - - - - - - - - - - - - - - - - -for ac_func in asprintf fwprintf getcwd getegid geteuid getgid getuid \ -mempcpy munmap putenv setenv setlocale snprintf stpcpy strcasecmp strdup \ -strtoul tsearch wcslen __argz_count __argz_stringify __argz_next \ -__fsetlocking -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - - - echo "$as_me:$LINENO: checking whether _snprintf is declared" >&5 -echo $ECHO_N "checking whether _snprintf is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl__snprintf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - -#ifndef _snprintf - char *p = (char *) _snprintf; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl__snprintf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_have_decl__snprintf=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl__snprintf" >&5 -echo "${ECHO_T}$ac_cv_have_decl__snprintf" >&6 - if test $ac_cv_have_decl__snprintf = yes; then - gt_value=1 - else - gt_value=0 - fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL__SNPRINTF $gt_value -_ACEOF - - - - echo "$as_me:$LINENO: checking whether _snwprintf is declared" >&5 -echo $ECHO_N "checking whether _snwprintf is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl__snwprintf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - -#ifndef _snwprintf - char *p = (char *) _snwprintf; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl__snwprintf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_have_decl__snwprintf=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl__snwprintf" >&5 -echo "${ECHO_T}$ac_cv_have_decl__snwprintf" >&6 - if test $ac_cv_have_decl__snwprintf = yes; then - gt_value=1 - else - gt_value=0 - fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL__SNWPRINTF $gt_value -_ACEOF - - - - - echo "$as_me:$LINENO: checking whether feof_unlocked is declared" >&5 -echo $ECHO_N "checking whether feof_unlocked is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl_feof_unlocked+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - -#ifndef feof_unlocked - char *p = (char *) feof_unlocked; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl_feof_unlocked=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_have_decl_feof_unlocked=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl_feof_unlocked" >&5 -echo "${ECHO_T}$ac_cv_have_decl_feof_unlocked" >&6 - if test $ac_cv_have_decl_feof_unlocked = yes; then - gt_value=1 - else - gt_value=0 - fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_FEOF_UNLOCKED $gt_value -_ACEOF - - - - echo "$as_me:$LINENO: checking whether fgets_unlocked is declared" >&5 -echo $ECHO_N "checking whether fgets_unlocked is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl_fgets_unlocked+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - -#ifndef fgets_unlocked - char *p = (char *) fgets_unlocked; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl_fgets_unlocked=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_have_decl_fgets_unlocked=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl_fgets_unlocked" >&5 -echo "${ECHO_T}$ac_cv_have_decl_fgets_unlocked" >&6 - if test $ac_cv_have_decl_fgets_unlocked = yes; then - gt_value=1 - else - gt_value=0 - fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_FGETS_UNLOCKED $gt_value -_ACEOF - - - - echo "$as_me:$LINENO: checking whether getc_unlocked is declared" >&5 -echo $ECHO_N "checking whether getc_unlocked is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl_getc_unlocked+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - -#ifndef getc_unlocked - char *p = (char *) getc_unlocked; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl_getc_unlocked=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_have_decl_getc_unlocked=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl_getc_unlocked" >&5 -echo "${ECHO_T}$ac_cv_have_decl_getc_unlocked" >&6 - if test $ac_cv_have_decl_getc_unlocked = yes; then - gt_value=1 - else - gt_value=0 - fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_GETC_UNLOCKED $gt_value -_ACEOF - - - - case $gt_cv_func_printf_posix in - *yes) HAVE_POSIX_PRINTF=1 ;; - *) HAVE_POSIX_PRINTF=0 ;; - esac - - if test "$ac_cv_func_asprintf" = yes; then - HAVE_ASPRINTF=1 - else - HAVE_ASPRINTF=0 - fi - - if test "$ac_cv_func_snprintf" = yes; then - HAVE_SNPRINTF=1 - else - HAVE_SNPRINTF=0 - fi - - if test "$ac_cv_func_wprintf" = yes; then - HAVE_WPRINTF=1 - else - HAVE_WPRINTF=0 - fi - - - - - - - - am_save_CPPFLAGS="$CPPFLAGS" - - for element in $INCICONV; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - - echo "$as_me:$LINENO: checking for iconv" >&5 -echo $ECHO_N "checking for iconv... $ECHO_C" >&6 -if test "${am_cv_func_iconv+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - am_cv_func_iconv=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - am_cv_lib_iconv=yes - am_cv_func_iconv=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$am_save_LIBS" - fi - -fi -echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5 -echo "${ECHO_T}$am_cv_func_iconv" >&6 - if test "$am_cv_func_iconv" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ICONV 1 -_ACEOF - - fi - if test "$am_cv_lib_iconv" = yes; then - echo "$as_me:$LINENO: checking how to link with libiconv" >&5 -echo $ECHO_N "checking how to link with libiconv... $ECHO_C" >&6 - echo "$as_me:$LINENO: result: $LIBICONV" >&5 -echo "${ECHO_T}$LIBICONV" >&6 - else - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - - - - if test "$am_cv_func_iconv" = yes; then - echo "$as_me:$LINENO: checking for iconv declaration" >&5 -echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6 - if test "${am_cv_proto_iconv+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - am_cv_proto_iconv_arg1="" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -am_cv_proto_iconv_arg1="const" -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" -fi - - am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - echo "$as_me:$LINENO: result: ${ac_t:- - }$am_cv_proto_iconv" >&5 -echo "${ECHO_T}${ac_t:- - }$am_cv_proto_iconv" >&6 - -cat >>confdefs.h <<_ACEOF -#define ICONV_CONST $am_cv_proto_iconv_arg1 -_ACEOF - - fi - - - echo "$as_me:$LINENO: checking for nl_langinfo and CODESET" >&5 -echo $ECHO_N "checking for nl_langinfo and CODESET... $ECHO_C" >&6 -if test "${am_cv_langinfo_codeset+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -char* cs = nl_langinfo(CODESET); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - am_cv_langinfo_codeset=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -am_cv_langinfo_codeset=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $am_cv_langinfo_codeset" >&5 -echo "${ECHO_T}$am_cv_langinfo_codeset" >&6 - if test $am_cv_langinfo_codeset = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LANGINFO_CODESET 1 -_ACEOF - - fi - - if test $ac_cv_header_locale_h = yes; then - - echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5 -echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6 -if test "${gt_cv_val_LC_MESSAGES+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -return LC_MESSAGES - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_val_LC_MESSAGES=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_val_LC_MESSAGES=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gt_cv_val_LC_MESSAGES" >&5 -echo "${ECHO_T}$gt_cv_val_LC_MESSAGES" >&6 - if test $gt_cv_val_LC_MESSAGES = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LC_MESSAGES 1 -_ACEOF - - fi - - fi - - if test -n "$INTL_MACOSX_LIBS"; then - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - fi - - for ac_prog in bison -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_INTLBISON+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$INTLBISON"; then - ac_cv_prog_INTLBISON="$INTLBISON" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_INTLBISON="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -INTLBISON=$ac_cv_prog_INTLBISON -if test -n "$INTLBISON"; then - echo "$as_me:$LINENO: result: $INTLBISON" >&5 -echo "${ECHO_T}$INTLBISON" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$INTLBISON" && break -done - - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - echo "$as_me:$LINENO: checking version of bison" >&5 -echo $ECHO_N "checking version of bison... $ECHO_C" >&6 - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - echo "$as_me:$LINENO: result: $ac_prog_version" >&5 -echo "${ECHO_T}$ac_prog_version" >&6 - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi - - - - - - - - - - - - - - - - - echo "$as_me:$LINENO: checking for CFPreferencesCopyAppValue" >&5 -echo $ECHO_N "checking for CFPreferencesCopyAppValue... $ECHO_C" >&6 -if test "${gt_cv_func_CFPreferencesCopyAppValue+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - gt_save_LIBS="$LIBS" - LIBS="$LIBS -framework CoreFoundation" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -CFPreferencesCopyAppValue(NULL, NULL) - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_CFPreferencesCopyAppValue=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_func_CFPreferencesCopyAppValue=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS" -fi -echo "$as_me:$LINENO: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 -echo "${ECHO_T}$gt_cv_func_CFPreferencesCopyAppValue" >&6 - if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CFPREFERENCESCOPYAPPVALUE 1 -_ACEOF - - fi - echo "$as_me:$LINENO: checking for CFLocaleCopyCurrent" >&5 -echo $ECHO_N "checking for CFLocaleCopyCurrent... $ECHO_C" >&6 -if test "${gt_cv_func_CFLocaleCopyCurrent+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" - gt_save_LIBS="$LIBS" - LIBS="$LIBS -framework CoreFoundation" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -CFLocaleCopyCurrent(); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_CFLocaleCopyCurrent=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_func_CFLocaleCopyCurrent=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS" -fi -echo "$as_me:$LINENO: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 -echo "${ECHO_T}$gt_cv_func_CFLocaleCopyCurrent" >&6 - if test $gt_cv_func_CFLocaleCopyCurrent = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CFLOCALECOPYCURRENT 1 -_ACEOF - - fi - INTL_MACOSX_LIBS= - if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then - INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" - fi - - - - - echo "$as_me:$LINENO: checking whether NLS is requested" >&5 -echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6 - # Check whether --enable-nls or --disable-nls was given. -if test "${enable_nls+set}" = set; then - enableval="$enable_nls" - USE_NLS=$enableval -else - USE_NLS=yes -fi; - echo "$as_me:$LINENO: result: $USE_NLS" >&5 -echo "${ECHO_T}$USE_NLS" >&6 - - - - - BUILD_INCLUDED_LIBINTL=no - USE_INCLUDED_LIBINTL=no - - LIBINTL= - LTLIBINTL= - POSUB= - - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - - echo "$as_me:$LINENO: checking whether included gettext is requested" >&5 -echo $ECHO_N "checking whether included gettext is requested... $ECHO_C" >&6 - -# Check whether --with-included-gettext or --without-included-gettext was given. -if test "${with_included_gettext+set}" = set; then - withval="$with_included_gettext" - nls_cv_force_use_gnu_gettext=$withval -else - nls_cv_force_use_gnu_gettext=no -fi; - echo "$as_me:$LINENO: result: $nls_cv_force_use_gnu_gettext" >&5 -echo "${ECHO_T}$nls_cv_force_use_gnu_gettext" >&6 - - nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" - if test "$nls_cv_force_use_gnu_gettext" != "yes"; then - - - - - - - echo "$as_me:$LINENO: checking for GNU gettext in libc" >&5 -echo $ECHO_N "checking for GNU gettext in libc... $ECHO_C" >&6 -if test "${gt_cv_func_gnugettext1_libc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings; -int -main () -{ -bindtextdomain ("", ""); -return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_gnugettext1_libc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_func_gnugettext1_libc=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libc" >&5 -echo "${ECHO_T}$gt_cv_func_gnugettext1_libc" >&6 - - if test "$gt_cv_func_gnugettext1_libc" != "yes"; then - - - - use_additional=yes - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - -# Check whether --with-libintl-prefix or --without-libintl-prefix was given. -if test "${with_libintl_prefix+set}" = set; then - withval="$with_libintl_prefix" - - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi - -fi; - LIBINTL= - LTLIBINTL= - INCINTL= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='intl ' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$hardcode_direct" = yes; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - else - LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" - else - LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" - ;; - esac - done - fi - else - LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" - done - fi - - echo "$as_me:$LINENO: checking for GNU gettext in libintl" >&5 -echo $ECHO_N "checking for GNU gettext in libintl... $ECHO_C" >&6 -if test "${gt_cv_func_gnugettext1_libintl+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *); -int -main () -{ -bindtextdomain ("", ""); -return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - gt_cv_func_gnugettext1_libintl=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -gt_cv_func_gnugettext1_libintl=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *); -int -main () -{ -bindtextdomain ("", ""); -return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - gt_cv_func_gnugettext1_libintl=yes - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS" -fi -echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libintl" >&5 -echo "${ECHO_T}$gt_cv_func_gnugettext1_libintl" >&6 - fi - - if test "$gt_cv_func_gnugettext1_libc" = "yes" \ - || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \ - && test "$PACKAGE" != gettext-runtime \ - && test "$PACKAGE" != gettext-tools; }; then - gt_use_preinstalled_gnugettext=yes - else - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - - if test "$gt_use_preinstalled_gnugettext" != "yes"; then - nls_cv_use_gnu_gettext=yes - fi - fi - - if test "$nls_cv_use_gnu_gettext" = "yes"; then - BUILD_INCLUDED_LIBINTL=yes - USE_INCLUDED_LIBINTL=yes - LIBINTL="\${top_builddir}/intl/libintl.a $LIBICONV" - LTLIBINTL="\${top_builddir}/intl/libintl.a $LTLIBICONV" - LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` - fi - - CATOBJEXT= - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - CATOBJEXT=.gmo - fi - - - if test -n "$INTL_MACOSX_LIBS"; then - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" - LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" - fi - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - -cat >>confdefs.h <<\_ACEOF -#define ENABLE_NLS 1 -_ACEOF - - else - USE_NLS=no - fi - fi - - echo "$as_me:$LINENO: checking whether to use NLS" >&5 -echo $ECHO_N "checking whether to use NLS... $ECHO_C" >&6 - echo "$as_me:$LINENO: result: $USE_NLS" >&5 -echo "${ECHO_T}$USE_NLS" >&6 - if test "$USE_NLS" = "yes"; then - echo "$as_me:$LINENO: checking where the gettext function comes from" >&5 -echo $ECHO_N "checking where the gettext function comes from... $ECHO_C" >&6 - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then - gt_source="external libintl" - else - gt_source="libc" - fi - else - gt_source="included intl directory" - fi - echo "$as_me:$LINENO: result: $gt_source" >&5 -echo "${ECHO_T}$gt_source" >&6 - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then - echo "$as_me:$LINENO: checking how to link with libintl" >&5 -echo $ECHO_N "checking how to link with libintl... $ECHO_C" >&6 - echo "$as_me:$LINENO: result: $LIBINTL" >&5 -echo "${ECHO_T}$LIBINTL" >&6 - - for element in $INCINTL; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - fi - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETTEXT 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_DCGETTEXT 1 -_ACEOF - - fi - - POSUB=po - fi - - - if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then - BUILD_INCLUDED_LIBINTL=yes - fi - - - - - - nls_cv_header_intl= - nls_cv_header_libgt= - - DATADIRNAME=share - - - INSTOBJEXT=.mo - - - GENCAT=gencat - - - INTLOBJS= - if test "$USE_INCLUDED_LIBINTL" = yes; then - INTLOBJS="\$(GETTOBJS)" - fi - - - INTL_LIBTOOL_SUFFIX_PREFIX= - - - - INTLLIBS="$LIBINTL" - - - - - - - -_localedir=`eval "echo $datadir/locale"` -if test "$_localedir" = "NONE/share/locale"; then - cat >>confdefs.h <<_ACEOF -#define LOCALEDIR "/usr/local/share/locale" -_ACEOF - -else - _localedir=`echo \"$_localedir\"` - cat >>confdefs.h <<_ACEOF -#define LOCALEDIR $_localedir -_ACEOF - -fi - - - -if test x$USE_INCLUDED_LIBINTL = xyes; then - COMPILE_INTL_TRUE= - COMPILE_INTL_FALSE='#' -else - COMPILE_INTL_TRUE='#' - COMPILE_INTL_FALSE= -fi - - - ac_config_files="$ac_config_files Makefile gsmlib/Makefile tests/Makefile apps/Makefile win32/Makefile doc/Makefile scripts/Makefile intl/Makefile po/Makefile.in ext/Makefile" - ac_config_commands="$ac_config_commands default" -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${COMPILE_INTL_TRUE}" && test -z "${COMPILE_INTL_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"COMPILE_INTL\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"COMPILE_INTL\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to ." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2003 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -INSTALL="$INSTALL" -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - ac_shift=: - ;; - -*) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; - esac - - case $ac_option in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -# -# INIT-COMMANDS section. -# - -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" -# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it - # from automake. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - - -_ACEOF - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "gsmlib/Makefile" ) CONFIG_FILES="$CONFIG_FILES gsmlib/Makefile" ;; - "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; - "apps/Makefile" ) CONFIG_FILES="$CONFIG_FILES apps/Makefile" ;; - "win32/Makefile" ) CONFIG_FILES="$CONFIG_FILES win32/Makefile" ;; - "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "scripts/Makefile" ) CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; - "intl/Makefile" ) CONFIG_FILES="$CONFIG_FILES intl/Makefile" ;; - "po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; - "ext/Makefile" ) CONFIG_FILES="$CONFIG_FILES ext/Makefile" ;; - "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; - "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; - "gsm_config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS gsm_config.h" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -s,@INSTALL_DATA@,$INSTALL_DATA,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@CYGPATH_W@,$CYGPATH_W,;t t -s,@PACKAGE@,$PACKAGE,;t t -s,@VERSION@,$VERSION,;t t -s,@ACLOCAL@,$ACLOCAL,;t t -s,@AUTOCONF@,$AUTOCONF,;t t -s,@AUTOMAKE@,$AUTOMAKE,;t t -s,@AUTOHEADER@,$AUTOHEADER,;t t -s,@MAKEINFO@,$MAKEINFO,;t t -s,@install_sh@,$install_sh,;t t -s,@STRIP@,$STRIP,;t t -s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t -s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t -s,@mkdir_p@,$mkdir_p,;t t -s,@AWK@,$AWK,;t t -s,@SET_MAKE@,$SET_MAKE,;t t -s,@am__leading_dot@,$am__leading_dot,;t t -s,@AMTAR@,$AMTAR,;t t -s,@am__tar@,$am__tar,;t t -s,@am__untar@,$am__untar,;t t -s,@DEPDIR@,$DEPDIR,;t t -s,@am__include@,$am__include,;t t -s,@am__quote@,$am__quote,;t t -s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t -s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t -s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t -s,@CCDEPMODE@,$CCDEPMODE,;t t -s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t -s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t -s,@build@,$build,;t t -s,@build_cpu@,$build_cpu,;t t -s,@build_vendor@,$build_vendor,;t t -s,@build_os@,$build_os,;t t -s,@host@,$host,;t t -s,@host_cpu@,$host_cpu,;t t -s,@host_vendor@,$host_vendor,;t t -s,@host_os@,$host_os,;t t -s,@EGREP@,$EGREP,;t t -s,@LN_S@,$LN_S,;t t -s,@ECHO@,$ECHO,;t t -s,@AR@,$AR,;t t -s,@ac_ct_AR@,$ac_ct_AR,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@CPP@,$CPP,;t t -s,@CXX@,$CXX,;t t -s,@CXXFLAGS@,$CXXFLAGS,;t t -s,@ac_ct_CXX@,$ac_ct_CXX,;t t -s,@CXXDEPMODE@,$CXXDEPMODE,;t t -s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t -s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t -s,@CXXCPP@,$CXXCPP,;t t -s,@F77@,$F77,;t t -s,@FFLAGS@,$FFLAGS,;t t -s,@ac_ct_F77@,$ac_ct_F77,;t t -s,@LIBTOOL@,$LIBTOOL,;t t -s,@ALLOCA@,$ALLOCA,;t t -s,@GSM_VERSION@,$GSM_VERSION,;t t -s,@MKINSTALLDIRS@,$MKINSTALLDIRS,;t t -s,@USE_NLS@,$USE_NLS,;t t -s,@MSGFMT@,$MSGFMT,;t t -s,@GMSGFMT@,$GMSGFMT,;t t -s,@XGETTEXT@,$XGETTEXT,;t t -s,@MSGMERGE@,$MSGMERGE,;t t -s,@GLIBC2@,$GLIBC2,;t t -s,@GLIBC21@,$GLIBC21,;t t -s,@INTL_MACOSX_LIBS@,$INTL_MACOSX_LIBS,;t t -s,@HAVE_POSIX_PRINTF@,$HAVE_POSIX_PRINTF,;t t -s,@HAVE_ASPRINTF@,$HAVE_ASPRINTF,;t t -s,@HAVE_SNPRINTF@,$HAVE_SNPRINTF,;t t -s,@HAVE_WPRINTF@,$HAVE_WPRINTF,;t t -s,@LIBICONV@,$LIBICONV,;t t -s,@LTLIBICONV@,$LTLIBICONV,;t t -s,@INTLBISON@,$INTLBISON,;t t -s,@BUILD_INCLUDED_LIBINTL@,$BUILD_INCLUDED_LIBINTL,;t t -s,@USE_INCLUDED_LIBINTL@,$USE_INCLUDED_LIBINTL,;t t -s,@CATOBJEXT@,$CATOBJEXT,;t t -s,@DATADIRNAME@,$DATADIRNAME,;t t -s,@INSTOBJEXT@,$INSTOBJEXT,;t t -s,@GENCAT@,$GENCAT,;t t -s,@INTLOBJS@,$INTLOBJS,;t t -s,@INTL_LIBTOOL_SUFFIX_PREFIX@,$INTL_LIBTOOL_SUFFIX_PREFIX,;t t -s,@INTLLIBS@,$INTLLIBS,;t t -s,@LIBINTL@,$LIBINTL,;t t -s,@LTLIBINTL@,$LTLIBINTL,;t t -s,@POSUB@,$POSUB,;t t -s,@COMPILE_INTL_TRUE@,$COMPILE_INTL_TRUE,;t t -s,@COMPILE_INTL_FALSE@,$COMPILE_INTL_FALSE,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; - esac - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_HEADER section. -# - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='[ ].*$,\1#\2' -ac_dC=' ' -ac_dD=',;t' -# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='$,\1#\2define\3' -ac_uC=' ' -ac_uD=',;t' - -for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - # Do quote $f, to prevent DOS paths from being IFS'd. - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } - # Remove the trailing spaces. - sed 's/[ ]*$//' $ac_file_inputs >$tmp/in - -_ACEOF - -# Transform confdefs.h into two sed scripts, `conftest.defines' and -# `conftest.undefs', that substitutes the proper values into -# config.h.in to produce config.h. The first handles `#define' -# templates, and the second `#undef' templates. -# And first: Protect against being on the right side of a sed subst in -# config.status. Protect against being in an unquoted here document -# in config.status. -rm -f conftest.defines conftest.undefs -# Using a here document instead of a string reduces the quoting nightmare. -# Putting comments in sed scripts is not portable. -# -# `end' is used to avoid that the second main sed command (meant for -# 0-ary CPP macros) applies to n-ary macro definitions. -# See the Autoconf documentation for `clear'. -cat >confdef2sed.sed <<\_ACEOF -s/[\\&,]/\\&/g -s,[\\$`],\\&,g -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp -t end -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp -: end -_ACEOF -# If some macros were called several times there might be several times -# the same #defines, which is useless. Nevertheless, we may not want to -# sort them, since we want the *last* AC-DEFINE to be honored. -uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines -sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs -rm -f confdef2sed.sed - -# This sed command replaces #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -cat >>conftest.undefs <<\_ACEOF -s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, -_ACEOF - -# Break up conftest.defines because some shells have a limit on the size -# of here documents, and old seds have small limits too (100 cmds). -echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS -echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS -echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS -echo ' :' >>$CONFIG_STATUS -rm -f conftest.tail -while grep . conftest.defines >/dev/null -do - # Write a limited-size here document to $tmp/defines.sed. - echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS - # Speed up: don't consider the non `#define' lines. - echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS - # Work around the forget-to-reset-the-flag bug. - echo 't clr' >>$CONFIG_STATUS - echo ': clr' >>$CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS - echo 'CEOF - sed -f $tmp/defines.sed $tmp/in >$tmp/out - rm -f $tmp/in - mv $tmp/out $tmp/in -' >>$CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail - rm -f conftest.defines - mv conftest.tail conftest.defines -done -rm -f conftest.defines -echo ' fi # grep' >>$CONFIG_STATUS -echo >>$CONFIG_STATUS - -# Break up conftest.undefs because some shells have a limit on the size -# of here documents, and old seds have small limits too (100 cmds). -echo ' # Handle all the #undef templates' >>$CONFIG_STATUS -rm -f conftest.tail -while grep . conftest.undefs >/dev/null -do - # Write a limited-size here document to $tmp/undefs.sed. - echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS - # Speed up: don't consider the non `#undef' - echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS - # Work around the forget-to-reset-the-flag bug. - echo 't clr' >>$CONFIG_STATUS - echo ': clr' >>$CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS - echo 'CEOF - sed -f $tmp/undefs.sed $tmp/in >$tmp/out - rm -f $tmp/in - mv $tmp/out $tmp/in -' >>$CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail - rm -f conftest.undefs - mv conftest.tail conftest.undefs -done -rm -f conftest.undefs - -cat >>$CONFIG_STATUS <<\_ACEOF - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - echo "/* Generated by configure. */" >$tmp/config.h - else - echo "/* $ac_file. Generated by configure. */" >$tmp/config.h - fi - cat $tmp/in >>$tmp/config.h - rm -f $tmp/in - if test x"$ac_file" != x-; then - if diff $ac_file $tmp/config.h >/dev/null 2>&1; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} - else - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - rm -f $ac_file - mv $tmp/config.h $ac_file - fi - else - cat $tmp/config.h - rm -f $tmp/config.h - fi -# Compute $ac_file's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $ac_file | $ac_file:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || -$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X$ac_file : 'X\(//\)[^/]' \| \ - X$ac_file : 'X\(//\)$' \| \ - X$ac_file : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X$ac_file | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'`/stamp-h$_am_stamp_count -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_COMMANDS section. -# -for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue - ac_dest=`echo "$ac_file" | sed 's,:.*,,'` - ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_dir=`(dirname "$ac_dest") 2>/dev/null || -$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_dest" : 'X\(//\)[^/]' \| \ - X"$ac_dest" : 'X\(//\)$' \| \ - X"$ac_dest" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_dest" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 -echo "$as_me: executing $ac_dest commands" >&6;} - case $ac_dest in - depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`(dirname "$mf") 2>/dev/null || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`(dirname "$file") 2>/dev/null || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p $dirpart/$fdir - else - as_dir=$dirpart/$fdir - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 -echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} - { (exit 1); exit 1; }; }; } - - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done - ;; - default-1 ) - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - # Treat a directory as a PO directory if and only if it has a - # POTFILES.in file. This allows packages to have multiple PO - # directories under different names or in different locations. - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assigment from automake. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - # Compute POFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) - # Compute UPDATEPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) - # Compute DUMMYPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) - # Compute GMOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - UPDATEPOFILES= - DUMMYPOFILES= - GMOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done ;; - default ) echo timestamp > stamp-h ;; - esac -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure.in deleted file mode 100644 index d586c4e35d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure.in +++ /dev/null @@ -1,131 +0,0 @@ -dnl ************************************************************************* -dnl * GSM TA/ME library -dnl * -dnl * File: configure.in -dnl * -dnl * Purpose: autoconf configure script template -dnl * -dnl * Author: Peter Hofmann (software@pxh.de) -dnl * -dnl * Created: 11.11.1999 -dnl ************************************************************************* - -dnl Process this file with autoconf to produce a configure script. -AC_INIT(gsmlib/gsm_error.h) - -dnl Other -AC_CONFIG_AUX_DIR(scripts) -AC_PROG_INSTALL - -dnl check for libintl -AC_CHECK_LIB(intl, textdomain) - -dnl use config header -AM_CONFIG_HEADER(gsm_config.h) - -dnl use automake -AM_INIT_AUTOMAKE(gsmlib, 1.10) - -dnl change to no if you want no shared libraries for debugging purposes -AM_ENABLE_SHARED(yes) - -dnl use -O2 optimization by default -if test "$CXXFLAGS" = ""; then - CXXFLAGS="-O2" -fi - -dnl comment out this line to get extensive debugging output and asserts -dnl CXXFLAGS="-DNDEBUG $CXXFLAGS" - -dnl uncomment to get translations without installing gsmlib -dnl CXXFLAGS="-DLOCAL_TRANSLATIONS $CXXFLAGS" - -dnl check _REENTRANT in header files -if test x"`egrep _REENTRANT /usr/include/features.h`" != x; then - CXXFLAGS="-D_REENTRANT $CXXFLAGS" - CFLAGS="-D_REENTRANT $CFLAGS" -fi - -dnl output all warnings -CXXFLAGS="-Wall $CXXFLAGS" - -dnl use libtool -AM_PROG_LIBTOOL - -dnl Checks for programs. -AC_PROG_CPP -AC_PROG_CXX - -dnl check for gcc 2.95.x -AC_TRY_RUN([ -#include -main() -{ -#if defined(__GNUC__) && \ - ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)) - return 1; -#endif - return 0; -} -],, -[echo "need at least gcc 2.95 to compile correctly" -exit 1]) - -dnl check for alloca -AC_FUNC_ALLOCA - -dnl check for getopt_long in the C library -AC_CHECK_LIB(c, getopt_long, AC_DEFINE(HAVE_GETOPT_LONG)) - -dnl check for alarm in the C library -AC_CHECK_LIB(c, alarm, AC_DEFINE(HAVE_ALARM)) - -dnl check for netinet/in.h header -AC_CHECK_HEADERS(netinet/in.h) - -dnl check for string.h header -AC_CHECK_HEADERS(string.h) - -dnl check for libintl.h header -AC_CHECK_HEADERS(libintl.h) - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST - -dnl check for vsnprintf() -dnl AC_FUNC_VPRINTF -AC_EGREP_HEADER(vsnprintf, stdio.h, AC_DEFINE(HAVE_VSNPRINTF)) - -dnl checks for builtin data type sizes -AC_CHECK_SIZEOF(unsigned short int, 2) -AC_CHECK_SIZEOF(unsigned long int, 4) -AC_CHECK_SIZEOF(unsigned int, 4) - -dnl Project-specific settings -GSM_VERSION="1:4:0" -AC_SUBST(GSM_VERSION) - -dnl national language support (NLS) -LINGUAS="de" -ALL_LINGUAS=$LINGUAS -AM_GNU_GETTEXT - -dnl set locale dir (FIXME there must be a better way) -_localedir=`eval "echo $datadir/locale"` -if test "$_localedir" = "NONE/share/locale"; then - AC_DEFINE_UNQUOTED(LOCALEDIR, "/usr/local/share/locale") -else - _localedir=`echo \"$_localedir\"` - AC_DEFINE_UNQUOTED(LOCALEDIR, $_localedir) -fi - -dnl whether to compile the intl directory -AM_CONDITIONAL(COMPILE_INTL, test x$USE_INCLUDED_LIBINTL = xyes) - -AC_OUTPUT(Makefile gsmlib/Makefile tests/Makefile apps/Makefile win32/Makefile - doc/Makefile scripts/Makefile intl/Makefile po/Makefile.in - ext/Makefile, - echo timestamp > stamp-h) - -dnl repair Makefile in po subdir -dnl sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.cron.d b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.cron.d deleted file mode 100644 index 7974513ccc..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.cron.d +++ /dev/null @@ -1,3 +0,0 @@ -# /etc/cron.d/gsm-utils: crontab fragment for gsm-utils - -*/5 * * * * root if [ -x /usr/bin/gsmsmsrequeue ]; then /usr/bin/gsmsmsrequeue; fi diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.default b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.default deleted file mode 100644 index 8ab73a9530..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.default +++ /dev/null @@ -1,13 +0,0 @@ -PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0 -BAUDRATE=9600 -PIN="" # or 1234 - -SPOOLDIR=/var/spool/sms -PRIORITIES=3 - -SMSADMIN=root -SUBJECT="SMS delivery report:" - -SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor - -do_accounting () { true; } # it's your turn diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.init b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.init deleted file mode 100644 index 7bb3ac0cd1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsm-utils.init +++ /dev/null @@ -1,81 +0,0 @@ -#! /bin/sh -### BEGIN INIT INFO -# Provides: gsm-utils -# Required-Start: $remote_fs $syslog -# Required-Stop: $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start daemon at boot time -# Description: Enable service provided by daemon. -### END INIT INFO -# -# /etc/init.d/gsm-utils: Controls the GSM SMS send daemon -# -# written by Matthias Goebl - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -DAEMON=/usr/bin/gsmsmsd -NAME=gsmsmsd -DESC="GSM SMS send daemon" - -test -x $DAEMON || exit 0 - -PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0 -BAUDRATE=9600 -PIN="" # or 1234 -SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor -SPOOLDIR=/var/spool/sms -PRIORITIES=3 -STARTOPTS="" -SMSUSER="gsmsms:gsmsms" -test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting some parameters - -OPTIONS="-d $PHONEDEV -b $BAUDRATE -L -P $PRIORITIES" -OPTIONS="$OPTIONS -s $SPOOLDIR/queue -S $SPOOLDIR/sent -F $SPOOLDIR/failed" -test -n "$SMSPROCESSOR" && OPTIONS="$OPTIONS -a $SMSPROCESSOR" -test -n "$SMSUSER" && STARTOPTS="$STARTOPTS --chuid $SMSUSER" -test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting OPTIONS - -case "$1" in - start) - echo -n "Starting $DESC: " - if [ -n "$PIN" ];then - echo -n "entering PIN.. " - ( - # This is ugly.. But if the PIN is already entered, the ME returns - # "ERROR" and makes gsmctl retrying.. - /usr/bin/gsmctl -d $PHONEDEV -b $BAUDRATE -I "+cpin=$PIN" & - PID=$! - sleep 3 - kill $PID 2>/dev/null - ) >/dev/null 2>&1 - fi - echo -n "$NAME" - start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS - echo "." - ;; - stop) - echo -n "Stopping $DESC: $NAME " - start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --exec $DAEMON - sleep 5 - echo "." - ;; - restart|force-reload) - echo -n "Restarting $DESC: $NAME" - start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS - sleep 5 - start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --make-pidfile --background --exec $DAEMON -- $OPTIONS - echo "." - ;; - *) - N=/etc/init.d/gsm-utils - echo "Usage: $N {start|stop|restart|force-reload}" >&2 - exit 1 - ;; -esac - -exit 0 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsrequeue b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsrequeue deleted file mode 100644 index 88b65c15bf..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsrequeue +++ /dev/null @@ -1,48 +0,0 @@ -#! /bin/bash -# -# /usr/bin/gsmsmsrequeue: Re-queues failed SMS -# -# written by Matthias Goebl - -SPOOLDIR=/var/spool/sms -PRIORITIES=3 -SMSADMIN=root -SUBJECT="SMS delivery report:" - -send_notify() -{ - tmpfile="$SPOOLDIR/tmp/"`basename "$1"` - status="$2" - if mv "$1" "$tmpfile" 2>/dev/null; then - # extract the first tab-separated field after the phone number as - # email-address to send the notification to - mailto=` cat "$tmpfile" | sed -ne '1s/^[^ ]* \([^ ]*\).*/\1/p' ` - test -z "$mailto" && mailto="$SMSADMIN" - cat "$tmpfile" | mail -s "$SUBJECT $status" "$mailto" - rm "$tmpfile" - fi -} -do_accounting() -{ - true; -} - -test -r /etc/default/gsm-utils && . /etc/default/gsm-utils - -for p in `seq 1 $PRIORITIES`; do - ls "$SPOOLDIR/failed$p" | while read file; do - if expr "$file" : ".*rrrrrrrrrrrr" >/dev/null; then - send_notify "$SPOOLDIR/failed$p/$file" "failed" - else - # re-queue SMS - mv "$SPOOLDIR/failed$p/$file" "$SPOOLDIR/queue$p/${file}r" 2>/dev/null - fi - done -done - -for p in `seq 1 $PRIORITIES`; do - ls "$SPOOLDIR/sent$p" | while read file; do - do_accounting "$SPOOLDIR/sent$p/$file" "sent" - send_notify "$SPOOLDIR/sent$p/$file" "sent" - done -done diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsspool b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsspool deleted file mode 100644 index 75bc1f9b79..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/contrib/gsmsmsspool +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/bash -# -# /usr/bin/gsmsmsspool: Queues SMS for sending -# -# written by Matthias Goebl - -SPOOLDIR=/var/spool/sms -PRIORITIES=3 -test -r /etc/default/gsm-utils && . /etc/default/gsm-utils - -if [ -z "$1" ]; then - echo "Usage: gsmsmsspool NUMBER [MESSAGE]" - exit 1 -fi - -priority=$PRIORITIES # default priority -test -n "$GSMSMS_PRIORITY" && priority="$GSMSMS_PRIORITY" -mailto=`id -un` -test -n "$GSMSMS_NOTIFY" && mailto="$GSMSMS_NOTIFY" - -tmpfile="$SPOOLDIR/tmp/`date +%s`.$$" -umask 022 -echo "$1 $mailto" > "$tmpfile" -if [ -n "$2" ]; then - echo "$2" | head -c 160 >> "$tmpfile" -else - head -c 160 >> "$tmpfile" -fi - -if [ "`id -un`" = "root" ]; then - chown gsmsms:gsmsms "$tmpfile" -fi - -mv "$tmpfile" "$SPOOLDIR/queue$priority/" diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/changelog b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/changelog deleted file mode 100644 index 86bca0b277..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/changelog +++ /dev/null @@ -1,284 +0,0 @@ -gsmlib (1.10-13) unstable; urgency=low - - * Ack NMU, Thanks Michael, Christoph & Petter - * debian/control add Homepage: - * Update debian/copyright; gsm-lib/COPYING actually specifies LGPL: - - fixes lintian:copyright-without-copyright-notice - * Update manpages fixes lintian:hyphen-used-as-minus-sign - * Update debian/gsm-utils.init - - fixes lintian:init.d-script-missing-lsb-short-description - * Bug fixes from ubuntu - - Don't install contrib/gsm-utils.init dh_installinit debian/gsm-utils.init - - Create /var/run/gsm-utils - * Add case 'L' to apps/gsmsmsd.cc - thks to Andrew Suffield - - syslog support does not work (Closes: #346240) - * gsm-utils.init really call restart with --stop first - - init script calls --start twice (Closes: #377448) - * Explictly set /bin/bash: gsmsmsspool & gsmsmsrequeue - - bashism in /bin/sh script (Closes: #464981) - - gsmsmsrequeue contains bashism or function error (Closes: #459396) - * Patch apps/gsmsmsstore.cc - thks Isaac Wilcox - - gsmsmsstore device existence check causes problems with RFCOMM - devices (Closes: #340179) - * Only start gsmsmsd if set in /etc/default/gsm-utils. crontab -> examples - - gsmsmsd should be optional / start only if told so in - /etc/default/gsm-utils (Closes: #474093) - * Apply patch from Stefan Katerkamp & Jacob Nevins - - Gsmsendsms fails with SonyEricsson W880 (fix included) (Closes: - #413341) - - -- Mark Purcell Mon, 06 Oct 2008 15:01:49 +1100 - -gsmlib (1.10-12.5) unstable; urgency=low - - * Non-maintainer upload. - * Yet another bashism that was later on reported on the old bug report, thus - again closes: #464981 - * Also found a shell related problem in debian/rules and fixed it. - * Bumped standard to 3.7.3. - - -- Michael Meskes Mon, 14 Apr 2008 10:48:19 +0200 - -gsmlib (1.10-12.4) unstable; urgency=low - - * Non-maintainer upload. - * Argh, somehow I mananged to upload without fixing the bug completely, - sorry. Added those missing braces, closes: #464981. - - -- Michael Meskes Wed, 09 Apr 2008 14:46:08 +0200 - -gsmlib (1.10-12.3) unstable; urgency=high - - * Non-maintainer upload. - * Removed bashism in contrib/gsmsmsrequeue (Closes: #464981). - - -- Michael Meskes Sun, 06 Apr 2008 15:37:35 +0200 - -gsmlib (1.10-12.2) unstable; urgency=low - - * Non-maintainer upload. - * Fix FTBFS with GCC 4.3: 'strerror' was not declared in this scope, thanks - to Cyril Brulebois for the patch (Closes: #455402). - - -- Christoph Berg Fri, 04 Apr 2008 18:01:05 +0200 - -gsmlib (1.10-12.1) unstable; urgency=low - - * Non-maintainer upload to solve release goal. - * Add LSB dependency header to init.d scripts (Closes: #464061). - - -- Petter Reinholdtsen Fri, 28 Mar 2008 11:39:20 +0100 - -gsmlib (1.10-12) unstable; urgency=low - - * addgroup --system gsmsms works better. Thanks Jon - * only delete gsmsms on purge - - gsm-utils: deletes and recreates the gsmsms user on each upgrade - (Closes: #346238) - - gsm-utils fails installation / addgroup: The user gsmsms; does - not exist (Closes: #445404) - * lintian cleanup: debian-rules-ignores-make-clean-error substvar- - source-version-is-deprecated - * Scripts are installed +x - - gsm-utils: uselessly installs non-executable scripts into /usr/bin - (Closes: #346230) - * Remove bogus symlink - - gsm-utils: wrong symlink for manpage gsmsiectl.1 (Closes: #322382) - - gsm-utils: gsmsiectl.1 dangling symlink (Closes: #399582) - * debian/gsm-utils.init reload/restart was not calling --stop. Thanks - Barry - - init script calls --start twice (Closes: #377448) - - -- Mark Purcell Mon, 08 Oct 2007 21:44:00 +0100 - -gsmlib (1.10-11) unstable; urgency=low - - * Create system group gsmsms - Thanks Emmanuel - - gsm-utils: creates group in non-system gid range (Closes: #353967) - - gsm-utils: postinst should create system grp gsmsms (Closes: - #390266) - * Upgrade to compat 4 - * Apply gcc-4.3 patch from Martin - - FTBFS with GCC 4.3: missing #includes (Closes: #417222) - - -- Mark Purcell Sat, 29 Sep 2007 18:22:56 +0100 - -gsmlib (1.10-10) unstable; urgency=low - - * FTBFS with G++ 4.1: extra qualifications (Closes: #356109) - - -- Mark Purcell Sat, 20 May 2006 21:54:42 +0100 - -gsmlib (1.10-9) unstable; urgency=low - - * library package needs to be renamed (libstdc++ allocator change) - (Closes: #339179) - - -- Mark Purcell Mon, 21 Nov 2005 21:19:51 +0000 - -gsmlib (1.10-8) unstable; urgency=low - - * removal of automake1.6 (Closes: #335123) - * fails with dash [bashisms in scripts] (Closes: #309834) - * Update libtool Fixes: gsmlib(GNU/k*BSD): FTBFS: out of date libtool scripts (Closes: - #319688) - * [INTL:de] German PO file corrections (Closes: #314060) - * Fix: old-fsf-address-in-copyright-file - - -- Mark Purcell Thu, 3 Nov 2005 22:40:19 +0000 - -gsmlib (1.10-7) unstable; urgency=low - - * C++ 4.0 transition - * Closes: #315864: Missing manpages - * gsm-utils: maintainer-script-needs-depends-on-adduser postinst - - -- Mark Purcell Sat, 23 Jul 2005 00:46:31 +1000 - -gsmlib (1.10-6) unstable; urgency=low - - * Rebuild for invalid dependancies - * Closes: #258056: libgsmme 99% cpu usage - - Patch from Emard - * Closes: #274382: FTBFS with gcc-3.4: template-id `operator< - <>' for `bool gsmlib::operator<(const - gsmlib::MapKey<gsmlib::SortedPhonebookBase>&, const - gsmlib::MapKey<gsmlib::SortedPhonebookBase>&)' does not - match any template declaration - - Patch from Andreas Jochens - * Closes: #294251: FTBFS (amd64/gcc-4.0): explicit qualification in - declaration of `bool gsmlib::operator<(const - gsmlib::MapKey<SortedStore>&, const - gsmlib::MapKey<SortedStore>&)' - - Patch from Andreas Jochens - * Closes: #200189: Patch and contribution - + Added multi-queue-priority-system and syslog patch (Matthias Goebl) - + Included init, spool and requeue scripts for gsmsmsd (Matthias Goebl) - + gsmsmsd runs with own user and group (gsmsms:gsmsms) (Matthias Goebl) - - -- Mark Purcell Tue, 17 May 2005 11:34:45 +0100 - -gsmlib (1.10-5) unstable; urgency=low - - * Change Section: libdevel - * gsm_unix_serial.cc patch from Daniel Schepler to fix g++-3.3 - compliation. Thanks. (Closes: Bug#195151) - - -- Mark Purcell Sat, 19 Jul 2003 15:57:28 +1000 - -gsmlib (1.10-4) unstable; urgency=low - - * Include file descriptor leak patch from Edd Dumbill (Closes: - Bug#168475) - * lintian cleanup: description-synopsis-might-not-be-phrased-properly - * lintian cleanup: configure-generated-file-in-source - - -- Mark Purcell Sun, 9 Feb 2003 14:04:54 +1100 - -gsmlib (1.10-3) unstable; urgency=low - - * New Maintainer (Closes: Bug#180061). Thanks Mikael for your work. - - -- Mark Purcell Sat, 8 Feb 2003 16:55:26 +1100 - -gsmlib (1.10-2) unstable; urgency=low - - * Rebuild to use the new c++ ABI (GCC 3.2) - - -- Mikael Hedin Thu, 23 Jan 2003 20:57:50 +0100 - -gsmlib (1.10-1) unstable; urgency=low - - * New upstrem release. - - -- Mikael Hedin Wed, 6 Nov 2002 17:44:17 +0100 - -gsmlib (1.9-2) unstable; urgency=low - - * Made new rules for the config.guess/sub update thing (closes: #146865, - #146867). - - -- Mikael Hedin Tue, 14 May 2002 09:28:03 +0200 - -gsmlib (1.9-1) unstable; urgency=low - - * New upstream version. - * Use chrpath to get rid of rpaths. - * Add mini-manpage for gsmsiexfer. - * Remove b-d on auto-stuff, we don't use them. - - -- Mikael Hedin Mon, 13 May 2002 22:10:28 +0200 - -gsmlib (1.8-2) unstable; urgency=low - - * Removed b-d on gcc 3.0, as they are no longer nessecary. - - -- Mikael Hedin Thu, 24 Jan 2002 12:59:07 +0100 - -gsmlib (1.8-1) unstable; urgency=low - - * New upstream version. - * Revert the arch hack, now it should compile with either g++. - * Include the new lib in libgsmme1. Run dh_makeshlibs -V because of this. - * Added info for gsmsiectl in gsmctl(1). - - -- Mikael Hedin Wed, 9 Jan 2002 22:38:45 +0100 - -gsmlib (1.7-2) unstable; urgency=low - - * gsm-utils: Added shlibs:Depends (closes: #126127). - * Spelling correction (closes: #124705, #124972) - * Rm libgsmme1.postins, and let dh_makeshlibs take care of ldconfig. - * Made explicit arch list without sparc and arm, they cannot use g++-3.0 - right now. - - -- Mikael Hedin Sat, 22 Dec 2001 20:27:54 +0100 - -gsmlib (1.7-1) unstable; urgency=low - - * New upstream - * Use gcc-3.0 and g++-3.0, 2.95 doesn't compile. - - -- Mikael Hedin Thu, 1 Nov 2001 10:24:33 +0100 - -gsmlib (1.6-5) unstable; urgency=low - - * Updated manpage (closes: #110973) - * Corrected problem with OP status (closes: #110970) - - -- Mikael Hedin Sat, 8 Sep 2001 18:12:17 +0200 - -gsmlib (1.6-4) unstable; urgency=low - - * Support DEB_BUILD_OPTIONS - * Changed libgsmme-dev to section devel. - * Reran libtoolize. - * Lots of small patches to compile with g++-3.0. (Closes: #104411) - * Removed dh_testversion. - - -- Mikael Hedin Thu, 12 Jul 2001 16:06:23 +0200 - -gsmlib (1.6-3) unstable; urgency=low - - * Various minor corrections. - - -- Mikael Hedin Thu, 8 Mar 2001 16:24:07 +0100 - -gsmlib (1.6-2) unstable; urgency=low - - * Dont install INSTALL. Correct indentation for libgsmme1 description. - - -- Mikael Hedin Tue, 6 Mar 2001 14:55:05 +0100 - -gsmlib (1.6-1) unstable; urgency=low - - * New upstream version. - - -- Mikael Hedin Mon, 29 Jan 2001 17:57:21 +0100 - -gsmlib (1.5-1) unstable; urgency=low - - * Initial Release. - - -- Mikael Hedin Thu, 14 Dec 2000 01:06:40 +0100 - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/compat b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/compat deleted file mode 100644 index b8626c4cff..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/compat +++ /dev/null @@ -1 +0,0 @@ -4 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/control b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/control deleted file mode 100644 index b230b8b838..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/control +++ /dev/null @@ -1,45 +0,0 @@ -Source: gsmlib -Section: comm -Priority: extra -Maintainer: Mark Purcell -Build-Depends: debhelper (>= 3.0.0), chrpath -Standards-Version: 3.7.3 -Homepage: http://www.pxh.de/fs/gsmlib/ - -Package: libgsmme-dev -Section: libdevel -Architecture: any -Depends: libgsmme1c2a (= ${binary:Version}), libc6-dev -Description: Header files and static libraries for gsmlib - Headers and static libraries for use when compiling programs with - gsmlib. - . - gsmlib is a library for access to a GSM mobile phone using the - standards ETSI GSM 07.07, ETSI GSM 07.05, and others. - -Package: libgsmme1c2a -Conflicts: libgsmme1, libgsmme1c102, libgsmme1c2 -Replaces: libgsmme1c102, libgsmme1c2 -Section: libs -Architecture: any -Depends: ${shlibs:Depends} -Description: GSM mobile phone access library - Library to access GSM mobile phones through GSM modems or IrDA devices. - Features include: - . - * modification of phone books stored in the mobile phone or on the - SIM card - * reading and writing of SMS messages stored in the mobile phone - * sending and reception of SMS messages - . - gsmlib uses standard ETSI GSM 07.07, ETSI GSM 07.05, and others. - -Package: gsm-utils -Section: comm -Architecture: any -Depends: ${shlibs:Depends}, adduser -Description: GSM mobile phone access applications - Some simple command line programs to access a GSM mobile phone via - GSM modem or IrDA. Functions include: modification of phone books and - reading, writing, sending and receiving SMS messages. Uses the GSM - standards ETSI GSM 07.07, ETSI GSM 07.05, and others. diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/copyright b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/copyright deleted file mode 100644 index dcb44c32cd..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/copyright +++ /dev/null @@ -1,34 +0,0 @@ -This package was debianized by Mikael Hedin on -Thu, 14 Dec 2000 01:06:40 +0100. - -It was downloaded from http://www.pxh.de/fs/gsmlib/index.html - -Upstream Author: Peter Hofmann - -ext/gsmsiexfer.cc:// * Author: Christian W. Zuckschwerdt - -Copyright: - - Copyright (C) 1999-2002 Peter Hofmann - -License: - - This package is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -On Debian systems, the complete text of the GNU Lesser General -Public License can be found in `/usr/share/common-licenses/LGPL'. - -The Debian packaging is (C) 2000, Mikael Hedin and -is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/dirs b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/dirs deleted file mode 100644 index a39a14c5cf..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/dirs +++ /dev/null @@ -1 +0,0 @@ -/var/run/gsm-utils diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.cron.d b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.cron.d deleted file mode 100644 index 7974513ccc..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.cron.d +++ /dev/null @@ -1,3 +0,0 @@ -# /etc/cron.d/gsm-utils: crontab fragment for gsm-utils - -*/5 * * * * root if [ -x /usr/bin/gsmsmsrequeue ]; then /usr/bin/gsmsmsrequeue; fi diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.default b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.default deleted file mode 100644 index 11901da54a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.default +++ /dev/null @@ -1,18 +0,0 @@ -PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0 -BAUDRATE=9600 -PIN="" # or 1234 - -# RUNGSMSMS: If set to anything other that 'yes', the asterisk init.d script -# will not run. The default is 'yes'. -# You should probaly also install the crontab from /usr/share/doc/gsm-utils/examples -RUNGSMSMS=no - -SPOOLDIR=/var/spool/sms -PRIORITIES=3 - -SMSADMIN=root -SUBJECT="SMS delivery report:" - -SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor - -do_accounting () { true; } # it's your turn diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.dirs b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.dirs deleted file mode 100644 index 7bc765edd6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.dirs +++ /dev/null @@ -1,11 +0,0 @@ -var/spool/sms/queue1 -var/spool/sms/queue2 -var/spool/sms/queue3 -var/spool/sms/sent1 -var/spool/sms/sent2 -var/spool/sms/sent3 -var/spool/sms/failed1 -var/spool/sms/failed2 -var/spool/sms/failed3 -var/spool/sms/tmp -var/run/gsm-utils diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.docs b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.docs deleted file mode 100644 index d4f3801ab1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.docs +++ /dev/null @@ -1,4 +0,0 @@ -NEWS -README -TODO -doc/FAQ diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.examples b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.examples deleted file mode 100644 index bd892f97be..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.examples +++ /dev/null @@ -1,2 +0,0 @@ -contrib/gsm-utils.cron.d -contrib/gsm-utils.init diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.init b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.init deleted file mode 100644 index bc51002f65..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.init +++ /dev/null @@ -1,87 +0,0 @@ -#! /bin/sh -### BEGIN INIT INFO -# Provides: gsm-utils -# Required-Start: $remote_fs $syslog -# Required-Stop: $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start daemon at boot time -# Description: Enable service provided by daemon. -### END INIT INFO -# -# /etc/init.d/gsm-utils: Controls the GSM SMS send daemon -# -# written by Matthias Goebl - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -DAEMON=/usr/bin/gsmsmsd -NAME=gsmsmsd -DESC="GSM SMS send daemon" - -test -x $DAEMON || exit 0 - -if [ "$RUNGSMSMS" != "yes" ];then - echo "GSM SMS deamon not yet configured. Edit /etc/default/gsm-utils first." - exit 0 -fi - - -PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0 -BAUDRATE=9600 -PIN="" # or 1234 -SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor -SPOOLDIR=/var/spool/sms -PRIORITIES=3 -STARTOPTS="" -SMSUSER="gsmsms:gsmsms" -test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting some parameters - -OPTIONS="-d $PHONEDEV -b $BAUDRATE -L -P $PRIORITIES" -OPTIONS="$OPTIONS -s $SPOOLDIR/queue -S $SPOOLDIR/sent -F $SPOOLDIR/failed" -test -n "$SMSPROCESSOR" && OPTIONS="$OPTIONS -a $SMSPROCESSOR" -test -n "$SMSUSER" && STARTOPTS="$STARTOPTS --chuid $SMSUSER" -test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting OPTIONS - -case "$1" in - start) - echo -n "Starting $DESC: " - if [ -n "$PIN" ];then - echo -n "entering PIN.. " - ( - # This is ugly.. But if the PIN is already entered, the ME returns - # "ERROR" and makes gsmctl retrying.. - /usr/bin/gsmctl -d $PHONEDEV -b $BAUDRATE -I "+cpin=$PIN" & - PID=$! - sleep 3 - kill $PID 2>/dev/null - ) >/dev/null 2>&1 - fi - echo -n "$NAME" - start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS - echo "." - ;; - stop) - echo -n "Stopping $DESC: $NAME " - start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --exec $DAEMON - sleep 5 - echo "." - ;; - restart|force-reload) - echo -n "Restarting $DESC: $NAME" - start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --make-pidfile --background --exec $DAEMON -- $OPTIONS - sleep 5 - start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \ - --make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS - echo "." - ;; - *) - N=/etc/init.d/gsm-utils - echo "Usage: $N {start|stop|restart|force-reload}" >&2 - exit 1 - ;; -esac - -exit 0 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postinst b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postinst deleted file mode 100644 index 2954c4a400..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postinst +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -e - -# create gsmsms group if necessary. -if ! grep -q ^gsmsms: /etc/group; then -# echo Adding system group: gsmsms. - addgroup --system gsmsms -fi - -# create gsmsms user if necessary. -if ! grep -q ^gsmsms: /etc/passwd; then -# echo Adding system user: gsmsms. - adduser --system --ingroup gsmsms \ - --no-create-home --home /var/spool/sms gsmsms -fi - -# allow gsmsms to use serial lines -if ! groups gsmsms | grep -q dialout ; then - adduser gsmsms dialout -fi - -# echo Updating spool directory structure: /var/spool/sms -chown -R gsmsms:gsmsms /var/spool/sms /var/run/gsm-utils -chmod 700 /var/spool/sms/* -chmod 750 /var/spool/sms -chmod 730 /var/spool/sms/queue* /var/spool/sms/tmp - -# Add the rest automatically.. -#DEBHELPER# diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postrm b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postrm deleted file mode 100644 index cba60a894c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsm-utils.postrm +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# postrm script for #PACKAGE# -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `purge' -# * `upgrade' -# * `failed-upgrade' -# * `abort-install' -# * `abort-install' -# * `abort-upgrade' -# * `disappear' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - - purge) - deluser gsmsms - ;; - - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsmsiexfer.1 b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsmsiexfer.1 deleted file mode 100644 index 4dc996578a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/gsmsiexfer.1 +++ /dev/null @@ -1,29 +0,0 @@ -.\" -*- eval: (nroff-mode) -*- -.de TQ -.br -.ns -.TP \\$1 -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.TH GSMSIEXFER 1 "" "gsmsiexfer" -.SH NAME -gsmsiexfer \- Siemens ME file transfer program for Siemens phones S25, S35, S45, ME45, SL45 -.SH SYNOPSIS -.B gsmsiexfer \-\-help -.PP -.SH DESCRIPTION -\fIgsmsiexer\fP comes with no man page. Try gsmsiexfer \-\-help, or -read the source. -.PP -.SH "SEE ALSO" -.BR gsminfo(7), -.BR gsmctl(1), -.BR gsmsendsms(1), -.BR gsmsmsd(8), -.BR gsmsmsstore(1). - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/libgsmme-dev.docs b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/libgsmme-dev.docs deleted file mode 100644 index 8c378905c5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/libgsmme-dev.docs +++ /dev/null @@ -1,2 +0,0 @@ -doc/README.developers -doc/README.NLS diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/rules b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/rules deleted file mode 100644 index a615ea02d4..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/rules +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/make -f - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -# shared library versions, option 1 -#version=2.0.5 -#major=2 -# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so -me_version=`ls gsmlib/.libs/libgsmme*.so.* | \ - awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'` -me_major=`ls gsmlib/.libs/libgsmme*.so.* | \ - awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'` -ex_version=`ls ext/.libs/libgsmext*.so.* | \ - awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'` -ex_major=`ls ext/.libs/libgsmext*.so.* | \ - awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'` - - -export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) -export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) - - -# FOR AUTOCONF 2.13 ONLY -ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) - confflags += $(DEB_HOST_GNU_TYPE) -else - confflags += --host $(DEB_BUILD_GNU_TYPE) --build $(DEB_HOST_GNU_TYPE) -endif - -ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) -CFLAGS += -g -CXXFLAGS += -g -endif - -configure: configure-stamp -configure-stamp: - dh_testdir - # Add here commands to configure the package. - CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" INSTALL_PROGRAM=$(INSTALL_PROGRAM) \ - ./configure $(confflags) --prefix=/usr --mandir=\$${prefix}/share/man \ - --infodir=\$${prefix}/share/info - - touch configure-stamp - -build: configure-stamp build-stamp -build-stamp: - dh_testdir - - # Add here commands to compile the package. - $(MAKE) - - touch build-stamp - -clean: - dh_testdir - dh_testroot - - # Add here commands to clean up after the build process. - [ ! -f Makefile ] || $(MAKE) distclean - rm -f build-stamp configure-stamp config.log config.status po/de.gmo - - -test -r /usr/share/misc/config.sub && \ - cp -f /usr/share/misc/config.sub scripts/config.sub - -test -r /usr/share/misc/config.guess && \ - cp -f /usr/share/misc/config.guess scripts/config.guess - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - dh_installdirs -pgsm-utils - - # Add here commands to install the package into debian/gsmlib. - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - chrpath -d debian/tmp/usr/bin/* - cp contrib/gsmsmsspool contrib/gsmsmsrequeue debian/tmp/usr/bin - - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - # - # build libgsmlib${major} package by moving files from gsmlib-dev - # - dh_movefiles -plibgsmme$(me_major)c2a \ - usr/lib/libgsmme.so.$(me_major) \ - usr/lib/libgsmme.so.$(me_version) \ - usr/lib/libgsmext.so.$(ex_major) \ - usr/lib/libgsmext.so.$(ex_version) \ - usr/share/locale - - dh_movefiles -plibgsmme-dev \ - usr/include \ - usr/lib - - dh_movefiles -pgsm-utils \ - usr/bin - - - dh_installdocs - dh_installexamples - dh_installmenu - dh_installinit - dh_installcron - dh_installman -pgsm-utils debian/*.1 debian/tmp/usr/share/man/man*/* - dh_installinfo - dh_installchangelogs ChangeLog - dh_link - dh_strip - dh_compress - dh_fixperms - dh_makeshlibs -V - dh_installdeb - dh_shlibdeps -ldebian/libgsmme1c2a/usr/lib - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/watch b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/watch deleted file mode 100644 index 530c7916ca..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/debian/watch +++ /dev/null @@ -1,2 +0,0 @@ -version=2 -http://www.pxh.de/fs/gsmlib/download/content.html gsmlib-(.*)\.tar\.gz diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/FAQ b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/FAQ deleted file mode 100644 index 303ab14555..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/FAQ +++ /dev/null @@ -1,101 +0,0 @@ -*** 1. I get the error - /usr/local/bin/gsmsmsd [ERROR]: cannot route status report message to TE - -Some phones/modems cannot route all kinds of SMS to the TE -(computer). Please try - - gsmsmsd no_stat - -This is documented in the gsmsmsd manual page. - - -*** 2. Siemens M20T expects an initial PIN. - -For the Siemens M20T an initial PIN must be send once (probably when -it is switched on or the computer is powered on). This PIN is used for -all subsequent invocations of gsmlib-based programs. The trick is to -issue the following program (eg. in the rc-scripts of the operating system): - - gsmctl -I "+cpin=" - - -*** 3. Sending SMS with or retrieving SMS from my Ericsson SH888 does -not work. - -Set the environment variable GSMLIB_SH888_FIX: - -export GSMLIB_SH888_FIX=1 (bash) -setenv GSMLIB_SH888_FIX 1 (tcsh) - -If it works now, I need your model number. You could just enter -"AT+CGMM" in a terminal program and send me the results. Alternatively -set the environment variable GSMLIB_DEBUG=2 and me the dump. - -*** 4. I get the error "ME/TA error 'Unidentified subscriber' (code -28)" when trying to send SMS using gsmsendsms or gsmsmsd. - -The SMS service centre address (SCA, the phone number of the centre that is -accepting SMS for delivery) is not set correctly in your phone. There -are three ways to correct this: - -1. set the default SCA (example is for Germany T-D1): - - gsmctl -o setsca "+491710760000" - -2. Use the menus of your phone to set the SMS SCA. - -3. Use the option "--sca 1234567" for the gsmsmsd, gsmsmsstore, and -gsmsendsms programs. This tries to set the SCA in the SMS itself (does -not change default SCA) and might not work with all phones. - -*** 5. gsmlib works unreliably with my phone. - -Try another baudrate, even higher baudrates sometimes work better then -lower ones. - -*** 6. On Win32 accessing the COM device fails. - -Use COMx: (x is the number of the COM device) instead of the UNIX -device name. If this doesn't work use "\\.\COMx:". - -*** 7. Windows 2000 Does Not Support Mapping Virtual COM Ports to - Infrared Ports. - -Windows 2000 users should follow the instructions in -support.microsoft.com article Q252795 in order to connect with their -mobile. - -*** 8. gcc-compiled shared C++ libraries do not work properly on some - commercial UNIX systems and with older version of gcc. - -The symptoms may be that the program dumps core on exceptions (AIX) or that -global constructors are not called (Solaris). - -Try to compile gsmlib with - - ./configure --disable-shared --enable-static - -if you encounter strange problems. - -*** 9. How to support unicode? - -You need 6 steps: - -1. set datacodingschema to DCS_SIXTEEN_BIT_ALPHABET - -2. set your locale correctly, for example, my locale, china. - setlocale(LC_ALL, "chs"); - -3. translate MBCS(multiple byte character set) string to unicode string. - wchar_t wstr[ 1000 ]; - memset(wstr, 0, 2000); - mbstowcs(wstr, data.c_str(), data.length()); - -4. get unicode string length. - int wcs_len = wcslen(wstr); - -5. change unicode string to net order. - for (int i = 0; i < wcs_len; i++) - wstr[ i ] = htons(wstr[ i ]); - -6. put unicode string into pdu. diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.am deleted file mode 100644 index f194f8d496..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: doc Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 11.6.1999 -# ************************************************************************* - -man_MANS = gsmsmsd.8 gsmctl.1 gsmpb.1 gsmsendsms.1 gsmsmsstore.1 gsminfo.7 - -EXTRA_DIST = gsmsmsd.man gsmctl.man gsmpb.man gsmsendsms.man \ - gsmsmsstore.man gsmlib.lsm gsminfo.man \ - README.NLS README.developers FAQ - -%.1: %.man - sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \ - $< > $@ - -%.7: %.man - sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \ - $< > $@ - -%.8: %.man - sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \ - $< > $@ - -clean-local: - rm -f *.1 *.7 *.8 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.in deleted file mode 100644 index f0f33528e3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/Makefile.in +++ /dev/null @@ -1,412 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: doc Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 11.6.1999 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -man_MANS = gsmsmsd.8 gsmctl.1 gsmpb.1 gsmsendsms.1 gsmsmsstore.1 gsminfo.7 - -EXTRA_DIST = gsmsmsd.man gsmctl.man gsmpb.man gsmsendsms.man \ - gsmsmsstore.man gsmlib.lsm gsminfo.man \ - README.NLS README.developers FAQ - -subdir = doc -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -DIST_SOURCES = - -NROFF = nroff -MANS = $(man_MANS) -DIST_COMMON = Makefile.am Makefile.in -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu doc/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -man1dir = $(mandir)/man1 -install-man1: $(man1_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man1dir) - @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.1*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 1*) ;; \ - *) ext='1' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ - done -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.1*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ - rm -f $(DESTDIR)$(man1dir)/$$inst; \ - done - -man7dir = $(mandir)/man7 -install-man7: $(man7_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man7dir) - @list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.7*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 7*) ;; \ - *) ext='7' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst; \ - done -uninstall-man7: - @$(NORMAL_UNINSTALL) - @list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.7*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man7dir)/$$inst"; \ - rm -f $(DESTDIR)$(man7dir)/$$inst; \ - done - -man8dir = $(mandir)/man8 -install-man8: $(man8_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man8dir) - @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 8*) ;; \ - *) ext='8' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ - done -uninstall-man8: - @$(NORMAL_UNINSTALL) - @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ - rm -f $(DESTDIR)$(man8dir)/$$inst; \ - done -tags: TAGS -TAGS: - -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(MANS) - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir) $(DESTDIR)$(man8dir) - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-local mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-generic distclean-libtool - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: install-man - -install-exec-am: - -install-info: install-info-am - -install-man: install-man1 install-man7 install-man8 - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -uninstall-am: uninstall-info-am uninstall-man - -uninstall-man: uninstall-man1 uninstall-man7 uninstall-man8 - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - clean-local distclean distclean-generic distclean-libtool \ - distdir dvi dvi-am info info-am install install-am install-data \ - install-data-am install-exec install-exec-am install-info \ - install-info-am install-man install-man1 install-man7 \ - install-man8 install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool uninstall \ - uninstall-am uninstall-info-am uninstall-man uninstall-man1 \ - uninstall-man7 uninstall-man8 - - -%.1: %.man - sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \ - $< > $@ - -%.7: %.man - sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \ - $< > $@ - -%.8: %.man - sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \ - $< > $@ - -clean-local: - rm -f *.1 *.7 *.8 -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.NLS b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.NLS deleted file mode 100644 index a5381f6104..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.NLS +++ /dev/null @@ -1,72 +0,0 @@ -0 Introduction --------------- - -This version of gsmlib contains national language support (NLS) using -the GNU (or OS-supplied) gettext library. gettext eases the handling -of translations of (usually english) output messages to other -languages by introducing the concept of message catalogs. - -Message catalogs can exist in various formats. The human-readable and --editable format is the PO file format. I have written a PO-file for -the german language (de.po). These human-readable files are then -translated to MO files which can be used by the gettext library. - -Please refer to the GNU gettext documentation (at the time of this -writing gettext-0.10) for further details. - - -1 Compiling gsmlib with localized messages ------------------------------------------- - -Gsmlib is compiled by default with NLS enabled. If you don't want -NLS invoke configure with the option - -./configure --disable-nls - - -2 Adding new message dialogs ----------------------------- - -1. Edit the ALL_LINGUAS line in "source/configure.in" and add your - language, eg. French: - - ALL_LINGUAS="de fr" - -2. Execute "autoconf" to create a new "configure" script (possible - problem: incompatible "autoconf") - -3. Now issue "./configure" in the "sources" directory. - -4. go to the "po" subdirectory - -5. do a "touch fr.po" to create an initially empty PO-file. - -6. do a "make update-po". This extracts all the strings from the files - listed in "POTFILES" and puts them with empty translations into "fr.po" - (it also updates existing po-Files such as "de.po"). - -7. Now use the editor of your choice to provide translations in - "fr.po". There is an emacs major mode (po-mode) that eases this - process. - -8. now issue "make". This causes an "fr.mo" to be created. - - -3 Adding new strings to gsmlib source code ------------------------------------------- - -1. If you add new strings to the gsmlib source code that need - translation enclose them with "_(" and ")" (see gettext documentation - for special cases). - -2. go to the "po" directory. - -3. do a "make update-po". This updates all existing PO-files (removing - obsolete translations, providing new, emptry entries). - -4. Provide translations for the new, empty entries (ideally using - emacs po-mode) - -5. now issue "make". This causes up-to-date MO-files to be created. - - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.developers b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.developers deleted file mode 100644 index 7fdcc11940..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/README.developers +++ /dev/null @@ -1,138 +0,0 @@ -OVERVIEW - - The GSM library is written in C++ and uses the latest C++ - features: namespaces, exceptions, the standard template library. - - The actual library source code is in the gsmlib subdirectory of - this distribution. The following modules are available: - - gsm_alloca.h OS-specific alloca defines - gsm_at.h Utility classes for AT command sequence handling - gsm_error.h Error codes and error handling functions - gsm_event.h Event handler interface - gsm_me_ta.h Mobile Equipment/Terminal Adapter and SMS functions - (ETSI GSM 07.07 and 07.05) - gsm_parser.h Parser to parse MA/TA result strings - gsm_phonebook.h Phonebook management functions - gsm_port.h Abstract port definition - gsm_sms.h SMS functions (ETSI GSM 07.05) - gsm_sms_codec.h Coder and Encoder for SMS TPDUs - gsm_sms_store.h SMS functions, SMS store (ETSI GSM 07.05) - gsm_sorted_phonebook.h Alphabetically sorted phonebook - (residing in files or in the ME) - gsm_sorted_sms_store.h Sorted SMS store - (sorted by address, time or type) - (residing in files or in the ME) - gsm_unix_serial.h UNIX serial port implementation - gsm_util.h Various utilities - - -REQUIREMENTS - - I have used egcs-1.1.2 and libstdc++.so.2.8.0 for compiling the - library and all programs. Older probably don't work because of - missing features. - - -AVAILABLE DOCUMENTATION - - If you want to do your own programming using the GSM library please - refer to the extensively documented header files or to the example - programs in the test or apps subdirectory. - - I have used the following documentation to develop this software: - - gts_gsm_02.30_v5.2.0.pdf - gts_gsm_03.40_v5.3.0.pdf - gts_gsm_04.11_v5.1.0.pdf - gts_gsm_02.82_v5.0.0.pdf - gts_gsm_03.41_v5.2.0.pdf - gts_gsm_07.05_v5.3.0.pdf - gts_gsm_03.38_v5.3.0.pdf - gts_gsm_04.08_v5.1.0.pdf - gts_gsm_07.07_v5.0.0.pdf - - Due to copyright reasons I cannot include this documentation in - this distribution. You can download it from the ETSI website - (www.etsi.org) for free, though. - - -COMPILATION - - The code is automatically compiled without debugging code enabled - (mostly assert()'s). - - If there are any problems you can generate a debug version - by issuing - - CXXFLAGS="-g" ./configure --disable-shared - - To switch on asserts and additional debugging output change the line - - CXXFLAGS="-DNEBUG $CXXFLAGS" - - in configure.in do - - dnl CXXFLAGS="-DNEBUG $CXXFLAGS" - - Then regenerate configure by executing autoconf. - - You must use at least gcc-2.95.2 to compile gsmlib successfully. - - -TESTS - - The tests directory contains a number of software tests. Two kinds - of test programs are provided: Those, that run without a mobile - phone and those that require a mobile phone to be connected to a - serial port. - - No access to mobile phone needed: - runparser.sh Test the parser for AT responses - runsms.sh Test SMS message encoding and decoding routines - runspb.sh Test sorted phonebook module - runssms.sh Test sorted SMS store module - - Give mobile phone device as argument: - testsms2 Manipulate SMS store in the mobile phone (read/write) - testgsmlib Test the gsm_me_ta module (readonly) - testpb Dump all phonebooks in the mobile phone to the stdout - (readonly) - testpb2 Manipulate phonebook in the mobile phone (read/write) - - The tests that do not require a mobile phone can be executed by - issuing "make check" in the tests subdirectory. The others must be - invoked manually. WARNING: These tests alter the contents of the - mobile phone's phonebook or SMS message memory!!! Make sure, that - you understand what the test does and be prepared for loss of data in - the mobile phone. - -HINTS - - - By default gsmlib is compiled with NDEBUG set. There are lots - of assert()s all over the library that may help to find problems - in programs that use the library. Disable NDEBUG to get best - debugging support. - -CUSTOM BACKENDS - - gsmlib now allows custom backends to be defined for sorted phonebooks - and sorted SMS stores. This can be used to store phonebook entries in - relational databases or LDAP servers. The interfaces are defined in - gsm_sorted_phonebook_base.h and gsm_sorted_sms_store_base.h, - respectively. - - To register a custom backend (eg. for sorted phonebooks) follow - these steps: - - 1. Define a subclass of CustomPhonebookFactory. - - 2. Define a static initializer class in your module that uses the - interface CustomPhonebookRegistry::registerCustomPhonebookFactory() - to make your custom backend available. - - 3. Link your module to any application that should use your custom - backend. The gsmpb and gsmsmsstore programs are prepared to use the - CustomPhonebookRegistry class to obtain your custom backend - objects. - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmctl.man b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmctl.man deleted file mode 100644 index fdd48d3377..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmctl.man +++ /dev/null @@ -1,683 +0,0 @@ -.TH GSMCTL 8 "##DATE##" "gsmctl v##VERSION##" -.SH NAME -gsmctl, gsmsiectl \- GSM mobile phone control program -.SH SYNOPSIS -.B gsmctl -.RB [\| \-b -.IR baudrate \|] -.RB [\| \-\-baudrate -.IR baudrate\| ] -.RB [ \|\-d -.IR device\| ] -.RB [ \|\-\-device -.IR device\fP ] -.RB [ \|\-h\| ] -.RB [ \|\-\-help\| ] -.RB [ \|\-I -.IR "init string" \|] -.RB [ \|\-\-init -.IR "init string" \|] -.RB [ \|\-v\| ] -.RB [ \|\-\-version\| ] -.RB [ \|\-X\| ] -.RB [ \|\-\-xonxoff\| ] -.BI \-o \ operation -.RB | \ \-\-operation -.IR operation \ | -.I parameters -.PP -.B gsmsiectl -.RB [\| \-b -.IR baudrate \|] -.RB [\| \-\-baudrate -.IR baudrate\| ] -.RB [ \|\-d -.IR device\| ] -.RB [ \|\-\-device -.IR device\fP ] -.RB [ \|\-h\| ] -.RB [ \|\-\-help\| ] -.RB [ \|\-I -.IR "init string" \|] -.RB [ \|\-\-init -.IR "init string" \|] -.RB [ \|\-v\| ] -.RB [ \|\-\-version\| ] -.RB [ \|\-X\| ] -.RB [ \|\-\-xonxoff\| ] -.BI \-o \ operation -.RB | \ \-\-operation -.IR operation \ | -.I parameters -.SH DESCRIPTION -.B gsmctl -can request information from or perform operations on an GSM mobile -phone. -.PP -.B gsmctl -attaches itself to the -.I device -given on the command line (usually an GSM modem) using the specified -.IR baudrate . -If no -.I device -is given, the device -.I /dev/mobilephone -is used. If no -.I baudrate -is given, a default baud rate of 38400 is used. -.PP -.B gsmctl -can be used in to modes: If no -.B \-\-operation -option is given the -.I parameters -specify the status information to be retrieved from -the mobile phone. See the section -.B STATUS INFORMATION -for more details. If an -.B \-\-operation -option is given the requested -.I operation -is performed on the mobile using the -.IR parameters . -See the section -.B OPERATIONS -for more details. -.PP -.B gsmsiectl -is the same program with some extension for Siemens mobile phones. -Some extra -.B OPERATIONS -are available in this case. -.PP -Error messages are printed to the standard error output. If the -program terminates on error the error code 1 is returned. -.SH OPTIONS -.TP -.BI \-b\ baudrate ,\ \-\-baudrate\ baudrate -The baud rate to use. Defaults to 38400. -.TP -.BI \-d\ device ,\ \-\-device\ device -The device to which the GSM modem is connected. The default is -.IR /dev/mobilephone . -.TP -.B \-h,\ \-\-help -Prints an option summary. -.TP -.BI \-I\ "init string" ,\ \-\-init\ "init string" -Initialization string to send to the TA (default: "E0"). Note that the -sequence "ATZ" is sent first. -.TP -.BI \-o\ operation ,\ \-\-operation\ operation -This option is used to perform an operation on the mobile phone. Refer -to the section -.B OPERATIONS -for more information on the available -operations and the -.I parameters -required for each operation. -.TP -.B \-v,\ \-\-version -Prints the program version. -.TP -.B \-X,\ \-\-xonxoff -Uses software handshaking (XON/XOFF) for accessing the device. -.SH STATUS INFORMATION -If called without the -.B \-\-operation -option -.B gsmctl -prints out default mobile phone status information as specified by the -.I parameters -described below: -.TP 7 -.B ALL -Prints all available information. -.TP 7 -.B BATT -Prints out information about the current battery status. Two lines of -the form " text" and " charge" are printed. Text may be -of "0 ME is powered by the battery", "1 ME has a battery connected, -but is not powered by it", "2 ME does not have a battery connected", -or "3 Recognized power fault, calls inhibited". Charge is a number in -the range 0..100 where 0 means that the battery is empty or not -connected and 100 means full charge. -.TP 7 -.B BITERR -Prints information about the current bit error rate. The output is of -form " value" where value can be of 0..7, 99 (99 means not -available or not detectable). -.TP 7 -.B CLIP -This option prints a line of the form " on" if caller line -identification is turned on in the network, " off" otherwise. -.TP 7 -.B CSET -Display info about charsets. The output is in the form " -available" and " current", which describes the charsets -available and which is current. -.TP 7 -.B CURROP -Prints information about the current operator. The output line has the -form " Long name: \'xxxx\' Short name: \'yyyy\' Numeric Name: zzzz". -.TP 7 -.B FLCAP -Prints out the two-letter names of available facility locks. The -meaning of standardized facility lock names is as follows: -.RS -.TP 3 -.I CS -Lock control surface (eg. phone keyboard) -.TP 3 -.I PS -Lock phone to SIM card (mobile phone asks password when other than -current SIM card inserted) -.TP 3 -.I SC -Lock SIM card (SIM asks password in mobile phone power-up and when -this lock command issued) -.TP 3 -.I AO -Barr all outgoing calls -.TP 3 -.I OI -Barr outgoing international calls -.TP 3 -.I OX -Barr outgoing international calls except to home country -.TP 3 -.I AI -Barr all incoming calls -.TP 3 -.I IR -Barr incoming calls when roaming outside the home country -.TP 3 -.I NT -Barr incoming calls from numbers not stored to TA memory -.TP 3 -.I NM -Barr incoming calls from numbers not stored to mobile phone memory -.TP 3 -.I NS -Barr incoming calls from numbers not stored to SIM memory -.TP 3 -.I NA -Barr incoming calls from numbers not stored in Any memory -.TP 3 -.I AB -All Barring services (FIXME) -.TP 3 -.I AG -All outGoing barring services (FIXME) -.TP 3 -.I AC -All inComing barring services (FIXME) -.TP 3 -.I FD -SIM fixed dialling memory feature (if PIN2 authentication has not been -done during the current session, PIN2 is required as ) -.PP -Note that mobile phones may implement facility locks not documented -here. -.RE -.TP 7 -.B FLSTAT -Prints information about the status of facility locking in the mobile -phone. For each facility a line of the form " \'facilityname\' -classes" is printed. The classes may be "Voice", "Data", and/or "Fax" -depending on the class for which the facility is enabled. If "unknown" -is printed out this means that the TA is not able to report the -status. If the facility is not enabled for any class, no class -identifier is printed. See -.B FLCAP -for information about the available two-letter names of facility -locks. -.TP 7 -.B FORW -Prints information about call forwarding enabled in the mobile -phone. For each combination of reason (UnconditionalReason, -MobileBusyReason, NoReplyReason, and NotReachableReason) and class -(Voice, Data, and Fax) a line of the form " reason class -number: xxx subaddr: yyy time: zzz" is printed. The time is the number -of seconds to wait before forwarding in case of NoReplyReason. -.TP 7 -.B ME -Prints manufacturer, model, revision, and serial number of -the mobile phone (ME = mobile equipment). Output lines are numbered from -"" to "". -.TP 7 -.B OP -Prints information about the currently available mobile network -operators. For each operator an output line of the form " status -Long name: \'xxxx\' Short name: \'yyyy\' Numeric name: zzz" is returned -where status may be of: -.RS -.TP 10 -.I unknown -The status of the operator is unknown. -.TP -.I current -This is the currently selected operator. -.TP -.I available -This operator is available for selection. -.TP -.I forbidden -This operator is not available for selection, ie. not -accessible with this SIM card. -.RE -.TP 7 -.B PIN -Prints information about the current PIN status. The output is of -form " status". Where status can be one of the following lines: -.RS -.TP 10 -.I READY -ME is not pending for any password. -.TP -.I SIM PIN -ME is waiting SIM PIN to be given. -.TP -.I SIM PUK -ME is waiting SIM PUK to be given. -.TP -.I PH\-SIM PIN -ME is waiting phone/-to/-SIM card password to be given. -.TP -.I PH/-FSIM PIN -ME is waiting phone/-to/-very first SIM card password to be given. -.TP -.I PH/-FSIM PUK -ME is waiting phone/-to/-very first SIM card unblocking password to be -given. -.TP -.I SIM PIN2 -ME is waiting SIM PIN2 to be given. -.TP -.I SIM PUK2 -ME is waiting SIM PUK2 to be given. -.TP -.I PH/-NET PIN -ME is waiting network personalisation password to be given. -.TP -.I PH/-NET PUK -ME is waiting network personalisation unblocking password to be given. -.TP -.I PH/-NETSUB PIN -ME is waiting network subset personalisation password to be given. -.RE -.TP 7 -.B PW -Facilities in the mobile phone may be protected by passwords (ie. PINs -or PUKs). This option prints out lines of the form " -\'facilityname\' len" for each facility for which a facility lock -password exists. See -.B FLCAP -for information about the available two-letter names of facility -locks. -.TP 7 -.B SCA -Reports the default SMS service centre address currently set in the -mobile phone. -.TP 7 -.B SIG -Prints information about the current network signal -strength. The output is of the form " value". Following values -are possible: -.TP -.po +7 -.I 0 --113 dBm or less -.TP -.I 1 --111 dBm -.TP -.I 2...30 --109... -53 dBm (in steps of 2 dBm) -.TP -.I 31 --51 dBm or greater -.TP -.I 99 -not known or not detectable -.PP -.po -.SH OPERATIONS -.TP -.BI dial\ number -Dials -.IR number . -After dialling -.B gsmctl -waits for a keypress to terminate. -.PP -.B forw -.IR mode\ reason\ number\ [\| facilityclass\| ]\ [ forwardtime ] -.RS -Changes the call forwarding behaviour in the network. -.I mode -can be any of: -.RS 3 -.I disable -Call forwarding is disabled. -.PP -.I enable -Call forwarding is enabled. The call forwarding reason, number, and -(optionally) forwardtime must be registered beforehand. -.PP -.I register -This registers the call forwarding reason, number, and forwardtime in -the network. -.PP -.I erase -This is the counterpart to register. It erase the call forwarding info -in the network. -.RE -.PP -.I reason -can be any of: -.RS 3 -.I unconditional -This applies to every call. -.PP -.I mobilebusy -The mobile phone is busy. -.PP -.I noreply -The call is not answered in \fIforwardtime\fP seconds. -.PP -.I notreachable -Mobile phone cannot be reached (ie. switched off). -.PP -.I all -This refers to all forwarding reasons. -.PP -.I allconditional -This refers to all conditional forward reasons -.RI ( mobilebusy ,\ noreply ,\ notreachable ). -.RE -.PP -.I number -is the number the incoming call is forwarded to. See the explanation -for -.I lock -operation for the meaning of -.IR facilityclass . -The default for -.I forwardtime -is 20 seconds if omitted. -.I forwardtime -can be in the range 1..30. -.RE -.PP -.TP -.BI off -Sets functionality level of the phone to 0 (low functionality). The -effects of this command depend on the phone (eg. sets low power -consumption). -.PP -.TP -.BI on -Sets functionality level of the phone to 1 (high functionality). The -effects of this command depend on the phone. -.PP -.TP -.BI pin\ pin -Sets PIN code. Use -.BI gsmctl\ pin -to get the current pin status. -.PP -.B lock -.IR facility\ [\| facilityclass \|]\ [\| passwd \|] -.RS -Locks the named facility. Use -.BI gsmctl\ flcap -to get a list of supported facilities. The -.I facilityclass -can be any of: -.RS 3 -.I all -Voice, data, and fax. -.PP -.I v\ vf\ vd\ f\ fd\ d -Any combination of voice, data and fax. -.RE -.PP -The default is \fIall\fP if \fIfacilityclass\fP is omitted. The -\fIpasswd\fP is password for the facility. If no password is given -this parameter can be omitted. -.RE -.PP -.BI setop\ opmode\ numericname -.RS -Sets the current operator to -.IR numericname . -Use -.BI gsmctl\ op -to get a list of operators with their numeric codes. -.I opmode -can be any of: -.RS 3 -.I automatic -.PP -.I manual -.PP -.I deregister -Deregister from network. -.PP -.I manualautomatic -If manual selection fails, automatic mode is entered. -.RE -.RE -.PP -.B setpw -.IR facility\ [\| oldpasswd\| ]\ [\| newpasswd\| ] -.RS -Sets the password for the facility. If one of the passwords is omitted -this means that the facility has no password protection. Passwords are -PIN1, PIN2, PUK etc. -.RE -.TP -.BI setsca\ service\ centre\ address -Sets the default SMS service centre address. -.PP -.B unlock -.IR facility\ [\| facilityclass\| ]\ [ \|passwd\| ] -.RS -This is the reverse operation to \fBlock\fP. See above for a -description of the parameters. -.RE -.PP -.B Extra operators for gsmsiectl: -.PP -.B cset -.RS -Charset info. -.RE -.PP -.B pbook -.RS -Phone book info. -.RE -.PP -.B signal -.RS -Signal tone info. -.RE -.PP -.B ring -.RS -Ringing tone info. -.RE -.PP -.B binary -.RS -Binary info. -.RE -.SH EXAMPLES -The following invocation of -.I gsmctl -prints out all available status information for the mobile phone -connected to -.B /dev/mobilephone -.PP -.nf -.IP "" 3 -gsmctl all -.fi -.PP -The output could look like (lines edited to fit): -.RS 3 -.PP -.PD 0 - Manufacturer: SIEMENS -.HP - Model: S10 -.HP - Revision: 06 -.HP - Serial Number: 448058511817585 -.HP - Status: available Long name: 'D1/-TELEKOM' Short name: '' Numeric name: 26201 -.HP - Status: forbidden Long name: 'D2 PRIVAT' Short name: '' Numeric name: 26202 -.HP - Long name: 'D1/-TELEKOM' Short name: '' Numeric name: 26201 Mode: automatic -.HP - 'CS' -.HP - 'PS' -.HP - 'SC' Voice Data Fax -.HP - 'AO' -.HP - 'OI' -.HP - 'OX' -.HP - 'AI' -.HP - 'IR' -.HP - 'CS' 'PS' 'SC' 'AO' 'OI' 'OX' 'AI' 'IR' 'AB' 'AG' 'AC' -.HP - 'PS' 8 -.HP - 'SC' 8 -.HP - 'AO' 4 -.HP - 'OI' 4 -.HP - 'OX' 4 -.HP - 'AI' 4 -.HP - 'IR' 4 -.HP - 'AB' 4 -.HP - 'AG' 4 -.HP - 'AC' 4 -.HP - on -.HP - UnconditionalReason Voice inactive number: subaddr: time: -1 -.HP - UnconditionalReason Data inactive number: subaddr: time: -1 -.HP - UnconditionalReason Fax inactive number: subaddr: time: -1 -.HP - MobileBusyReason Voice active number: +494012345678 subaddr: time: -1 -.HP - MobileBusyReason Data inactive number: subaddr: time: -1 -.HP - MobileBusyReason Fax inactive number: subaddr: time: -1 -.HP - NoReplyReason Voice active number: +494012345678 subaddr: time: 20 -.HP - NoReplyReason Data inactive number: subaddr: time: -1 -.HP - NoReplyReason Fax inactive number: subaddr: time: -1 -.HP - NotReachableReason Voice active number: +494012345678 subaddr: time: -1 -.HP - NotReachableReason Data inactive number: subaddr: time: -1 -.HP - NotReachableReason Fax inactive number: subaddr: time: -1 -.HP - 0 ME is powered by the battery -.HP - 100 -.HP - 0 -.HP - 19 -.RE -.PD -.PP -The following locks the keys on the mobile phone: -.nf -.IP "" 3 -gsmctl -o lock cs -.fi -.PP -This changes the SIM card PIN from 1234 to 2345: -.nf -.IP "" 3 -gsmctl -o setpw sc 1234 2345 -.fi -.PP -Switch off all call forwarding (actually erase the numbers): -.nf -.IP "" 3 -gsmctl -o forw erase all -.fi -.PP -Switch on call forwarding to German D1 voice box: -.nf -.IP "" 3 -gsmctl -o forw register notreachable 3313 -gsmctl -o forw enable notreachable -.fi -.PP -.SH FILES -.TP -.B /dev/mobilephone -Default mobile phone device. -.SH AUTHOR -Peter Hofmann -.SH BUGS -Report bugs to software@pxh.de. Include a complete, self-ncontained -example that will allow the bug to be reproduced, and say which -version of \fIgsmctl\fP you are using. -.SH COPYRIGHT -Copyright \(co 1999 Peter Hofmann -.PP -.B gsmctl -is free software; you can redistribute it and/or modify it under the -terms of the GNU Library General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. -.PP -.B gsmctl -is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -License for more details. -.PP -You should have received a copy of the GNU Library General Public -License along with -.BR gsmctl ; -see the file COPYING. If not, write to the Free Software Foundation, -675 Mass Ave, Cambridge, MA 02139, USA. -.SH "SEE ALSO" -.BR gsminfo (7), -.BR gsmpb (1), -.BR gsmsendsms (1), -.BR gsmsmsd (8), -.BR gsmsmsstore (1). - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsminfo.man b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsminfo.man deleted file mode 100644 index 7939502779..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsminfo.man +++ /dev/null @@ -1,56 +0,0 @@ -.\" -*- eval: (nroff-mode) -*- -.de TQ -.br -.ns -.TP \\$1 -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.TH GSMINFO 7 "##DATE##" "gsmctl v##VERSION##" -.PP -.SH NAME -gsminfo \- GSM general information -.PP -.SH DESCRIPTION -\fIgsmlib\fP is a library to access GSM mobile phones through GSM -modems or via IrDA devices. In the \fIgsmlib\fP documentation and error -messages the following abbreviations are used: -.TP .7i -\fBME\fP -Mobile Equipment. The mobile phone, usually. -.TP .7i -\fBSC\fP -Service Centre. In the context of this documentation, the center -responsible for sending and relaying SMs. -.TP .7i -\fBSM\fP -Short Message. -.TP .7i -\fBSME\fP -Short Message Equipment. Usually the mobile phone. -.TP .7i -\fBTA\fP -Terminal Adapter. This can be a GSM modem PC card or it can be -integrated into the ME. -.TP .7i -\fBTE\fP -Terminal Equipment. This is the device to which the TA is connected, -usually the computer. -.PP -.SH AUTHOR -Peter Hofmann -.PP -.SH COPYRIGHT -Copyright \(co 1999 Peter Hofmann -.PP -.SH "SEE ALSO" -.BR gsmctl(1), -.BR gsmpb(1), -.BR gsmsendsms(1), -.BR gsmsmsd(8), -.BR gsmsmsstore(1). - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmlib.lsm b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmlib.lsm deleted file mode 100644 index 6056b88eed..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmlib.lsm +++ /dev/null @@ -1,20 +0,0 @@ -Begin3 -Title: gsmlib -Version: 1.0 -Entered-date: 29JUL99 -Description: This distribution contains a library to access - GSM mobile phones through GSM modems. Features include: - * modification of phonebooks stored in the - mobile phone or on the SIM card - * reading and writing of SMS messages stored in - the mobile phone - * sending and reception of SMS messages - Additionally, some simple command line programs are - provided to use these functionalities. -Keywords: gsm mobile phone modem sms -Author: Peter Hofmann -Maintained-by: Peter Hofmann -Primary-site: http://www.pxh.de/fs/gsmlib/ -Platforms: Linux -Copying-policy: LGPL -End diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmpb.man b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmpb.man deleted file mode 100644 index fef171e0aa..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmpb.man +++ /dev/null @@ -1,245 +0,0 @@ -.\" -*- eval: (nroff-mode) -*- -.de TQ -.br -.ns -.TP \\$1 -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.TH GSMPB 8 "##DATE##" "gsmpb v##VERSION##" -.SH NAME -gsmpb \- GSM mobile phone phonebook manipulation program -.SH SYNOPSIS -.B gsmpb -[ \fB\-b\fP \fIbaudrate\fP ] -[ \fB\-\-baudrate\fP \fIbaudrate\fP ] -[ \fB\-c\fP ] -[ \fB\-\-copy\fP ] -[ \fB\-d\fP \fIdestination device or file\fP ] -[ \fB\-\-destination\fP \fIdestination device or file\fP ] -[ \fB\-h\fP ] -[ \fB\-\-help\fP ] -[ \fB\-i\fP ] -[ \fB\-\-index\fP ] -[ \fB\-I\fP \fIinit string\fP ] -[ \fB\-\-init\fP \fIinit string\fP ] -[ \fB\-p\fP \fIphonebook name\fP ] -[ \fB\-\-phonebook\fP \fIphonebook name\fP ] -[ \fB\-s\fP \fIsource device or file\fP ] -[ \fB\-\-source\fP \fIsource device or file\fP ] -[ \fB\-t\fP \fIcharacter set\fP ] -[ \fB\-\-charset\fP \fIcharacter set\fP ] -[ \fB\-v\fP ] -[ \fB\-\-version\fP ] -[ \fB\-V\fP ] -[ \fB\-\-verbose\fP ] -[ \fB\-X\fP ] -[ \fB\-\-xonxoff\fP ] -[ \fB\-y\fP ] -[ \fB\-\-synchronize\fP ] -.PP -.SH DESCRIPTION -\fIgsmpb\fP can store or retrieve phonebook entries residing in a GSM -mobile phone's phonebook to or from a file. A synchronization mode is -also available. -.PP -\fIgsmpb\fP reads entries from the source which can be a mobile phone -(if a serial device file is given) or a file (if a file name is -given). The source is never modified. \fIgsmpb\fP writes phonebook -entries to a destination file or device. Depending on the mode the -source is copied to the destination file, thus overwriting the -destination, or the destination is synchronized with regard to the -source which is the default (details see below). -.PP -If "\-" is given as the parameter for the \fB\-\-source\fP or -\fB\-\-destination\fP options, the phonebook is read from standard input -and/or written to standard output, respectively. -.PP -Phonebook entries names are encoded using the GSM default alphabet in -the mobile phone, whereas they are stored using the Latin\-1 encoding -in phonebook files. When reading phonebook entries from a mobile phone -entry names are converted from the GSM default to Latin\-1. Characters -that can not be converted to Latin\-1 are encoded as character code -172 (Latin\-1 boolean "not"). When writing file-based phonebook entries -to a mobile phone a conversion to the GSM default alphabet takes -place. Characters that can not be converted are encoded as GSM delta -(code 16). If the default character set has been changed using the -\fB\-\-charset\fP option no conversion takes place. -.PP -Error messages are printed to the standard error output. If the program -terminates on error the error code 1 is returned. -.PP -.SH OPTIONS -.TP .7i -\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP -The baud rate to use. The default baudrate is 38400. -.TP .7i -\fB\-c\fP, \fB\-\-copy\fP -This causes the contents of the source to be copied to the -destination. After this operation the destination has exactly the same -contents as the source. -.TP .7i -\fB\-d\fP \fIdestination\fP, \fB\-\-destination\fP \fIdestination\fP -The destination device or file. -.TP .7i -\fB\-h\fP, \fB\-\-help\fP -Prints an option summary. -.TP .7i -\fB\-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP -Initialization string to send to the TA (default: "E0"). Note that the -sequence "ATZ" is sent first. -.TP .7i -\fB\-i\fP, \fB\-\-index\fP -If the index position is given, \fIgsmpb\fP preserves the assignment -of entries to memory slots in the mobile phone's phonebook. This can -be used to backup phonebook entries with their position into a -phonebook file or to change the position of entries by editing a -phonebook file and writing them back to the mobile phone. -If this option is given the phonebook file used as the source -must contain indices for every entry. Additionally, these indices must -be unique, ie. it is not allowed to assign one entry twice to a -specific position in the mobile phone's phonebook. -.TP .7i -\fB\-p\fP \fIphonebook\fP, \fB\-\-phonebook\fP \fIphonebook\fP -The name of the phonebook to read from or write to. This is only used -for device sources and destinations. Commonly available phonebooks -are: -.TP .3i -.po +0.7i -.ll 5.8i -\fIFD\fP -SIM fixdialling\-phonebook -.TP .3i -\fILD\fP -SIM last\-dialling\-phonebook -.TP .3i -\fIME\fP -ME phonebook -.TP .3i -\fIMT\fP -combined ME and SIM phonebook -.TP .3i -\fISM\fP -SIM phonebook -.TP .3i -\fITA\fP -TA phonebook -.TP .7i -.po -0.7i -.ll 6.5i -\fB\-s\fP \fIsource\fP, \fB\-\-source\fP \fIsource\fP -The source device or file. -.TP -\fB\-t\fP \fIcharacter set\fP, \fB\-\-charset\fP \fIcharacter set\fP -Set the character set to use for phonebook operations (default is the -GSM default alphabet). -.TP -\fB\-v\fP, \fB\-\-version\fP -Prints the program version. -.TP .7i -\fB\-V\fP, \fB\-\-verbose\fP -Prints out a detailed progress report. -.TP .7i -\fB\-X\fP, \fB\-\-xonxoff\fP -Uses software handshaking (XON/XOFF) for accessing the device. -.TP .7i -\fB\-y\fP, \fB\-\-synchronize\fP -This causes the contents of the source to be synchronized with the -destination (default). Synchronization in this context means: -.TP .2i -.po +0.7i -.ll 5.8i -\- -If the source contains an entry with a name that does not exist in the -destination this entry is added to the destination. -.TP .2i -\- -If the source contains an entry with a name that can also be found in -the destination, the entry in the destination is overwritten (ie. the -telephone number is updated). Exception: More then one entry with the -name exists in the destination. In this case the new entry ist just added. -.TP .2i -\- -Entries in the destination that do not exist in the source are -deleted. -.PP -Note that synchronization has the following properties that differ -from copying: This algorithm does not change the location of unchanged -entries in the destination phonebook. The synchronization function -is not case-sensitive when comparing names. -.PP -.po -0.7i -.ll 6.5i -.SH PHONEBOOK FILE FORMAT -Phonebook entries are stored in phonebook files that are meant to be -human-readable and -editable. There is one phonebook entry per line, -and each line has the format: -.PP -.nf -index|text|phone number -.fi -.PP -The fields have the following meanings: -.TP .7i -\fIindex\fP -The index of the entry which must be a positive number. The index may -also be empty. Indices can be used in conjunction with the -\fB\-\-index\fP option to store the entry into a specific position in -the mobile phone. -.TP .7i -\fItext\fP -Descriptive text for the entry. The text may contain the special -characters '\\', '|', carriage return (ASCII code 13), or line feed -(ASCII code 10). These must be written "\\\\", "\\|", "\\r", "\\n", -respectively. The text should only contain characters that can be -encoded using the GSM default alphabet (see comments above). -.TP .7i -\fIphone number\fP -Phone numbers can only contains the digits 0\-9 and the '+' sign. A '+' -sign denotes an international number. -.PP -.SH EXAMPLES -The following invocation of \fIgsmpb\fP synchronizes the mobile phone's -SIM phonebook with the file $HOME/.phonebook: -.PP -.nf -gsmpb \-\-synchronize \-b 19200 \-d /dev/mobilephone \\ - \-s $HOME/.phonebook \-p "SM" -.fi -.PP -.SH AUTHOR -Peter Hofmann -.PP -.SH BUGS -Report bugs to software@pxh.de. Include a complete, self-contained -example that will allow the bug to be reproduced, and say which -version of \fIgsmpb\fP you are using. -.PP -.SH COPYRIGHT -Copyright \(co 1999 Peter Hofmann -.LP -\fIgsmpb\fP is free software; you can redistribute it and/or modify it under -the terms of the GNU Library General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. -.LP -\fIgsmpb\fP is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License -for more details. -.LP -You should have received a copy of the GNU Library General Public License along -with \fIgsmpb\fP; see the file COPYING. If not, write to the Free Software -Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -.PP -.SH "SEE ALSO" -.BR gsminfo(7), -.BR gsmctl(1), -.BR gsmsendsms(1), -.BR gsmsmsd(8), -.BR gsmsmsstore(1). - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsendsms.man b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsendsms.man deleted file mode 100644 index d3c8a9c395..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsendsms.man +++ /dev/null @@ -1,154 +0,0 @@ -.\" -*- eval: (nroff-mode) -*- -.de TQ -.br -.ns -.TP \\$1 -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.TH GSMSENDSMS 8 "##DATE##" "gsmsendsms v##VERSION##" -.PP -.SH NAME -gsmsendsms \- SMS message sender utility -.PP -.SH SYNOPSIS -.B gsmsendsms -[ \fB\-b\fP \fIbaudrate\fP ] -[ \fB\-\-baudrate\fP \fIbaudrate\fP ] -[ \fB\-c\fP \fIconcatenatedID\fP ] -[ \fB\-\-concatenate\fP \fIconcatenatedID\fP ] -[ \fB\-C\fP \fIservice centre address\fP ] -[ \fB\-\-sca\fP \fIservice centre address\fP ] -[ \fB\-d\fP \fIdevice\fP ] -[ \fB\-\-device\fP \fIdevice\fP ] -[ \fB\-h\fP ] -[ \fB\-\-help\fP ] -[ \fB\-I\fP \fIinit string\fP ] -[ \fB\-\-init\fP \fIinit string\fP ] -[ \fB\-r\fP ] -[ \fB\-\-requeststat\fP ] -[ \fB\-t\fP ] -[ \fB\-\-test\fP ] -[ \fB\-v\fP ] -[ \fB\-\-version\fP ] -[ \fB\-X\fP ] -[ \fB\-\-xonxoff\fP ] -\fIphonenumber\fP -[ \fItext\fP ] -.PP -.SH DESCRIPTION -\fIgsmsendsms\fP sends SMS short messages using an GSM mobile phone. -.PP -\fIgsmsendsms\fP attaches itself to the \fIdevice\fP given on the command -line (usually an GSM modem) using the specified \fIbaudrate\fP. If no -\fIdevice\fP is given, the device \fI/dev/mobilephone\fP is used. If -no \fIbaudrate\fP is given, a default baud rate of 38400 is used. -.PP -\fIgsmsendsms\fP accepts a phone number (recipient address) and the -short message text as parameters. The text may have a maximum length -of 160 characters which is the maximum SMS message length. The GSM -default alphabet is used for encoding. ASCII and Latin\-1 characters -that can not be encoded using the GSM default alphabet are converted -to the GSM delta character (GSM code 16). -.PP -Error messages are printed to the standard error output. If the program -terminates on error the error code 1 is returned. -.PP -.SH OPTIONS -.TP -\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP -The baud rate to use. -.TP -\fB\-c\fP \fIconcatenatedID\fP, \fB\-\-concatenate\fP \fIconcatenatedID\fP -If an ID is given, large SMSs are split into several, concatenated -SMSs. All SMSs have the same ID and are numbered consecutively so that -the receiving phone can assemble them in the correct order. IDs must -be in the range 0..255. Not all receiving phones will support -concatenated SMSs (and display them as separate SMSs), -since all the numbering and ID information is -carried in the user data header element at the beginning of the SMS -user data. This information may show up as garbage in such phones. -.TP -\fB\-C\fP \fIservice centre address\fP, \fB\-\-sca\fP \fIservice centre address\fP -Sets the service centre address to use for all SUBMIT SMSs (may not -work with some phones). -.TP -\fB\-d\fP \fIdevice\fP, \fB\-\-device\fP \fIdevice\fP -The device to which the GSM modem is connected. The default is -\fI/dev/mobilephone\fP. -.TP -\fB\-h\fP, \fB\-\-help\fP -Prints an option summary. -.TP -\fB-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP -Initialization string to send to the TA (default: "E0"). Note that the -sequence "ATZ" is sent first. -.TP -\fB\-r\fP, \fB\-\-requeststat\fP -Request status reports for sent SMS. -.TP -\fB\-t\fP, \fB\-\-test\fP -If this option is given the text is converted -to the GSM default alphabet and back to Latin\-1. This option can be -used to find out how ASCII or Latin\-1 texts are converted to the GSM -default alphabet. Characters that can not be converted to the GSM default -alphabet are reported as ASCII code 172 (Latin\-1 boolean "not") -after this double conversion. No SMS messages are sent, a connection -to a mobile phone is not established. -.TP -\fB\-v\fP, \fB\-\-version\fP -Prints the program version. -.TP -\fB\-X\fP, \fB\-\-xonxoff\fP -Uses software handshaking (XON/XOFF) for accessing the device. -.PP -.SH EXAMPLES -The following two invocations of \fIgsmsendsms\fP each send the same -SMS message to the number "1234": -.PP -.nf -gsmsendsms \-d /dev/ttyS2 \-b 19200 1234 "This is a test." -echo "This is a test." | gsmsendsms \-d /dev/ttyS2 \-b 19200 1234 -.fi -.PP -.SH FILES -.TP 1.4i -.B /dev/mobilephone -Default mobile phone device. -.PP -.SH AUTHOR -Peter Hofmann -.PP -.SH BUGS -Report bugs to software@pxh.de. Include a complete, self-contained -example that will allow the bug to be reproduced, and say which -version of \fIgsmsendsms\fP you are using. -.PP -.SH COPYRIGHT -Copyright \(co 1999 Peter Hofmann -.LP -\fIgsmsendsms\fP is free software; you can redistribute it and/or modify it under -the terms of the GNU Library General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. -.LP -\fIgsmsendsms\fP is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. -.LP -You should have received a copy of the GNU Library General Public License along -with \fIgsmsendsms\fP; see the file COPYING. If not, write to the Free Software -Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -.PP -.SH "SEE ALSO" -.BR gsminfo(7), -.BR gsmpb(1), -.BR gsmctl(1), -.BR gsmsmsd(8), -.BR gsmsmsstore(1). - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsd.man b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsd.man deleted file mode 100644 index 89e9c95f39..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsd.man +++ /dev/null @@ -1,269 +0,0 @@ -.\" -*- eval: (nroff-mode) -*- -.de TQ -.br -.ns -.TP \\$1 -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.TH GSMSMSD 8 "##DATE##" "gsmsmsd v##VERSION##" -.PP -.SH NAME -gsmsmsd \- SMS message reception daemon -.PP -.SH SYNOPSIS -.B gsmsmsd -[ \fB\-a\fP \fIaction\fP ] -[ \fB\-\-action\fP \fIaction\fP ] -[ \fB\-b\fP \fIbaudrate\fP ] -[ \fB\-\-baudrate\fP \fIbaudrate\fP ] -[ \fB\-c\fP \fIconcatenatedID\fP ] -[ \fB\-\-concatenate\fP \fIconcatenatedID\fP ] -[ \fB\-C\fP \fIservice centre address\fP ] -[ \fB\-\-sca\fP \fIservice centre address\fP ] -[ \fB\-d\fP \fIdevice\fP ] -[ \fB\-\-device\fP \fIdevice\fP ] -[ \fB\-D\fP ] -[ \fB\-\-direct\fP ] -[ \fB\-f\fP ] -[ \fB\-\-flush\fP ] -[ \fB\-h\fP ] -[ \fB\-\-help\fP ] -[ \fB\-I\fP \fIinit string\fP ] -[ \fB\-\-init\fP \fIinit string\fP ] -[ \fB\-r\fP ] -[ \fB\-\-requeststat\fP ] -[ \fB\-s\fP \fIspool directory\fP ] -[ \fB\-\-spool\fP \fIspool directory\fP ] -[ \fB\-t\fP \fISMS store name\fP ] -[ \fB\-\-store\fP \fISMS store name\fP ] -[ \fB\-v\fP ] -[ \fB\-\-version\fP ] -[ \fB\-X\fP ] -[ \fB\-\-xonxoff\fP ] -{ \fIsms_type\fP } -.PP -.SH DESCRIPTION -\fIgsmsmsd\fP reads new incoming SMS from the mobile phone and -dispatches them to a user-defined action. Additionally it can send SMS -message that it reads from a spooldir. -.PP -\fIgsmsmsd\fP attaches itself to the \fIdevice\fP given on the command -line (usually an GSM modem) using the specified \fIbaudrate\fP and -waits for incoming SMS messages. If no \fIdevice\fP is given, the -device \fI/dev/mobilephone\fP is used. If no \fIbaudrate\fP is given, a -default baud rate of 38400 is used. -.PP -If no action is given, the SMS message is printed to the standard -output. If an \fIaction\fP is specified the \fIaction\fP is excecuted using the -shell and the SMS message is written to the standard input of the action. -.PP -\fIgsmsmsd\fP needs one empty storage slot for SMS messages in the -mobile phone, otherwise SMS reception will not work. The SMS store to -use for temporary storage of incoming SMS can be selected using the -\fB\-\-store\fP option, otherwise the ME default store is used. -.PP -To terminate \fIgsmsmsd\fP cleanly (without losing SMS messages) one -should send either SIGINT (CTRL\-C on the command line) or SIGTERM to -the process. -.PP -Error messages are printed to the standard error output. If the program -terminates on error the error code 1 is returned. -.PP -\fIsms_type\fP may be any combination of: -.TP -\fIsms\fP, \fIno_sms\fP -Controls reception of normal SMS messages. -.TP -\fIcb\fP, \fIno_cb\fP -Controls reception of cell broadcast messages. -.TP -\fIstat\fP, \fIno_stat\fP -Controls reception of status reports. -.PP -The default is \fIsms\fP, \fIcb\fP, and \fIstat\fP. -.PP -.SH OPTIONS -.TP -\fB\-a\fP \fIaction\fP, \fB\-\-action\fP \fIaction\fP -The action to execute for each incoming SMS message. If no action -is given the SMS is written to the standard output. -.TP -\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP -The baud rate to use. -.TP -\fB\-c\fP \fIconcatenatedID\fP, \fB\-\-concatenate\fP \fIconcatenatedID\fP -If an ID is given, large SMSs are split into several, concatenated -SMSs. All SMSs have the same ID and are numbered consecutively so that -the receiving phone can assemble them in the correct order. IDs must -be in the range 0..255. This number is increased by one for every -outgoing concatenated SMS and wraps around after 255. -Not all receiving phones will support -concatenated SMSs (and display them as separate SMSs), -since all the numbering and ID information is -carried in the user data header element at the beginning of the SMS -user data. This information may show up as garbage in such phones. -.TP -\fB\-C\fP \fIservice centre address\fP, \fB\-\-sca\fP \fIservice centre address\fP -Sets the service centre address to use for all SUBMIT SMSs (may not -work with some phones). -.TP -\fB\-d\fP \fIdevice\fP, \fB\-\-device\fP \fIdevice\fP -The device to which the GSM modem is connected. The default is -\fI/dev/mobilephone\fP. -.TP -\fB\-D\fP, \fB\-\-direct\fP -Enables direct routing of incoming SMS messages to the TE. This is not -supported by many mobile phone/GSM modem combinations. Therefore, the -default is to store incoming SMS temporarily before processing them in -the indicated store. -.TP -\fB\-f\fP, \fB\-\-flush\fP -This option causes \fIgsmsmsd\fP to flush (ie. read and erase) -existing SMS messages from -the SMS store selected by the \fB\-\-store\fP option. The action given -by the \fB\-\-action\fP option is executed on each of the flushed -SMS. This option should be used to ensure that enough space is -available in the SMS store for temporary storage of incoming SMS, -otherwise incoming SMS might be ignored silently by the ME. -.TP -\fB\-h\fP, \fB\-\-help\fP -Prints an option summary. -.TP -\fB\-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP -Initialization string to send to the TA (default: "E0"). Note that the -sequence "ATZ" is sent first. -.TP -\fB\-r\fP, \fB\-\-requeststat\fP -Request status reports for sent SMS. Note: This option only makes -sense if the phone supports routing of status reports to the -TE. Otherwise the status reports might show on the phone's display or -get lost. -.TP -\fB\-s\fP \fIspool directory\fP, \fB\-\-spool\fP \fIspool directory\fP -This option sets the spool directory where \fIgsmsmsd\fP expects SMS -messages to send. The format of SMS files is very simple: The first -line contains the phone number of the recipient. Everything else after -the first line is interpreted as the SMS text. Please refer to -.BR gsmsendsms(1) -for details on the SMS text character set and maximum length. -\fIgsmsmsd\fP polls the spool directory every 5 seconds. Sent -SMS message files are removed. -.TP -\fB\-t\fP \fISMS store name\fP, \fB\-\-store\fP \fISMS store name\fP -The name of the SMS store to read from (for the \fB\-\-flush\fP option) -or write to (for temporary SMS storage). This option must -be must be used in conjunction with the \fB\-\-flush\fP option. If this -option is omitted the ME uses it's default SMS store for temporary -storage of incoming SMS. A commonly available message -store is "SM" (SIM card). -.TP -\fB\-v\fP, \fB\-\-version\fP -Prints the program version. -.TP -\fB\-X\fP, \fB\-\-xonxoff\fP -Uses software handshaking (XON/XOFF) for accessing the device. -.PP -.SH EXAMPLES -The following invocation of \fIgsmsmsd\fP sends each incoming SMS message -as a mail to the user "smsadmin": -.PP -.nf -gsmsmsd \-d /dev/ttyS2 \-b 19200 \-a "mail smsadmin" -.fi -.PP -This is the format of SMS deliver messages as output from \fIgsmsmsd\fP: -.PP -.nf ----------------------------------------------------------------- -Message type: SMS\-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '01805000102' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 17.12.98 14:10:55(+0100) -User data length: 159 -User data header: 0x -User data: 'Nicht vergessen! Die XtraWeihnachtsverlosung lauft -noch bis zum 24.12. Nutzen Sie jetzt Ihre Gewinnchance und faxen -Sie Ihren Teiln.-Gutschein an 0180/5000 056' ----------------------------------------------------------------- -.fi -.PP -This is the format of SMS status report messages as output from \fIgsmsmsd\fP: -.PP -.nf ----------------------------------------------------------------- -Message type: SMS\-STATUS\-REPORT -SC address: '' -More messages to send: 0 -Status report qualifier: 0 -Message reference: 0 -Recipient address: '' -SC timestamp: 00.00.00 00:00:00(+0000) -Discharge time: 00.00.00 00:00:00(+0000) -Status: 0x0 'Short message received by the SME' ----------------------------------------------------------------- -.fi -.PP -The following invocation of \fIgsmsmsd\fP flushes all existing -messages from the "SM" SMS store and looks in the "/tmp/spooldir" -directory for SMS to send: -.PP -.nf -gsmsmsd \-d /dev/ttyS2 \-\-spool /tmp/spooldir \-f \-\-store sm \\ -\-\-action 'mail smsadmin' -.fi -.PP -.SH FILES -.TP 1.4i -.B /dev/mobilephone -Default mobile phone device. -.PP -.SH AUTHOR -Peter Hofmann -.PP -.SH BUGS -Cell broadcast SMS message reception has not been tested, but it has -been enabled in the \fIgsmsmsd\fP daemon. -.PP -The mobile phone device is blocked when the \fIgsmsmsd\fP daemon is -running, ie. it cannot be used for data transfer or from the other -programs of this suite (\fIgsmpb\fP, \fIgsmsms\fP). -.PP -Report bugs to software@pxh.de. Include a complete, self-contained -example that will allow the bug to be reproduced, and say which -version of \fIgsmsmsd\fP you are using. -.PP -.SH COPYRIGHT -Copyright \(co 1999 Peter Hofmann -.LP -\fIgsmsmsd\fP is free software; you can redistribute it and/or modify it under -the terms of the GNU Library General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. -.LP -\fIgsmsmsd\fP is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. -.LP -You should have received a copy of the GNU Library General Public License along -with \fIgsmsmsd\fP; see the file COPYING. If not, write to the Free Software -Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -.PP -.SH "SEE ALSO" -.BR gsminfo(7), -.BR gsmpb(1), -.BR gsmctl(1), -.BR gsmsendsms(1), -.BR gsmsmsstore(1). - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsstore.man b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsstore.man deleted file mode 100644 index fb3fb9bc7f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/doc/gsmsmsstore.man +++ /dev/null @@ -1,185 +0,0 @@ -.\" -*- eval: (nroff-mode) -*- -.de TQ -.br -.ns -.TP \\$1 -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.TH GSMSMSSTORE 8 "##DATE##" "gsmsmsstore v##VERSION##" -.SH NAME -gsmsmsstore \- SMS store manipulation program -.SH SYNOPSIS -.B gsmsmsstore -[ \fB\-a\fP ] -[ \fB\-\-add\fP ] -[ \fB\-b\fP \fIbaudrate\fP ] -[ \fB\-\-baudrate\fP \fIbaudrate\fP ] -[ \fB\-c\fP ] -[ \fB\-\-copy\fP ] -[ \fB\-C\fP \fIservice centre address\fP ] -[ \fB\-\-sca\fP \fIservice centre address\fP ] -[ \fB\-d\fP \fIdestination device or file\fP ] -[ \fB\-\-destination\fP \fIdestination device or file\fP ] -[ \fB\-h\fP ] -[ \fB\-\-help\fP ] -[ \fB\-I\fP \fIinit string\fP ] -[ \fB\-\-init\fP \fIinit string\fP ] -[ \fB\-k\fP ] -[ \fB\-\-backup\fP ] -[ \fB\-l\fP ] -[ \fB\-\-list\fP ] -[ \fB\-s\fP \fIsource device or file\fP ] -[ \fB\-\-source\fP \fIsource device or file\fP ] -[ \fB\-t\fP \fISMS store name\fP ] -[ \fB\-\-store\fP \fISMS store name\fP ] -[ \fB\-v\fP ] -[ \fB\-\-version\fP ] -[ \fB\-V\fP ] -[ \fB\-\-verbose\fP ] -[ \fB\-x\fP ] -[ \fB\-\-delete\fP ] -[ \fB\-X\fP ] -[ \fB\-\-xonxoff\fP ] -{ \fIindices\fP } -[ \fIphonenumber\fP \fItext\fP ] -.PP -.SH DESCRIPTION -\fIgsmsmsstore\fP can store or retrieve SMS messages entries residing -in a GSM mobile phone's SMS store to or from a file, add SMS messages -to a store, or list the store's contents. Additionally, it is possible -to add SMS submit messages to a store. -.PP -\fIgsmsmsstore\fP reads entries from the source which can be a mobile -phone (if a serial device file is given) or a file (if a file name is -given). The source is never modified. \fIgsmsmsstore\fP writes SMS -messages to a destination file or device in the case of \fB\-\-copy\fP, -\fB\-\-backup\fP, and \fB\-\-add\fP. -.PP -The \fB\-\-list\fP option does not change any file but just lists the -contents to standard output. -.PP -The \fB\-\-backup\fP and \fB\-\-copy\fP options require both source and -destination files or devices. The \fB\-\-list\fP option requires a -source. The \fB\-\-add\fP and \fB\-\-delete\fP options require a -destination file or device. -.PP -If "\-" is given as the parameter for the \fB\-\-source\fP or -\fB\-\-destination\fP options, the SMS store is read from standard input -and/or written to standard output, respectively. -.PP -SMS message files are not human-readable. -.PP -Error messages are printed to the standard error output. If the program -terminates on error the error code 1 is returned. -.PP -.SH OPTIONS -.TP -\fB\-a\fP, \fB\-\-add\fP -Adds an SMS submit message with recipient address \fIphonenumber\fP and -text \fItext\fP to the destination. -.TP -\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP -The baud rate to use. The default baudrate is 38400. -.TP -\fB\-c\fP, \fB\-\-copy\fP -This causes the contents of the source to be copied to the -destination. After this operation the destination has exactly the same -contents as the source. If \fIindices\fP are given on the command -line only those SMS messages denoted by the indices are copied to the -destination. -.TP -\fB\-C\fP \fIservice centre address\fP, \fB\-\-sca\fP \fIservice centre address\fP -Sets the service centre address to use for all SUBMIT SMSs (may not -work with some phones). -.TP -\fB\-d\fP \fIdestination\fP, \fB\-\-destination\fP \fIdestination\fP -The destination device or file. -.TP -\fB\-h\fP, \fB\-\-help\fP -Prints an option summary. -.TP -\fB\-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP -Initialization string to send to the TA (default: "E0"). Note that the -sequence "ATZ" is sent first. -.TP -\fB\-k\fP, \fB\-\-backup\fP -This causes those entries to be added from the source to the -destination that are not already present in the destination. If -\fIindices\fP are given on the command line only those SMS messages -denoted by the indices are backed up (ie. added) to the destination. -.TP -\fB\-l\fP, \fB\-\-list\fP -Prints out the entire contents of the source in human-readable form. -.TP -\fB\-s\fP \fIsource\fP, \fB\-\-source\fP \fIsource\fP -The source device or file. -.TP -\fB\-t\fP \fISMS store name\fP, \fB\-\-store\fP \fISMS store name\fP -The name of the SMS store to read from or write to. This information is -only used for device sources and destinations. A commonly available message -store is "SM" (SIM card). -.TP -\fB\-v\fP, \fB\-\-version\fP -Prints the program version. -.TP -\fB\-V\fP, \fB\-\-verbose\fP -Prints out a detailed progress report. -.TP -\fB\-x\fP, \fB\-\-delete\fP -Delete the SMS messages as denoted by the \fIindices\fP from the destination. -.TP -\fB\-X\fP, \fB\-\-xonxoff\fP -Uses software handshaking (XON/XOFF) for accessing the device. -.PP -.SH EXAMPLES -The following command lists all entries in the mobile phone connected -to \fI/dev/mobilephone\fP to the standard output: -.PP -.nf -gsmsmsstore \-b 19200 \-s /dev/mobilephone \-t SM \-l -.fi -.PP -The following adds entries 4, 7, and 10 from the device -\fI/dev/mobilephone\fP to the file \fIsmsstore\fP: -.PP -.nf -gsmsmsstore \-s /dev/mobilephone \-d /home/fred/smsstore - \-t SM \-b 4 7 10 -.fi -.PP -.SH AUTHOR -Peter Hofmann -.PP -.SH BUGS -Report bugs to software@pxh.de. Include a complete, self-contained -example that will allow the bug to be reproduced, and say which -version of \fIgsmsmsstore\fP you are using. -.PP -.SH COPYRIGHT -Copyright \(co 1999 Peter Hofmann -.LP -\fIgsmsmsstore\fP is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2, or (at -your option) any later version. -.LP -\fIgsmsmsstore\fP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. -.LP -You should have received a copy of the GNU Library General Public License -along with \fIgsmsmsstore\fP; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -.PP -.SH "SEE ALSO" -.BR gsminfo(7), -.BR gsmctl(1), -.BR gsmpb(1), -.BR gsmsendsms(1), -.BR gsmsmsd(8). diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.am deleted file mode 100644 index 1c1d2fc3ce..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: Makefile for phone-specific extensions -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 16.12.2001 -# ************************************************************************* - -INCLUDES = -I.. - -EXTRA_DIST = README.sieme - -# build addon library -lib_LTLIBRARIES = libgsmext.la - -libgsmext_la_SOURCES = gsm_sie_me.cc - -libgsmext_la_LDFLAGS = -version-info $(GSM_VERSION) - -gsmincludedir = $(includedir)/gsmlib - -gsminclude_HEADERS = gsm_sie_me.h - -# build programs -bin_PROGRAMS = gsmsiectl gsmsiexfer - -# build gsmsiectl from gsmsiectl.cc and libgsmme.la -gsmsiectl_SOURCES = gsmsiectl.cc -gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS) - -# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la -gsmsiexfer_SOURCES = gsmsiexfer.cc -gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS) - - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.in deleted file mode 100644 index 42240fb530..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/Makefile.in +++ /dev/null @@ -1,480 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: Makefile for phone-specific extensions -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 16.12.2001 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -INCLUDES = -I.. - -EXTRA_DIST = README.sieme - -# build addon library -lib_LTLIBRARIES = libgsmext.la - -libgsmext_la_SOURCES = gsm_sie_me.cc - -libgsmext_la_LDFLAGS = -version-info $(GSM_VERSION) - -gsmincludedir = $(includedir)/gsmlib - -gsminclude_HEADERS = gsm_sie_me.h - -# build programs -bin_PROGRAMS = gsmsiectl gsmsiexfer - -# build gsmsiectl from gsmsiectl.cc and libgsmme.la -gsmsiectl_SOURCES = gsmsiectl.cc -gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS) - -# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la -gsmsiexfer_SOURCES = gsmsiexfer.cc -gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS) -subdir = ext -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -LTLIBRARIES = $(lib_LTLIBRARIES) - -libgsmext_la_LIBADD = -am_libgsmext_la_OBJECTS = gsm_sie_me.lo -libgsmext_la_OBJECTS = $(am_libgsmext_la_OBJECTS) -bin_PROGRAMS = gsmsiectl$(EXEEXT) gsmsiexfer$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) - -am_gsmsiectl_OBJECTS = gsmsiectl.$(OBJEXT) -gsmsiectl_OBJECTS = $(am_gsmsiectl_OBJECTS) -gsmsiectl_DEPENDENCIES = ../gsmlib/libgsmme.la libgsmext.la -gsmsiectl_LDFLAGS = -am_gsmsiexfer_OBJECTS = gsmsiexfer.$(OBJEXT) -gsmsiexfer_OBJECTS = $(am_gsmsiexfer_OBJECTS) -gsmsiexfer_DEPENDENCIES = ../gsmlib/libgsmme.la libgsmext.la -gsmsiexfer_LDFLAGS = - -DEFS = @DEFS@ -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp -am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsm_sie_me.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsmsiectl.Po ./$(DEPDIR)/gsmsiexfer.Po -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CXXFLAGS = @CXXFLAGS@ -DIST_SOURCES = $(libgsmext_la_SOURCES) $(gsmsiectl_SOURCES) \ - $(gsmsiexfer_SOURCES) -HEADERS = $(gsminclude_HEADERS) - -DIST_COMMON = $(gsminclude_HEADERS) Makefile.am Makefile.in -SOURCES = $(libgsmext_la_SOURCES) $(gsmsiectl_SOURCES) $(gsmsiexfer_SOURCES) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .cc .lo .o .obj -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu ext/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -libLTLIBRARIES_INSTALL = $(INSTALL) -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libdir) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \ - $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \ - $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test -z "$dir" && dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libgsmext.la: $(libgsmext_la_OBJECTS) $(libgsmext_la_DEPENDENCIES) - $(CXXLINK) -rpath $(libdir) $(libgsmext_la_LDFLAGS) $(libgsmext_la_OBJECTS) $(libgsmext_la_LIBADD) $(LIBS) -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - || test -f $$p1 \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ - rm -f $(DESTDIR)$(bindir)/$$f; \ - done - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -gsmsiectl$(EXEEXT): $(gsmsiectl_OBJECTS) $(gsmsiectl_DEPENDENCIES) - @rm -f gsmsiectl$(EXEEXT) - $(CXXLINK) $(gsmsiectl_LDFLAGS) $(gsmsiectl_OBJECTS) $(gsmsiectl_LDADD) $(LIBS) -gsmsiexfer$(EXEEXT): $(gsmsiexfer_OBJECTS) $(gsmsiexfer_DEPENDENCIES) - @rm -f gsmsiexfer$(EXEEXT) - $(CXXLINK) $(gsmsiexfer_LDFLAGS) $(gsmsiexfer_OBJECTS) $(gsmsiexfer_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sie_me.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsiectl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsiexfer.Po@am__quote@ - -distclean-depend: - -rm -rf ./$(DEPDIR) - -.cc.o: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -.cc.obj: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `cygpath -w $<` - -.cc.lo: -@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -CXXDEPMODE = @CXXDEPMODE@ - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -gsmincludeHEADERS_INSTALL = $(INSTALL_HEADER) -install-gsmincludeHEADERS: $(gsminclude_HEADERS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(gsmincludedir) - @list='$(gsminclude_HEADERS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f"; \ - $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f; \ - done - -uninstall-gsmincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(gsminclude_HEADERS)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " rm -f $(DESTDIR)$(gsmincludedir)/$$f"; \ - rm -f $(DESTDIR)$(gsmincludedir)/$$f; \ - done - -ETAGS = etags -ETAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) -install-binPROGRAMS: install-libLTLIBRARIES - - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) $(DESTDIR)$(gsmincludedir) - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-compile distclean-depend \ - distclean-generic distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: install-gsmincludeHEADERS - -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -uninstall-am: uninstall-binPROGRAMS uninstall-gsmincludeHEADERS \ - uninstall-info-am uninstall-libLTLIBRARIES - -.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libLTLIBRARIES clean-libtool distclean \ - distclean-compile distclean-depend distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am info \ - info-am install install-am install-binPROGRAMS install-data \ - install-data-am install-exec install-exec-am \ - install-gsmincludeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-gsmincludeHEADERS \ - uninstall-info-am uninstall-libLTLIBRARIES - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/README.sieme b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/README.sieme deleted file mode 100644 index 4305ae33a2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/README.sieme +++ /dev/null @@ -1,75 +0,0 @@ -Extended support for Siemens mobile phones via gsmlib ------------------------------------------------------ - -* Hardware: - -Supported phones: S25, S35, S45, ME45, SL45 -Tested phones: S45, ME45 - -* Feature list: - - - ACM: Output ACM (accumulated call meter) and ACMmax => maybe not - - - BNR/BNW: Binary read and write => yes, xfer - - - CID: Output card ID => maybe - - - CKS: Output SIM card status => maybe - - - CNI: Output call number information => maybe - - - DBR: Database Read => yes, phonebook - - - DLD: Delete the "last number redial" memory => maybe dangerous? - - - GAUTH: Select Type of Authentication for PPP => no - - - ICO: Icon control => no - - - LCK: Switch locks on and off => yes, lock/unlock - - - LNG: Language settings => maybe - - - MGL: List SMS => no - - - MGO: SMS overflow indicator => no - - - MGR: Read SMS (same as AT+CMGR) => no - - - MSO: Switch device off => maybe not - - - NFS: Select NF hardware => maybe - - - NFV: Set the volume => maybe - - - PBC: Seek in telephone book => no - - - PBG: Sorted telephone book => yes - - - PBS: Select a telephone book => yes - - - PIC: Output PIN counter => maybe - - - PLM: Read the PLMN list => yes - - - PLR/PLW: read/write preferred-operator list => yes - - - PST: Play Signal Tone => yes - - - PWD: Change password to a lock => maybe - - - RTC: Set the ringing tone => yes - - - STK: SIM toolkit => no - - -* Additional References - -http://www.s45-world.net/vissie.htm - - -* Author and contact - -Christian W. Zuckschwerdt -http://triq.net/gsm.html - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.cc deleted file mode 100644 index fb22260836..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.cc +++ /dev/null @@ -1,258 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sie_me.cc -// * -// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions -// * (According to "AT command set for S45 Siemens mobile phones" -// * v1.8, 26. July 2001 - Common AT prefix is "^S") -// * -// * Author: Christian W. Zuckschwerdt -// * -// * Created: 2001-12-15 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// SieMe members - -void SieMe::init() throw(GsmException) -{ -} - -SieMe::SieMe(Ref port) throw(GsmException) : MeTa::MeTa(port) -{ - // initialize Siemens ME - - init(); -} - -vector SieMe::getSupportedPhonebooks() throw(GsmException) -{ - Parser p(_at->chat("^SPBS=?", "^SPBS:")); - return p.parseStringList(); -} - -string SieMe::getCurrentPhonebook() throw(GsmException) -{ - if (_lastPhonebookName == "") - { - Parser p(_at->chat("^SPBS?", "^SPBS:")); - // answer is e.g. ^SPBS: "SM",41,250 - _lastPhonebookName = p.parseString(); - p.parseComma(); - int _currentNumberOfEntries = p.parseInt(); - p.parseComma(); - int _maxNumberOfEntries = p.parseInt(); - } - return _lastPhonebookName; -} - -void SieMe::setPhonebook(string phonebookName) throw(GsmException) -{ - if (phonebookName != _lastPhonebookName) - { - _at->chat("^SPBS=\"" + phonebookName + "\""); - _lastPhonebookName = phonebookName; - } -} - - -IntRange SieMe:: getSupportedSignalTones() throw(GsmException) -{ - Parser p(_at->chat("^SPST=?", "^SPST:")); - // ^SPST: (0-4),(0,1) - IntRange typeRange = p.parseRange(); - p.parseComma(); - vector volumeList = p.parseIntList(); - return typeRange; -} - -void SieMe:: playSignalTone(int tone) throw(GsmException) -{ - _at->chat("^SPST=" + intToStr(tone) + ",1"); -} - -void SieMe:: stopSignalTone(int tone) throw(GsmException) -{ - _at->chat("^SPST=" + intToStr(tone) + ",0"); -} - - -IntRange SieMe::getSupportedRingingTones() throw(GsmException) // (AT^SRTC=?) -{ - Parser p(_at->chat("^SRTC=?", "^SRTC:")); - // ^SRTC: (0-42),(1-5) - IntRange typeRange = p.parseRange(); - p.parseComma(); - IntRange volumeRange = p.parseRange(); - return typeRange; -} - -int SieMe::getCurrentRingingTone() throw(GsmException) // (AT^SRTC?) -{ - Parser p(_at->chat("^SRTC?", "^SRTC:")); - // ^SRTC: 41,2,0 - int type = p.parseInt(); - p.parseComma(); - int volume = p.parseInt(); - p.parseComma(); - int ringing = p.parseInt(); - return type; -} - -void SieMe::setRingingTone(int tone, int volume) throw(GsmException) -{ - _at->chat("^SRTC=" + intToStr(tone) + "," + intToStr(volume)); -} - -void SieMe:: playRingingTone() throw(GsmException) -{ - // get ringing bool - Parser p(_at->chat("^SRTC?", "^SRTC:")); - // ^SRTC: 41,2,0 - int type = p.parseInt(); - p.parseComma(); - int volume = p.parseInt(); - p.parseComma(); - int ringing = p.parseInt(); - - if (ringing == 0) - toggleRingingTone(); -} - -void SieMe::stopRingingTone() throw(GsmException) -{ - // get ringing bool - Parser p(_at->chat("^SRTC?", "^SRTC:")); - // ^SRTC: 41,2,0 - int type = p.parseInt(); - p.parseComma(); - int volume = p.parseInt(); - p.parseComma(); - int ringing = p.parseInt(); - - if (ringing == 1) - toggleRingingTone(); -} - -void SieMe::toggleRingingTone() throw(GsmException) // (AT^SRTC) -{ - _at->chat("^SRTC"); -} - -// Siemens get supported binary read -vector SieMe::getSupportedBinaryReads() throw(GsmException) -{ - Parser p(_at->chat("^SBNR=?", "^SBNR:")); - // ^SBNR: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50)) - - return p.parseParameterRangeList(); -} - -// Siemens get supported binary write -vector SieMe::getSupportedBinaryWrites() throw(GsmException) -{ - Parser p(_at->chat("^SBNW=?", "^SBNW:")); - // ^SBNW: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50)),("t9d",(0)) - - return p.parseParameterRangeList(); -} - -// Siemens Binary Read -BinaryObject SieMe::getBinary(string type, int subtype) throw(GsmException) -{ - // expect several response lines - vector result; - result = _at->chatv("^SBNR=\"" + type + "\"," + intToStr(subtype), "^SBNR:"); - // "bmp",0,1,5 pdu "bmp",0,2,5 ... - // most likely to be PDUs of 382 chars (191 * 2) - string pdu; - int fragmentCount = 0; - for (vector::iterator i = result.begin(); i != result.end(); ++i) - { - ++fragmentCount; - // parse header - Parser p(*i); - string fragmentType = p.parseString(); - if (fragmentType != type) - throw GsmException(_("bad PDU type"), ChatError); - p.parseComma(); - int fragmentSubtype = p.parseInt(); - if (fragmentSubtype != subtype) - throw GsmException(_("bad PDU subtype"), ChatError); - p.parseComma(); - int fragmentNumber = p.parseInt(); - if (fragmentNumber != fragmentCount) - throw GsmException(_("bad PDU number"), ChatError); - p.parseComma(); - int numberOfFragments = p.parseInt(); - if (fragmentNumber > numberOfFragments) - throw GsmException(_("bad PDU number"), ChatError); - - // concat pdu fragment - ++i; - pdu += *i; - } - - BinaryObject bnr; - bnr._type = type; - bnr._subtype = subtype; - bnr._size = pdu.length() / 2; - bnr._data = new unsigned char[pdu.length() / 2]; - if (! hexToBuf(pdu, bnr._data)) - throw GsmException(_("bad hexadecimal PDU format"), ChatError); - - return bnr; -} - -// Siemens Binary Write -void SieMe::setBinary(string type, int subtype, BinaryObject obj) - throw(GsmException) -{ - if (obj._size <= 0) - throw GsmException(_("bad object"), ParameterError); - - // Limitation: The maximum pdu size is 176 bytes (or 352 characters) - // this should be a configurable field - int maxPDUsize = 176; - int numberOfPDUs = (obj._size + maxPDUsize - 1) / maxPDUsize; - unsigned char *p = obj._data; - - for (int i = 1; i <= numberOfPDUs; ++i) - { - // construct pdu - int size = maxPDUsize; - if (i == numberOfPDUs) - size = obj._size - (numberOfPDUs - 1) * maxPDUsize; - string pdu = bufToHex(p, size); - p += size; - - cout << "processing " << i << " of " << numberOfPDUs - << " of " << size << " bytes." << endl; - cout << "^SBNW=\"" + type + "\"," + intToStr(subtype) + "," - + intToStr(i) + "," + intToStr(numberOfPDUs) << endl; - cout << pdu << endl; - - _at->sendPdu("^SBNW=\"" + type + "\"," + intToStr(subtype) + "," - + intToStr(i) + "," + intToStr(numberOfPDUs), "", - pdu, true); - cout << "OK" << endl; - } -} - - - - - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.h deleted file mode 100644 index 2c827a0379..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsm_sie_me.h +++ /dev/null @@ -1,99 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sie_me.h -// * -// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions -// * (According to "AT command set for S45 Siemens mobile phones" -// * v1.8, 26. July 2001 - Common AT prefix is "^S") -// * -// * Author: Christian W. Zuckschwerdt -// * -// * Created: 2001-12-15 -// ************************************************************************* - -#ifndef GSM_SIE_ME_H -#define GSM_SIE_ME_H - -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // *** Siemens mobile phone binary objects (bitmap, midi, vcal, vcard) - - struct BinaryObject - { - string _type; // Object type - int _subtype; // Object subtype (storage number) - unsigned char *_data; // Object binary data - int _size; // Object data size - }; - - // *** this class allows extended access to Siemens moblie phones - - class SieMe : public MeTa - { - private: - // init ME/TA to sensible defaults - void init() throw(GsmException); - - public: - // initialize a new MeTa object given the port - SieMe(Ref port) throw(GsmException); - - - // get the current phonebook in the Siemens ME - vector getSupportedPhonebooks() throw(GsmException);// (AT^SPBS=?) - - // get the current phonebook in the Siemens ME - string getCurrentPhonebook() throw(GsmException); // (AT^SPBS?) - - // set the current phonebook in the Siemens ME - // remember the last phonebook set for optimisation - void setPhonebook(string phonebookName) throw(GsmException); // (AT^SPBS=) - - - // Siemens get supported signal tones - IntRange getSupportedSignalTones() throw(GsmException); // (AT^SPST=?) - - // Siemens set ringing tone - void playSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,1) - - // Siemens set ringing tone - void stopSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,0) - - - // Siemens get ringing tone - IntRange getSupportedRingingTones() throw(GsmException); // (AT^SRTC=?) - // Siemens get ringing tone - int getCurrentRingingTone() throw(GsmException); // (AT^SRTC?) - // Siemens set ringing tone - void setRingingTone(int tone, int volume) throw(GsmException);// (AT^SRTC=) - // Siemens set ringing tone on - void playRingingTone() throw(GsmException); - // Siemens set ringing tone of - void stopRingingTone() throw(GsmException); - // Siemens toggle ringing tone - void toggleRingingTone() throw(GsmException); // (AT^SRTC) - - // Siemens get supported binary read - vector getSupportedBinaryReads() throw(GsmException); - - // Siemens get supported binary write - vector getSupportedBinaryWrites() throw(GsmException); - - // Siemens Binary Read - BinaryObject getBinary(string type, int subtype) throw(GsmException); - - // Siemens Binary Write - void setBinary(string type, int subtype, BinaryObject obj) - throw(GsmException); - }; -}; - -#endif // GSM_ME_TA_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiectl.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiectl.cc deleted file mode 100644 index 4ea92edfea..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiectl.cc +++ /dev/null @@ -1,698 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmsiectl.cc -// * -// * Purpose: GSM Siemens mobile phone control program -// * -// * Author: Christian W. Zuckschwerdt -// * -// * Created: 2001-12-15 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#include - -using namespace std; -using namespace gsmlib; - -// my ME - -static SieMe *m; - -// information parameters - -enum InfoParameter {AllInfo, // print all info - MeInfo, // MeInfo must be first! - OperatorInfo, - CurrentOperatorInfo, - FacilityLockStateInfo, - FacilityLockCapabilityInfo, - PasswordInfo, - CLIPInfo, - CallForwardingInfo, - BatteryInfo, - BitErrorInfo, - SCAInfo, - CharSetInfo, - PhonebookInfo, // extended Siemens info - SignalToneInfo, - RingingToneInfo, - BinaryInfo, - SignalInfo}; // SignalInfo must be last! - -// operation parameters - -// FIXME operations not implemented yet - -// options - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"operation", required_argument, (int*)NULL, 'o'}, - {"device", required_argument, (int*)NULL, 'd'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -// helper function, prints forwarding info - -void printForwardReason(string s, ForwardInfo &info) -{ - cout << s << " " - << (info._active ? _("active ") : _("inactive ")) - << _("number: ") << info._number - << _(" subaddr: ") << info._subAddr - << _(" time: ") << info._time << endl; -} - -// helper function, prints integer range - -void printIntRange(IntRange ir) -{ - cout << "(" << ir._low; - if (ir._high != NOT_SET) - cout << "-" << ir._high; - cout << ")"; -} - -// helper function, prints parameter range - -void printParameterRange(ParameterRange pr) -{ - cout << "(\"" << pr._parameter << "\","; - printIntRange(pr._range); - cout << ")"; -} - -// print information - -static void printInfo(InfoParameter ip) -{ - switch (ip) - { - case MeInfo: - { - MEInfo mei = m->getMEInfo(); - cout << _(" Manufacturer: ") << mei._manufacturer << endl - << _(" Model: ") << mei._model << endl - << _(" Revision: ") << mei._revision << endl - << _(" Serial Number: ") << mei._serialNumber << endl; - break; - } - case OperatorInfo: - { - int count = 0; - vector opis = m->getAvailableOPInfo(); - for (vector::iterator i = opis.begin(); i != opis.end(); ++i) - { - cout << " Status: "); - switch (i->_status) - { - case UnknownOPStatus: cout << _("unknown"); break; - case CurrentOPStatus: cout << _("current"); break; - case AvailableOPStatus: cout << _("available"); break; - case ForbiddenOPStatus: cout << _("forbidden"); break; - } - cout << _(" Long name: '") << i->_longName << "' " - << _(" Short name: '") << i->_shortName << "' " - << _(" Numeric name: ") << i->_numericName << endl; - ++count; - } - break; - } - case CurrentOperatorInfo: - { - OPInfo opi = m->getCurrentOPInfo(); - cout << "" - << _(" Long name: '") << opi._longName << "' " - << _(" Short name: '") << opi._shortName << "' " - << _(" Numeric name: ") << opi._numericName - << _(" Mode: "); - switch (opi._mode) - { - case AutomaticOPMode: cout << _("automatic"); break; - case ManualOPMode: cout << _("manual"); break; - case DeregisterOPMode: cout << _("deregister"); break; - case ManualAutomaticOPMode: cout << _("manual/automatic"); break; - } - cout << endl; - break; - } - case FacilityLockStateInfo: - { - int count = 0; - vector fclc = m->getFacilityLockCapabilities(); - for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) - if (*i != "AB" && *i != "AG" && *i != "AC") - { - cout << " '" << *i << "'"; - try - { - if (m->getFacilityLockStatus(*i, VoiceFacility)) - cout << _(" Voice"); - } - catch (GsmException &e) - { - cout << _(" unknown"); - } - try - { - if (m->getFacilityLockStatus(*i, DataFacility)) - cout << _(" Data"); - } - catch (GsmException &e) - { - cout << _(" unknown"); - } - try - { - if (m->getFacilityLockStatus(*i, FaxFacility)) - cout << _(" Fax"); - } - catch (GsmException &e) - { - cout << _(" unknown"); - } - cout << endl; - ++count; - } - break; - } - case FacilityLockCapabilityInfo: - { - cout << " "; - vector fclc = m->getFacilityLockCapabilities(); - for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) - cout << "'" << *i << "' "; - cout << endl; - break; - } - case PasswordInfo: - { - vector pwi = m->getPasswords(); - int count = 0; - for (vector::iterator i = pwi.begin(); i != pwi.end(); ++i) - { - cout << " '" - << i->_facility << "' " << i->_maxPasswdLen << endl; - ++count; - } - break; - } - case CLIPInfo: - { - cout << " " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl; - break; - } - case CallForwardingInfo: - { - for (int r = 0; r < 4; ++r) - { - string text; - switch (r) - { - case 0: text = _("UnconditionalReason"); break; - case 1: text = _("MobileBusyReason"); break; - case 2: text = _("NoReplyReason"); break; - case 3: text = _("NotReachableReason"); break; - } - ForwardInfo voice, fax, data; - m->getCallForwardInfo((ForwardReason)r, voice, fax, data); - cout << " " + text + _(" Voice"), voice); - cout << " " + text + _(" Data"), data); - cout << " " + text + _(" Fax"), fax); - } - break; - } - case BatteryInfo: - { - cout << " "; - int bcs = m->getBatteryChargeStatus(); - switch (bcs) - { - case 0: cout << _("0 ME is powered by the battery") << endl; break; - case 1: cout << _("1 ME has a battery connected, but is not powered by it") - << endl; break; - case 2: cout << _("2 ME does not have a battery connected") << endl; break; - case 3: - cout << _("3 Recognized power fault, calls inhibited") << endl; - break; - } - cout << " " << m->getBatteryCharge() << endl; - break; - } - case BitErrorInfo: - { - cout << " " << m->getBitErrorRate() << endl; - break; - } - case SCAInfo: - { - cout << " " << m->getServiceCentreAddress() << endl; - break; - } - case CharSetInfo: - { - cout << " "; - vector cs = m->getSupportedCharSets(); - for (vector::iterator i = cs.begin(); i != cs.end(); ++i) - cout << "'" << *i << "' "; - cout << endl; - cout << " '" << m->getCurrentCharSet() << "'" << endl; - break; - } - case SignalInfo: - { - cout << " " << m->getSignalStrength() << endl; - break; - } - case PhonebookInfo: - { - cout << " "; - vector pb = m->getSupportedPhonebooks(); - for (vector::iterator i = pb.begin(); i != pb.end(); ++i) - cout << "'" << *i << "' "; - cout << endl; - cout << " '" << m->getCurrentPhonebook() << "'" << endl; - break; - } - case SignalToneInfo: - { - cout << " "; - IntRange st = m->getSupportedSignalTones(); - printIntRange(st); - cout << endl; -// cout << " '" << m->getCurrentSignalTone() << "'" << endl; - break; - } - case RingingToneInfo: - { - cout << " "; - IntRange rt = m->getSupportedRingingTones(); - printIntRange(rt); - cout << endl; - cout << " " << m->getCurrentRingingTone() << endl; - break; - } - case BinaryInfo: - { - cout << " "; - vector bnr = m->getSupportedBinaryReads(); - for (vector::iterator i = bnr.begin(); i != bnr.end(); ++i) - { - printParameterRange(*i); - cout << " "; - } - cout << endl; - cout << " "; - vector bnw = m->getSupportedBinaryWrites(); - for (vector::iterator i = bnw.begin(); i != bnw.end(); ++i) - { - printParameterRange(*i); - cout << " "; - } - cout << endl; - break; - } - default: - assert(0); - break; - } -} - -// convert facility class string of the form "", "all", or any combination -// of "v" (voice), "d" (data), or "f" (fax) to numeric form - -FacilityClass strToFacilityClass(string facilityClassS) -{ - facilityClassS = lowercase(facilityClassS); - FacilityClass facilityClass = (FacilityClass)0; - if (facilityClassS == "all" || facilityClassS == "") - return (FacilityClass)ALL_FACILITIES; - - // OR in facility class bits - for (unsigned int i = 0; i < facilityClassS.length(); ++i) - if (facilityClassS[i] == 'v') - facilityClass = (FacilityClass)(facilityClass | VoiceFacility); - else if (facilityClassS[i] == 'd') - facilityClass = (FacilityClass)(facilityClass | DataFacility); - else if (facilityClassS[i] == 'f') - facilityClass = (FacilityClass)(facilityClass | FaxFacility); - else - throw GsmException( - stringPrintf(_("unknown facility class parameter '%c'"), - facilityClassS[i]), ParameterError); - - return facilityClass; -} - -// check if argc - optind is in range min..max -// throw exception otherwise - -void checkParamCount(int optind, int argc, int min, int max) -{ - int paramCount = argc - optind; - if (paramCount < min) - throw GsmException(stringPrintf(_("not enough parameters, minimum number " - "of parameters is %d"), min), - ParameterError); - else if (paramCount > max) - throw GsmException(stringPrintf(_("too many parameters, maximum number " - "of parameters is %d"), max), - ParameterError); -} - -// *** main program - -int main(int argc, char *argv[]) -{ - try - { - // handle command line options - string device = "/dev/mobilephone"; - string operation; - string baudrate; - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy)) - != -1) - switch (opt) - { - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 'd': - device = optarg; - break; - case 'o': - operation = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-b baudrate][-d device][-h]" - "[-I init string][-o operation]\n" - " [-v][-X]{parameters}") << endl - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -d, --device sets the destination device to " - "connect to") << endl - << _(" -h, --help prints this message") << endl - << _(" -I, --init device AT init sequence") << endl - << _(" -o, --operation operation to perform on the mobile \n" - " phone with the specified parameters") - << endl - << _(" -v, --version prints version and exits") << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << endl - << _(" parameters parameters to use for the operation\n" - " (if an operation is given) or\n" - " a specification which kind of\n" - " information to read from the mobile " - "phone") - << endl << endl - << _("Refer to gsmctl(1) for details on the available parameters" - " and operations.") - << endl << endl; - exit(0); - break; - case '?': - throw GsmException(_("unknown option"), ParameterError); - break; - } - - // open the port and ME/TA - m = new SieMe(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (device, - baudrate == "" ? - DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), - initString, swHandshake)); - - if (operation == "") - { // process info parameters - for (int i = optind; i < argc; ++i) - { - string param = lowercase(argv[i]); - if (param == "all") - for (int ip = MeInfo; ip <= SignalInfo; ++ip) - printInfo((InfoParameter)ip); - else if (param == "me") - printInfo(MeInfo); - else if (param == "op") - printInfo(OperatorInfo); - else if (param == "currop") - printInfo(CurrentOperatorInfo); - else if (param == "flstat") - printInfo(FacilityLockStateInfo); - else if (param == "flcap") - printInfo(FacilityLockCapabilityInfo); - else if (param == "pw") - printInfo(PasswordInfo); - else if (param == "clip") - printInfo(CLIPInfo); - else if (param == "forw") - printInfo(CallForwardingInfo); - else if (param == "batt") - printInfo(BatteryInfo); - else if (param == "biterr") - printInfo(BitErrorInfo); - else if (param == "sig") - printInfo(SignalInfo); - else if (param == "sca") - printInfo(SCAInfo); - else if (param == "cset") - printInfo(CharSetInfo); - else if (param == "pbook") - printInfo(PhonebookInfo); - else if (param == "signal") - printInfo(SignalToneInfo); - else if (param == "ring") - printInfo(RingingToneInfo); - else if (param == "binary") - printInfo(BinaryInfo); - else - throw GsmException( - stringPrintf(_("unknown information parameter '%s'"), - param.c_str()), - ParameterError); - } - } - else - { // process operation - operation = lowercase(operation); - if (operation == "dial") - { - // dial: number - checkParamCount(optind, argc, 1, 1); - - m->dial(argv[optind]); - - // wait for keypress from stdin - char c; - read(1, &c, 1); - } - else if (operation == "setop") - { - // setop: opmode numeric FIXME allow long and numeric too - checkParamCount(optind, argc, 2, 2); - string opmodeS = lowercase(argv[optind]); - OPModes opmode; - if (opmodeS == "automatic") - opmode = AutomaticOPMode; - else if (opmodeS == "manual") - opmode = ManualOPMode; - else if (opmodeS == "deregister") - opmode = DeregisterOPMode; - else if (opmodeS == "manualautomatic") - opmode = ManualAutomaticOPMode; - else - throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"), - opmodeS.c_str()), ParameterError); - - m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1])); - } - else if (operation == "lock") - { - // lock: facility [facilityclass] [passwd] - checkParamCount(optind, argc, 1, 3); - string passwd = (argc - optind == 3) ? - (string)argv[optind + 2] : (string)""; - - m->lockFacility(argv[optind], - (argc - optind >= 2) ? - strToFacilityClass(argv[optind + 1]) : - (FacilityClass)ALL_FACILITIES, - passwd); - } - else if (operation == "unlock") - { - // unlock: facility [facilityclass] [passwd] - checkParamCount(optind, argc, 1, 3); - string passwd = argc - optind == 3 ? argv[optind + 2] : ""; - - m->unlockFacility(argv[optind], - (argc - optind >= 2) ? - strToFacilityClass(argv[optind + 1]) : - (FacilityClass)ALL_FACILITIES, - passwd); - } - else if (operation == "setpw") - { - // set password: facility oldpasswd newpasswd - checkParamCount(optind, argc, 1, 3); - string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : ""; - string newPasswd = argc - optind == 3 ? argv[optind + 2] : ""; - - m->setPassword(argv[optind], oldPasswd, newPasswd); - } - else if (operation == "forw") - { - // call forwarding: mode reason number [facilityclass] [forwardtime] - checkParamCount(optind, argc, 2, 5); - - // get optional parameters facility class and forwardtime - int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) : - NOT_SET; - FacilityClass facilityClass = - argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) : - (FacilityClass)ALL_FACILITIES; - - // get forward reason - string reasonS = lowercase(argv[optind + 1]); - ForwardReason reason; - if (reasonS == "unconditional") - reason = UnconditionalReason; - else if (reasonS == "mobilebusy") - reason = MobileBusyReason; - else if (reasonS == "noreply") - reason = NoReplyReason; - else if (reasonS == "notreachable") - reason = NotReachableReason; - else if (reasonS == "all") - reason = AllReasons; - else if (reasonS == "allconditional") - reason = AllConditionalReasons; - else - throw GsmException( - stringPrintf(_("unknown forward reason parameter '%s'"), - reasonS.c_str()), ParameterError); - - // get mode - string modeS = lowercase(argv[optind]); - ForwardMode mode; - if (modeS == "disable") - mode = DisableMode; - else if (modeS == "enable") - mode = EnableMode; - else if (modeS == "register") - mode = RegistrationMode; - else if (modeS == "erase") - mode = ErasureMode; - else - throw GsmException( - stringPrintf(_("unknown forward mode parameter '%s'"), - modeS.c_str()), ParameterError); - - m->setCallForwarding(reason, mode, - (argc - optind >= 3) ? argv[optind + 2] : "", - "", // subaddr - facilityClass, forwardTime); - } - else if (operation == "setsca") - { - // set sca: number - checkParamCount(optind, argc, 1, 1); - m->setServiceCentreAddress(argv[optind]); - } - else if (operation == "cset") - { - // set charset: string - checkParamCount(optind, argc, 1, 1); - m->setCharSet(argv[optind]); - } - else if (operation == "signal") - { - // play signal tone: int - checkParamCount(optind, argc, 1, 1); - int tone = atoi(argv[optind]); - m->playSignalTone(tone); - } - else if (operation == "setrt") - { - // set ringing tone: int int - checkParamCount(optind, argc, 2, 2); - int tone = atoi(argv[optind]); - int volume = atoi(argv[optind + 1]); - m->setRingingTone(tone, volume); - } - else if (operation == "playrt") - { - // play/stop ringing tone - m->toggleRingingTone(); - } - else - throw GsmException(stringPrintf(_("unknown operation '%s'"), - operation.c_str()), ParameterError); - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiexfer.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiexfer.cc deleted file mode 100644 index 90fce1f471..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/ext/gsmsiexfer.cc +++ /dev/null @@ -1,292 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsmsiexfer.cc -// * -// * Purpose: Siemens ME file transfer program -// * -// * Author: Christian W. Zuckschwerdt -// * -// * Created: 2001-12-16 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#if defined(HAVE_GETOPT_LONG) || defined(WIN32) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -#ifdef HAVE_GETOPT_LONG -static struct option longOpts[] = -{ - {"xonxoff", no_argument, (int*)NULL, 'X'}, - {"init", required_argument, (int*)NULL, 'I'}, - {"destination", required_argument, (int*)NULL, 'd'}, - {"source", required_argument, (int*)NULL, 's'}, - {"baudrate", required_argument, (int*)NULL, 'b'}, - {"type", required_argument, (int*)NULL, 't'}, - {"subtype", required_argument, (int*)NULL, 'i'}, - {"help", no_argument, (int*)NULL, 'h'}, - {"version", no_argument, (int*)NULL, 'v'}, - {"verbose", no_argument, (int*)NULL, 'V'}, - {(char*)NULL, 0, (int*)NULL, 0} -}; -#else -#define getopt_long(argc, argv, options, longopts, indexptr) \ - getopt(argc, argv, options) -#endif - -// I f*ck up this file IO thing. - -// read binary object from stdin -BinaryObject readBinaryFile(istream &ifs, string filename) -{ - size_t size = 10000; // Bad coder, no biscuits! - BinaryObject bnr; - bnr._data = new unsigned char[size]; - ifs.read((char*)bnr._data, size); - bnr._size = ifs.gcount(); - return bnr; -} - -// read binary object from file -BinaryObject readFile(string filename) -{ - // open the file - ifstream ifs(filename.c_str()); - if (ifs.bad()) - throw GsmException(stringPrintf(_("cannot open file '%s'"), - filename.c_str()), - OSError); - // and read the file - return readBinaryFile(ifs, filename); -} - -// read binary object from stdin -BinaryObject readFile(bool fromStdin) -{ - // read from stdin -// if (fromStdin) - return readBinaryFile(cin, (string)_("")); -} - -// write binary object to file -void writeBinaryFile(ostream &ofs, string filename, BinaryObject bnw) -{ - // well just dump the data - ofs.write((char*)bnw._data, bnw._size); -} - -// write binary object -void writeFile(string filename, BinaryObject obj) -{ - // open the file - ofstream ofs(filename.c_str()); - if (ofs.bad()) - throw GsmException(stringPrintf(_("cannot open file '%s'"), - filename.c_str()), - OSError); - // and read the file - writeBinaryFile(ofs, filename, obj); -} - -// write binary object to stdout -void writeFile(bool toStdout, BinaryObject obj) -{ -// if (toStdout) - writeBinaryFile(cout, (string)_(""), obj); -} - -// *** main program - -int main(int argc, char *argv[]) -{ - try - { - // handle command line options - string destination; - string source; - string baudrate; - string type; - string subtype; - int subtypeN; - bool verbose = false; - string initString = DEFAULT_INIT_STRING; - bool swHandshake = false; - Ref sourceMeTa, destMeTa; - BinaryObject sourceObject; - - int opt; - int dummy; - while((opt = getopt_long(argc, argv, "XI:s:d:b:hvVt:i:", longOpts, - &dummy)) - != -1) - switch (opt) - { - case 'X': - swHandshake = true; - break; - case 'I': - initString = optarg; - break; - case 'V': - verbose = true; - break; - case 't': - type = optarg; - break; - case 'i': - subtype = optarg; - subtypeN = atoi(optarg); - break; - case 'd': - destination = optarg; - break; - case 's': - source = optarg; - break; - case 'b': - baudrate = optarg; - break; - case 'v': - cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), - VERSION, __DATE__) << endl; - exit(0); - break; - case 'h': - cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]" - "[-I init string]\n" - " [-p phonebook name][-s device or file]" - "[-t charset][-v]" - "[-V][-y][-X]") << endl - << endl - << _(" -b, --baudrate baudrate to use for device " - "(default: 38400)") - << endl - << _(" -c, --copy copy source entries to destination") - << endl - << _(" -d, --destination sets the destination device to " - "connect \n" - " to, or the file to write") << endl - << _(" -D, --destination-backend sets the destination backend") - << endl - << _(" -h, --help prints this message") << endl - << _(" -i, --index takes index positions into account") - << endl - << _(" -I, --init device AT init sequence") << endl - << _(" -p, --phonebook name of phonebook to use") << endl - << _(" -s, --source sets the source device to connect to,\n" - " or the file to read") << endl - << _(" -t, --charset sets the character set to use for\n" - " phonebook entries") << endl - << _(" -S, --source-backend sets the source backend") - << endl - << _(" -v, --version prints version and exits") << endl - << _(" -V, --verbose print detailed progress messages") - << endl - << _(" -X, --xonxoff switch on software handshake") << endl - << _(" -y, --synchronize synchronize destination with source\n" - " entries (destination is overwritten)\n" - " (see gsmpb(1) for details)") - << endl << endl; - exit(0); - break; - case '?': - throw GsmException(_("unknown option"), ParameterError); - break; - } - - // check if all parameters all present - if (destination == "" || source == "") - throw GsmException(_("both source and destination must be given"), - ParameterError); - - // start accessing source mobile phone or file - if (source == "-") - sourceObject = readFile(true); - else if (isFile(source)) - sourceObject = readFile(source); - else - { - if (type == "") - throw GsmException(_("type be given"), ParameterError); - if (subtype == "") - throw GsmException(_("subtype be given"), ParameterError); - - sourceMeTa = new SieMe(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (source, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), initString, - swHandshake)); - sourceObject = sourceMeTa->getBinary(type, subtypeN); - } - - // make sure destination.c_str file exists - if (destination != "") - { - try - { - ofstream f(destination.c_str(), ios::out | ios::app); - } - catch (exception) - { - } - } - - // start accessing destination mobile phone or file - if (destination == "-") - writeFile(true, sourceObject); - else if (isFile(destination)) - writeFile(destination, sourceObject); - else - { - if (type == "") - throw GsmException(_("type must be given"), ParameterError); - if (subtype == "") - throw GsmException(_("subtype must be given"), ParameterError); - - destMeTa = new SieMe(new -#ifdef WIN32 - Win32SerialPort -#else - UnixSerialPort -#endif - (destination, - baudrate == "" ? DEFAULT_BAUD_RATE : - baudRateStrToSpeed(baudrate), initString, - swHandshake)); - destMeTa->setBinary(type, subtypeN, sourceObject); - } - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/g41.patch b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/g41.patch deleted file mode 100644 index 4c33e6a7d2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/g41.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- ./gsmlib/gsm_me_ta.h~ 2006-03-09 19:15:59.000000000 +0000 -+++ ./gsmlib/gsm_me_ta.h 2006-03-09 19:16:31.000000000 +0000 -@@ -291,8 +291,8 @@ - // 3 disable phone receive RF circuits only - // 4 disable phone both transmit and receive RF circuits - // 5...127 implementation-defined -- int MeTa::getFunctionalityLevel() throw(GsmException); -- void MeTa::setFunctionalityLevel(int level) throw(GsmException); -+ int getFunctionalityLevel() throw(GsmException); -+ void setFunctionalityLevel(int level) throw(GsmException); - - // return battery charge status (+CBC): - // 0 ME is powered by the battery -@@ -386,13 +386,13 @@ - void setCallWaitingLockStatus(FacilityClass cl, - bool lock)throw(GsmException); - -- void MeTa::setCLIRPresentation(bool enable) throw(GsmException); -+ void setCLIRPresentation(bool enable) throw(GsmException); - //(+CLIR) - - // 0:according to the subscription of the CLIR service - // 1:CLIR invocation - // 2:CLIR suppression -- int MeTa::getCLIRPresentation() throw(GsmException); -+ int getCLIRPresentation() throw(GsmException); - - friend class Phonebook; - friend class SMSStore; diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsm_config.h.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsm_config.h.in deleted file mode 100644 index 4ed31e1464..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsm_config.h.in +++ /dev/null @@ -1,344 +0,0 @@ -/* gsm_config.h.in. Generated from configure.in by autoheader. */ -/* used by libtool*/ -#define PACKAGE 0 - -/* used by libtool*/ -#define VERSION 0 - -/* Define if getopt_long() available */ -#undef HAVE_GETOPT_LONG - -/* Define if alarm() available */ -#undef HAVE_ALARM - -/* Define if netinet/in.h header available */ -#undef HAVE_NETINET_IN_H - -/* Define if string.h header available */ -#undef HAVE_STRING_H - -/* Define for NLS */ -#undef ENABLE_NLS -#undef HAVE_CATGETS -#undef HAVE_GETTEXT -#undef HAVE_LC_MESSAGES -#undef HAVE_STPCPY - -/* Define LOCALEDIR */ -#define LOCALEDIR "/usr/share/locale" - -/* Define if libintl.h header available */ -#undef HAVE_LIBINTL_H - -/* Define if vsnprintf() function available */ -#undef HAVE_VSNPRINTF - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -#undef C_ALLOCA - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -#undef ENABLE_NLS - -/* Define to 1 if you have `alloca', as a function or macro. */ -#undef HAVE_ALLOCA - -/* Define to 1 if you have and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ARGZ_H - -/* Define to 1 if you have the `asprintf' function. */ -#undef HAVE_ASPRINTF - -/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -#undef HAVE_CFLOCALECOPYCURRENT - -/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -#undef HAVE_CFPREFERENCESCOPYAPPVALUE - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -#undef HAVE_DCGETTEXT - -/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you - don't. */ -#undef HAVE_DECL_FEOF_UNLOCKED - -/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if - you don't. */ -#undef HAVE_DECL_FGETS_UNLOCKED - -/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you - don't. */ -#undef HAVE_DECL_GETC_UNLOCKED - -/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you - don't. */ -#undef HAVE_DECL__SNPRINTF - -/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you - don't. */ -#undef HAVE_DECL__SNWPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the `fwprintf' function. */ -#undef HAVE_FWPRINTF - -/* Define to 1 if you have the `getcwd' function. */ -#undef HAVE_GETCWD - -/* Define to 1 if you have the `getegid' function. */ -#undef HAVE_GETEGID - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getgid' function. */ -#undef HAVE_GETGID - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define if the GNU gettext() function is already present or preinstalled. */ -#undef HAVE_GETTEXT - -/* Define to 1 if you have the `getuid' function. */ -#undef HAVE_GETUID - -/* Define if you have the iconv() function. */ -#undef HAVE_ICONV - -/* Define if you have the 'intmax_t' type in or . */ -#undef HAVE_INTMAX_T - -/* Define if exists and doesn't clash with . */ -#undef HAVE_INTTYPES_H - -/* Define if exists, doesn't clash with , and - declares uintmax_t. */ -#undef HAVE_INTTYPES_H_WITH_UINTMAX - -/* Define if you have and nl_langinfo(CODESET). */ -#undef HAVE_LANGINFO_CODESET - -/* Define if your file defines LC_MESSAGES. */ -#undef HAVE_LC_MESSAGES - -/* Define to 1 if you have the `intl' library (-lintl). */ -#undef HAVE_LIBINTL - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBINTL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define if you have the 'long double' type. */ -#undef HAVE_LONG_DOUBLE - -/* Define if you have the 'long long' type. */ -#undef HAVE_LONG_LONG - -/* Define to 1 if you have the header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `mempcpy' function. */ -#undef HAVE_MEMPCPY - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the `munmap' function. */ -#undef HAVE_MUNMAP - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NL_TYPES_H - -/* Define if your printf() function supports format strings with positions. */ -#undef HAVE_POSIX_PRINTF - -/* Define to 1 if you have the `putenv' function. */ -#undef HAVE_PUTENV - -/* Define to 1 if you have the `setenv' function. */ -#undef HAVE_SETENV - -/* Define to 1 if you have the `setlocale' function. */ -#undef HAVE_SETLOCALE - -/* Define to 1 if you have the `snprintf' function. */ -#undef HAVE_SNPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDDEF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define if exists, doesn't clash with , and declares - uintmax_t. */ -#undef HAVE_STDINT_H_WITH_UINTMAX - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `stpcpy' function. */ -#undef HAVE_STPCPY - -/* Define to 1 if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - -/* Define to 1 if you have the `strdup' function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strtoul' function. */ -#undef HAVE_STRTOUL - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the `tsearch' function. */ -#undef HAVE_TSEARCH - -/* Define if you have the 'uintmax_t' type in or . */ -#undef HAVE_UINTMAX_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define if you have the 'unsigned long long' type. */ -#undef HAVE_UNSIGNED_LONG_LONG - -/* Define if you have the 'wchar_t' type. */ -#undef HAVE_WCHAR_T - -/* Define to 1 if you have the `wcslen' function. */ -#undef HAVE_WCSLEN - -/* Define if you have the 'wint_t' type. */ -#undef HAVE_WINT_T - -/* Define to 1 if you have the `__argz_count' function. */ -#undef HAVE___ARGZ_COUNT - -/* Define to 1 if you have the `__argz_next' function. */ -#undef HAVE___ARGZ_NEXT - -/* Define to 1 if you have the `__argz_stringify' function. */ -#undef HAVE___ARGZ_STRINGIFY - -/* Define to 1 if you have the `__fsetlocking' function. */ -#undef HAVE___FSETLOCKING - -/* Define as const if the declaration of iconv() needs const. */ -#undef ICONV_CONST - -/* Define if integer division by zero raises signal SIGFPE. */ -#undef INTDIV0_RAISES_SIGFPE - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define if exists and defines unusable PRI* macros. */ -#undef PRI_MACROS_BROKEN - -/* The size of a `unsigned int', as computed by sizeof. */ -#undef SIZEOF_UNSIGNED_INT - -/* The size of a `unsigned long int', as computed by sizeof. */ -#undef SIZEOF_UNSIGNED_LONG_INT - -/* The size of a `unsigned short int', as computed by sizeof. */ -#undef SIZEOF_UNSIGNED_SHORT_INT - -/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -#undef SIZE_MAX - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -#undef STACK_DIRECTION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `long' if does not define. */ -#undef off_t - -/* Define as the type of the result of subtracting two pointers, if the system - doesn't define it. */ -#undef ptrdiff_t - -/* Define to empty if the C compiler doesn't support this keyword. */ -#undef signed - -/* Define to `unsigned' if does not define. */ -#undef size_t - -/* Define to unsigned long or unsigned long long if and - don't define. */ -#undef uintmax_t diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.dirs b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.dirs deleted file mode 100644 index 7bc765edd6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.dirs +++ /dev/null @@ -1,11 +0,0 @@ -var/spool/sms/queue1 -var/spool/sms/queue2 -var/spool/sms/queue3 -var/spool/sms/sent1 -var/spool/sms/sent2 -var/spool/sms/sent3 -var/spool/sms/failed1 -var/spool/sms/failed2 -var/spool/sms/failed3 -var/spool/sms/tmp -var/run/gsm-utils diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.postinst b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.postinst deleted file mode 100644 index cc623b611b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.postinst +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -e - -# create gsmsms group if necessary. -if ! grep -q ^gsmsms: /etc/group; then -# echo Adding system group: gsmsms. - addgroup gsmsms -fi - -# create gsmsms user if necessary. -if ! grep -q ^gsmsms: /etc/passwd; then -# echo Adding system user: gsmsms. - adduser --system --ingroup gsmsms \ - --no-create-home --home /var/spool/sms gsmsms -fi - -# allow gsmsms to use serial lines -if ! groups gsmsms | grep -q dialout ; then - adduser gsmsms dialout -fi - -# echo Updating spool directory structure: /var/spool/sms -chown -R gsmsms:gsmsms /var/spool/sms /var/run/gsm-utils -chmod 700 /var/spool/sms/* -chmod 750 /var/spool/sms -chmod 730 /var/spool/sms/queue* /var/spool/sms/tmp - -# Add the rest automatically.. -#DEBHELPER# diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.prerm b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.prerm deleted file mode 100644 index 34c947e93e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.prerm +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -e - -deluser gsmsms || true -delgroup gsmsms || true - -# Add the rest automatically.. -#DEBHELPER# diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.undocumented b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.undocumented deleted file mode 100644 index 62d096021d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib-1.10.debmg/debian/gsm-utils.undocumented +++ /dev/null @@ -1,2 +0,0 @@ -gsmsmsspool.1 -gsmsmsrequeue.8 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib.spec b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib.spec deleted file mode 100644 index c262954cc5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib.spec +++ /dev/null @@ -1,92 +0,0 @@ -%define LIBVER 1.0.4 -Summary: Library to access GSM mobile phones through GSM modems -Name: gsmlib -Version: 1.10 -Release: 1 -Source: gsmlib-%{version}.tar.gz -Group: System Environment/Libraries -Copyright: GNU LIBRARY GENERAL PUBLIC LICENSE -URL: http://www.pxh.de/fs/gsmlib/ -Vendor: Peter Hofmann -Buildroot: /var/tmp/gsmlib-root - -%package devel -Summary: Development tools for programs which will use the gsmlib library. -Group: Development/Libraries -Requires: gsmlib - -%package ext -Summary: Extensions to gsmlib to support non-standard phone features. -Group: Development/Libraries -Requires: gsmlib - -%description -This distribution contains a library to access -GSM mobile phones through GSM modems. Features include: - * modification of phonebooks stored in the - mobile phone or on the SIM card - * reading and writing of SMS messages stored in - the mobile phone - * sending and reception of SMS messages -Additionally, some simple command line programs are -provided to use these functionalities. - -%description devel -The gsmlib-devel package includes the header files and static libraries -necessary for developing programs which use the gsmlib library. - -%description ext -The extension package of gsmlib contains programs, libraries, and -documentation to support non-standard features of GSM phones. The -following phones/phone types are currently supported: - * Siemens GSM phones - -%prep -%setup - -%build -CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr -make - -%install -make DESTDIR="$RPM_BUILD_ROOT" install - -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%defattr(-,root,root) -/usr/lib/libgsmme.so -/usr/lib/libgsmme.so.%{LIBVER} -/usr/bin/gsmsmsstore -/usr/bin/gsmctl -/usr/bin/gsmsmsd -/usr/bin/gsmpb -/usr/bin/gsmsendsms -/usr/man/man1/gsmctl.1.gz -/usr/man/man7/gsminfo.7.gz -/usr/man/man1/gsmpb.1.gz -/usr/man/man1/gsmsendsms.1.gz -/usr/man/man8/gsmsmsd.8.gz -/usr/man/man1/gsmsmsstore.1.gz -/usr/share/locale/de/LC_MESSAGES/gsmlib.mo - -%doc README INSTALL ABOUT-NLS AUTHORS COPYING NEWS TODO -%doc doc/README.NLS doc/README.developers doc/FAQ ChangeLog - -%files devel -%defattr(-,root,root) -/usr/lib/libgsmme.a -/usr/include/gsmlib - -%files ext -/usr/bin/gsmsiectl -/usr/bin/gsmsiexfer -/usr/lib/libgsmext.so -/usr/lib/libgsmext.so.%{LIBVER} - -%doc ext/README.sieme diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.am deleted file mode 100644 index 12d6948c52..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: GSM library Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 5.5.1999 -# ************************************************************************* - -INCLUDES = -I.. - -lib_LTLIBRARIES = libgsmme.la - -libgsmme_la_SOURCES = gsm_phonebook.cc gsm_util.cc gsm_unix_serial.cc \ - gsm_me_ta.cc gsm_at.cc gsm_error.cc gsm_parser.cc \ - gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \ - gsm_event.cc gsm_sorted_phonebook.cc \ - gsm_sorted_sms_store.cc gsm_nls.cc \ - gsm_sorted_phonebook_base.cc gsm_cb.cc - -gsmincludedir = $(includedir)/gsmlib - -gsminclude_HEADERS = gsm_at.h gsm_parser.h gsm_sms.h gsm_unix_serial.h \ - gsm_error.h gsm_phonebook.h gsm_sms_codec.h \ - gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \ - gsm_event.h gsm_sorted_phonebook.h \ - gsm_sorted_sms_store.h gsm_map_key.h \ - gsm_sorted_phonebook_base.h gsm_cb.h - -noinst_HEADERS = gsm_nls.h gsm_sysdep.h - -libgsmme_la_LDFLAGS = -version-info $(GSM_VERSION) - -EXTRA_DIST = gsm_win32_serial.h gsm_win32_serial.cc diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.in deleted file mode 100644 index 5e1f2477cb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/Makefile.in +++ /dev/null @@ -1,461 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: GSM library Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 5.5.1999 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -INCLUDES = -I.. - -lib_LTLIBRARIES = libgsmme.la - -libgsmme_la_SOURCES = gsm_phonebook.cc gsm_util.cc gsm_unix_serial.cc \ - gsm_me_ta.cc gsm_at.cc gsm_error.cc gsm_parser.cc \ - gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \ - gsm_event.cc gsm_sorted_phonebook.cc \ - gsm_sorted_sms_store.cc gsm_nls.cc \ - gsm_sorted_phonebook_base.cc gsm_cb.cc - - -gsmincludedir = $(includedir)/gsmlib - -gsminclude_HEADERS = gsm_at.h gsm_parser.h gsm_sms.h gsm_unix_serial.h \ - gsm_error.h gsm_phonebook.h gsm_sms_codec.h \ - gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \ - gsm_event.h gsm_sorted_phonebook.h \ - gsm_sorted_sms_store.h gsm_map_key.h \ - gsm_sorted_phonebook_base.h gsm_cb.h - - -noinst_HEADERS = gsm_nls.h gsm_sysdep.h - -libgsmme_la_LDFLAGS = -version-info $(GSM_VERSION) - -EXTRA_DIST = gsm_win32_serial.h gsm_win32_serial.cc -subdir = gsmlib -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -LTLIBRARIES = $(lib_LTLIBRARIES) - -libgsmme_la_LIBADD = -am_libgsmme_la_OBJECTS = gsm_phonebook.lo gsm_util.lo gsm_unix_serial.lo \ - gsm_me_ta.lo gsm_at.lo gsm_error.lo gsm_parser.lo gsm_sms.lo \ - gsm_sms_codec.lo gsm_sms_store.lo gsm_event.lo \ - gsm_sorted_phonebook.lo gsm_sorted_sms_store.lo gsm_nls.lo \ - gsm_sorted_phonebook_base.lo gsm_cb.lo -libgsmme_la_OBJECTS = $(am_libgsmme_la_OBJECTS) - -DEFS = @DEFS@ -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp -am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsm_at.Plo ./$(DEPDIR)/gsm_cb.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_error.Plo ./$(DEPDIR)/gsm_event.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_me_ta.Plo ./$(DEPDIR)/gsm_nls.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_parser.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_phonebook.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms_codec.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms_store.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_phonebook.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_phonebook_base.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_sms_store.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_unix_serial.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/gsm_util.Plo -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CXXFLAGS = @CXXFLAGS@ -DIST_SOURCES = $(libgsmme_la_SOURCES) -HEADERS = $(gsminclude_HEADERS) $(noinst_HEADERS) - -DIST_COMMON = $(gsminclude_HEADERS) $(noinst_HEADERS) Makefile.am \ - Makefile.in -SOURCES = $(libgsmme_la_SOURCES) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .cc .lo .o .obj -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu gsmlib/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -libLTLIBRARIES_INSTALL = $(INSTALL) -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libdir) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \ - $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \ - $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test -z "$dir" && dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libgsmme.la: $(libgsmme_la_OBJECTS) $(libgsmme_la_DEPENDENCIES) - $(CXXLINK) -rpath $(libdir) $(libgsmme_la_LDFLAGS) $(libgsmme_la_OBJECTS) $(libgsmme_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_at.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_cb.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_event.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_me_ta.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_nls.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_parser.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_phonebook.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms_codec.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms_store.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_phonebook.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_phonebook_base.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_sms_store.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_unix_serial.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_util.Plo@am__quote@ - -distclean-depend: - -rm -rf ./$(DEPDIR) - -.cc.o: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -.cc.obj: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `cygpath -w $<` - -.cc.lo: -@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -CXXDEPMODE = @CXXDEPMODE@ - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -gsmincludeHEADERS_INSTALL = $(INSTALL_HEADER) -install-gsmincludeHEADERS: $(gsminclude_HEADERS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(gsmincludedir) - @list='$(gsminclude_HEADERS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f"; \ - $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f; \ - done - -uninstall-gsmincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(gsminclude_HEADERS)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " rm -f $(DESTDIR)$(gsmincludedir)/$$f"; \ - rm -f $(DESTDIR)$(gsmincludedir)/$$f; \ - done - -ETAGS = etags -ETAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(gsmincludedir) - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-compile distclean-depend \ - distclean-generic distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: install-gsmincludeHEADERS - -install-exec-am: install-libLTLIBRARIES - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -uninstall-am: uninstall-gsmincludeHEADERS uninstall-info-am \ - uninstall-libLTLIBRARIES - -.PHONY: GTAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool distclean distclean-compile \ - distclean-depend distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am info info-am install \ - install-am install-data install-data-am install-exec \ - install-exec-am install-gsmincludeHEADERS install-info \ - install-info-am install-libLTLIBRARIES install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - tags uninstall uninstall-am uninstall-gsmincludeHEADERS \ - uninstall-info-am uninstall-libLTLIBRARIES - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.cc deleted file mode 100644 index 1c163d06e1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.cc +++ /dev/null @@ -1,444 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_at.cc -// * -// * Purpose: Utility classes for AT command sequence handling -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// GsmAt members - -bool GsmAt::matchResponse(string answer, string responseToMatch) -{ - if (answer.substr(0, responseToMatch.length()) == responseToMatch) - return true; - else - // some TAs omit the ':' at the end of the response - if (_meTa.getCapabilities()._omitsColon && - responseToMatch[responseToMatch.length() - 1] == ':' && - answer.substr(0, responseToMatch.length() - 1) == - responseToMatch.substr(0, responseToMatch.length() - 1)) - return true; - return false; -} - -string GsmAt::cutResponse(string answer, string responseToMatch) -{ - if (answer.substr(0, responseToMatch.length()) == responseToMatch) - return normalize(answer.substr(responseToMatch.length(), - answer.length() - - responseToMatch.length())); - else - // some TAs omit the ':' at the end of the response - if (_meTa.getCapabilities()._omitsColon && - responseToMatch[responseToMatch.length() - 1] == ':' && - answer.substr(0, responseToMatch.length() - 1) == - responseToMatch.substr(0, responseToMatch.length() - 1)) - return normalize(answer.substr(responseToMatch.length() - 1, - answer.length() - - responseToMatch.length() + 1)); - assert(0); - return ""; -} - -void GsmAt::throwCmeException(string s) throw(GsmException) -{ - if (matchResponse(s, "ERROR")) - throw GsmException(_("unspecified ME/TA error"), ChatError); - - bool meError = matchResponse(s, "+CME ERROR:"); - if (meError) - s = cutResponse(s, "+CME ERROR:"); - else - s = cutResponse(s, "+CMS ERROR:"); - istrstream is(s.c_str()); - int error; - is >> error; - throw GsmException(_("ME/TA error '") + - (meError ? getMEErrorText(error) : - getSMSErrorText(error)) + - "' " + - stringPrintf(_("(code %s)"), s.c_str()), - ChatError, error); -} - -GsmAt::GsmAt(MeTa &meTa) : - _meTa(meTa), _port(meTa.getPort()), _eventHandler(NULL) -{ -} - -string GsmAt::chat(string atCommand, string response, - bool ignoreErrors, bool acceptEmptyResponse) - throw(GsmException) -{ - string dummy; - return chat(atCommand, response, dummy, ignoreErrors, false, - acceptEmptyResponse); -} - -string GsmAt::chat(string atCommand, string response, string &pdu, - bool ignoreErrors, bool expectPdu, - bool acceptEmptyResponse) throw(GsmException) -{ - string s; - bool gotOk = false; // special handling for empty SMS entries - - // send AT command - putLine("AT" + atCommand); - // and gobble up CR/LF (and possibly echoed characters if echo can't be - // switched off) - // Also, some mobiles (e.g., Sony Ericsson K800i) respond to commands - // like "at+cmgf=0" with "+CMGF: 0" on success as well as the "OK" - // status -- so gobble that (but not if that sort of response was expected) - // FIXME: this is a gross hack, should be done via capabilities or sth - #include - string::size_type loc = atCommand.find( "=", 1 ); - string expect; - if (loc != string::npos) { - expect = atCommand; - expect.replace(loc, 1, " "); - expect.insert(loc, ":"); - } else { - expect = ""; - } - do - { - s = normalize(getLine()); - } - while (s.length() == 0 || s == "AT" + atCommand || - ((response.length() == 0 || !matchResponse(s, response)) && - (expect.length() > 0 && matchResponse(s, expect)))); - - // handle errors - if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:")) - if (ignoreErrors) - return ""; - else - throwCmeException(s); - if (matchResponse(s, "ERROR")) - if (ignoreErrors) - return ""; - else - throw GsmException(_("ME/TA error '' (code not known)"), - ChatError, -1); - - // return if response is "OK" and caller says this is OK - if (acceptEmptyResponse && s == "OK") - return ""; - - // handle PDU if one is expected - if (expectPdu) - { - string ps; - do - { - ps = normalize(getLine()); - } - while (ps.length() == 0 && ps != "OK"); - if (ps == "OK") - gotOk = true; - else - { - pdu = ps; - // remove trailing zero added by some devices (e.g. Falcom A2-1) - if (pdu.length() > 0 && pdu[pdu.length() - 1] == 0) - pdu.erase(pdu.length() - 1); - } - } - - // handle expected response - if (response.length() == 0) // no response expected - { - if (s == "OK") return ""; - // else fall through to error - } - else - { - string result; - // some TA/TEs don't prefix their response with the response string - // as proscribed by the standard: just handle either case - if (matchResponse(s, response)) - result = cutResponse(s, response); - else - result = s; - - if (gotOk) - return result; - else - { - // get the final "OK" - do - { - s = normalize(getLine()); - } - while (s.length() == 0); - - if (s == "OK") return result; - // else fall through to error - } - } - throw GsmException( - stringPrintf(_("unexpected response '%s' when sending 'AT%s'"), - s.c_str(), atCommand.c_str()), - ChatError); -} - -vector GsmAt::chatv(string atCommand, string response, - bool ignoreErrors) throw(GsmException) -{ - string s; - vector result; - - // send AT command - putLine("AT" + atCommand); - // and gobble up CR/LF (and possibly echoed characters if echo can't be - // switched off) - do - { - s = normalize(getLine()); - } - while (s.length() == 0 || s == "AT" + atCommand); - - // handle errors - if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:")) - if (ignoreErrors) - return result; - else - throwCmeException(s); - if (matchResponse(s, "ERROR")) - if (ignoreErrors) - return result; - else - throw GsmException(_("ME/TA error '' (code not known)"), - ChatError, -1); - - // push all lines that are not empty - // cut response prefix if it is there - // stop when an OK line is read - while (1) - { - if (s == "OK") - return result; - // some TA/TEs don't prefix their response with the response string - // as proscribed by the standard: just handle either case - if (response.length() != 0 && matchResponse(s, response)) - result.push_back(cutResponse(s, response)); - else - result.push_back(s); - // get next line - do - { - s = normalize(getLine()); - } - while (s.length() == 0); - reportProgress(); - } - - // never reached - assert(0); - return result; -} - -string GsmAt::normalize(string s) -{ - size_t start = 0, end = s.length(); - bool changed = true; - - while (start < end && changed) - { - changed = false; - if (isspace(s[start])) - { - ++start; - changed = true; - } - else - if (isspace(s[end - 1])) - { - --end; - changed = true; - } - } - return s.substr(start, end - start); -} - -string GsmAt::sendPdu(string atCommand, string response, string pdu, - bool acceptEmptyResponse) throw(GsmException) -{ - string s; - bool errorCondition; - bool retry = false; - int tries = 5; // How many error conditions do we accept - - int c; - do - { - errorCondition = false; - putLine("AT" + atCommand); - do - { - retry = false; - try - { - do - { - // read first of two bytes "> " - c = readByte(); - } - // there have been reports that some phones give spurious CRs - // LF separates CDSI messages if there are more than one - while (c == CR || c == LF); - } - catch (GsmException &e) - { - c = '-'; - errorCondition = true; // TA does not expect PDU anymore, retry - } - - if (c == '+' || c == 'E') // error or unsolicited result code - { - _port->putBack(c); - s = normalize(getLine()); - errorCondition = (s != ""); - - retry = ! errorCondition; - } - } - while (retry); - } - while (errorCondition && tries--); - - if (! errorCondition) - { - - if (c != '>' || readByte() != ' ') - throw GsmException(_("unexpected character in PDU handshake"), - ChatError); - - putLine(pdu + "\032", false); // write pdu followed by CTRL-Z - - // some phones (Ericcson T68, T39) send spurious zero characters after - // accepting the PDU - c = readByte(); - if (c != 0) - _port->putBack(c); - - // loop while empty lines (maybe with a zero, Ericsson T39m) - // or an echo of the pdu (with or without CTRL-Z) - // is read - do - { - s = normalize(getLine()); - } - while (s.length() == 0 || s == pdu || s == (pdu + "\032") || - (s.length() == 1 && s[0] == 0)); - } - - // handle errors - if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:")) - throwCmeException(s); - if (matchResponse(s, "ERROR")) - throw GsmException(_("ME/TA error '' (code not known)"), - ChatError, -1); - - // return if response is "OK" and caller says this is OK - if (acceptEmptyResponse && s == "OK") - return ""; - - if (matchResponse(s, response)) - { - string result = cutResponse(s, response); - // get the final "OK" - do - { - s = normalize(getLine()); - } - while (s.length() == 0); - - if (s == "OK") return result; - // else fall through to error - } - throw GsmException( - stringPrintf(_("unexpected response '%s' when sending 'AT%s'"), - s.c_str(), atCommand.c_str()), - ChatError); -} - -string GsmAt::getLine() throw(GsmException) -{ - if (_eventHandler == (GsmEvent*)NULL) - return _port->getLine(); - else - { - bool eventOccurred; - string result; - do - { - eventOccurred = false; - result = _port->getLine(); - string s = normalize(result); - if (matchResponse(s, "+CMT:") || - matchResponse(s, "+CBM:") || - matchResponse(s, "+CDS:") || - matchResponse(s, "+CMTI:") || - matchResponse(s, "+CBMI:") || - matchResponse(s, "+CDSI:") || - matchResponse(s, "RING") || - matchResponse(s, "NO CARRIER") || - // hack: the +CLIP? sequence returns +CLIP: n,m - // which is NOT an unsolicited result code - (matchResponse(s, "+CLIP:") && s.length() > 10)) - { - _eventHandler->dispatch(s, *this); - eventOccurred = true; - } - } - while (eventOccurred); - return result; - } -} - -void GsmAt::putLine(string line, - bool carriageReturn) throw(GsmException) -{ - _port->putLine(line, carriageReturn); - // remove empty echo line - if (carriageReturn) - getLine(); -} - -bool GsmAt::wait(GsmTime timeout) throw(GsmException) -{ - return _port->wait(timeout); -} - -int GsmAt::readByte() throw(GsmException) -{ - return _port->readByte(); -} - -GsmEvent *GsmAt::setEventHandler(GsmEvent *newHandler) -{ - GsmEvent *result = _eventHandler; - _eventHandler = newHandler; - return result; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.h deleted file mode 100644 index 96c3359425..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_at.h +++ /dev/null @@ -1,104 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_at.h -// * -// * Purpose: Utility classes for AT command sequence handling -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.5.1999 -// ************************************************************************* - -#ifndef GSM_AT_H -#define GSM_AT_H - -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // forward declarations - - class GsmEvent; - class MeTa; - - // utiliy class to handle AT sequences - - class GsmAt : public RefBase - { - protected: - MeTa &_meTa; - Ref _port; - GsmEvent *_eventHandler; - - // return true if response matches - bool matchResponse(string answer, string responseToMatch); - - // cut response and normalize - string cutResponse(string answer, string responseToMatch); - - // parse CME error contained in string and throw MeTaException - void throwCmeException(string s) throw(GsmException); - - public: - GsmAt(MeTa &meTa); - - // return MeTa object for this AT object - MeTa &getMeTa() {return _meTa;} - - // the following sequence functions recognize asynchronous messages - // from the TA and return the appropriate event - - // send AT command, wait for response response, returns response line - // without response match - // if response == "" only an OK is expected - // white space at beginning or end are removed - // +CME ERROR or ERROR raises exception (if ignoreErrors == true) - // additionally, accept empty responses (just an OK) - // if acceptEmptyResponse == true - // in this case an empty string is returned - string chat(string atCommand = "", - string response = "", - bool ignoreErrors = false, - bool acceptEmptyResponse = false) throw(GsmException); - - // same as chat() above but also get pdu if expectPdu == true - string chat(string atCommand, - string response, - string &pdu, - bool ignoreErrors = false, - bool expectPdu = true, - bool acceptEmptyResponse = false) throw(GsmException); - - // same as above, but expect several response lines - vector chatv(string atCommand = "", - string response = "", - bool ignoreErrors = false) - throw(GsmException); - - // removes whitespace at beginning and end of string - string normalize(string s); - - // send pdu (wait for and send - // at the end - // return text after response - string sendPdu(string atCommand, string response, string pdu, - bool acceptEmptyResponse = false) throw(GsmException); - - // functions from class Port - string getLine() throw(GsmException); - void putLine(string line, - bool carriageReturn = true) throw(GsmException); - bool wait(GsmTime timeout) throw(GsmException); - int readByte() throw(GsmException); - - // set event handler class, return old one - GsmEvent *setEventHandler(GsmEvent *newHandler); - }; -}; - -#endif // GSM_AT_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.cc deleted file mode 100644 index 37c0e4aae7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.cc +++ /dev/null @@ -1,176 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_cb.cc -// * -// * Purpose: Cell Broadcast Message Implementation -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.8.2001 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// local constants - -static const string dashes = -"---------------------------------------------------------------------------"; - -// CBDataCodingScheme members - -CBDataCodingScheme::CBDataCodingScheme(unsigned char dcs) : _dcs(dcs) -{ - if ((_dcs & 0xf0) <= 0x30) // bits 7..4 in the range 0000..0011 - if ((_dcs & 0x30) == 0) - _language = (Language)_dcs; - else - _language = Unknown; -} - -string CBDataCodingScheme::toString() const -{ - string result; - if (compressed()) result += _("compressed "); - switch (getLanguage()) - { - case German: - result += _("German"); - break; - case English: - result += _("English"); - break; - case Italian: - result += _("Italian"); - break; - case French: - result += _("French"); - break; - case Spanish: - result += _("Spanish"); - break; - case Dutch: - result += _("Dutch"); - break; - case Swedish: - result += _("Swedish"); - break; - case Danish: - result += _("Danish"); - break; - case Portuguese: - result += _("Portuguese"); - break; - case Finnish: - result += _("Finnish"); - break; - case Norwegian: - result += _("Norwegian"); - break; - case Greek: - result += _("Greek"); - break; - case Turkish: - result += _("Turkish"); - break; - } - result += " "; - switch (getAlphabet()) - { - case DCS_DEFAULT_ALPHABET: - result += _("default alphabet"); - break; - case DCS_EIGHT_BIT_ALPHABET: - result += _("8-bit alphabet"); - break; - case DCS_SIXTEEN_BIT_ALPHABET: - result += _("16-bit alphabet"); - break; - case DCS_RESERVED_ALPHABET: - result += _("reserved alphabet"); - break; - } - return result; -} - -// CBMessage members - -CBMessage::CBMessage(string pdu) throw(GsmException) -{ - SMSDecoder d(pdu); - _messageCode = d.getInteger(6) << 4; - _geographicalScope = (GeographicalScope)d.get2Bits(); - _updateNumber = d.getInteger(4); - _messageCode |= d.getInteger(4); - _messageIdentifier = d.getInteger(8) << 8; - _messageIdentifier |= d.getInteger(8); - _dataCodingScheme = CBDataCodingScheme(d.getOctet()); - _totalPageNumber = d.getInteger(4); - _currentPageNumber = d.getInteger(4); - - // the values 82 and 93 come from ETSI GSM 03.41, section 9.3 - d.markSeptet(); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - { - _data = d.getString(93); - _data = gsmToLatin1(_data); - } - else - { - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * 82); - d.getOctets(s, 82); - _data.assign((char*)s, (unsigned int)82); - } -} - -string CBMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: CB") << endl - << _("Geographical scope: "); - switch (_geographicalScope) - { - case CellWide: - os << "Cell wide" << endl; - break; - case PLMNWide: - os << "PLMN wide" << endl; - break; - case LocationAreaWide: - os << "Location area wide" << endl; - break; - case CellWide2: - os << "Cell wide (2)" << endl; - break; - } - // remove trailing \r characters for output - string data = _data; - string::iterator i; - for (i = data.end(); i > data.begin() && *(i - 1) == '\r'; - --i); - data.erase(i, data.end()); - - os << _("Message Code: ") << _messageCode << endl - << _("Update Number: ") << _updateNumber << endl - << _("Message Identifer: ") << _messageIdentifier << endl - << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl - << _("Total page number: ") << _totalPageNumber << endl - << _("Current page number: ") << _currentPageNumber << endl - << _("Data: '") << data << "'" << endl - << dashes << endl << endl << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.h deleted file mode 100644 index 3457c8105c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_cb.h +++ /dev/null @@ -1,106 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_cb.h -// * -// * Purpose: Cell Broadcast Message Implementation -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.8.2001 -// ************************************************************************* - -#ifndef GSM_CB_H -#define GSM_CB_H - -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // representation of DataCodingScheme - // The data coding scheme is described in detail in ETSI GSM 03.38, section 5 - // This class reuses the DCS_* constants from DataCodingScheme in - // gsm_sms_codec - - class CBDataCodingScheme - { - public: - enum Language {German = 0, English = 1, Italian = 2, French = 3, - Spanish = 4, Dutch = 5, Swedish = 6, Danish = 7, - Portuguese = 8, Finnish = 9, Norwegian = 10, Greek = 11, - Turkish = 12, Unknown = 1000}; - - private: - unsigned char _dcs; - Language _language; - - public: - // initialize with data coding scheme octet - CBDataCodingScheme(unsigned char dcs); - - // default constructor - CBDataCodingScheme() : _dcs(DCS_DEFAULT_ALPHABET), _language(English) {} - - // return language of CBM - Language getLanguage() const {return _language;} - - // return compression level (if language == Unknown) - bool compressed() const {return (_dcs & DCS_COMPRESSED) == DCS_COMPRESSED;} - - // return type of alphabet used - // (DCS_DEFAULT_ALPHABET, DCS_EIGHT_BIT_ALPHABET, DCS_SIXTEEN_BIT_ALPHABET, - // DCS_RESERVED_ALPHABET) - unsigned char getAlphabet() const - {return _language == Unknown ? _dcs & (3 << 2) : DCS_DEFAULT_ALPHABET;} - - // create textual representation of CB data coding scheme - string toString() const; - }; - - // representation of Cell Broadcast message (CBM) - // The CBM format is described in detail in ETSI GSM 03.41, section 9.3 - - class CBMessage : public RefBase - { - public: - enum GeographicalScope {CellWide, PLMNWide, LocationAreaWide, - CellWide2}; - - private: - // fields parsed from the CB TPDU - GeographicalScope _geographicalScope; - int _messageCode; - int _updateNumber; - int _messageIdentifier; - CBDataCodingScheme _dataCodingScheme; - int _totalPageNumber; - int _currentPageNumber; - string _data; - - public: - // constructor with given pdu - CBMessage(string pdu) throw(GsmException); - - // accessor functions - GeographicalScope getGeographicalScope() const {return _geographicalScope;} - int getMessageCode() const {return _messageCode;} - int getUpdateNumber() const {return _updateNumber;} - int getMessageIdentifier() const {return _messageIdentifier;} - CBDataCodingScheme getDataCodingScheme() const {return _dataCodingScheme;} - int getTotalPageNumber() const {return _totalPageNumber;} - int getCurrentPageNumber() const {return _currentPageNumber;} - string getData() const {return _data;} - - // create textual representation of CBM - string toString() const; - }; - - // some useful typdefs - typedef Ref CBMessageRef; -}; - -#endif // GSM_CB_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.cc deleted file mode 100644 index 2cf9179ede..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.cc +++ /dev/null @@ -1,424 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_error.cc -// * -// * Purpose: Error codes and error handling functions -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 11.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -string gsmlib::getMEErrorText(const int errorCode) throw(GsmException) -{ - switch (errorCode) - { - case ME_PHONE_FAILURE: - return _("phone failure"); - break; - case ME_NO_CONNECTION_TO_PHONE: - return _("no connection to phone"); - break; - case ME_PHONE_ADAPTOR_LINK_RESERVED: - return _("phone adaptor link reserved"); - break; - case ME_OPERATION_NOT_ALLOWED: - return _("operation not allowed"); - break; - case ME_OPERATION_NOT_SUPPORTED: - return _("operation not supported"); - break; - case ME_PH_SIM_PIN_REQUIRED: - return _("ph SIM PIN required"); - break; - case ME_SIM_NOT_INSERTED: - return _("SIM not inserted"); - break; - case ME_SIM_PIN_REQUIRED: - return _("SIM PIN required"); - break; - case ME_SIM_PUK_REQUIRED: - return _("SIM PUK required"); - break; - case ME_SIM_FAILURE: - return _("SIM failure"); - break; - case ME_SIM_BUSY: - return _("SIM busy"); - break; - case ME_SIM_WRONG: - return _("SIM wrong"); - break; - case ME_INCORRECT_PASSWORD: - return _("incorrect password"); - break; - case ME_SIM_PIN2_REQUIRED: - return _("SIM PIN2 required"); - break; - case ME_SIM_PUK2_REQUIRED: - return _("SIM PUK2 required"); - break; - case ME_MEMORY_FULL: - return _("memory full"); - break; - case ME_INVALID_INDEX: - return _("invalid index"); - break; - case ME_NOT_FOUND: - return _("not found"); - break; - case ME_MEMORY_FAILURE: - return _("memory failure"); - break; - case ME_TEXT_STRING_TOO_LONG: - return _("text string too long"); - break; - case ME_INVALID_CHARACTERS_IN_TEXT_STRING: - return _("invalid characters in text string"); - break; - case ME_DIAL_STRING_TOO_LONG: - return _("dial string too long"); - break; - case ME_INVALID_CHARACTERS_IN_DIAL_STRING: - return _("invalid characters in dial string"); - break; - case ME_NO_NETWORK_SERVICE: - return _("no network service"); - break; - case ME_NETWORK_TIMEOUT: - return _("network timeout"); - break; - case ME_UNKNOWN: - return _("unknown"); - break; - default: - throw GsmException(stringPrintf(_("invalid ME error %d"), errorCode), - OtherError); - } -} - -string gsmlib::getSMSErrorText(const int errorCode) throw(GsmException) -{ - switch (errorCode) - { - case SMS_UNASSIGNED_OR_UNALLOCATED_NUMBER: - return _("Unassigned (unallocated) number"); - break; - case SMS_OPERATOR_DETERMINED_BARRING: - return _("Operator determined barring"); - break; - case SMS_CALL_BARRED: - return _("Call barred"); - break; - case SMS_NETWORK_FAILURE: - return _("Network failure"); - break; - case SMS_SHORT_MESSAGE_TRANSFER_REJECTED: - return _("Short message transfer rejected"); - break; - case SMS_CONGESTION: - case SMS_CONGESTION2: - return _("Congestion"); - break; - case SMS_DESTINATION_OUT_OF_SERVICE: - return _("Destination out of service"); - break; - case SMS_UNIDENTIFIED_SUBSCRIBER: - return _("Unidentified subscriber"); - break; - case SMS_FACILITY_REJECTED: - return _("Facility rejected"); - break; - case SMS_UNKNOWN_SUBSCRIBER: - return _("Unknown subscriber"); - break; - case SMS_NETWORK_OUT_OF_ORDER: - return _("Network out of order"); - break; - case SMS_TEMPORARY_FAILURE: - return _("Temporary failure"); - break; - case SMS_RESOURCES_UNAVAILABLE_UNSPECIFIED: - return _("Resources unavailable, unspecified"); - break; - case SMS_REQUESTED_FACILITY_NOT_SUBSCRIBED: - return _("Requested facility not subscribed"); - break; - case SMS_REQUESTED_FACILITY_NOT_IMPLEMENTED: - return _("Requested facility not implemented"); - break; - case SMS_INVALID_TRANSACTION_IDENTIFIER: - return _("Invalid Transaction Identifier"); - break; - case SMS_SEMANTICALLY_INCORRECT_MESSAGE: - return _("Semantically incorrect message"); - break; - case SMS_INVALID_MANDATORY_INFORMATION: - return _("Invalid mandatory information"); - break; - case SMS_MESSAGE_TYPE_NONEXISTENT_OR_NOT_IMPLEMENTED: - return _("Message type non-existent or not implemented"); - break; - case SMS_MESSAGE_NOT_COMPATIBLE_WITH_SHORT_MESSAGE_PROTOCOL_STATE: - return _("Message not compatible with short message protocol state"); - break; - case SMS_INFORMATION_ELEMENT_NONEXISTENT_OR_NOT_IMPLEMENTED: - return _("Information element non-existent or not implemented"); - break; - case SMS_UNSPECIFIED_PROTOCOL_ERROR: - return _("Protocol error, unspecified"); - break; - case SMS_UNSPECIFIED_INTERWORKING_ERROR: - return _("Interworking, unspecified"); - break; - case SMS_TELEMATIC_INTERWORKING_NOT_SUPPORTED: - return _("Telematic interworking not supported"); - break; - case SMS_SHORT_MESSAGE_TYPE_0_NOT_SUPPORTED: - return _("Short message Type 0 not supported"); - break; - case SMS_CANNOT_REPLACE_SHORT_MESSAGE: - return _("Cannot replace short message"); - break; - case SMS_UNSPECIFIED_TP_PID_ERROR: - return _("Unspecified TP-PID error"); - break; - case SMS_DATA_CODING_SCHEME_NOT_SUPPORTED: - return _("Data coding scheme (alphabet) not supported"); - break; - case SMS_MESSAGE_CLASS_NOT_SUPPORTED: - return _("Message class not supported"); - break; - case SMS_UNSPECIFIEC_TP_DCS_ERROR: - return _("Unspecifiec TP-DCS error"); - break; - case SMS_COMMAND_CANNOT_BE_ACTIONED: - return _("Command cannot be actioned"); - break; - case SMS_COMMAND_UNSUPPORTED: - return _("Command unsupported"); - break; - case SMS_UNSPECIFIED_TP_COMMAND_ERROR: - return _("Unspecified TP-Command error"); - break; - case SMS_TPDU_NOT_SUPPORTED: - return _("TPDU not supported"); - break; - case SMS_SC_BUSY: - return _("SC busy"); - break; - case SMS_NO_SC_SUBSCRIPTION: - return _("No SC subscription"); - break; - case SMS_SC_SYSTEM_FAILURE: - return _("SC system failure"); - break; - case SMS_INVALID_SME_ADDRESS: - return _("Invalid SME address"); - break; - case SMS_DESTINATION_SME_BARRED: - return _("Destination SME barred"); - break; - case SMS_SM_REJECTED_DUPLICATED_SM: - return _("SM Rejected-Duplicated SM"); - break; - case SMS_SIM_SMS_STORAGE_FULL: - return _("SIM SMS storage full"); - break; - case SMS_NO_SMS_STORAGE_CAPABILITY_IN_SIM: - return _("No SMS storage capability in SIM"); - break; - case SMS_ERROR_IN_MS: - return _("Error in MS"); - break; - case SMS_MEMORY_CAPACITY_EXCEED: - return _("Memory Capacity Exceed"); - break; - case SMS_UNSPECIFIED_ERROR_CAUSE: - return _("Unspecified error cause"); - break; - case SMS_ME_FAILURE: - return _("ME failure"); - break; - case SMS_SMS_SERVICE_OF_ME_RESERVED: - return _("SMS service of ME reserved"); - break; - case SMS_OPERATION_NOT_ALLOWED: - return _("operation not allowed"); - break; - case SMS_OPERATION_NOT_SUPPORTED: - return _("operation not supported"); - break; - case SMS_INVALID_PDU_MODE_PARAMETER: - return _("invalid PDU mode parameter"); - break; - case SMS_INVALID_TEXT_MODE_PARAMETER: - return _("invalid text mode parameter"); - break; - case SMS_SIM_NOT_INSERTED: - return _("SIM not inserted"); - break; - case SMS_SIM_PIN_REQUIRED: - return _("SIM PIN required"); - break; - case SMS_PH_SIM_PIN_REQUIRED: - return _("PH-SIM PIN required"); - break; - case SMS_SIM_FAILURE: - return _("SIM failure"); - break; - case SMS_SIM_BUSY: - return _("SIM busy"); - break; - case SMS_SIM_WRONG: - return _("SIM wrong"); - break; - case SMS_SIM_PUK_REQUIRED: - return _("SIM PUK required"); - break; - case SMS_SIM_PIN2_REQUIRED: - return _("SIM PIN2 required"); - break; - case SMS_SIM_PUK2_REQUIRED: - return _("SIM PUK2 required"); - break; - case SMS_MEMORY_FAILURE: - return _("memory failure"); - break; - case SMS_INVALID_MEMORY_INDEX: - return _("invalid memory index"); - break; - case SMS_MEMORY_FULL: - return _("memory full"); - break; - case SMS_SMSC_ADDRESS_UNKNOWN: - return _("SMSC address unknown"); - break; - case SMS_NO_NETWORK_SERVICE: - return _("no network service"); - break; - case SMS_NETWORK_TIMEOUT: - return _("network timeout"); - break; - case SMS_NO_CNMA_ACKNOWLEDGEMENT_EXPECTED: - return _("no +CNMA acknowledgement expected"); - break; - case SMS_UNKNOWN_ERROR: - return _("unknown error"); - break; - default: - throw GsmException(stringPrintf(_("invalid SMS error %d"), errorCode), - OtherError); - } -} - -string gsmlib::getSMSStatusString(unsigned char status) -{ - string result; - if (status < SMS_STATUS_TEMPORARY_BIT) - { - switch (status) - { - case SMS_STATUS_RECEIVED: - result = _("Short message received by the SME"); - break; - case SMS_STATUS_FORWARDED: - result = _("Short message forwarded by the SC to the SME but the SC " - "is unable to confirm delivery"); - break; - case SMS_STATUS_SM_REPLACES: - result = _("Short message replaced by the SC"); - break; - default: - result = _("reserved"); - break; - } - return result; - } - else if (status & SMS_STATUS_TEMPORARY_BIT) - { - switch (status & ~(SMS_STATUS_TEMPORARY_BIT | SMS_STATUS_PERMANENT_BIT)) - { - case SMS_STATUS_CONGESTION: - result = _("Congestion"); - break; - case SMS_STATUS_SME_BUSY: - result = _("SME busy"); - break; - case SMS_STATUS_NO_RESPONSE_FROM_SME: - result = _("No response from SME"); - break; - case SMS_STATUS_SERVICE_REJECTED: - result = _("Service rejected"); - break; - case SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE: - result = _("Quality of service not available"); - break; - case SMS_STATUS_ERROR_IN_SME: - result = _("Error in SME"); - break; - default: - result = _("reserved"); - break; - } - if (status & SMS_STATUS_PERMANENT_BIT) - return result + _(" (Temporary error, SC is not making any " - "more transfer attempts)"); - else - return result + _(" (Temporary error, SC still trying to " - "transfer SM)"); - } - else - { - switch (status & ~SMS_STATUS_PERMANENT_BIT) - { - case SMS_STATUS_REMOTE_PROCECURE_ERROR: - result = _("Remote Procedure Error"); - break; - case SMS_STATUS_INCOMPATIBLE_DESTINATION: - result = _("Incompatible destination"); - break; - case SMS_STATUS_CONNECTION_REJECTED_BY_SME: - result = _("Connection rejected by SME"); - break; - case SMS_STATUS_NOT_OBTAINABLE: - result = _("Not obtainable"); - break; - case SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE: - result = _("Quality of service not available"); - break; - case SMS_STATUS_NO_INTERWORKING_AVAILABLE: - result = _("No interworking available"); - break; - case SMS_STATUS_SM_VALIDITY_PERDIOD_EXPIRED: - result = _("SM validity period expired"); - break; - case SMS_STATUS_SM_DELETED_BY_ORIGINATING_SME: - result = _("SM deleted by originating SME"); - break; - case SMS_STATUS_SM_DELETED_BY_ADMINISTRATION: - result = _("SM deleted by SC administration"); - break; - case SMS_STATUS_SM_DOES_NOT_EXIST: - result = _("SM does not exit"); - break; - default: - result = _("reserved"); - break; - } - return result + _(" (Permanent Error, SC is not making any " - "more transfer attempts)"); - } -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.h deleted file mode 100644 index 5dc96538e3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_error.h +++ /dev/null @@ -1,209 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_error.h -// * -// * Purpose: Error codes and error handling functions -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.5.1999 -// ************************************************************************* - -#ifndef GSM_ERROR_H -#define GSM_ERROR_H - -#include -#include - -using namespace std; - -namespace gsmlib -{ - // different classes of GSM errors - enum GsmErrorClass{OSError, // error caused by OS call (eg. file handling) - ParserError, // error when parsing AT response - ChatError, // error in chat sequence (ME/TA/SMS error) - ParameterError, // gsmlib function called with bad params - NotImplementedError, // feature not implemented - MeTaCapabilityError, // non-existent capability in ME - SMSFormatError, // SMS format error - InterruptException, // gsmlib was interrupted() - OtherError}; // all other errors - - // all gsmlib exceptions - - class GsmException : public runtime_error - { - private: - GsmErrorClass _errorClass; - int _errorCode; - - public: - GsmException(string errorText, GsmErrorClass errorClass) : - runtime_error(errorText), _errorClass(errorClass), _errorCode(-1) {} - - GsmException(string errorText, GsmErrorClass errorClass, int errorCode) : - runtime_error(errorText), _errorClass(errorClass), - _errorCode(errorCode) {} - - int getErrorCode() const {return _errorCode;} - - GsmErrorClass getErrorClass() const {return _errorClass;} - }; - - // error codes returned by TA/ME (+CMEE) - - const int ME_PHONE_FAILURE = 0; - const int ME_NO_CONNECTION_TO_PHONE = 1; - const int ME_PHONE_ADAPTOR_LINK_RESERVED = 2; - const int ME_OPERATION_NOT_ALLOWED = 3; - const int ME_OPERATION_NOT_SUPPORTED = 4; - const int ME_PH_SIM_PIN_REQUIRED = 5; - const int ME_SIM_NOT_INSERTED = 10; - const int ME_SIM_PIN_REQUIRED = 11; - const int ME_SIM_PUK_REQUIRED = 12; - const int ME_SIM_FAILURE = 13; - const int ME_SIM_BUSY = 14; - const int ME_SIM_WRONG = 15; - const int ME_INCORRECT_PASSWORD = 16; - const int ME_SIM_PIN2_REQUIRED = 17; - const int ME_SIM_PUK2_REQUIRED = 18; - const int ME_MEMORY_FULL = 20; - const int ME_INVALID_INDEX = 21; - const int ME_NOT_FOUND = 22; - const int ME_MEMORY_FAILURE = 23; - const int ME_TEXT_STRING_TOO_LONG = 24; - const int ME_INVALID_CHARACTERS_IN_TEXT_STRING = 25; - const int ME_DIAL_STRING_TOO_LONG = 26; - const int ME_INVALID_CHARACTERS_IN_DIAL_STRING = 27; - const int ME_NO_NETWORK_SERVICE = 30; - const int ME_NETWORK_TIMEOUT = 31; - const int ME_UNKNOWN = 100; - - // return descriptive text for the given error code - // the text is already translated - extern string getMEErrorText(const int errorCode) throw(GsmException); - - // SMS error codes - - // error codes from ETSI GSM 04.11, Annex E - const int SMS_UNASSIGNED_OR_UNALLOCATED_NUMBER = 1; - const int SMS_OPERATOR_DETERMINED_BARRING = 8; - const int SMS_CALL_BARRED = 10; - const int SMS_NETWORK_FAILURE = 17; - const int SMS_SHORT_MESSAGE_TRANSFER_REJECTED = 21; - const int SMS_CONGESTION = 22; - const int SMS_DESTINATION_OUT_OF_SERVICE = 27; - const int SMS_UNIDENTIFIED_SUBSCRIBER = 28; - const int SMS_FACILITY_REJECTED = 29; - const int SMS_UNKNOWN_SUBSCRIBER = 30; - const int SMS_NETWORK_OUT_OF_ORDER = 38; - const int SMS_TEMPORARY_FAILURE = 41; - const int SMS_CONGESTION2 = 42; - const int SMS_RESOURCES_UNAVAILABLE_UNSPECIFIED = 47; - const int SMS_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; - const int SMS_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; - const int SMS_INVALID_TRANSACTION_IDENTIFIER = 81; - const int SMS_SEMANTICALLY_INCORRECT_MESSAGE = 95; - const int SMS_INVALID_MANDATORY_INFORMATION = 96; - const int SMS_MESSAGE_TYPE_NONEXISTENT_OR_NOT_IMPLEMENTED = 97; - const int SMS_MESSAGE_NOT_COMPATIBLE_WITH_SHORT_MESSAGE_PROTOCOL_STATE = 98; - const int SMS_INFORMATION_ELEMENT_NONEXISTENT_OR_NOT_IMPLEMENTED = 99; - const int SMS_UNSPECIFIED_PROTOCOL_ERROR = 111; - const int SMS_UNSPECIFIED_INTERWORKING_ERROR = 127; - - // error codes from ETSI GSM 03.40, section 9.2.3.22 - const int SMS_TELEMATIC_INTERWORKING_NOT_SUPPORTED = 0x80; - const int SMS_SHORT_MESSAGE_TYPE_0_NOT_SUPPORTED = 0x81; - const int SMS_CANNOT_REPLACE_SHORT_MESSAGE = 0x82; - const int SMS_UNSPECIFIED_TP_PID_ERROR = 0x8f; - const int SMS_DATA_CODING_SCHEME_NOT_SUPPORTED = 0x90; - const int SMS_MESSAGE_CLASS_NOT_SUPPORTED = 0x91; - const int SMS_UNSPECIFIEC_TP_DCS_ERROR = 0x9f; - const int SMS_COMMAND_CANNOT_BE_ACTIONED = 0xa0; - const int SMS_COMMAND_UNSUPPORTED = 0xa1; - const int SMS_UNSPECIFIED_TP_COMMAND_ERROR = 0xaf; - const int SMS_TPDU_NOT_SUPPORTED = 0xb0; - const int SMS_SC_BUSY = 0xc0; - const int SMS_NO_SC_SUBSCRIPTION = 0xc1; - const int SMS_SC_SYSTEM_FAILURE = 0xc2; - const int SMS_INVALID_SME_ADDRESS = 0xc3; - const int SMS_DESTINATION_SME_BARRED = 0xc4; - const int SMS_SM_REJECTED_DUPLICATED_SM = 0xc5; - const int SMS_SIM_SMS_STORAGE_FULL = 0xd0; - const int SMS_NO_SMS_STORAGE_CAPABILITY_IN_SIM = 0xd1; - const int SMS_ERROR_IN_MS = 0xd2; - const int SMS_MEMORY_CAPACITY_EXCEED = 0xd3; - const int SMS_UNSPECIFIED_ERROR_CAUSE = 0xff; - - // error codes from ETSI GSM 07.05, section 3.2.5 - const int SMS_ME_FAILURE = 300; - const int SMS_SMS_SERVICE_OF_ME_RESERVED = 301; - const int SMS_OPERATION_NOT_ALLOWED = 302; - const int SMS_OPERATION_NOT_SUPPORTED = 303; - const int SMS_INVALID_PDU_MODE_PARAMETER = 304; - const int SMS_INVALID_TEXT_MODE_PARAMETER = 305; - const int SMS_SIM_NOT_INSERTED = 310; - const int SMS_SIM_PIN_REQUIRED = 311; - const int SMS_PH_SIM_PIN_REQUIRED = 312; - const int SMS_SIM_FAILURE = 313; - const int SMS_SIM_BUSY = 314; - const int SMS_SIM_WRONG = 315; - const int SMS_SIM_PUK_REQUIRED = 316; - const int SMS_SIM_PIN2_REQUIRED = 317; - const int SMS_SIM_PUK2_REQUIRED = 318; - const int SMS_MEMORY_FAILURE = 320; - const int SMS_INVALID_MEMORY_INDEX = 321; - const int SMS_MEMORY_FULL = 322; - const int SMS_SMSC_ADDRESS_UNKNOWN = 330; - const int SMS_NO_NETWORK_SERVICE = 331; - const int SMS_NETWORK_TIMEOUT = 332; - const int SMS_NO_CNMA_ACKNOWLEDGEMENT_EXPECTED = 340; - const int SMS_UNKNOWN_ERROR = 500; - - // return descriptive text for the given error code - // the text is already translated - extern string getSMSErrorText(const int errorCode) throw(GsmException); - - // SMS status handling - // success codes - const int SMS_STATUS_RECEIVED = 0; - const int SMS_STATUS_FORWARDED = 1; - const int SMS_STATUS_SM_REPLACES = 2; - - // if this bit is set, the error is only temporary and - // the SC is still trying to transfer the SM - const int SMS_STATUS_TEMPORARY_BIT = 32; - - // if this bit is set, the error is only temporary and - // the SC is still trying to transfer the SM - const int SMS_STATUS_PERMANENT_BIT = 64; - // both bits may be set at once - - // temporary errors (both bits may be set) - const int SMS_STATUS_CONGESTION = 0; - const int SMS_STATUS_SME_BUSY = 1; - const int SMS_STATUS_NO_RESPONSE_FROM_SME = 2; - const int SMS_STATUS_SERVICE_REJECTED = 3; - const int SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE = 4; - const int SMS_STATUS_ERROR_IN_SME = 5; - - // permanent errors (SMS_STATUS_PERMANENT_BIT is set) - const int SMS_STATUS_REMOTE_PROCECURE_ERROR = 0; - const int SMS_STATUS_INCOMPATIBLE_DESTINATION = 1; - const int SMS_STATUS_CONNECTION_REJECTED_BY_SME = 2; - const int SMS_STATUS_NOT_OBTAINABLE = 3; - // const int SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE = 4; - const int SMS_STATUS_NO_INTERWORKING_AVAILABLE = 5; - const int SMS_STATUS_SM_VALIDITY_PERDIOD_EXPIRED = 6; - const int SMS_STATUS_SM_DELETED_BY_ORIGINATING_SME = 7; - const int SMS_STATUS_SM_DELETED_BY_ADMINISTRATION = 8; - const int SMS_STATUS_SM_DOES_NOT_EXIST = 9; - - // return text for SMS status code - // the text is already translated - string getSMSStatusString(unsigned char status); -}; - -#endif // GSM_ERROR_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.cc deleted file mode 100644 index a608b04f62..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.cc +++ /dev/null @@ -1,174 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_event.cc -// * -// * Purpose: Event handler interface -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 7.6.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// GsmEvent members - -void GsmEvent::dispatch(string s, GsmAt &at) throw(GsmException) -{ - SMSMessageType messageType; - bool indication = false; - if (s.substr(0, 5) == "+CMT:") - messageType = NormalSMS; - else if (s.substr(0, 5) == "+CBM:") - messageType = CellBroadcastSMS; - else if (s.substr(0, 5) == "+CDS:") - { - // workaround for phones that report CDS when they actually mean CDSI - indication = at.getMeTa().getCapabilities()._CDSmeansCDSI; - messageType = StatusReportSMS; - } - else if (s.substr(0, 6) == "+CMTI:") - { - indication = true; - messageType = NormalSMS; - } - else if (s.substr(0, 6) == "+CBMI:") - { - indication = true; - messageType = CellBroadcastSMS; - } - else if (s.substr(0, 6) == "+CDSI:") - { - indication = true; - messageType = StatusReportSMS; - } - else if (s.substr(0, 4) == "RING") - { - ringIndication(); - return; - } - // handling NO CARRIER - else if (s.substr(0, 10) == "NO CARRIER") - { - noAnswer(); - return; - } - - else if (s.substr(0, 6) == "+CLIP:") - { - // ,[,,[,]] - s = s.substr(6); - Parser p(s); - string num = p.parseString(); - if (p.parseComma(true)) - { - unsigned int numberFormat; - if ((numberFormat = p.parseInt()) == InternationalNumberFormat) - num = "+" + num; - else if (numberFormat != UnknownNumberFormat) - throw GsmException(stringPrintf(_("unexpected number format %d"), - numberFormat), OtherError); - } - string subAddr; - string alpha; - if (p.parseComma(true)) - { - subAddr = p.parseString(true); - p.parseComma(); - p.parseInt(true); // FIXME subaddr type ignored - - if (p.parseComma(true)) - alpha = p.parseString(true); - } - - // call the event handler - callerLineID(num, subAddr, alpha); - return; - } - else - throw GsmException(stringPrintf(_("unexpected unsolicited event '%s'"), - s.c_str()), OtherError); - - if (indication) - { - // handle SMS storage indication - s = s.substr(6); - Parser p(s); - string storeName = p.parseString(); - p.parseComma(); - unsigned int index = p.parseInt(); - SMSReceptionIndication(storeName, index - 1, messageType); - } - else - if (messageType == CellBroadcastSMS) - { - // handle CB message - string pdu = at.getLine(); - - CBMessageRef cb = new CBMessage(pdu); - - // call the event handler - CBReception(cb); - } - else - { - // handle SMS - string pdu = at.getLine(); - - // add missing service centre address if required by ME - if (! at.getMeTa().getCapabilities()._hasSMSSCAprefix) - pdu = "00" + pdu; - - SMSMessageRef sms = SMSMessage::decode(pdu); - - // send acknowledgement if necessary - if (at.getMeTa().getCapabilities()._sendAck) - at.chat("+CNMA"); - - // call the event handler - SMSReception(sms, messageType); - } -} - -void GsmEvent::callerLineID(string number, string subAddr, string alpha) -{ - // ignore event -} - -void GsmEvent::SMSReception(SMSMessageRef newMessage, - SMSMessageType messageType) -{ - // ignore event -} - -void GsmEvent::CBReception(CBMessageRef newMessage) -{ - // ignore event -} - -void GsmEvent::SMSReceptionIndication(string storeName, unsigned int index, - SMSMessageType messageType) -{ - // ignore event -} - -void GsmEvent::ringIndication() -{ - // ignore event -} - -void GsmEvent::noAnswer() -{ - // ignore event -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.h deleted file mode 100644 index b2b986cd15..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_event.h +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_event.h -// * -// * Purpose: Event handler interface -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 7.6.1999 -// ************************************************************************* - -#ifndef GSM_EVENT_H -#define GSM_EVENT_H - -#include -#include - -using namespace std; - -namespace gsmlib -{ - // forward declarations - - class GsmAt; - - // event handler interface - - class GsmEvent - { - private: - // dispatch CMT/CBR/CDS/CLIP etc. - void dispatch(string s, GsmAt &at) throw(GsmException); - - public: - // for SMSReception, type of SMS - enum SMSMessageType {NormalSMS, CellBroadcastSMS, StatusReportSMS}; - - // caller line identification presentation - // only called if setCLIPEvent(true) is set - virtual void callerLineID(string number, string subAddr, string alpha); - - // called if the string NO CARRIER is read - virtual void noAnswer(); - - // SMS reception - // only called if setSMSReceptionEvent(...true...) is set - virtual void SMSReception(SMSMessageRef newMessage, - SMSMessageType messageType); - - // CB reception - // only called if setSMSReceptionEvent(...true...) is set - // storage of CBM in ME is not supported by the standard - virtual void CBReception(CBMessageRef newMessage); - - // SMS reception indication (called when SMS is not delivered to TE - // but stored in ME memory) - virtual void SMSReceptionIndication(string storeName, unsigned int index, - SMSMessageType messageType); - - // RING indication - virtual void ringIndication(); - - friend class gsmlib::GsmAt; - }; -}; - -#endif // GSM_EVENT_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_map_key.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_map_key.h deleted file mode 100644 index d47b7e0cd9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_map_key.h +++ /dev/null @@ -1,128 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_map_key.h -// * -// * Purpose: Common MapKey implementation for the multimaps in -// * gsm_sorted_sms_store and gsm_sorted_phonebook -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 5.11.1999 -// ************************************************************************* - -#ifndef GSM_MAP_KEY_H -#define GSM_MAP_KEY_H - -#include - -namespace gsmlib -{ - // sort order for MapKeys - - enum SortOrder {ByText = 0, ByTelephone = 1, ByIndex = 2, ByDate = 3, - ByType = 4, ByAddress = 5}; - - // wrapper for map key, can access Sortedtore to get sortOrder() - - template class MapKey - { - public: - SortedStore &_myStore; // my store - // different type keys - Address _addressKey; - Timestamp _timeKey; - int _intKey; - string _strKey; - - public: - // constructors for the different sort keys - MapKey(SortedStore &myStore, Address key) : - _myStore(myStore), _addressKey(key) {} - MapKey(SortedStore &myStore, Timestamp key) : - _myStore(myStore), _timeKey(key) {} - MapKey(SortedStore &myStore, int key) : - _myStore(myStore), _intKey(key) {} - MapKey(SortedStore &myStore, string key) : - _myStore(myStore), _strKey(key) {} - -/* - friend - bool operator< -#ifndef WIN32 - <> -#endif - (const MapKey &x, - const MapKey &y); - friend - bool operator== -#ifndef WIN32 - <> -#endif - (const MapKey &x, - const MapKey &y); -*/ - }; - - // compare two keys - template - extern bool operator<(const MapKey &x, - const MapKey &y); - template - extern bool operator==(const MapKey &x, - const MapKey &y); - - // MapKey members - - template - bool operator<(const MapKey &x, - const MapKey &y) - { - assert(&x._myStore == &y._myStore); - - switch (x._myStore.sortOrder()) - { - case ByDate: - return x._timeKey < y._timeKey; - case ByAddress: - return x._addressKey < y._addressKey; - case ByIndex: - case ByType: - return x._intKey < y._intKey; - case ByTelephone: - return Address(x._strKey) < Address(y._strKey); - case ByText: - return x._strKey < y._strKey; - default: - assert(0); - return true; - } - } - - template - bool operator==(const MapKey &x, - const MapKey &y) - { - assert(&x._myStore == &y._myStore); - - switch (x._myStore.sortOrder()) - { - case ByDate: - return x._timeKey == y._timeKey; - case ByAddress: - return x._addressKey == y._addressKey; - case ByIndex: - case ByType: - return x._intKey == y._intKey; - case ByTelephone: - return Address(x._strKey) == Address(y._strKey); - case ByText: - return x._strKey == y._strKey; - default: - assert(0); - return true; - } - } -}; - -#endif // GSM_MAP_KEY_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.cc deleted file mode 100644 index 1f9e84581a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.cc +++ /dev/null @@ -1,1254 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_me_ta.cc -// * -// * Purpose: Mobile Equipment/Terminal Adapter functions -// * (ETSI GSM 07.07) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 10.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#include - -using namespace std; -using namespace gsmlib; - -// Capabilities members - -Capabilities::Capabilities() : - _hasSMSSCAprefix(true), - _cpmsParamCount(-1), // initialize to -1, must be set later by - // setSMSStore() function - _omitsColon(true), // FIXME - _veryShortCOPSanswer(false), // Falcom A2-1 - _wrongSMSStatusCode(false), // Motorola Timeport 260 - _CDSmeansCDSI(false), // Nokia Cellular Card Phone RPE-1 GSM900 and - // Nokia Card Phone RPM-1 GSM900/1800 - _sendAck(false) // send ack for directly routed SMS -{ -} - -// MeTa members - -void MeTa::init() throw(GsmException) -{ - // switch on extended error codes - // caution: may be ignored by some TAs, so allow it to fail - _at->chat("+CMEE=1", "", true, true); - - // select SMS pdu mode - _at->chat("+CMGF=0"); - - // now fill in capability object - MEInfo info = getMEInfo(); - - // Ericsson model 6050102 - if ((info._manufacturer == "ERICSSON" && - (info._model == "1100801" || - info._model == "1140801")) || - getenv("GSMLIB_SH888_FIX") != NULL) - { - // the Ericsson leaves out the service centre address - _capabilities._hasSMSSCAprefix = false; - } - - // handle Falcom strangeness - if ((info._manufacturer == "Funkanlagen Leipoldt OHG" && - info._revision == "01.95.F2") || - getenv("GSMLIB_FALCOM_A2_1_FIX") != NULL) - { - _capabilities._veryShortCOPSanswer = true; - } - - // handle Motorola SMS store bug - wrong status code - if ((info._manufacturer == "Motorola" && - info._model == "L Series")) - { - _capabilities._wrongSMSStatusCode = true; - } - - // handle Nokia Cellular Card Phone RPE-1 GSM900 and - // Nokia Card Phone RPM-1 GSM900/1800 bug - CDS means CDSI - if ((info._manufacturer == "Nokia Mobile Phones" && - (info._model == "Nokia Cellular Card Phone RPE-1 GSM900" || - info._model == "Nokia Card Phone RPM-1 GSM900/1800"))) - { - _capabilities._CDSmeansCDSI = true; - } - - // find out whether we are supposed to send an acknowledgment - Parser p(_at->chat("+CSMS?", "+CSMS:")); - _capabilities._sendAck = p.parseInt() >= 1; - - // set GSM default character set - try - { - setCharSet("GSM"); - } - catch (GsmException) - { - // ignore errors, some devices don't support this - } - - // set default event handler - // necessary to handle at least RING indications that might - // otherwise confuse gsmlib - _at->setEventHandler(&_defaultEventHandler); -} - -MeTa::MeTa(Ref port) throw(GsmException) : _port(port) -{ - // initialize AT handling - _at = new GsmAt(*this); - - init(); -} - -// MeTa::MeTa(Ref at) throw(GsmException) : -// _at(at) -// { -// init(); -// } - -void MeTa::setPIN(string pin) throw(GsmException) -{ - _at->chat("+CPIN=\"" + pin + "\""); -} - -string MeTa::getPINStatus() throw(GsmException) -{ - Parser p(_at->chat("+CPIN?", "+CPIN:")); - return p.parseString(); -} - -void MeTa::setPhonebook(string phonebookName) throw(GsmException) -{ - if (phonebookName != _lastPhonebookName) - { - _at->chat("+CPBS=\"" + phonebookName + "\""); - _lastPhonebookName = phonebookName; - } -} - -string MeTa::setSMSStore(string smsStore, int storeTypes, bool needResultCode) - throw(GsmException) -{ - if (_capabilities._cpmsParamCount == -1) - { - // count the number of parameters for the CPMS AT sequences - _capabilities._cpmsParamCount = 1; - Parser p(_at->chat("+CPMS=?", "+CPMS:")); - p.parseStringList(); - while (p.parseComma(true)) - { - ++_capabilities._cpmsParamCount; - p.parseStringList(); - } - } - - // optimatization: only set current SMS store if different from last call - // or the result code is needed - if (needResultCode || _lastSMSStoreName != smsStore) - { - _lastSMSStoreName = smsStore; - - // build chat string - string chatString = "+CPMS=\"" + smsStore + "\""; - for (int i = 1; i < min(_capabilities._cpmsParamCount, storeTypes); ++i) - chatString += ",\"" + smsStore + "\""; - - return _at->chat(chatString, "+CPMS:"); - } - return ""; -} - -void MeTa::getSMSStore(string &readDeleteStore, - string &writeSendStore, - string &receiveStore) throw(GsmException) -{ - Parser p(_at->chat("+CPMS?", "+CPMS:")); - writeSendStore = receiveStore = ""; - readDeleteStore = p.parseString(); - p.parseComma(); - p.parseInt(); - p.parseComma(); - p.parseInt(); - if (p.parseComma(true)) - { - writeSendStore = p.parseString(); - p.parseComma(); - p.parseInt(); - p.parseComma(); - p.parseInt(); - if (p.parseComma(true)) - { - receiveStore = p.parseString(); - } - } -} - -void MeTa::waitEvent(GsmTime timeout) throw(GsmException) -{ - if (_at->wait(timeout)) - _at->chat(); // send AT, wait for OK, handle events -} - -// aux function for MeTa::getMEInfo() - -static string stringVectorToString(const vector& v, - char separator = '\n') -{ - if (v.empty()) - return ""; - - // concatenate string in vector as rows - string result; - for (vector::const_iterator i = v.begin();;) - { - string s = *i; - // remove leading and trailing "s - if (s.length() > 0 && s[0] == '"') - s.erase(s.begin()); - if (s.length() > 0 && s[s.length() - 1] == '"') - s.erase(s.end() - 1); - - result += s; - // don't add end line to last - if ( ++i == v.end() || !separator) - break; - result += separator; - } - return result; -} - -MEInfo MeTa::getMEInfo() throw(GsmException) -{ - MEInfo result; - // some TAs just return OK and no info line - // leave the info empty in this case - // some TAs return multirows with info like address, firmware version - result._manufacturer = - stringVectorToString(_at->chatv("+CGMI", "+CGMI:", false)); - result._model = stringVectorToString(_at->chatv("+CGMM", "+CGMM:", false)); - result._revision = - stringVectorToString(_at->chatv("+CGMR", "+CGMR:", false)); - result._serialNumber = - stringVectorToString(_at->chatv("+CGSN", "+CGSN:", false),0); - return result; -} - -vector MeTa::getSupportedCharSets() throw(GsmException) -{ - Parser p(_at->chat("+CSCS=?", "+CSCS:")); - return p.parseStringList(); -} - -string MeTa::getCurrentCharSet() throw(GsmException) -{ - if (_lastCharSet == "") - { - Parser p(_at->chat("+CSCS?", "+CSCS:")); - _lastCharSet = p.parseString(); - } - return _lastCharSet; -} - -void MeTa::setCharSet(string charSetName) throw(GsmException) -{ - _at->chat("+CSCS=\"" + charSetName + "\""); - _lastCharSet = ""; -} - -string MeTa::getExtendedErrorReport() throw(GsmException) -{ - return _at->chat("+CEER", "+CEER:"); -} - -void MeTa::dial(string number) throw(GsmException) -{ - _at->chat("D" + number + ";"); -} - -void MeTa::answer() throw(GsmException) -{ - _at->chat("A"); -} - -void MeTa::hangup() throw(GsmException) -{ - _at->chat("H"); - -} - -vector MeTa::getAvailableOPInfo() throw(GsmException) -{ - vector result; - vector responses = _at->chatv("+COPS=?", "+COPS:"); - - // special treatment for Falcom A2-1, answer looks like - // responses.push_back("(1,29341),(3,29340)"); - if (_capabilities._veryShortCOPSanswer) - { - if (responses.size() == 1) - { - Parser p(responses[0]); - while (p.parseChar('(', true)) - { - OPInfo opi; - opi._status = (OPStatus)p.parseInt(); - p.parseComma(); - opi._numericName = p.parseInt(); - p.parseChar(')'); - p.parseComma(true); - result.push_back(opi); - } - } - } - else - // some formats I have encountered... - //responses.push_back("2,,,31017,,(0,1),(2)"); - //responses.push_back("(3,\"UK CELLNET\",\"CLNET\",\"23410\")," - // "(3,\"ONE2 ONE\",\"ONE2ONE\",\"23430\")," - // "(3,\"ORANGE\",\"ORANGE\",\"23433\")"); - //responses.push_back("(2,\"D1-TELEKOM\",,26201)," - // "(3,\"D2 PRIVAT\",,26202),,(0,1,3,4),(0,2)"); - // some phones arbitrarily split the response into several lines - //responses.push_back("(1,\"AMENA\",,\"21403\")," - // "(3,\"MOVISTAR\",,\"21407\"),"); - //responses.push_back("(3,\"E VODAFONE\",,\"21401\"),,(0,1),(2)"); - - // GSM modems might return - // 1. quadruplets of info enclosed in brackets separated by comma - // 2. several lines of quadruplets of info enclosed in brackets - // 3. several lines of quadruplets without brackets and additional - // info at EOL (e.g. Nokia 8290) - for (vector::iterator i = responses.begin(); - i != responses.end(); ++i) - { -// while (i->length() > 0 && ! isprint((*i)[i->length() - 1])) -// i->erase(i->length() - 1, 1); - - bool expectClosingBracket = false; - Parser p(*i); - while (1) - { - OPInfo opi; - expectClosingBracket = p.parseChar('(', true); - int status = p.parseInt(true); - opi._status = (status == NOT_SET ? UnknownOPStatus : (OPStatus)status); - p.parseComma(); - opi._longName = p.parseString(true); - p.parseComma(); - opi._shortName = p.parseString(true); - p.parseComma(); - try - { - opi._numericName = p.parseInt(true); - } - catch (GsmException &e) - { - if (e.getErrorClass() == ParserError) - { - // the Ericsson GM12 GSM modem returns the numeric ID as string - string s = p.parseString(); - opi._numericName = checkNumber(s); - } - else - throw e; - } - if (expectClosingBracket) p.parseChar(')'); - result.push_back(opi); - if (! p.parseComma(true)) break; - // two commas ",," mean the list is finished - if (p.getEol() == "" || p.parseComma(true)) break; - } - // without brackets, the ME/TA must use format 3. - if (! expectClosingBracket) break; - } - return result; -} - -OPInfo MeTa::getCurrentOPInfo() throw(GsmException) -{ - OPInfo result; - - // 1. This exception thing is necessary because not all ME/TA combinations - // might support all the formats and then return "ERROR". - // 2. Additionally some modems return "ERROR" for all "COPS=3,n" command - // and report only one format with the "COPS?" command (e.g. Nokia 8290). - - // get long format - try - { - try - { - _at->chat("+COPS=3,0"); - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - Parser p(_at->chat("+COPS?", "+COPS:")); - result._mode = (OPModes)p.parseInt(); - // some phones (e.g. Nokia Card Phone 2.0) just return "+COPS: 0" - // if no network connection - if (p.parseComma(true)) - { - if (p.parseInt() == 0) - { - p.parseComma(); - result._longName = p.parseString(); - } - } - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - - // get short format - try - { - try - { - _at->chat("+COPS=3,1"); - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - Parser p(_at->chat("+COPS?", "+COPS:")); - result._mode = (OPModes)p.parseInt(); - // some phones (e.g. Nokia Card Phone 2.0) just return "+COPS: 0" - // if no network connection - if (p.parseComma(true)) - { - if (p.parseInt() == 1) - { - p.parseComma(); - result._shortName = p.parseString(); - } - } - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - - // get numeric format - try - { - try - { - _at->chat("+COPS=3,2"); - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - Parser p(_at->chat("+COPS?", "+COPS:")); - result._mode = (OPModes)p.parseInt(); - // some phones (e.g. Nokia Card Phone 2.0) just return "+COPS: 0" - // if no network connection - if (p.parseComma(true)) - { - if (p.parseInt() == 2) - { - p.parseComma(); - try - { - result._numericName = p.parseInt(); - } - catch (GsmException &e) - { - if (e.getErrorClass() == ParserError) - { - // the Ericsson GM12 GSM modem returns the numeric ID as string - string s = p.parseString(); - result._numericName = checkNumber(s); - } - else - throw e; - } - } - } - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - return result; -} - -void MeTa::setCurrentOPInfo(OPModes mode, - string longName, - string shortName, - int numericName) throw(GsmException) -{ - bool done = false; - if (longName != "") - { - try - { - _at->chat("+COPS=" + intToStr((int)mode) + ",0,\"" + longName + "\""); - done = true; - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - } - if (shortName != "" && ! done) - { - try - { - _at->chat("+COPS=" + intToStr((int)mode) + ",1,\"" + shortName + "\""); - done = true; - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - } - if (numericName != NOT_SET && ! done) - { - try - { - _at->chat("+COPS=" + intToStr((int)mode) + ",2," + - intToStr(numericName)); - done = true; - } - catch (GsmException &e) - { - if (e.getErrorClass() != ChatError) throw; - } - } - if (! done) - throw GsmException(_("unable to set operator"), OtherError); -} - -vector MeTa::getFacilityLockCapabilities() throw(GsmException) -{ - string locks = _at->chat("+CLCK=?", "+CLCK:"); - // some TA don't add '(' and ')' (Option FirstFone) - if (locks.length() && locks[0] != '(') - { - locks.insert(locks.begin(),'('); - locks += ')'; - } - Parser p(locks); - return p.parseStringList(); -} - -bool MeTa::getFacilityLockStatus(string facility, FacilityClass cl) - throw(GsmException) -{ - // some TA return always multiline response with all classes - // (Option FirstFone) - // !!! errors handling is correct (responses.empty() true) ? - vector responses = - _at->chatv("+CLCK=\"" + facility + "\",2,," + intToStr((int)cl),"+CLCK:",true); - for (vector::iterator i = responses.begin(); - i != responses.end(); ++i) - { - Parser p(*i); - int enabled = p.parseInt(); - - // if the first time and there is no comma this - // return direct state of classes - // else return all classes - if (i == responses.begin()) - { - if (!p.parseComma(true)) - return enabled == 1; - } - else - p.parseComma(); - - if ( p.parseInt() == (int)cl ) - return enabled == 1; - } - return false; - -// Parser p(_at->chat("+CLCK=\"" + facility + "\",2,," + intToStr((int)cl), -// "+CLCK:")); -// return p.parseInt() == 1; -} - -void MeTa::lockFacility(string facility, FacilityClass cl, string passwd) - throw(GsmException) -{ - if (passwd == "") - _at->chat("+CLCK=\"" + facility + "\",1,," + intToStr((int)cl)); - else - _at->chat("+CLCK=\"" + facility + "\",1,\"" + passwd + "\"," - + intToStr((int)cl)); -} - -void MeTa::unlockFacility(string facility, FacilityClass cl, string passwd) - throw(GsmException) -{ - if (passwd == "") - _at->chat("+CLCK=\"" + facility + "\",0,," + intToStr((int)cl)); - else - _at->chat("+CLCK=\"" + facility + "\",0,\"" + passwd + "\"," - + intToStr((int)cl)); -} - -vector MeTa::getPasswords() throw(GsmException) -{ - vector result; - Parser p(_at->chat("+CPWD=?", "+CPWD:")); - while (1) - { - PWInfo pwi; - if (!p.parseChar('(', true)) break; // exit if no new tuple - pwi._facility = p.parseString(); - p.parseComma(); - pwi._maxPasswdLen = p.parseInt(); - p.parseChar(')'); - p.parseComma(true); - result.push_back(pwi); - } - return result; -} - -void MeTa::setPassword(string facility, string oldPasswd, string newPasswd) - throw(GsmException) -{ - _at->chat("+CPWD=\"" + facility + "\",\"" + oldPasswd + "\",\"" + - newPasswd + "\""); -} - -bool MeTa::getNetworkCLIP() throw(GsmException) -{ - Parser p(_at->chat("+CLIP?", "+CLIP:")); - p.parseInt(); // ignore result code presentation - p.parseComma(); - return p.parseInt() == 1; -} - -void MeTa::setCLIPPresentation(bool enable) throw(GsmException) -{ - if (enable) - _at->chat("+CLIP=1"); - else - _at->chat("+CLIP=0"); -} - -bool MeTa::getCLIPPresentation() throw(GsmException) -{ - Parser p(_at->chat("+CLIP?", "+CLIP:")); - return p.parseInt() == 1; // ignore rest of line -} - -void MeTa::setCallForwarding(ForwardReason reason, - ForwardMode mode, - string number, - string subaddr, - FacilityClass cl, - int forwardTime) throw(GsmException) -{ - // FIXME subaddr is currently ignored - if (forwardTime != NOT_SET && (forwardTime < 0 || forwardTime > 30)) - throw GsmException(_("call forward time must be in the range 0..30"), - ParameterError); - - int numberType; - number = removeWhiteSpace(number); - if (number.length() > 0 && number[0] == '+') - { - numberType = InternationalNumberFormat; - number = number.substr(1); // skip the '+' at the beginning - } - else - numberType = UnknownNumberFormat; - _at->chat("+CCFC=" + intToStr(reason) + "," + intToStr(mode) + "," - "\"" + number + "\"," + - (number.length() > 0 ? intToStr(numberType) : "") + - "," + intToStr(cl) + - // FIXME subaddr and type - (forwardTime == NOT_SET ? "" : - (",,," + intToStr(forwardTime)))); -} - -void MeTa::getCallForwardInfo(ForwardReason reason, - ForwardInfo &voice, - ForwardInfo &fax, - ForwardInfo &data) throw(GsmException) -{ - // Initialize to some sensible values: - voice._active = false; - voice._cl = VoiceFacility; - voice._time = -1; - voice._reason = NoReason; - data._active = false; - data._cl = DataFacility; - data._time = -1; - data._reason = NoReason; - fax._active = false; - fax._cl = FaxFacility; - fax._time = -1; - fax._reason = NoReason; - - vector responses = - _at->chatv("+CCFC=" + intToStr(reason) + ",2", "+CCFC:"); - if (responses.size() == 1) - { - // only one line was returned. We have to ask for all three classes - // (voice, data, fax) separately - responses.clear(); - responses.push_back(_at->chat("+CCFC=" + intToStr(reason) + - ",2,,,1", "+CCFC:")); - responses.push_back(_at->chat("+CCFC=" + intToStr(reason) + - ",2,,,2", "+CCFC:")); - responses.push_back(_at->chat("+CCFC=" + intToStr(reason) + - ",2,,,4", "+CCFC:")); - } - - for (vector::iterator i = responses.begin(); - i != responses.end(); ++i) - { - Parser p(*i); - int status = p.parseInt(); - p.parseComma(); - FacilityClass cl = (FacilityClass)p.parseInt(); - string number; - string subAddr; - int forwardTime = NOT_SET; - - // parse number - if (p.parseComma(true)) - { - number = p.parseString(); - p.parseComma(); - unsigned int numberType = p.parseInt(); - if (numberType == InternationalNumberFormat) number = "+" + number; - - // parse subaddr - if (p.parseComma(true)) - { - // FIXME subaddr type not handled - subAddr = p.parseString(true); - p.parseComma(); - p.parseInt(true); - - // parse forwardTime - if (p.parseComma(true)) - { - forwardTime = p.parseInt(); - } - } - } - switch (cl) - { - case VoiceFacility: - voice._active = (status == 1); - voice._cl = VoiceFacility; - voice._number = number; - voice._subAddr = subAddr; - voice._time = forwardTime; - voice._reason = reason; - break; - case DataFacility: - data._active = (status == 1); - data._cl = DataFacility; - data._number = number; - data._subAddr = subAddr; - data._time = forwardTime; - data._reason = reason; - break; - case FaxFacility: - fax._active = (status == 1); - fax._cl = FaxFacility; - fax._number = number; - fax._subAddr = subAddr; - fax._time = forwardTime; - fax._reason = reason; - break; - } - } -} - -int MeTa::getBatteryChargeStatus() throw(GsmException) -{ - Parser p(_at->chat("+CBC", "+CBC:")); - return p.parseInt(); -} - -int MeTa::getBatteryCharge() throw(GsmException) -{ - Parser p(_at->chat("+CBC", "+CBC:")); - p.parseInt(); - p.parseComma(); - return p.parseInt(); -} - -int MeTa::getFunctionalityLevel() throw(GsmException) -{ - try { - Parser p(_at->chat("+CFUN?", "+CFUN:")); - // some phones return functionality level like "(2)" - bool expectClosingParen = p.parseChar('(', true); - int result = p.parseInt(); - if (expectClosingParen) - p.parseChar(')'); - return result; - } - catch (GsmException &x) - { - if (x.getErrorClass() == ChatError) - { - throw GsmException(_("Functionality Level commands not supported by ME"), - MeTaCapabilityError); - } else { - throw; - } - } -} - -void MeTa::setFunctionalityLevel(int level) throw(GsmException) -{ - try { - Parser p(_at->chat("+CFUN=" + intToStr(level))); - } catch (GsmException &x) { - if (x.getErrorClass() == ChatError) - { - // If the command AT+CFUN commands really aren't supported by the ME, - // then this will throw an appropriate exception for us. - getFunctionalityLevel(); - // If the number was just out of range, we get here. - throw GsmException(_("Requested Functionality Level out of range"), - ParameterError); - } - throw; - } -} - -int MeTa::getSignalStrength() throw(GsmException) -{ - Parser p(_at->chat("+CSQ", "+CSQ:")); - return p.parseInt(); -} - -int MeTa::getBitErrorRate() throw(GsmException) -{ - Parser p(_at->chat("+CSQ", "+CSQ:")); - p.parseInt(); - p.parseComma(); - return p.parseInt(); -} - -vector MeTa::getPhoneBookStrings() throw(GsmException) -{ - Parser p(_at->chat("+CPBS=?", "+CPBS:")); - return p.parseStringList(); -} - -PhonebookRef MeTa::getPhonebook(string phonebookString, - bool preload) throw(GsmException) -{ - for (PhonebookVector::iterator i = _phonebookCache.begin(); - i != _phonebookCache.end(); ++i) - { - if ((*i)->name() == phonebookString) - return *i; - } - PhonebookRef newPb(new Phonebook(phonebookString, _at, *this, preload)); - _phonebookCache.push_back(newPb); - return newPb; -} - -string MeTa::getServiceCentreAddress() throw(GsmException) -{ - Parser p(_at->chat("+CSCA?", "+CSCA:")); - return p.parseString(); -} - -void MeTa::setServiceCentreAddress(string sca) throw(GsmException) -{ - int type; - sca = removeWhiteSpace(sca); - if (sca.length() > 0 && sca[0] == '+') - { - type = InternationalNumberFormat; - sca = sca.substr(1, sca.length() - 1); - } - else - type = UnknownNumberFormat; - Parser p(_at->chat("+CSCA=\"" + sca + "\"," + intToStr(type))); -} - -vector MeTa::getSMSStoreNames() throw(GsmException) -{ - Parser p(_at->chat("+CPMS=?", "+CPMS:")); - // only return values - return p.parseStringList(); -} - -SMSStoreRef MeTa::getSMSStore(string storeName) throw(GsmException) -{ - for (SMSStoreVector::iterator i = _smsStoreCache.begin(); - i != _smsStoreCache.end(); ++i) - { - if ((*i)->name() == storeName) - return *i; - } - SMSStoreRef newSs(new SMSStore(storeName, _at, *this)); - _smsStoreCache.push_back(newSs); - return newSs; -} - -void MeTa::sendSMS(Ref smsMessage) throw(GsmException) -{ - smsMessage->setAt(_at); - smsMessage->send(); -} - -void MeTa::sendSMSs(Ref smsTemplate, string text, - bool oneSMS, - int concatenatedMessageId) - throw(GsmException) -{ - assert(! smsTemplate.isnull()); - - // compute maximum text length for normal SMSs and concatenated SMSs - unsigned int maxTextLength, concMaxTextLength; - switch (smsTemplate->dataCodingScheme().getAlphabet()) - { - case DCS_DEFAULT_ALPHABET: - maxTextLength = 160; - concMaxTextLength = 152; - break; - case DCS_EIGHT_BIT_ALPHABET: - maxTextLength = 140; - concMaxTextLength = 134; - break; - case DCS_SIXTEEN_BIT_ALPHABET: - maxTextLength = 70; - concMaxTextLength = 67; - break; - default: - throw GsmException(_("unsupported alphabet for SMS"), - ParameterError); - break; - } - - // simple case, only send one SMS - if (oneSMS || text.length() <= maxTextLength) - { - if (text.length() > maxTextLength) - throw GsmException(_("SMS text is larger than allowed"), - ParameterError); - smsTemplate->setUserData(text); - sendSMS(smsTemplate); - } - else // send multiple SMSs - { - if (concatenatedMessageId != -1) - maxTextLength = concMaxTextLength; - - int numMessages = (text.length() + maxTextLength - 1) / maxTextLength; - if (numMessages > 255) - throw GsmException(_("not more than 255 concatenated SMSs allowed"), - ParameterError); - unsigned char numMessage = 0; - while (true) - { - if (concatenatedMessageId != -1) - { - unsigned char udhs[] = {0x00, 0x03, concatenatedMessageId, - numMessages, ++numMessage}; - UserDataHeader udh(string((char*)udhs, 5)); - smsTemplate->setUserDataHeader(udh); - } - smsTemplate->setUserData(text.substr(0, maxTextLength)); - sendSMS(smsTemplate); - if (text.length() < maxTextLength) - break; - text.erase(0, maxTextLength); - } - } -} - -void MeTa::setMessageService(int serviceLevel) throw(GsmException) -{ - string s; - switch (serviceLevel) - { - case 0: - s = "0"; - break; - case 1: - s = "1"; - break; - default: - throw GsmException(_("only serviceLevel 0 or 1 supported"), - ParameterError); - } - // some devices (eg. Origo 900) don't support service level setting - _at->chat("+CSMS=" + s, "+CSMS:", true); -} - -unsigned int MeTa::getMessageService() throw(GsmException) -{ - Parser p(_at->chat("+CSMS?", "+CSMS:")); - return p.parseInt(); -} - -void MeTa::getSMSRoutingToTA(bool &smsRouted, - bool &cbsRouted, - bool &statusReportsRouted) throw(GsmException) -{ - Parser p(_at->chat("+CNMI?", "+CNMI:")); - p.parseInt(); - int smsMode = 0; - int cbsMode = 0; - int statMode = 0; - int bufferMode = 0; - - if (p.parseComma(true)) - { - smsMode = p.parseInt(); - if (p.parseComma(true)) - { - cbsMode = p.parseInt(); - if (p.parseComma(true)) - { - statMode = p.parseInt(); - if (p.parseComma(true)) - { - bufferMode = p.parseInt(); - } - } - } - } - - smsRouted = (smsMode == 2) || (smsMode == 3); - cbsRouted = (cbsMode == 2) || (cbsMode == 3); - statusReportsRouted = (statMode == 1); -} - -void MeTa::setSMSRoutingToTA(bool enableSMS, bool enableCBS, - bool enableStatReport, - bool onlyReceptionIndication) - throw(GsmException) -{ - bool smsModesSet = false; - bool cbsModesSet = false; - bool statModesSet = false; - bool bufferModesSet = false; - - // find out capabilities - Parser p(_at->chat("+CNMI=?", "+CNMI:")); - vector modes = p.parseIntList(); - vector smsModes(1); - vector cbsModes(1); - vector statModes(1); - vector bufferModes(1); - if (p.parseComma(true)) - { - smsModes = p.parseIntList(); - smsModesSet = true; - if (p.parseComma(true)) - { - cbsModes = p.parseIntList(); - cbsModesSet = true; - if (p.parseComma(true)) - { - statModes = p.parseIntList(); - statModesSet = true; - if (p.parseComma(true)) - { - bufferModes = p.parseIntList(); - bufferModesSet = true; - } - } - } - } - - // now set the mode vectors to the default if not set - if (! smsModesSet) smsModes[0] = true; - if (! cbsModesSet) cbsModes[0] = true; - if (! statModesSet) statModes[0] = true; - if (! bufferModesSet) bufferModes[0] = true; - - string chatString; - - // now try to set some optimal combination depending on - // ME/TA's capabilities - - // handle modes - if (isSet(modes, 2)) - chatString = "2"; - else if (isSet(modes, 1)) - chatString = "1"; - else if (isSet(modes, 0)) - chatString = "0"; - else if (isSet(modes, 3)) - chatString = "3"; - - if (onlyReceptionIndication) - { - // handle sms mode - if (enableSMS) - { - if (isSet(smsModes, 1)) - chatString += ",1"; - else - throw GsmException(_("cannot route SMS messages to TE"), - MeTaCapabilityError); - } - else - chatString += ",0"; - - // handle cbs mode - if (enableCBS) - { - if (isSet(cbsModes, 1)) - chatString += ",1"; - else if (isSet(cbsModes, 2)) - chatString += ",2"; - else - throw GsmException(_("cannot route cell broadcast messages to TE"), - MeTaCapabilityError); - } - else - chatString += ",0"; - - // handle stat mode - if (enableStatReport) - { - if (isSet(statModes, 2)) - chatString += ",2"; - else - throw GsmException(_("cannot route status reports messages to TE"), - MeTaCapabilityError); - } - else - chatString += ",0"; - } - else - { - // handle sms mode - if (enableSMS) - { - if (isSet(smsModes, 2)) - chatString += ",2"; - else if (isSet(smsModes, 3)) - chatString += ",3"; - else - throw GsmException(_("cannot route SMS messages to TE"), - MeTaCapabilityError); - } - else - chatString += ",0"; - - // handle cbs mode - if (enableCBS) - { - if (isSet(cbsModes, 2)) - chatString += ",2"; - else if (isSet(cbsModes, 3)) - chatString += ",3"; - else - throw GsmException(_("cannot route cell broadcast messages to TE"), - MeTaCapabilityError); - } - else - chatString += ",0"; - - // handle stat mode - if (enableStatReport) - { - if (isSet(statModes, 1)) - chatString += ",1"; - else if (isSet(statModes, 2)) - chatString += ",2"; - else - throw GsmException(_("cannot route status report messages to TE"), - MeTaCapabilityError); - } - else - chatString += ",0"; - } - - // handle buffer mode but only if it was reported by the +CNMI=? command - // the Ericsson GM12 GSM modem does not like it otherwise - if (bufferModesSet) - if (isSet(bufferModes, 1)) - chatString += ",1"; - else - chatString += ",0"; - - _at->chat("+CNMI=" + chatString); -} - -bool MeTa::getCallWaitingLockStatus(FacilityClass cl) - throw(GsmException) -{ - // some TA return always multiline response with all classes - // (Option FirstFone) - // !!! errors handling is correct (responses.empty() true) ? - vector responses = - _at->chatv("+CCWA=0,2," + intToStr((int)cl),"+CCWA:",true); - for (vector::iterator i = responses.begin(); - i != responses.end(); ++i) - { - Parser p(*i); - int enabled = p.parseInt(); - - // if the first time and there is no comma this - // return direct state of classes - // else return all classes - if (i == responses.begin()) - { - if (! p.parseComma(true)) - return enabled == 1; - } - else - p.parseComma(); - - if (p.parseInt() == (int)cl) - return enabled == 1; - } - return false; - -} -void MeTa::setCallWaitingLockStatus(FacilityClass cl, bool lock) - throw(GsmException) -{ - if(lock) - _at->chat("+CCWA=0,1," + intToStr((int)cl)); - else - _at->chat("+CCWA=0,0," + intToStr((int)cl)); -} - -void MeTa::setCLIRPresentation(bool enable) throw(GsmException) -{ - if (enable) - _at->chat("+CLIR=1"); - else - _at->chat("+CLIR=0"); -} - -int MeTa::getCLIRPresentation() throw(GsmException) -{ - // 0:according to the subscription of the CLIR service - // 1:CLIR invocation - // 2:CLIR suppression - Parser p(_at->chat("+CLIR?", "+CLIR:")); - return p.parseInt(); -} - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.h deleted file mode 100644 index f397e84695..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_me_ta.h +++ /dev/null @@ -1,402 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_me_ta.h -// * -// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions -// * (ETSI GSM 07.07 and 07.05) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.5.1999 -// ************************************************************************* - -#ifndef GSM_ME_TA_H -#define GSM_ME_TA_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // *** phone capability description (you could also call it phone quirks) - - struct Capabilities - { - bool _hasSMSSCAprefix; // SMS have service centre address prefix - int _cpmsParamCount; // number of SMS store parameters to - // CPMS command - bool _omitsColon; // omits trailing ':' in AT responses - bool _veryShortCOPSanswer; // Falcom A2-1 - bool _wrongSMSStatusCode; // Motorola Timeport 260 - bool _CDSmeansCDSI; // Nokia Cellular Card Phone RPE-1 GSM900 - bool _sendAck; // send ack for directly routed SMS - Capabilities(); // constructor, set default behaviours - }; - - // *** auxiliary structs - - // Static ME information (AT command sequences given in brackets) - struct MEInfo - { - string _manufacturer; // (+CGMI) - string _model; // (+CGMM) - string _revision; // (+CGMR) - string _serialNumber; // (+CGSN), IMEI - }; - - // modes for network operation selection - enum OPModes {AutomaticOPMode = 0, ManualOPMode = 1, - DeregisterOPMode = 2, ManualAutomaticOPMode = 4}; - - // status codes or network operaton selection - enum OPStatus {UnknownOPStatus = 0, AvailableOPStatus = 1, - CurrentOPStatus = 2, ForbiddenOPStatus = 3}; - - // network operator info - struct OPInfo - { - OPModes _mode; - OPStatus _status; - string _longName; - string _shortName; - int _numericName; // may be NOT_SET - - OPInfo() : _status(UnknownOPStatus), _numericName(NOT_SET) {} - }; - - // facility classes - enum FacilityClass {VoiceFacility = 1, DataFacility = 2, FaxFacility = 4}; - const int ALL_FACILITIES = VoiceFacility | DataFacility | FaxFacility; - - // struct to hold password info - struct PWInfo - { - string _facility; - int _maxPasswdLen; - }; - - // call forward reasons - // AllReasons encompasses 0..3 - // AllConditionalReasons encompasses 1..3 - enum ForwardReason {UnconditionalReason = 0, MobileBusyReason = 1, - NoReplyReason = 2, NotReachableReason = 3, - AllReasons = 4, AllConditionalReasons = 5, NoReason = 6}; - - // call forward modes - enum ForwardMode {DisableMode = 0, EnableMode = 1, - RegistrationMode = 3, ErasureMode = 4}; - - // call forward info - struct ForwardInfo - { - bool _active; // status in the network - FacilityClass _cl; // voice, fax, or data - string _number; // telephone number - string _subAddr; // subaddress - int _time; // time in the range 1..30 (for NoReplyReason) - ForwardReason _reason; // reason for the forwarding - }; - - // SMS types - typedef Ref SMSStoreRef; - typedef vector SMSStoreVector; - - // this class allows access to all functions of a ME/TA as described - // in sections 5-8 of ETSI GSM 07.07 - // Note: If the ME is changed (ie. disconnected an another one connected - // to the TA), a new ME object must be created - // (Mobile equipment = ME, terminal adapter = TA) - class MeTa : public RefBase - { - protected: - Ref _port; // port the ME/TA is connected to - Ref _at; // chat object for the port - PhonebookVector _phonebookCache; // cache of all used phonebooks - SMSStoreVector _smsStoreCache; // cache of all used phonebooks - string _lastPhonebookName; // remember last phonebook set on ME/TA - string _lastSMSStoreName; // remember last SMS store set on ME/TA - Capabilities _capabilities; // ME/TA quirks - GsmEvent _defaultEventHandler; // default event handler - // see comments in MeTa::init() - string _lastCharSet; // remember last character set - - // init ME/TA to sensible defaults - void init() throw(GsmException); - - public: - // initialize a new MeTa object given the port - MeTa(Ref port) throw(GsmException); - - // initialize a new MeTa object given the AT handler - //MeTa(Ref at) throw(GsmException); - - // set the current phonebook in the ME - // remember the last phonebook set for optimisation - void setPhonebook(string phonebookName) throw(GsmException); - - // set the current SMS store in the ME - // set storeTypes to - // 1 to set store for reading and deleting - // 2 to set store for writing and sending (includes type 1) - // 3 to preferred store for receiving SMS (includes types 1 and 2) - // remember the last SMS store set for optimisation - // if needResultCode is set this optimisation is not done - string setSMSStore(string smsStore, int storeTypes, - bool needResultCode = false) - throw(GsmException); - - // get current SMS store settings - void getSMSStore(string &readDeleteStore, - string &writeSendStore, - string &receiveStore) throw(GsmException); - - // get capabilities of this ME/TA - Capabilities getCapabilities() const {return _capabilities;} - - // return my port - Ref getPort() {return _port;} - - // return my at handler - Ref getAt() {return _at;} - - // set event handler for unsolicited result codes - GsmEvent *setEventHandler(GsmEvent *newHandler) - {return _at->setEventHandler(newHandler);} - - // wait for an event - void waitEvent(GsmTime timeout) throw(GsmException); - - // *** ETSI GSM 07.07 Section 5: "General Commands" - - // return ME information - MEInfo getMEInfo() throw(GsmException); - - // return available character sets - vector getSupportedCharSets() throw(GsmException);// (+CSCS=?) - - // return current character set (default: GSM) - string getCurrentCharSet() throw(GsmException);// (+CSCS?) - - // set character set to use - void setCharSet(string charSetName) throw(GsmException);// (+CSCS=) - - // *** ETSI GSM 07.07 Section 6: "Call control commands and methods" - - // get extended error report - string getExtendedErrorReport() throw(GsmException);// (+CEER) - - // dial a number, CLI presentation as defined in network - void dial(string number) throw(GsmException);// (ATD) - - // answer - void answer() throw(GsmException); // (ATA) - - // hangup - void hangup() throw(GsmException); // (ATH) - - // set Personal Identification Number - void setPIN(string number) throw(GsmException);// (+CPIN) - - // get PIN Status - string getPINStatus() throw(GsmException);// (+CPIN?) - - // *** ETSI GSM 07.07 Section 7: "Network service related commands" - - // return available network operators - // this fills in all fields of OPInfo with the exception of _mode - vector getAvailableOPInfo() throw(GsmException); // (+COPS=?) - - // return current network operators - // this fills in all the fields of OPInfo with the exception of _status - OPInfo getCurrentOPInfo() throw(GsmException); - - // set network operator - // caller must fill in ALL names it has read from previous calls - // of getCurrentOPInfo() or getAvailableOPInfo() - // (because ME/TA might not implement all names) - void setCurrentOPInfo(OPModes mode, - string longName = "", - string shortName = "", - int numericName = NOT_SET) throw(GsmException); - - // get facility lock capabilities (+CLCK) - vector getFacilityLockCapabilities() throw(GsmException); - - // query facility lock status for named facility - bool getFacilityLockStatus(string facility, FacilityClass cl) - throw(GsmException); - - // lock facility - void lockFacility(string facility, FacilityClass cl, string passwd = "") - throw(GsmException); - - // unlock facility - void unlockFacility(string facility, FacilityClass cl, string passwd = "") - throw(GsmException); - - // return names of facility for which a password can be set - // and the maximum length of the respective password - vector getPasswords() throw(GsmException);// (+CPWD=?) - - // set password for the given facility - void setPassword(string facility, string oldPasswd, string newPasswd) - throw(GsmException); - // (+CPWD=) - - // get CLIP (caller line identification presentation) in the network - bool getNetworkCLIP() throw(GsmException);// (+CLIP?) - - // set CLIP presentation on or off - // enables GsmEvent::callerLineID - void setCLIPPresentation(bool enable) throw(GsmException);// (+CLIP=) - - // returns if the above is enable - bool getCLIPPresentation() throw(GsmException);// (+CLIP?) - - // set call forwarding - void setCallForwarding(ForwardReason reason, - ForwardMode mode, - string number, - string subaddr, - FacilityClass cl = (FacilityClass)ALL_FACILITIES, - int forwardTime = NOT_SET) - throw(GsmException); // (+CCFC=) - - // get Information of currently set CF in the network - // the caller must give the reason to query - void getCallForwardInfo(ForwardReason reason, - ForwardInfo &voice, - ForwardInfo &fax, - ForwardInfo &data) - throw(GsmException); // (+CCFC=) - - - // *** ETSI GSM 07.07 Section 8: "Mobile Equipment control - // and status commands" - - // return/set ME functionality level (+CFUN): - // 0 Minimum functionality - // 1 full functionality - // 2 disable phone transmit RF circuits only - // 3 disable phone receive RF circuits only - // 4 disable phone both transmit and receive RF circuits - // 5...127 implementation-defined - int getFunctionalityLevel() throw(GsmException); - void setFunctionalityLevel(int level) throw(GsmException); - - // return battery charge status (+CBC): - // 0 ME is powered by the battery - // 1 ME has a battery connected, but is not powered by it - // 2 ME does not have a battery connected - // 3 Recognized power fault, calls inhibited - int getBatteryChargeStatus() throw(GsmException); - - // return battery charge (range 0..100) (+CBC) - int getBatteryCharge() throw(GsmException); - - // get signal strength indication (+CSQ): - // 0 -113 dBm or less - // 1 -111 dBm - // 2...30 -109... -53 dBm - // 31 -51 dBm or greater - // 99 not known or not detectable - int getSignalStrength() throw(GsmException); - - // get channel bit error rate (+CSQ): - // 0...7 as RXQUAL values in the table in GSM 05.08 [20] subclause 8.2.4 - // 99 not known or not detectable - int getBitErrorRate() throw(GsmException); - - // get available phone book memory storage strings (+CPBS=?) - vector getPhoneBookStrings() throw(GsmException); - - // get phone book given the phone book memory storage string - PhonebookRef getPhonebook(string phonebookString, - bool preload = false) throw(GsmException); - - - // *** ETSI GSM 07.05 SMS functions - - // return service centre address (+CSCA?) - string getServiceCentreAddress() throw(GsmException); - - // set service centre address (+CSCA=) - void setServiceCentreAddress(string sca) throw(GsmException); - - // return names of available message stores (, +CPMS=?) - vector getSMSStoreNames() throw(GsmException); - - // return SMS store given the name - SMSStoreRef getSMSStore(string storeName) throw(GsmException); - - // send a single SMS message - void sendSMS(Ref smsMessage) throw(GsmException); - - // send one or several (concatenated) SMS messages - // The SUBMIT message template must have all options set, only - // the userData and the userDataHeader are changed. - // If oneSMS is true, only one SMS is sent. Otherwise several SMSs - // are sent. If concatenatedMessageId is != -1 this is used as the message - // ID for concatenated SMS (for this a user data header as defined in - // GSM GTS 3.40 is used, the old UDH in the template is overwritten). - void sendSMSs(Ref smsTemplate, string text, - bool oneSMS = false, - int concatenatedMessageId = -1) - throw(GsmException); - - // set SMS service level - // if set to 1 send commands return ACK PDU, 0 is the default - void setMessageService(int serviceLevel) throw(GsmException); - - // return SMS service level - unsigned int getMessageService() throw(GsmException); - - // return true if any of the thre message types GsmEvent::SMSMessageType - // is routed directly to the TA and not stored in the ME - void getSMSRoutingToTA(bool &smsRouted, // (+CNMI?) - bool &cbsRouted, - bool &statusReportsRouted) throw(GsmException); - - // sets routing of SMS to TA to true for all supported SMSMessageTypes - // if onlyReceptionIndication is set to true - // only GsmEvent::SMSReceptionIndication is called - // this has two reasons: GSM 07.05 section 3.4.1 does not recommend - // direct routing of new SMS to the TA - // I cannot test direct routing of SMS because it does not work with - // my hardware - void setSMSRoutingToTA(bool enableSMS, bool enableCBS, - bool enableStatReport, - bool onlyReceptionIndication = true) - throw(GsmException); - // (+CNMI=) - - bool getCallWaitingLockStatus(FacilityClass cl) - throw(GsmException); - - void setCallWaitingLockStatus(FacilityClass cl, - bool lock)throw(GsmException); - - void setCLIRPresentation(bool enable) throw(GsmException); - //(+CLIR) - - // 0:according to the subscription of the CLIR service - // 1:CLIR invocation - // 2:CLIR suppression - int getCLIRPresentation() throw(GsmException); - - friend class Phonebook; - friend class SMSStore; - }; -}; - -#endif // GSM_ME_TA_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.cc deleted file mode 100644 index 5eb205bf81..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.cc +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_nls.cc -// * -// * Purpose: Groups macros, initialization and includes -// * for National Language Support (NLS) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.11.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include - -using namespace std; - -#ifdef ENABLE_NLS - -using namespace gsmlib; - -#ifdef HAVE_LOCALE_H -#include -#endif - -bool InitNLS::initialized = false; - -#endif // ENABLE_NLS diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.h deleted file mode 100644 index 6bfa6eb2f7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_nls.h +++ /dev/null @@ -1,71 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_nls.h -// * -// * Purpose: Groups macros, initialization and includes -// * for National Language Support (NLS) -// * -// * Warning: Only include this header from gsmlib .cc-files -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.11.1999 -// ************************************************************************* - -#ifndef GSM_NLS_H -#define GSM_NLS_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef ENABLE_NLS - -#ifdef HAVE_LIBINTL_H -#include -#else -#include "../intl/libintl.h" -#endif -#ifdef HAVE_LOCALE_H -#include -#endif - -#define _(String) dgettext(PACKAGE, String) - -// this causes automatic NLS initialization if one file of the library -// includes gsm_nls.h - -namespace gsmlib -{ - const class InitNLS - { - static bool initialized; - - public: - InitNLS() - { - if (! initialized) // do only once - { - setlocale(LC_ALL, ""); -#ifdef LOCAL_TRANSLATIONS - bindtextdomain(PACKAGE, "../po"); -#else - bindtextdomain(PACKAGE, LOCALEDIR); -#endif - textdomain(PACKAGE); - initialized = true; - } - } - } initNLS; -}; - -#else - -#define _(String) (String) - -#endif // ENABLE_NLS - -#define N_(String) (String) - -#endif // GSM_NLS_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.cc deleted file mode 100644 index 38a21cd515..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.cc +++ /dev/null @@ -1,381 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_parser.cc -// * -// * Purpose: Parser to parse MA/TA result strings -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 13.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// Parser members - -int Parser::nextChar(bool skipWhiteSpace) -{ - if (skipWhiteSpace) - while (_i < _s.length() && isspace(_s[_i])) ++_i; - - if (_i == _s.length()) - { - _eos = true; - return -1; - } - - return _s[_i++]; -} - -bool Parser::checkEmptyParameter(bool allowNoParameter) throw(GsmException) -{ - int c = nextChar(); - if (c == ',' || c == -1) - if (allowNoParameter) - { - putBackChar(); - return true; - } - else - throwParseException(_("expected parameter")); - - putBackChar(); - return false; -} - -string Parser::parseString2(bool stringWithQuotationMarks) - throw(GsmException) -{ - int c; - string result; - if (parseChar('"', true)) // OK, string starts and ends with quotation mark - if (stringWithQuotationMarks) - { - // read till end of line - while ((c = nextChar(false)) != -1) - result += c; - - // check for """ at end of line - if (result.length() == 0 || result[result.length() - 1] != '"') - throwParseException(_("expected '\"'")); - - // remove """ at the end - result.resize(result.length() - 1); - } - else - { - // read till next """ - while ((c = nextChar(false)) != '"') - if (c == -1) - throwParseException(); - else - result += c; - } - else // string ends with "," or EOL - { - c = nextChar(false); - while (c != ',' && c != -1) - { - result += c; - c = nextChar(false); - } - if (c == ',') putBackChar(); - } - - return result; -} - -int Parser::parseInt2() throw(GsmException) -{ - string s; - int c; - int result; - - while (isdigit(c = nextChar())) s += c; - - putBackChar(); - if (s.length() == 0) - throwParseException(_("expected number")); - - istrstream is(s.c_str()); - is >> result; - return result; -} - -void Parser::throwParseException(string message) throw(GsmException) -{ - ostrstream os; - if (message.length() == 0) - throw GsmException(stringPrintf(_("unexpected end of string '%s'"), - _s.c_str()), ParserError); - else - throw GsmException(message + - stringPrintf(_(" (at position %d of string '%s')"), _i, - _s.c_str()), ParserError); -} - -Parser::Parser(string s) : _i(0), _s(s), _eos(false) -{ -} - -bool Parser::parseChar(char c, bool allowNoChar) throw(GsmException) -{ - if (nextChar() != c) - if (allowNoChar) - { - putBackChar(); - return false; - } - else - throwParseException(stringPrintf(_("expected '%c'"), c)); - return true; -} - -vector Parser::parseStringList(bool allowNoList) - throw(GsmException) -{ - // handle case of empty parameter - vector result; - if (checkEmptyParameter(allowNoList)) return result; - - parseChar('('); - if (nextChar() != ')') - { - putBackChar(); - while (1) - { - result.push_back(parseString()); - int c = nextChar(); - if (c == ')') - break; - if (c == -1) - throwParseException(); - if (c != ',') - throwParseException(_("expected ')' or ','")); - } - } - - return result; -} - -vector Parser::parseIntList(bool allowNoList) - throw(GsmException) -{ - // handle case of empty parameter - bool isRange = false; - vector result; - int resultCapacity = 0; - unsigned int saveI = _i; - - if (checkEmptyParameter(allowNoList)) return result; - - // check for the case of a integer list consisting of only one parameter - // some TAs omit the parentheses in this case - if (isdigit(nextChar())) - { - putBackChar(); - int num = parseInt(); - result.resize(num + 1, false); - result[num] = true; - return result; - } - putBackChar(); - - // run in two passes - // pass 0: find capacity needed for result - // pass 1: resize result and fill it in - for (int pass = 0; pass < 2; ++pass) - { - if (pass == 1) - { - _i = saveI; - result.resize(resultCapacity + 1, false); - } - - parseChar('('); - if (nextChar() != ')') - { - putBackChar(); - int lastInt = -1; - while (1) - { - int thisInt = parseInt(); - - if (isRange) - { - assert(lastInt != -1); - if (lastInt <= thisInt) - for (int i = lastInt; i < thisInt; ++i) - { - if (i > resultCapacity) - resultCapacity = i; - if (pass == 1) - result[i] = true; - } - else - for (int i = thisInt; i < lastInt; ++i) - { - if (i > resultCapacity) - resultCapacity = i; - if (pass == 1) - result[i] = true; - } - isRange = false; - } - - if (thisInt > resultCapacity) - resultCapacity = thisInt; - if (pass == 1) - result[thisInt] = true; - lastInt = thisInt; - - int c = nextChar(); - if (c == ')') - break; - - if (c == -1) - throwParseException(); - - if (c != ',' && c != '-') - throwParseException(_("expected ')', ',' or '-'")); - - if (c == ',') - isRange = false; - else // is '-' - if (isRange) - throwParseException(_("range of the form a-b-c not allowed")); - else - isRange = true; - } - } - } - if (isRange) - throwParseException(_("range of the form a- no allowed")); - return result; -} - -vector Parser::parseParameterRangeList(bool allowNoList) - throw(GsmException) -{ - // handle case of empty parameter - vector result; - if (checkEmptyParameter(allowNoList)) return result; - - result.push_back(parseParameterRange()); - while (parseComma(true)) - { - result.push_back(parseParameterRange()); - } - - return result; -} - -ParameterRange Parser::parseParameterRange(bool allowNoParameterRange) - throw(GsmException) -{ - // handle case of empty parameter - ParameterRange result; - if (checkEmptyParameter(allowNoParameterRange)) return result; - - parseChar('('); - result._parameter = parseString(); - parseComma(); - result._range = parseRange(false, true); - parseChar(')'); - - return result; -} - -IntRange Parser::parseRange(bool allowNoRange, bool allowNonRange) - throw(GsmException) -{ - // handle case of empty parameter - IntRange result; - if (checkEmptyParameter(allowNoRange)) return result; - - parseChar('('); - result._low = parseInt(); - // allow non-ranges is allowNonRange == true - if (parseChar('-', allowNonRange)) - result._high = parseInt(); - parseChar(')'); - - return result; -} - -int Parser::parseInt(bool allowNoInt) throw(GsmException) -{ - // handle case of empty parameter - int result = NOT_SET; - if (checkEmptyParameter(allowNoInt)) return result; - - result = parseInt2(); - - return result; -} - -string Parser::parseString(bool allowNoString, - bool stringWithQuotationMarks) - throw(GsmException) -{ - // handle case of empty parameter - string result; - if (checkEmptyParameter(allowNoString)) return result; - - result = parseString2(stringWithQuotationMarks); - - return result; -} - -bool Parser::parseComma(bool allowNoComma) throw(GsmException) -{ - if (nextChar() != ',') - if(allowNoComma) - { - putBackChar(); - return false; - } - else - throwParseException(_("expected comma")); - return true; -} - -string Parser::parseEol() throw(GsmException) -{ - string result; - int c; - while ((c = nextChar()) != -1) result += c; - return result; -} - -void Parser::checkEol() throw(GsmException) -{ - if (nextChar() != -1) - { - putBackChar(); - throwParseException(_("expected end of line")); - } -} - -string Parser::getEol() -{ - string result; - int c; - unsigned int saveI = _i; - bool saveEos = _eos; - while ((c = nextChar()) != -1) result += c; - _i = saveI; - _eos = saveEos; - return result; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.h deleted file mode 100644 index 8404f9f1cb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_parser.h +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_parser.h -// * -// * Purpose: Parser to parse MA/TA result strings -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 13.5.1999 -// ************************************************************************* - -#ifndef GSM_PARSER_H -#define GSM_PARSER_H - -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - class Parser : public RefBase - { - private: - unsigned int _i; // index into _s, next character - string _s; // string to parse - bool _eos; // true if end-of-string reached in nextChar() - - // return next character or -1 if end of string - int nextChar(bool skipWhiteSpace = true); - - // "puts back" a character - void putBackChar() {if (! _eos) --_i;} - - // check for empty parameter (ie. "," or end of string) - // skips white space - // returns true if no parameter - // or throw an GsmException if allowNoParameter == false - bool checkEmptyParameter(bool allowNoParameter) throw(GsmException); - - // parse a string (like "string") - // throw an exception if not well-formed - string parseString2(bool stringWithQuotationMarks) throw(GsmException); - - // parse a int (like 1234) - // throw an exception if not well-formed - int parseInt2() throw(GsmException); - - // throw a parser exception - void throwParseException(string message = "") throw(GsmException); - - public: - Parser(string s); - - // the following functions skip white space - // parse a character, if absent throw a GsmException - // return false if allowNoChar == true and character not encountered - bool parseChar(char c, bool allowNoChar = false) throw(GsmException); - - // parse a list of the form "("ABC", DEF")" - // the list can be empty (ie. == "" ) if allowNoList == true - vector parseStringList(bool allowNoList = false) - throw(GsmException); - - // parse a list of the form "(12, 14)" or "(1-4, 10)" - // the result is returned as a bit vector where for each integer - // in the list and/or range(s) a bit is set - // the list can be empty (ie. == "") if allowNoList == true - vector parseIntList(bool allowNoList = false) - throw(GsmException); - - // parse a list of parameter ranges (see below) - // the list can be empty (ie. == "" ) if allowNoList == true - vector parseParameterRangeList(bool allowNoList = false) - throw(GsmException); - - // parse a string plus its valid integer range of the - // form "("string",(1-125))" - // the parameter range may be absent if allowNoParameterRange == true - ParameterRange parseParameterRange(bool allowNoParameterRange = false) - throw(GsmException); - - // parse an integer range of the form "(1-125)" - // the range may be absent if allowNoRange == true - // then IntRange::_high and _low are set to NOT_SET - // the range may be short if allowNonRange == true - // then IntRange::_high is set to NOT_SET - IntRange parseRange(bool allowNoRange = false, bool allowNonRange = false) - throw(GsmException); - - // parse an integer of the form "1234" - // allow absent int if allowNoInt == true - // then it returns NOT_SET - int parseInt(bool allowNoInt = false) throw(GsmException); - - // parse a string of the form ""string"" - // allow absent string if allowNoString == true - // then it returns "" - // if stringWithQuotationMarks == true the string may contain """ - // the string is then parsed till the end of the line - string parseString(bool allowNoString = false, - bool stringWithQuotationMarks = false) - throw(GsmException); - - // parse a single "," - // the comma may be absent if allowNoComma == true - // returns true if there was a comma - bool parseComma(bool allowNoComma = false) throw(GsmException); - - // parse till end of line, return result without whitespace - string parseEol() throw(GsmException); - - // check that end of line is reached - void checkEol() throw(GsmException); - - // return string till end of line without whitespace - // (does not change internal state) - string getEol(); - }; -}; - -#endif // GSM_PARSER_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.cc deleted file mode 100644 index 24d89e805d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.cc +++ /dev/null @@ -1,585 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_phonebook.cc -// * -// * Purpose: Phonebook management functions -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 6.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// PhonebookEntry members - -PhonebookEntry::PhonebookEntry(const PhonebookEntryBase &e) - throw(GsmException) : _cached(true), _myPhonebook(NULL) -{ - set(e.telephone(), e.text(), e.index(), e.useIndex()); -} - -void PhonebookEntry::set(string telephone, string text, int index, - bool useIndex) - throw(GsmException) -{ - checkTextAndTelephone(text, telephone); - - if (_myPhonebook != NULL) - { - if (text.length() > _myPhonebook->getMaxTextLen()) - throw GsmException( - stringPrintf(_("length of text '%s' exceeds maximum text " - "length (%d characters) of phonebook '%s'"), - text.c_str(), _myPhonebook->getMaxTextLen(), - _myPhonebook->name().c_str()), - ParameterError); - - if (telephone.length() > _myPhonebook->getMaxTelephoneLen()) - throw GsmException( - stringPrintf(_("length of telephone number '%s' " - "exceeds maximum telephone number " - "length (%d characters) of phonebook '%s'"), - telephone.c_str(), _myPhonebook->getMaxTelephoneLen(), - _myPhonebook->name().c_str()), - ParameterError); - - _myPhonebook->writeEntry(_index, telephone, text); - } - else - _index = index; - - _useIndex = useIndex; - _cached = true; - _telephone = telephone; - _text = text; - _changed = true; -} - -string PhonebookEntry::text() const throw(GsmException) -{ - if (! cached()) - { - assert(_myPhonebook != NULL); - // these operations are at least "logically const" - PhonebookEntry *thisEntry = const_cast(this); - _myPhonebook->readEntry(_index, thisEntry->_telephone, thisEntry->_text); - thisEntry->_cached = true; - } - return _text; -} - -string PhonebookEntry::telephone() const throw(GsmException) -{ - if (! cached()) - { - assert(_myPhonebook != NULL); - // these operations are at least "logically const" - PhonebookEntry *thisEntry = const_cast(this); - _myPhonebook->readEntry(_index, thisEntry->_telephone, thisEntry->_text); - thisEntry->_cached = true; - } - return _telephone; -} - -bool PhonebookEntry::cached() const -{ - if (_myPhonebook == NULL) - return _cached; - else - return _cached && _myPhonebook->_useCache; -} - -PhonebookEntry::PhonebookEntry(const PhonebookEntry &e) throw(GsmException) -{ - set(e._telephone, e._text, e._index, e._useIndex); -} - -PhonebookEntry &PhonebookEntry::operator=(const PhonebookEntry &e) - throw(GsmException) -{ - set(e._telephone, e._text, e._index, e._useIndex); - return *this; -} - -// Phonebook members - -int Phonebook::parsePhonebookEntry(string response, - string &telephone, string &text) -{ - // this is a workaround for a bug that occurs with my ME/TA combination - // some texts are truncated and don't have a trailing " - if (response.length() > 0 && response[response.length() - 1] != '"') - response += '"'; - Parser p(response); - - int index = p.parseInt(); - p.parseComma(); - - // handle case of empty entry - if (p.getEol().substr(0, 5) == "EMPTY") - { - telephone = ""; - text = ""; - return index; - } - - telephone = p.parseString(); - p.parseComma(); - unsigned int numberFormat = p.parseInt(); - if (numberFormat != UnknownNumberFormat && - numberFormat != InternationalNumberFormat) - cerr << "*** GSMLIB WARNING: Unexpected number format when reading from " - << "phonebook: " << numberFormat << " ***" << endl; - p.parseComma(); - text = p.parseString(false, true); - if (lowercase(_myMeTa.getCurrentCharSet()) == "gsm") - text = gsmToLatin1(text); - if (numberFormat == InternationalNumberFormat) - { - // skip leading "+" signs that may already exist - while (telephone.length() > 0 && telephone[0] == '+') - telephone = telephone.substr(1); - telephone = "+" + telephone; - } - - return index; -} - -void Phonebook::readEntry(int index, string &telephone, string &text) - throw(GsmException) -{ - // select phonebook - _myMeTa.setPhonebook(_phonebookName); - - // read entry - string response = _at->chat("+CPBR=" + intToStr(index), "+CPBR:", - false, // dont't ignore errors - true); // but accept empty responses - // (the latter is necessary for some mobile phones that return nothing - // if the entry is empty) - - if (response.length() == 0) // OK phone returned empty response - { - telephone = text = ""; // then the entry is empty as well - } - else - parsePhonebookEntry(response, telephone, text); - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Reading PB entry " << index << " number " << telephone - << " text " << text << endl; -#endif -} - -void Phonebook::findEntry(string text, int &index, string &telephone) - throw(GsmException) -{ - // select phonebook - _myMeTa.setPhonebook(_phonebookName); - - // read entry - string response = _at->chat("+CPBF=\"" + text + "\"", "+CPBF:", - false, // dont't ignore errors - true); // but accept empty responses - // (the latter is necessary for some mobile phones that return nothing - // if the entry is empty) - - if (response.length() == 0) // OK phone returned empty response - { - telephone = ""; // then the entry is empty as well - index = 0; - } - else - index=parsePhonebookEntry(response, telephone, text); - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Finding PB entry " << text << " number " << telephone - << " index " << index << endl; -#endif -} - -void Phonebook::writeEntry(int index, string telephone, string text) - throw(GsmException) -{ -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Writing PB entry #" << index << " number '" << telephone - << "' text '" << text << "'" << endl; -#endif - // select phonebook - _myMeTa.setPhonebook(_phonebookName); - - // write entry - string s; - if (telephone == "" && text == "") - { - ostrstream os; - os << "+CPBW=" << index; - os << ends; - char *ss = os.str(); - s = string(ss); - delete[] ss; - } - else - { - int type; - if (telephone.find('+') == string::npos) - type = UnknownNumberFormat; - else - type = InternationalNumberFormat; - string gsmText = text; - if (lowercase(_myMeTa.getCurrentCharSet()) == "gsm") - gsmText = latin1ToGsm(gsmText); - ostrstream os; - os << "+CPBW=" << index << ",\"" << telephone << "\"," << type - << ",\""; - os << ends; - char *ss = os.str(); - s = string(ss); - delete[] ss; - // this cannot be added with ostrstream because the gsmText can - // contain a zero (GSM default alphabet for '@') - s += gsmText + "\""; - } - _at->chat(s); -} - -Phonebook::iterator Phonebook::insertFirstEmpty(string telephone, string text) - throw(GsmException) -{ - for (int i = 0; i < _maxSize; i++) - if (_phonebook[i].empty()) - { - _phonebook[i].set(telephone, text); - adjustSize(1); - return begin() + i; - } - throw GsmException(_("phonebook full"), OtherError); -} - -Phonebook::iterator Phonebook::insert(const string telephone, - const string text, - const int index) -{ - for (int i = 0; i < _maxSize; i++) - if (_phonebook[i].index() == index) - if (_phonebook[i].empty()) - { - _phonebook[i].set(telephone, text); - adjustSize(1); - return begin() + i; - } - else - throw GsmException(_("attempt to overwrite phonebook entry"), - OtherError); - return end(); -} - -Phonebook::Phonebook(string phonebookName, Ref at, MeTa &myMeTa, - bool preload) throw(GsmException) : - _phonebookName(phonebookName), _at(at), _myMeTa(myMeTa), _useCache(true) -{ - // select phonebook - _myMeTa.setPhonebook(_phonebookName); - - // query size and maximum capacity of phonebook - _size = -1; // -1 means not known yet - _maxSize = -1; - Parser q(_at->chat("+CPBS?", "+CPBS:")); - string dummy = q.parseString(); - if (q.parseComma(true)) // this means that - { // used and total result is supported by ME - _size = q.parseInt(); - q.parseComma(); - _maxSize = q.parseInt(); - } - - // get basic phonebook info from ME - Parser p(_at->chat("+CPBR=?", "+CPBR:")); - - // get index of actually available entries in the phonebook - vector availablePositions = p.parseIntList(); - p.parseComma(); - _maxNumberLength = p.parseInt(); - p.parseComma(); - _maxTextLength = p.parseInt(); - - // find out capacity of phonebook in ME - // Note: The phonebook in the ME may be sparse, eg. the range of - // allowed index numbers may be something like (3-4, 20-100, 120). - // The standard allows this, even though it is unlikely to be - // implemented like that by anyone. - // In memory we store only phonebook entries that may actually be - // used, ie. the phonebook in memory is not sparse. - // Each entry has a member _index that corresponds to the index in the ME. - if (_maxSize == -1) - { - _maxSize = 0; - for (vector::iterator i = availablePositions.begin(); - i != availablePositions.end(); ++i) - if (*i) ++_maxSize; - } - - // for use with preload below - int *meToPhonebookIndexMap = - (int*)alloca(sizeof(int) * (availablePositions.size() + 1)); - - // initialize phone book entries - if (_maxSize == 0) - _phonebook = NULL; - else - _phonebook = new PhonebookEntry[_maxSize]; - int nextAvailableIndex = 0; - int i; - for (i = 0; i < _maxSize; i++) - { - while (! availablePositions[nextAvailableIndex]) - nextAvailableIndex++; - _phonebook[i]._index = nextAvailableIndex; - _phonebook[i]._cached = false; - _phonebook[i]._myPhonebook = this; - meToPhonebookIndexMap[nextAvailableIndex++] = i; - } - - // find out first index number of phonebook - int firstIndex = -1; - for (i = 0; i < _maxSize; i++) - if (availablePositions[i]) - { - firstIndex = i; - break; - } - - // preload phonebook - // Note: this contains a workaround for the bug that - // some MEs can not return the entire phonebook with one AT command - // To detect this condition, _size must be known - // also, this code only handles non-sparse phonebooks - if (preload && _size != -1 && - (int)availablePositions.size() == _maxSize + firstIndex) - { - int entriesRead = 0; - int startIndex = firstIndex; - - while (entriesRead < _size) - { - reportProgress(0, _maxSize); // chatv also calls reportProgress() - vector responses = - _at->chatv("+CPBR=" + intToStr(startIndex) + - "," + intToStr(_maxSize + firstIndex - 1), - "+CPBR:", true); - - // this means that we have read nothing even though not all - // entries have been retrieved (entriesRead < _size) - // this could be due to a malfunction of the ME... - // anyway, missing entries can be read later by readEntry() - if (responses.size() == 0) - { -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** error when preloading phonebook: " - "not all entries returned" << endl; -#endif - break; - } - - for (vector::iterator i = responses.begin(); - i != responses.end(); ++i) - { - string telephone, text; - int meIndex = parsePhonebookEntry(*i, telephone, text); - _phonebook[meToPhonebookIndexMap[meIndex]]._cached = true; - _phonebook[meToPhonebookIndexMap[meIndex]]._telephone = telephone; - _phonebook[meToPhonebookIndexMap[meIndex]]._text = text; - assert(_phonebook[meToPhonebookIndexMap[meIndex]]._index == meIndex); - - ++entriesRead; - startIndex = meIndex + 1; -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Preloading PB entry " << meIndex - << " number " << telephone - << " text " << text << endl; -#endif - } - } - } -} - -Phonebook::iterator Phonebook::begin() -{ - return &_phonebook[0]; -} - -Phonebook::const_iterator Phonebook::begin() const -{ - return &_phonebook[0]; -} - -Phonebook::iterator Phonebook::end() -{ - return &_phonebook[_maxSize]; -} - -Phonebook::const_iterator Phonebook::end() const -{ - return &_phonebook[_maxSize]; -} - -Phonebook::reference Phonebook::operator[](int n) -{ - return _phonebook[n]; -} - -Phonebook::const_reference Phonebook::operator[](int n) const -{ - return _phonebook[n]; -} - -Phonebook::reference Phonebook::front() -{ - return _phonebook[0]; -} - -Phonebook::const_reference Phonebook::front() const -{ - return _phonebook[0]; -} - -Phonebook::reference Phonebook::back() -{ - return _phonebook[_maxSize - 1]; -} - -Phonebook::const_reference Phonebook::back() const -{ - return _phonebook[_maxSize - 1]; -} - -int Phonebook::size() const throw(GsmException) -{ - if (_size != -1) - return _size; - else - { - int result = 0; - for (int i = 0; i < _maxSize; i++) - if (! _phonebook[i].empty()) - result++; - Phonebook *thisPhonebook = const_cast(this); - thisPhonebook->_size = result; - return result; - } -} - -Phonebook::iterator Phonebook::insert(iterator position, - const PhonebookEntry& x) - throw(GsmException) -{ - if (x.useIndex() && x.index() != -1) - return insert(x.telephone(), x.text(), x.index()); - else - return insertFirstEmpty(x.telephone(), x.text()); -} - -void Phonebook::insert (iterator pos, int n, const PhonebookEntry& x) - throw(GsmException) -{ - for (int i = 0; i < n; i++) - if (x.useIndex() && x.index() != -1) - insert(x.telephone(), x.text(), x.index()); - else - insertFirstEmpty(x.telephone(), x.text()); -} - -void Phonebook::insert (iterator pos, long n, const PhonebookEntry& x) - throw(GsmException) -{ - for (long i = 0; i < n; i++) - if (x.useIndex() && x.index() != -1) - insert(x.telephone(), x.text(), x.index()); - else - insertFirstEmpty(x.telephone(), x.text()); -} - -Phonebook::iterator Phonebook::erase(iterator position) - throw(GsmException) -{ - if (! position->empty()) - { - position->set("", ""); - adjustSize(-1); - } - return position + 1; -} - -Phonebook::iterator Phonebook::erase(iterator first, iterator last) - throw(GsmException) -{ - iterator i; - for (i = first; i != last; ++i) - erase(i); - return i; -} - -void Phonebook::clear() throw(GsmException) -{ - for (iterator i = begin(); i != end(); ++i) - erase(i); -} - -Phonebook::iterator Phonebook::find(string text) throw(GsmException) -{ - int index; - string telephone; - - int i; - for (i = 0; i < _maxSize; i++) - if (_phonebook[i].text() == text) - return begin() + i; - - findEntry(text, index, telephone); - - for (i = 0; i < _maxSize; i++) - if (_phonebook[i].index() == index) - if (_phonebook[i].cached()) - { - // if entry was already (= cached) and is now different - // the SIM card or it's contents were changed - if (_phonebook[i]._telephone != telephone || - _phonebook[i]._text != text) - throw GsmException(_("SIM card changed while accessing phonebook"), - OtherError); - } - else - { - _phonebook[i]._cached = true; - _phonebook[i]._telephone = telephone; - _phonebook[i]._text = text; - return begin() + i; - } - return end(); -} - -Phonebook::~Phonebook() -{ - delete []_phonebook; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.h deleted file mode 100644 index 4999da532e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_phonebook.h +++ /dev/null @@ -1,195 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_phonebook.h -// * -// * Purpose: Phonebook management functions -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.5.1999 -// ************************************************************************* - -#ifndef GSM_PHONEBOOK_H -#define GSM_PHONEBOOK_H - -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // forward declarations - class Phonebook; - - // a single entry in the phonebook that corresponds to an ME entry - - class PhonebookEntry : public PhonebookEntryBase - { - private: - // this constructor is only used by Phonebook - PhonebookEntry() {} - bool _cached; // true, if this entry corresponds to info - // in the ME - Phonebook *_myPhonebook; - - public: - PhonebookEntry(string telephone, string text) : - PhonebookEntryBase(telephone, text), - _cached(true), _myPhonebook(NULL) {} - PhonebookEntry(const PhonebookEntryBase &e) throw(GsmException); - - // accessor functions, inherited from PhonebookEntryBase - // set() does not use the index argument - void set(string telephone, string text, int index = -1, - bool useIndex = false) - throw(GsmException); - string text() const throw(GsmException); - string telephone() const throw(GsmException); - - // return true if entry is cached (and caching is enabled) - bool cached() const; - - PhonebookEntry(const PhonebookEntry &e) throw(GsmException); - PhonebookEntry &operator=(const PhonebookEntry &e) throw(GsmException); - - virtual ~PhonebookEntry() {} - - friend class Phonebook; - }; - - // this class corresponds to a phonebook in the ME - // all functions directly update storage in the ME - // if the ME is exchanged, the storage may become corrupted because - // of internal buffering in the Phonebook class - - class Phonebook : public RefBase, public NoCopy - { - public: - // iterator defs - typedef PhonebookEntry *iterator; - typedef const PhonebookEntry *const_iterator; - typedef PhonebookEntry &reference; - typedef const PhonebookEntry &const_reference; - - private: - PhonebookEntry *_phonebook; // array of size _maxSize of entries - int _maxSize; // maximum size of pb (-1 == not known yet) - int _size; // current size of pb (-1 == not known yet) - string _phonebookName; // name of the phonebook, 2-byte like "ME" - unsigned int _maxNumberLength; // maximum length of telephone number - unsigned int _maxTextLength; // maximum length of descriptive text - Ref _at; // my GsmAt class - vector _positionMap; // maps in-memory index to ME index - MeTa &_myMeTa; // the MeTa object that created this Phonebook - bool _useCache; // true if entries should be cached - - // helper function, parse phonebook response returned by ME/TA - // returns index of entry - int parsePhonebookEntry(string response, string &telephone, string &text); - - // internal access functions - // read/write/find entry from/to ME - void readEntry(int index, string &telephone, string &text) - throw(GsmException); - void writeEntry(int index, string telephone, string text) - throw(GsmException); - void findEntry(string text, int &index, string &telephone) - throw(GsmException); - - // adjust size only if it was set once - void adjustSize(int sizeAdjust) - { - if (_size != -1) _size += sizeAdjust; - } - - // insert into first empty position and return position where inserted - iterator insertFirstEmpty(const string telephone, const string text) - throw(GsmException); - - // insert into specified index position - iterator insert(const string telephone, const string text, - const int index); - - // used my class MeTa - // load phonebook name phonebookName, use AT handler at - // preload entire phonebook if preload == true - Phonebook(string phonebookName, Ref at, - MeTa &myMeTa, bool preload = false) throw(GsmException); - - public: - // set cache mode on or off - void setCaching(bool useCache) {_useCache = useCache;} - - // return name of this phonebook (2-character string) - string name() const {return _phonebookName;} - - // return maximum telephone number length - unsigned int getMaxTelephoneLen() const {return _maxNumberLength;} - - // return maximum entry description length - unsigned int getMaxTextLen() const { return _maxTextLength;} - - // phonebook traversal commands - // these are suitable to use stdc++ lib algorithms and iterators - // ME have fixed storage space implemented as memory slots - // that may either be empty or used - - // traversal commands - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - reference operator[](int n); - const_reference operator[](int n) const; - - // the size macros return the number of used entries - int size() const throw(GsmException); - int max_size() const {return _maxSize;} - int capacity() const {return _maxSize;} - bool empty() const throw(GsmException) {return size() == 0;} - - // insert iterators insert into the first empty cell regardless of position - // - existing iterators are not invalidated after an insert operation - // - return position where it was actually inserted (may be != position) - // - insert only writes to available positions - // - throw an exception if size() == max_size() (ie. not empty slots) - iterator insert(iterator position, const PhonebookEntry& x) - throw(GsmException); - - // insert n times, same procedure as above - void insert(iterator pos, int n, const PhonebookEntry& x) - throw(GsmException); - void insert(iterator pos, long n, const PhonebookEntry& x) - throw(GsmException); - - // erase operators set used slots to "empty" - iterator erase(iterator position) throw(GsmException); - iterator erase(iterator first, iterator last) throw(GsmException); - void clear() throw(GsmException); - - // finds an entry given the text - iterator find(string text) throw(GsmException); - - // destructor - virtual ~Phonebook(); - - friend class PhonebookEntry; - friend class MeTa; - }; - - // useful phonebook types - typedef Ref PhonebookRef; - typedef vector PhonebookVector; -}; - -#endif // GSM_PHONEBOOK_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_port.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_port.h deleted file mode 100644 index 83c4edf60e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_port.h +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_port.h -// * -// * Purpose: Abstract port definition -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.5.1999 -// ************************************************************************* - -#ifndef GSM_PORT_H -#define GSM_PORT_H - -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // TA defaults - const int TIMEOUT_SECS = 60; - const char DEFAULT_INIT_STRING[] = "E0"; - const int DEFAULT_BAUD_RATE = 38400; - - class Port : public RefBase - { - public: - // read line from port(including eol characters) - virtual string getLine() throw(GsmException) =0; - - // write line to port - virtual void putLine(string line, - bool carriageReturn = true) throw(GsmException) =0; - - // wait for new data to become available, return after timeout - // if timeout == 0, wait forever - // return true if data available - virtual bool wait(GsmTime timeout) throw(GsmException) =0; - - // put back one byte that can be read by a subsequent call to readByte() - virtual void putBack(unsigned char c) =0; - - // read a single byte, return -1 if error or file closed - virtual int readByte() throw(GsmException) =0; - - // set timeout for the readByte(), getLine(), and putLine() functions - // (globally for ALL ports) - virtual void setTimeOut(unsigned int timeout) =0; - - virtual ~Port() {} - }; -}; - -#endif // GSM_PORT_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.cc deleted file mode 100644 index e150423add..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.cc +++ /dev/null @@ -1,863 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sms.cc -// * -// * Purpose: SMS functions -// * (ETSI GSM 07.05) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 16.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// local constants - -static const string dashes = -"---------------------------------------------------------------------------"; - -// SMSMessage members - -Ref SMSMessage::decode(string pdu, - bool SCtoMEdirection, - GsmAt *at) throw(GsmException) -{ - Ref result; - SMSDecoder d(pdu); - d.getAddress(true); - MessageType messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - if (SCtoMEdirection) - // TPDUs from SC to ME - switch (messageTypeIndicator) - { - case SMS_DELIVER: - result = new SMSDeliverMessage(pdu); - break; - - case SMS_STATUS_REPORT: - result = new SMSStatusReportMessage(pdu); - break; - - case SMS_SUBMIT_REPORT: - // observed with Motorola Timeport 260, the SCtoMEdirection can - // be wrong in this case - if (at != NULL && at->getMeTa().getCapabilities()._wrongSMSStatusCode) - result = new SMSSubmitMessage(pdu); - else - result = new SMSSubmitReportMessage(pdu); - break; - - default: - throw GsmException(_("unhandled SMS TPDU type"), OtherError); - } - else - // TPDUs from ME to SC - switch (messageTypeIndicator) - { - case SMS_SUBMIT: - result = new SMSSubmitMessage(pdu); - break; - - case SMS_DELIVER_REPORT: - result = new SMSDeliverReportMessage(pdu); - break; - - case SMS_COMMAND: - result = new SMSCommandMessage(pdu); - break; - - default: - throw GsmException(_("unhandled SMS TPDU type"), OtherError); - } - result->_at = at; - return result; -} - -Ref SMSMessage::decode(istream& s) throw(gsmlib::GsmException) -{ - string pdu; - unsigned char ScToMe; - - s >> ScToMe; - s >> pdu; - - return decode(pdu,ScToMe=='S'); -} - -unsigned char SMSMessage::send(Ref &ackPdu) - throw(GsmException) -{ - if (_messageTypeIndicator != SMS_SUBMIT && - _messageTypeIndicator != SMS_COMMAND) - throw GsmException(_("can only send SMS-SUBMIT and SMS-COMMAND TPDUs"), - ParameterError); - - if (_at.isnull()) - throw GsmException(_("no device given for sending SMS"), ParameterError); - - string pdu = encode(); - Parser p(_at->sendPdu("+CMGS=" + - intToStr(pdu.length() / 2 - getSCAddressLen()), - "+CMGS:", pdu)); - unsigned char messageReference = p.parseInt(); - - if (p.parseComma(true)) - { - string pdu = p.parseEol(); - - // add missing service centre address if required by ME - if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix) - pdu = "00" + pdu; - - ackPdu = SMSMessage::decode(pdu); - } - else - ackPdu = SMSMessageRef(); - - return messageReference; -} - -unsigned char SMSMessage::send() throw(GsmException) -{ - SMSMessageRef mref; - return send(mref); -} - -unsigned int SMSMessage::getSCAddressLen() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - return e.getLength(); -} - -unsigned char SMSMessage::userDataLength() const -{ - unsigned int udhl = _userDataHeader.length(); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - return _userData.length() + (udhl ? ((1 + udhl) * 8 + 6) / 7 : 0); - else - return _userData.length() + (udhl ? (1 + udhl) : 0); -} - -ostream& SMSMessage::operator<<(ostream& s) -{ - unsigned char ScToMe; - - if (dynamic_cast(this) || - dynamic_cast(this) || - dynamic_cast(this)) - { - ScToMe = 'S'; - } - else if (dynamic_cast(this) || - dynamic_cast(this) || - dynamic_cast(this)) - { - ScToMe = 'M'; - } - else - { - throw GsmException(_("unhandled SMS TPDU type"), OtherError); - } - - s << ScToMe; - return s << encode(); -} - -// SMSMessage::SMSMessage(SMSMessage &m) -// { -// _at = m._at; - -// } - -// SMSMessage &SMSMessage::operator=(SMSMessage &m) -// { -// } - -SMSMessage::~SMSMessage() {} - -// SMSDeliverMessage members - -void SMSDeliverMessage::init() -{ - _messageTypeIndicator = SMS_DELIVER; - _moreMessagesToSend = false; - _replyPath = false; - _statusReportIndication = false; - _protocolIdentifier = 0; -} - -SMSDeliverMessage::SMSDeliverMessage() -{ - init(); -} - -SMSDeliverMessage::SMSDeliverMessage(string pdu) throw(GsmException) -{ - SMSDecoder d(pdu); - _serviceCentreAddress = d.getAddress(true); - _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - assert(_messageTypeIndicator == SMS_DELIVER); - _moreMessagesToSend = d.getBit(); // bit 2 - d.getBit(); // bit 3 - d.getBit(); // bit 4 - _statusReportIndication = d.getBit(); // bit 5 - bool userDataHeaderIndicator = d.getBit(); // bit 6 - _replyPath = d.getBit(); // bit 7 - _originatingAddress = d.getAddress(); - _protocolIdentifier = d.getOctet(); - _dataCodingScheme = d.getOctet(); - _serviceCentreTimestamp = d.getTimestamp(); - unsigned char userDataLength = d.getOctet(); - d.markSeptet(); - - if (userDataHeaderIndicator) - { - _userDataHeader.decode(d); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - userDataLength -= ((_userDataHeader.length() + 1) * 8 + 6) / 7; - else - userDataLength -= ((string)_userDataHeader).length() + 1; - } - else - _userDataHeader = UserDataHeader(); - - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - { // userDataLength is length in septets - _userData = d.getString(userDataLength); - _userData = gsmToLatin1(_userData); - } - else - { // userDataLength is length in octets - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * userDataLength); - d.getOctets(s, userDataLength); - _userData.assign((char*)s, (unsigned int)userDataLength); - } -} - -string SMSDeliverMessage::encode() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - e.set2Bits(_messageTypeIndicator); // bits 0..1 - e.setBit(_moreMessagesToSend); // bit 2 - e.setBit(); // bit 3 - e.setBit(); // bit 4 - e.setBit(_statusReportIndication); // bit 5 - e.setBit(_userDataHeader.length() != 0); // bit 6 - e.setBit(_replyPath); // bit 7 - e.setAddress(_originatingAddress); - e.setOctet(_protocolIdentifier); - e.setOctet(_dataCodingScheme); - e.setTimestamp(_serviceCentreTimestamp); - e.setOctet(userDataLength()); - e.markSeptet(); - if (_userDataHeader.length()) _userDataHeader.encode(e); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - e.setString(latin1ToGsm(_userData)); - else - e.setOctets((unsigned char*)_userData.data(), _userData.length()); - return e.getHexString(); -} - -string SMSDeliverMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: SMS-DELIVER") << endl - << _("SC address: '") << _serviceCentreAddress._number << "'" << endl - << _("More messages to send: ") << _moreMessagesToSend << endl - << _("Reply path: ") << _replyPath << endl - << _("User data header indicator: ") - << (_userDataHeader.length()!=0) << endl - << _("Status report indication: ") << _statusReportIndication << endl - << _("Originating address: '") << _originatingAddress._number - << "'" << endl - << _("Protocol identifier: 0x") << hex - << (unsigned int)_protocolIdentifier << dec << endl - << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl - << _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl - << _("User data length: ") << (int)userDataLength() << endl - << _("User data header: 0x") - << bufToHex((unsigned char*) - ((string)_userDataHeader).data(), - ((string)_userDataHeader).length()) - << endl - << _("User data: '") << _userData << "'" << endl - << dashes << endl << endl - << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -Address SMSDeliverMessage::address() const -{ - return _originatingAddress; -} - -Ref SMSDeliverMessage::clone() -{ - Ref result = new SMSDeliverMessage(*this); - return result; -} - -// SMSSubmitMessage members - -void SMSSubmitMessage::init() -{ - // set everything to sensible default values - _messageTypeIndicator = SMS_SUBMIT; - _validityPeriodFormat = TimePeriod::Relative; - _validityPeriod._format = TimePeriod::Relative; - _validityPeriod._relativeTime = 168; // 2 days - _statusReportRequest = false; - _replyPath = false; - _rejectDuplicates = true; - _messageReference = 0; - _protocolIdentifier = 0; -} - -SMSSubmitMessage::SMSSubmitMessage() -{ - init(); -} - -SMSSubmitMessage::SMSSubmitMessage(string pdu) throw(GsmException) -{ - SMSDecoder d(pdu); - _serviceCentreAddress = d.getAddress(true); - _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - assert(_messageTypeIndicator == SMS_SUBMIT); - _rejectDuplicates = d.getBit(); // bit 2 - _validityPeriodFormat = (TimePeriod::Format)d.get2Bits(); // bits 3..4 - _statusReportRequest = d.getBit(); // bit 5 - bool userDataHeaderIndicator = d.getBit(); // bit 6 - _replyPath = d.getBit(); // bit 7 - _messageReference = d.getOctet(); - _destinationAddress = d.getAddress(); - _protocolIdentifier = d.getOctet(); - _dataCodingScheme = d.getOctet(); - if (_validityPeriodFormat != TimePeriod::NotPresent) - _validityPeriod = d.getTimePeriod(_validityPeriodFormat); - unsigned char userDataLength = d.getOctet(); - d.markSeptet(); - - if (userDataHeaderIndicator) - { - _userDataHeader.decode(d); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - userDataLength -= ((_userDataHeader.length() + 1) * 8 + 6) / 7; - else - userDataLength -= ((string)_userDataHeader).length() + 1; - } - else - _userDataHeader = UserDataHeader(); - - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - { // userDataLength is length in septets - _userData = d.getString(userDataLength); - _userData = gsmToLatin1(_userData); - } - else - { // _userDataLength is length in octets - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * userDataLength); - d.getOctets(s, userDataLength); - _userData.assign((char*)s, userDataLength); - } -} - -SMSSubmitMessage::SMSSubmitMessage(string text, string number) -{ - init(); - _destinationAddress = Address(number); - _userData = text; -} - -string SMSSubmitMessage::encode() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - e.set2Bits(_messageTypeIndicator); // bits 0..1 - e.setBit(_rejectDuplicates); // bit 2 - e.set2Bits(_validityPeriodFormat); // bits 3..4 - e.setBit(_statusReportRequest); // bit 5 - bool userDataHeaderIndicator = _userDataHeader.length() != 0; - e.setBit(userDataHeaderIndicator); // bit 6 - e.setBit(_replyPath); // bit 7 - e.setOctet(_messageReference); - e.setAddress(_destinationAddress); - e.setOctet(_protocolIdentifier); - e.setOctet(_dataCodingScheme); - e.setTimePeriod(_validityPeriod); - e.setOctet(userDataLength()); - e.markSeptet(); - if (userDataHeaderIndicator) _userDataHeader.encode(e); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - e.setString(latin1ToGsm(_userData)); - else - e.setOctets((unsigned char*)_userData.data(), _userData.length()); - return e.getHexString(); -} - -string SMSSubmitMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: SMS-SUBMIT") << endl - << _("SC address: '") << _serviceCentreAddress._number << "'" << endl - << _("Reject duplicates: ") << _rejectDuplicates << endl - << _("Validity period format: "); - switch (_validityPeriodFormat) - { - case TimePeriod::NotPresent: - os << _("not present"); - break; - case TimePeriod::Relative: - os << _("relative"); - break; - case TimePeriod::Absolute: - os << _("absolute"); - break; - default: - os << _("unknown"); - break; - } - os << endl - << _("Reply path: ") << _replyPath << endl - << _("User data header indicator: ") - << (_userDataHeader.length()!=0) << endl - << _("Status report request: ") << _statusReportRequest << endl - << _("Message reference: ") << (unsigned int)_messageReference << endl - << _("Destination address: '") << _destinationAddress._number - << "'" << endl - << _("Protocol identifier: 0x") << hex - << (unsigned int)_protocolIdentifier << dec << endl - << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl - << _("Validity period: ") << _validityPeriod.toString() << endl - << _("User data length: ") << (int)userDataLength() << endl - << _("User data header: 0x") << bufToHex((unsigned char*) - ((string)_userDataHeader).data(), - _userDataHeader.length()) - << endl - << _("User data: '") << _userData << "'" << endl - << dashes << endl << endl - << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -Address SMSSubmitMessage::address() const -{ - return _destinationAddress; -} - -Ref SMSSubmitMessage::clone() -{ - Ref result = new SMSSubmitMessage(*this); - return result; -} - -// SMSStatusReportMessage members - -void SMSStatusReportMessage::init() -{ - _messageTypeIndicator = SMS_STATUS_REPORT; - _moreMessagesToSend = false; - _statusReportQualifier = false; - _messageReference = 0; - _status = SMS_STATUS_RECEIVED; -} - -SMSStatusReportMessage::SMSStatusReportMessage(string pdu) throw(GsmException) -{ - SMSDecoder d(pdu); - _serviceCentreAddress = d.getAddress(true); - _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - assert(_messageTypeIndicator == SMS_STATUS_REPORT); - _moreMessagesToSend = d.getBit(); // bit 2 - d.getBit(); // bit 3 - d.getBit(); // bit 4 - _statusReportQualifier = d.getBit(); // bit 5 - _messageReference = d.getOctet(); - _recipientAddress = d.getAddress(); - _serviceCentreTimestamp = d.getTimestamp(); - _dischargeTime = d.getTimestamp(); - _status = d.getOctet(); -} - -string SMSStatusReportMessage::encode() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - e.set2Bits(_messageTypeIndicator); // bits 0..1 - e.setBit(_moreMessagesToSend); // bit 2 - e.setBit(); // bit 3 - e.setBit(); // bit 4 - e.setBit(_statusReportQualifier); // bit 5 - e.setOctet(_messageReference); - e.setAddress(_recipientAddress); - e.setTimestamp(_serviceCentreTimestamp); - e.setTimestamp(_dischargeTime); - e.setOctet(_status); - return e.getHexString(); -} - -string SMSStatusReportMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: SMS-STATUS-REPORT") << endl - << _("SC address: '") << _serviceCentreAddress._number << "'" << endl - << _("More messages to send: ") << _moreMessagesToSend << endl - << _("Status report qualifier: ") << _statusReportQualifier << endl - << _("Message reference: ") << (unsigned int)_messageReference << endl - << _("Recipient address: '") << _recipientAddress._number << "'" << endl - << _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl - << _("Discharge time: ") << _dischargeTime.toString() << endl - << _("Status: 0x") << hex << (unsigned int)_status << dec - << " '" << getSMSStatusString(_status) << "'" << endl - << dashes << endl << endl - << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -Address SMSStatusReportMessage::address() const -{ - return _recipientAddress; -} - -Ref SMSStatusReportMessage::clone() -{ - Ref result = new SMSStatusReportMessage(*this); - return result; -} - -// SMSCommandMessage members - -void SMSCommandMessage::init() -{ - _messageTypeIndicator = SMS_COMMAND; - _messageReference = 0; - _statusReportRequest = true; - _protocolIdentifier = 0; - _commandType = EnquireSM; - _messageNumber = 0; - _commandDataLength = 0; -} - -SMSCommandMessage::SMSCommandMessage(string pdu) throw(GsmException) -{ - SMSDecoder d(pdu); - _serviceCentreAddress = d.getAddress(true); - _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - assert(_messageTypeIndicator == SMS_COMMAND); - d.getBit(); // bit 2 - d.getBit(); // bit 3 - d.getBit(); // bit 4 - _statusReportRequest = d.getBit(); // bit 5 - _messageReference = d.getOctet(); - _protocolIdentifier = d.getOctet(); - _commandType = d.getOctet(); - _messageNumber = d.getOctet(); - _destinationAddress = d.getAddress(); - _commandDataLength = d.getOctet(); - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * _commandDataLength); - d.getOctets(s, _commandDataLength); -} - -string SMSCommandMessage::encode() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - e.set2Bits(_messageTypeIndicator); // bits 0..1 - e.setBit(); // bit 2 - e.setBit(); // bit 3 - e.setBit(); // bit 4 - e.setBit(_statusReportRequest); // bit 5 - e.setOctet(_messageReference); - e.setOctet(_protocolIdentifier); - e.setOctet(_commandType); - e.setOctet(_messageNumber); - e.setAddress(_destinationAddress); - e.setOctet(_commandData.length()); - e.setOctets((const unsigned char*)_commandData.data(), - (short unsigned int)_commandData.length()); - return e.getHexString(); -} - -string SMSCommandMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: SMS-COMMAND") << endl - << _("SC address: '") << _serviceCentreAddress._number << "'" << endl - << _("Message reference: ") << (unsigned int)_messageReference << endl - << _("Status report request: ") << _statusReportRequest << endl - << _("Protocol identifier: 0x") << hex - << (unsigned int)_protocolIdentifier << dec << endl - << _("Command type: 0x") << hex << (unsigned int)_commandType - << dec << endl - << _("Message number: ") << (unsigned int)_messageNumber << endl - << _("Destination address: '") << _destinationAddress._number - << "'" << endl - << _("Command data length: ") << (unsigned int)_commandDataLength << endl - << _("Command data: '") << _commandData << "'" << endl - << dashes << endl << endl - << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -Address SMSCommandMessage::address() const -{ - return _destinationAddress; -} - -Ref SMSCommandMessage::clone() -{ - Ref result = new SMSCommandMessage(*this); - return result; -} - -// SMSDeliverReportMessage members - -void SMSDeliverReportMessage::init() -{ - _messageTypeIndicator = SMS_DELIVER_REPORT; - _protocolIdentifierPresent = false; - _dataCodingSchemePresent = false; - _userDataLengthPresent = false; -} - -SMSDeliverReportMessage::SMSDeliverReportMessage(string pdu) - throw(GsmException) -{ - SMSDecoder d(pdu); - _serviceCentreAddress = d.getAddress(true); - _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - assert(_messageTypeIndicator == SMS_DELIVER_REPORT); - d.alignOctet(); // skip to parameter indicator - _protocolIdentifierPresent = d.getBit(); // bit 0 - _dataCodingSchemePresent = d.getBit(); // bit 1 - _userDataLengthPresent = d.getBit(); // bit 2 - if (_protocolIdentifierPresent) - _protocolIdentifier = d.getOctet(); - if (_dataCodingSchemePresent) - _dataCodingScheme = d.getOctet(); - if (_userDataLengthPresent) - { - unsigned char userDataLength = d.getOctet(); - d.markSeptet(); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - { - _userData = d.getString(userDataLength); - _userData = gsmToLatin1(_userData); - } - else - { // userDataLength is length in octets - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * userDataLength); - d.getOctets(s, userDataLength); - _userData.assign((char*)s, userDataLength); - } - } -} - -string SMSDeliverReportMessage::encode() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - e.set2Bits(_messageTypeIndicator); // bits 0..1 - e.alignOctet(); // skip to parameter indicator - e.setBit(_protocolIdentifierPresent); // bit 0 - e.setBit(_dataCodingSchemePresent); // bit 1 - e.setBit(_userDataLengthPresent); // bit 2 - if (_protocolIdentifierPresent) - e.setOctet(_protocolIdentifier); - if (_dataCodingSchemePresent) - e.setOctet(_dataCodingScheme); - if (_userDataLengthPresent) - { - unsigned char userDataLength = _userData.length(); - e.setOctet(userDataLength); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - e.setString(latin1ToGsm(_userData)); - else - e.setOctets((unsigned char*)_userData.data(), userDataLength); - } - return e.getHexString(); -} - -string SMSDeliverReportMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: SMS-DELIVER-REPORT") << endl - << _("SC address: '") << _serviceCentreAddress._number << "'" << endl - << _("Protocol identifier present: ") << _protocolIdentifierPresent - << endl - << _("Data coding scheme present: ") << _dataCodingSchemePresent << endl - << _("User data length present: ") << _userDataLengthPresent << endl; - if (_protocolIdentifierPresent) - os << _("Protocol identifier: 0x") << hex - << (unsigned int)_protocolIdentifier - << dec << endl; - if (_dataCodingSchemePresent) - os << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl; - if (_userDataLengthPresent) - os << _("User data length: ") << (int)userDataLength() << endl - << _("User data: '") << _userData << "'" << endl; - os << dashes << endl << endl - << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -Address SMSDeliverReportMessage::address() const -{ - assert(0); // not address, should not be in SMS store - return Address(); -} - -Ref SMSDeliverReportMessage::clone() -{ - Ref result = new SMSDeliverReportMessage(*this); - return result; -} - -// SMSSubmitReportMessage members - -void SMSSubmitReportMessage::init() -{ - _messageTypeIndicator = SMS_SUBMIT_REPORT; - _protocolIdentifierPresent = false; - _dataCodingSchemePresent = false; - _userDataLengthPresent = false; -} - -SMSSubmitReportMessage::SMSSubmitReportMessage(string pdu) throw(GsmException) -{ - SMSDecoder d(pdu); - _serviceCentreAddress = d.getAddress(true); - _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 - assert(_messageTypeIndicator == SMS_SUBMIT_REPORT); - _serviceCentreTimestamp = d.getTimestamp(); - _protocolIdentifierPresent = d.getBit(); // bit 0 - _dataCodingSchemePresent = d.getBit(); // bit 1 - _userDataLengthPresent = d.getBit(); // bit 2 - if (_protocolIdentifierPresent) - _protocolIdentifier = d.getOctet(); - if (_dataCodingSchemePresent) - _dataCodingScheme = d.getOctet(); - if (_userDataLengthPresent) - { - unsigned char userDataLength = d.getOctet(); - d.markSeptet(); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - { - _userData = d.getString(userDataLength); - _userData = gsmToLatin1(_userData); - } - else - { // _userDataLength is length in octets - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * userDataLength); - d.getOctets(s, userDataLength); - _userData.assign((char*)s, userDataLength); - } - } -} - -string SMSSubmitReportMessage::encode() -{ - SMSEncoder e; - e.setAddress(_serviceCentreAddress, true); - e.set2Bits(_messageTypeIndicator); // bits 0..1 - e.setTimestamp(_serviceCentreTimestamp); - e.setBit(_protocolIdentifierPresent); // bit 0 - e.setBit(_dataCodingSchemePresent); // bit 1 - e.setBit(_userDataLengthPresent); // bit 2 - if (_protocolIdentifierPresent) - e.setOctet(_protocolIdentifier); - if (_dataCodingSchemePresent) - e.setOctet(_dataCodingScheme); - if (_userDataLengthPresent) - { - e.setOctet(userDataLength()); - if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) - e.setString(latin1ToGsm(_userData)); - else - e.setOctets((unsigned char*)_userData.data(), _userData.length()); - } - return e.getHexString(); -} - -string SMSSubmitReportMessage::toString() const -{ - ostrstream os; - os << dashes << endl - << _("Message type: SMS-SUBMIT-REPORT") << endl - << _("SC address: '") << _serviceCentreAddress._number << "'" << endl - << _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl - << _("Protocol identifier present: ") << _protocolIdentifierPresent - << endl - << _("Data coding scheme present: ") << _dataCodingSchemePresent << endl - << _("User data length present: ") << _userDataLengthPresent << endl; - if (_protocolIdentifierPresent) - os << _("Protocol identifier: 0x") << hex - << (unsigned int)_protocolIdentifier - << dec << endl; - if (_dataCodingSchemePresent) - os << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl; - if (_userDataLengthPresent) - os << _("User data length: ") << (int)userDataLength() << endl - << _("User data: '") << _userData << "'" << endl; - os << dashes << endl << endl - << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -Address SMSSubmitReportMessage::address() const -{ - assert(0); // not address, should not be in SMS store - return Address(); -} - -Ref SMSSubmitReportMessage::clone() -{ - Ref result = new SMSSubmitReportMessage(*this); - return result; -} - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.h deleted file mode 100644 index bd871391bb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms.h +++ /dev/null @@ -1,480 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sms.h -// * -// * Purpose: SMS functions -// * (ETSI GSM 07.05) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 16.5.1999 -// ************************************************************************* - -#ifndef GSM_SMS_H -#define GSM_SMS_H - -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // forward declarations - class SMSStore; - class SMSMessage; - - // this class represents a single SMS message - class SMSMessage : public RefBase - { - private: - Ref _at; // connection to the device - - public: - // possible values for message type indicator - enum MessageType {SMS_DELIVER = 0, SMS_DELIVER_REPORT = 0, - SMS_STATUS_REPORT = 2, SMS_COMMAND = 2, - SMS_SUBMIT = 1, SMS_SUBMIT_REPORT = 1}; - - protected: - // fields of the different TPDUs - // all PDUs - string _userData; - UserDataHeader _userDataHeader; - Address _serviceCentreAddress; - MessageType _messageTypeIndicator;// 2 bits - DataCodingScheme _dataCodingScheme; - - public: - // decode hexadecimal pdu string - // return SMSMessage of the appropriate type - // differentiate between SMS transfer directions SC to ME, ME to SC - // also give GsmAt object for send() - static Ref decode(string pdu, - bool SCtoMEdirection = true, - GsmAt *at = NULL) - throw(GsmException); - - static Ref decode(istream& s) throw(GsmException); - - // encode pdu, return hexadecimal pdu string - virtual string encode() = 0; - - // send this PDU - // returns message reference and ACK-PDU (if requested) - // only applicate to SMS-SUBMIT and SMS-COMMAND - unsigned char send(Ref &ackPdu) throw(GsmException); - - // same as above, but ACK-PDU is discarded - unsigned char send() throw(GsmException); - - // create textual representation of SMS - virtual string toString() const = 0; - - // return deep copy of this message - virtual Ref clone() = 0; - - // return length of SC address when encoded - unsigned int getSCAddressLen(); - - // accessor functions - MessageType messageType() const {return _messageTypeIndicator;} - Address serviceCentreAddress() const {return _serviceCentreAddress;} - - // provided for sorting messages by timestamp - virtual Timestamp serviceCentreTimestamp() const {return Timestamp();} - - // return recipient, destination etc. address (for sorting by address) - virtual Address address() const = 0; - - virtual void setUserData(string x) {_userData = x;} - virtual string userData() const {return _userData;} - - // return the size of user data (including user data header) - unsigned char userDataLength() const; - - // accessor functions - virtual void setUserDataHeader(UserDataHeader x) {_userDataHeader = x;} - virtual UserDataHeader userDataHeader() const {return _userDataHeader;} - - virtual DataCodingScheme dataCodingScheme() const - {return _dataCodingScheme;} - virtual void setDataCodingScheme(DataCodingScheme x) - {_dataCodingScheme = x;} - - void setServiceCentreAddress(Address &x) {_serviceCentreAddress = x;} - void setAt(Ref at) {_at = at;} - - virtual ~SMSMessage(); - - // print ASCII hex representation of message - ostream& operator<<(ostream& s); - - // copy constructor and assignment -// SMSMessage(SMSMessage &m); -// SMSMessage &operator=(SMSMessage &m); - - friend class SMSStore; - }; - - // SMS-DELIVER TPDU - class SMSDeliverMessage : public SMSMessage - { - private: - // SMS-DELIVER PDU members (see GSM 03.40 section 9.2.2.1) - bool _moreMessagesToSend; - bool _replyPath; - bool _statusReportIndication; - Address _originatingAddress; - unsigned char _protocolIdentifier; // octet - Timestamp _serviceCentreTimestamp; - - // initialize members to sensible values - void init(); - - public: - // constructor, sets sensible default values - SMSDeliverMessage(); - - // constructor with given pdu - SMSDeliverMessage(string pdu) throw(GsmException); - - // encode pdu, return hexadecimal pdu string - virtual string encode(); - - // create textual representation of SMS - virtual string toString() const; - - // inherited from SMSMessage - Address address() const; - Ref clone(); - - // accessor functions - bool moreMessagesToSend() const {return _moreMessagesToSend;} - bool replyPath() const {return _replyPath;} - bool statusReportIndication() const {return _statusReportIndication;} - Address originatingAddress() const {return _originatingAddress;} - unsigned char protocolIdentifier() const {return _protocolIdentifier;} - Timestamp serviceCentreTimestamp() const {return _serviceCentreTimestamp;} - - void setMoreMessagesToSend(bool x) {_moreMessagesToSend = x;} - void setReplyPath(bool x) {_replyPath = x;} - void setStatusReportIndication(bool x) {_statusReportIndication = x;} - void setOriginatingAddress(Address &x) {_originatingAddress = x;} - void setProtocolIdentifier(unsigned char x) {_protocolIdentifier = x;} - void setServiceCentreTimestamp(Timestamp &x) {_serviceCentreTimestamp = x;} - - virtual ~SMSDeliverMessage() {} - }; - - // SMS-SUBMIT TPDU - class SMSSubmitMessage : public SMSMessage - { - private: - // SMS-SUBMIT PDU (see GSM 03.40 section 9.2.2.2) - bool _rejectDuplicates; - TimePeriod::Format _validityPeriodFormat; // 2 bits - bool _replyPath; - bool _statusReportRequest; - unsigned char _messageReference; // integer - Address _destinationAddress; - unsigned char _protocolIdentifier; - TimePeriod _validityPeriod; - - // initialize members to sensible values - void init(); - - public: - // constructor, sets sensible default values - SMSSubmitMessage(); - - // constructor with given pdu - SMSSubmitMessage(string pdu) throw(GsmException); - - // convenience constructor - // given the text and recipient telephone number - SMSSubmitMessage(string text, string number); - - // encode pdu, return hexadecimal pdu string - virtual string encode(); - - // create textual representation of SMS - virtual string toString() const; - - // inherited from SMSMessage - Address address() const; - Ref clone(); - - // accessor functions - bool rejectDuplicates() const {return _rejectDuplicates;} - TimePeriod::Format validityPeriodFormat() const - {return _validityPeriodFormat;} - bool replyPath() const {return _replyPath;} - bool statusReportRequest() const {return _statusReportRequest;} - unsigned char messageReference() const {return _messageReference;} - Address destinationAddress() const {return _destinationAddress;} - unsigned char protocolIdentifier() const {return _protocolIdentifier;} - TimePeriod validityPeriod() const {return _validityPeriod;} - - void setRejectDuplicates(bool x) {_rejectDuplicates = x;} - void setValidityPeriodFormat(TimePeriod::Format &x) - {_validityPeriodFormat = x;} - void setReplyPath(bool x) {_replyPath = x;} - void setStatusReportRequest(bool x) {_statusReportRequest = x;} - void setMessageReference(unsigned char x) {_messageReference = x;} - void setDestinationAddress(Address &x) {_destinationAddress = x;} - void setProtocolIdentifier(unsigned char x) {_protocolIdentifier = x;} - void setValidityPeriod(TimePeriod &x) {_validityPeriod = x;} - - virtual ~SMSSubmitMessage() {} - }; - - // SMS-STATUS-REPORT TPDU - class SMSStatusReportMessage : public SMSMessage - { - private: - // SMS-STATUS-REPORT PDU (see GSM 03.40 section 9.2.2.3) - bool _moreMessagesToSend; - bool _statusReportQualifier; - unsigned char _messageReference; - Address _recipientAddress; - Timestamp _serviceCentreTimestamp; - Timestamp _dischargeTime; - unsigned char _status; // octet - - // initialize members to sensible values - void init(); - - public: - // constructor, sets sensible default values - SMSStatusReportMessage() {init();} - - // constructor with given pdu - SMSStatusReportMessage(string pdu) throw(GsmException); - - // encode pdu, return hexadecimal pdu string - virtual string encode(); - - // create textual representation of SMS - virtual string toString() const; - - // inherited from SMSMessage - Address address() const; - Ref clone(); - - // accessor functions - bool moreMessagesToSend() const {return _moreMessagesToSend;} - bool statusReportQualifier() const {return _statusReportQualifier;} - unsigned char messageReference() const {return _messageReference;} - Address recipientAddress() const {return _recipientAddress;} - Timestamp serviceCentreTimestamp() const {return _serviceCentreTimestamp;} - Timestamp dischargeTime() const {return _dischargeTime;} - unsigned char status() const {return _status;} - - void setMoreMessagesToSend(bool x) {_moreMessagesToSend = x;} - void setStatusReportQualifier(bool x) {_statusReportQualifier = x;} - void setMessageReference(unsigned char x) {_messageReference = x;} - void setRecipientAddress(Address x) {_recipientAddress = x;} - void setServiceCentreTimestamp(Timestamp x) {_serviceCentreTimestamp = x;} - void setDischargeTime(Timestamp x) {_serviceCentreTimestamp = x;} - void setStatus(unsigned char x) {_status = x;} - - virtual ~SMSStatusReportMessage() {} - }; - - // SMS-COMMAND TPDU - class SMSCommandMessage : public SMSMessage - { - public: - // command types, other values are reserved or SC-specific - enum CommandType {EnquireSM = 0, CancelStatusReportRequest = 1, - DeleteSubmittedSM = 2, EnalbeStatusReportRequest = 3}; - - private: - // SMS-COMMAND PDU (see GSM 03.40 section 9.2.2.4) - unsigned char _messageReference; - bool _statusReportRequest; - unsigned char _protocolIdentifier; - unsigned char _commandType; - unsigned char _messageNumber; - Address _destinationAddress; - unsigned char _commandDataLength; - string _commandData; - - // initialize members to sensible values - void init(); - - public: - // constructor, sets sensible default values - SMSCommandMessage() {init();} - - // constructor with given pdu - SMSCommandMessage(string pdu) throw(GsmException); - - // encode pdu, return hexadecimal pdu string - virtual string encode(); - - // create textual representation of SMS - virtual string toString() const; - - // inherited from SMSMessage - Address address() const; - Ref clone(); - - // accessor functions - unsigned char messageReference() const {return _messageReference;} - bool statusReportRequest() const {return _statusReportRequest;} - unsigned char protocolIdentifier() const {return _protocolIdentifier;} - unsigned char commandType() const {return _commandType;} - unsigned char messageNumber() const {return _messageNumber;} - Address destinationAddress() const {return _destinationAddress;} - unsigned char commandDataLength() const {return _commandDataLength;} - string commandData() const {return _commandData;} - - void setMessageReference(unsigned char x) {_messageReference = x;} - void setStatusReportRequest(bool x) {_statusReportRequest = x;} - void setProtocolIdentifier(unsigned char x) {_protocolIdentifier = x;} - void setCommandType(unsigned char x) {_commandType = x;} - void setMessageNumber(unsigned char x) {_messageNumber = x;} - void setDestinationAddress(Address &x) {_destinationAddress = x;} - void setCommandDataLength(unsigned char x) {_commandDataLength = x;} - void setCommandData(string x) {_commandData = x;} - - virtual ~SMSCommandMessage() {} - }; - - // SMS-DELIVER-REPORT TPDU for RP-ACK - class SMSDeliverReportMessage : public SMSMessage - { - private: - // SMS-DELIVER-REPORT PDU (see GSM 03.40 section 9.2.2.1a (II)) - bool _protocolIdentifierPresent; // parameter indicator - bool _dataCodingSchemePresent; - bool _userDataLengthPresent; - unsigned char _protocolIdentifier; - - // initialize members to sensible values - void init(); - - public: - // constructor, sets sensible default values - SMSDeliverReportMessage() {init();} - - // constructor with given pdu - SMSDeliverReportMessage(string pdu) throw(GsmException); - - // encode pdu, return hexadecimal pdu string - virtual string encode(); - - // create textual representation of SMS - virtual string toString() const; - - // inherited from SMSMessage - Address address() const; - Ref clone(); - - // accessor functions - bool protocolIdentifierPresent() const {return _protocolIdentifierPresent;} - bool dataCodingSchemePresent() const {return _dataCodingSchemePresent;} - bool userDataLengthPresent() const {return _userDataLengthPresent;} - unsigned char protocolIdentifier() const - {assert(_protocolIdentifierPresent); return _protocolIdentifier;} - DataCodingScheme dataCodingScheme() const - {assert(_dataCodingSchemePresent); return _dataCodingScheme;} - UserDataHeader userDataHeader() const - {assert(_userDataLengthPresent); return _userDataHeader;} - string userData() const - {assert(_userDataLengthPresent); return _userData;} - - void setProtocolIdentifier(unsigned char x) - {_protocolIdentifierPresent = true; _protocolIdentifier = x;} - void setDataCodingScheme(DataCodingScheme x) - {_dataCodingSchemePresent = true; _dataCodingScheme = x;} - void setUserDataHeader(UserDataHeader x) - { - _userDataLengthPresent = true; - _userDataHeader = x; - } - void setUserData(string x) - { - _userDataLengthPresent = true; - _userData = x; - } - - virtual ~SMSDeliverReportMessage() {} - }; - - // SMS-SUBMIT-REPORT TPDU for RP-ACK - class SMSSubmitReportMessage : public SMSMessage - { - private: - // SMS-SUBMIT-REPORT PDU (see GSM 03.40 section 9.2.2.2a (II)) - Timestamp _serviceCentreTimestamp; - bool _protocolIdentifierPresent; // parameter indicator - bool _dataCodingSchemePresent; - bool _userDataLengthPresent; - unsigned char _protocolIdentifier; - DataCodingScheme _dataCodingScheme; - - // initialize members to sensible values - void init(); - - public: - // constructor, sets sensible default values - SMSSubmitReportMessage() {init();} - - // constructor with given pdu - SMSSubmitReportMessage(string pdu) throw(GsmException); - - // encode pdu, return hexadecimal pdu string - virtual string encode(); - - // create textual representation of SMS - virtual string toString() const; - - // inherited from SMSMessage - Address address() const; - Ref clone(); - - // accessor functions - Timestamp serviceCentreTimestamp() const {return _serviceCentreTimestamp;} - bool protocolIdentifierPresent() const {return _protocolIdentifierPresent;} - bool dataCodingSchemePresent() const {return _dataCodingSchemePresent;} - bool userDataLengthPresent() const {return _userDataLengthPresent;} - unsigned char protocolIdentifier() const - {assert(_protocolIdentifierPresent); return _protocolIdentifier;} - DataCodingScheme dataCodingScheme() const - {assert(_dataCodingSchemePresent); return _dataCodingScheme;} - UserDataHeader userDataHeader() const - {assert(_userDataLengthPresent); return _userDataHeader;} - string userData() const - {assert(_userDataLengthPresent); return _userData;} - - void setServiceCentreTimestamp(Timestamp &x) {_serviceCentreTimestamp = x;} - void setProtocolIdentifier(unsigned char x) - {_protocolIdentifierPresent = true; _protocolIdentifier = x;} - void setDataCodingScheme(DataCodingScheme x) - {_dataCodingSchemePresent = true; _dataCodingScheme = x;} - void setUserDataHeader(UserDataHeader x) - { - _userDataLengthPresent = true; - _userDataHeader = x; - } - void setUserData(string x) - { - _userDataLengthPresent = true; - _userData = x; - } - virtual ~SMSSubmitReportMessage() {} - }; - - // some useful typdefs - typedef Ref SMSMessageRef; -}; - -#endif // GSM_SMS_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.cc deleted file mode 100644 index cdcb0032bc..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.cc +++ /dev/null @@ -1,702 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sms_codec.cc -// * -// * Purpose: Coder and Encoder for SMS TPDUs -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 17.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_STRING_H -#include -#endif -#include -#include -using namespace std; -using namespace gsmlib; - -// Address members - -Address::Address(string number) : _plan(ISDN_Telephone) -{ - number = removeWhiteSpace(number); - if (number.length() > 0 && number[0] == '+') - { - _type = International; - _number = number.substr(1, number.length() - 1); - } - else - { - _type = Unknown; - _number = number; - } -} - -string Address::toString() const -{ - if (_type == International) - return "+" + _number; - else - return _number; -} - -bool gsmlib::operator<(const Address &x, const Address &y) -{ - // normalize numbers according to the following two rules: - // - prepend "+" if international number - // - append 0s to the shorter number so that both numbers have equal length - string xnumber = x._number; - string ynumber = y._number; - static string twenty0s = "00000000000000000000"; - - if (x._type == Address::International) xnumber = "+" + xnumber; - if (y._type == Address::International) ynumber = "+" + ynumber; - - while (xnumber.length() != ynumber.length()) - if (xnumber.length() < ynumber.length()) - { - int diff = ynumber.length() - xnumber.length(); - xnumber += twenty0s.substr(0, (diff > 20 ? 20 : diff)); - } - else - { - int diff = xnumber.length() - ynumber.length(); - ynumber += twenty0s.substr(0, (diff > 20 ? 20 : diff)); - } - - return xnumber < ynumber; -} - -bool gsmlib::operator==(const Address &x, const Address &y) -{ - return x._number == y._number && x._plan == y._plan; -} - -// Timestamp members - -bool Timestamp::empty() const -{ - return _year == 0 && _month == 0 && _day == 0 && _hour == 0 && - _minute == 0 && _seconds == 0 && _timeZoneMinutes == 0; -} - -string Timestamp::toString(bool appendTimeZone) const -{ - short timeZoneMinutes = _timeZoneMinutes; - short timeZoneHours = timeZoneMinutes / 60; - timeZoneMinutes %= 60; - - // format date and time in a locale-specific way - struct tm t; - t.tm_sec = _seconds; - t.tm_min = _minute; - t.tm_hour = _hour; - t.tm_mon = _month - 1; - // year 2000 heuristics, SMSs cannot be older than start of GSM network - t.tm_year = _year < 80 ? _year + 100 : _year; - t.tm_mday = _day; - t.tm_isdst = -1; - t.tm_yday = 0; - t.tm_wday = 0; - -#ifdef BROKEN_STRFTIME - char formattedTime[1024]; - strftime(formattedTime, 1024, "%x %X", &t); -#else - int formattedTimeSize = strftime(NULL, INT_MAX, "%x %X", &t) + 1; - char *formattedTime = (char*)alloca(sizeof(char) * formattedTimeSize); - strftime(formattedTime, formattedTimeSize, "%x %X", &t); -#endif - - if (! appendTimeZone) - return formattedTime; - - ostrstream os; - os << formattedTime << " (" << (_negativeTimeZone ? '-' : '+') - << setfill('0') << setw(2) << timeZoneHours - << setw(2) << timeZoneMinutes << ')' << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; -} - -bool gsmlib::operator<(const Timestamp &x, const Timestamp &y) -{ - // we don't take time zone info into account because - // - it's more complicated to compute - // - it might confuse the user for whom it's also too complicated - if (x._year < y._year) - return true; - else if (x._year > y._year) - return false; - - if (x._month < y._month) - return true; - else if (x._month > y._month) - return false; - - if (x._day < y._day) - return true; - else if (x._day > y._day) - return false; - - if (x._hour < y._hour) - return true; - else if (x._hour > y._hour) - return false; - - if (x._minute < y._minute) - return true; - else if (x._minute > y._minute) - return false; - - return x._seconds < y._seconds; -} - -bool gsmlib::operator==(const Timestamp &x, const Timestamp &y) -{ - // we don't take time zone info in order to be consistent with operator< - return x._year == y._year && x._month == y._month && x._day == y._day && - x._hour == y._hour && x._minute == y._minute && x._seconds == y._seconds; -} - -// TimePeriod members - -string TimePeriod::toString() const -{ - switch (_format) - { - case NotPresent: - return _("not present"); - case Relative: - { - ostrstream os; - if (_relativeTime <= 143) - os << ((int)_relativeTime + 1) * 5 << _(" minutes"); - else if (_relativeTime <= 167) - os << 12 * 60 + ((int)_relativeTime - 143) * 30 << _(" minutes"); - else if (_relativeTime <= 196) - os << (int)_relativeTime - 166 << _(" days"); - else if (_relativeTime <= 143) - os << (int)_relativeTime - 192 << _(" weeks"); - os << ends; - char *ss = os.str(); - string result(ss); - delete[] ss; - return result; - } - case Absolute: - return _absoluteTime.toString(); - default: - return _("unknown"); - } -} - -// DataCodingScheme members - -string DataCodingScheme::toString() const -{ - string result; - if (compressed()) result += _("compressed "); - if (messageWaitingIndication()) - switch (getMessageWaitingType()) - { - case DCS_VOICEMAIL_MESSAGE_WAITING: - result += _("voicemail message waiting"); - break; - case DCS_FAX_MESSAGE_WAITING: - result += _("fax message waiting"); - break; - case DCS_ELECTRONIC_MAIL_MESSAGE_WAITING: - result += _("electronic mail message waiting"); - break; - case DCS_OTHER_MESSAGE_WAITING: - result += _("other message waiting"); - break; - } - else - switch (getAlphabet()) - { - case DCS_DEFAULT_ALPHABET: - result += _("default alphabet"); - break; - case DCS_EIGHT_BIT_ALPHABET: - result += _("8-bit alphabet"); - break; - case DCS_SIXTEEN_BIT_ALPHABET: - result += _("16-bit alphabet"); - break; - case DCS_RESERVED_ALPHABET: - result += _("reserved alphabet"); - break; - } - return result; -} - -// SMSDecoder members - -SMSDecoder::SMSDecoder(string pdu) : _bi(0), _septetStart(NULL) -{ - _p = new unsigned char[pdu.length() / 2]; - _op = _p; - if (! hexToBuf(pdu, _p)) - throw GsmException(_("bad hexadecimal PDU format"), SMSFormatError); - _maxop = _op + pdu.length() / 2; -} - -void SMSDecoder::alignOctet() -{ - if (_bi != 0) - { - _bi = 0; - ++_op; - } -} - -void SMSDecoder::alignSeptet() -{ - assert(_septetStart != NULL); - while (((_op - _septetStart) * 8 + _bi) % 7 != 0) getBit(); -} - -unsigned char SMSDecoder::get2Bits() -{ - unsigned char result = getBit(); - return result | (getBit() << 1); -} - -unsigned char SMSDecoder::getOctet() -{ - alignOctet(); - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - return *_op++; -} - -void SMSDecoder::getOctets(unsigned char* octets, unsigned short length) -{ - alignOctet(); - for (unsigned short i = 0; i < length; ++i) - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - *octets++ = *_op++; - } -} - -string SMSDecoder::getSemiOctets(unsigned short length) -{ - string result; - result.reserve(length); - alignOctet(); - for (unsigned short i = 0; i < length; ++i) - { - if (_bi == 0) - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - // bits 0..3 are most significant - result += '0' + (*_op & 0xf); - _bi = 4; - } - else - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - // bits 4..7 are least significant, skip 0xf digit - if ((*_op & 0xf0) != 0xf0) - result += '0' + (*_op >> 4); - _bi = 0; - ++_op; - } - } - alignOctet(); - return result; -} - -unsigned long SMSDecoder::getSemiOctetsInteger(unsigned short length) -{ - unsigned long result = 0; - alignOctet(); - for (unsigned short i = 0; i < length; ++i) - { - if (_bi == 0) - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - // bits 0..3 are most significant - result = result * 10 + (*_op & 0xf); - _bi = 4; - } - else - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - // bits 4..7 are least significant, skip 0xf digit - if ((*_op & 0xf0) != 0xf0) - result = result * 10 + (*_op >> 4); - _bi = 0; - ++_op; - } - } - alignOctet(); - return result; -} - -unsigned long SMSDecoder::getTimeZone(bool &negativeTimeZone) -{ - unsigned long result = 0; - alignOctet(); - for (unsigned short i = 0; i < 2; ++i) - { - if (_bi == 0) - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - // bits 0..3 are most significant - if (i == 0) - { // get sign - result = result * 10 + (*_op & 0x7); - negativeTimeZone = (*_op & 0x8 == 0); - } - else - result = result * 10 + (*_op & 0xf); - _bi = 4; - } - else - { - if (_op >= _maxop) - throw GsmException(_("premature end of PDU"), SMSFormatError); - // bits 4..7 are least significant - result = result * 10 + (*_op >> 4); - _bi = 0; - ++_op; - } - } - alignOctet(); - return result * 15; // compute minutes -} - -unsigned long SMSDecoder::getInteger(unsigned short length) -{ - unsigned long result = 0; - for (unsigned short i = 0; i < length; ++i) - result |= (getBit() << i); - return result; -} - -string SMSDecoder::getString(unsigned short length) -{ - string result; - alignSeptet(); - for (unsigned short i = 0; i < length; ++i) - { - unsigned char c = 0; - for (unsigned short j = 0; j < 7; ++j) - c |= getBit() << j; - result += c; - } - return result; -} - -Address SMSDecoder::getAddress(bool scAddressFormat) -{ - Address result; - alignOctet(); - - unsigned char addressLength = getOctet(); - if (addressLength == 0 && scAddressFormat) - return result; // special case for SUBMIT-PDUs - - // parse Type-of-Address - result._plan = (Address::NumberingPlan)getInteger(4); - result._type = (Address::Type)getInteger(3); - - // get address - if (result._type == Address::Alphanumeric) - { - markSeptet(); - // addressLength is number of semi-octets - // (addressLength / 2) * 8 is number of available bits - // divided by 7 is number of 7-bit characters - result._number = gsmToLatin1(getString(addressLength * 4 / 7)); - alignOctet(); - } - else - result._number = getSemiOctets(scAddressFormat ? - (addressLength - 1) * 2 : addressLength); - return result; -} - -Timestamp SMSDecoder::getTimestamp() -{ - Timestamp result; - - result._year = getSemiOctetsInteger(2); - result._month = getSemiOctetsInteger(2); - result._day = getSemiOctetsInteger(2); - result._hour = getSemiOctetsInteger(2); - result._minute = getSemiOctetsInteger(2); - result._seconds = getSemiOctetsInteger(2); - result._timeZoneMinutes = getTimeZone(result._negativeTimeZone); - return result; -} - -TimePeriod SMSDecoder::getTimePeriod(TimePeriod::Format format) -{ - TimePeriod result; - result._format = format; - switch (format) - { - case TimePeriod::NotPresent: - break; - case TimePeriod::Relative: - result._relativeTime = getOctet(); - break; - case TimePeriod::Absolute: - result._absoluteTime = getTimestamp(); - break; - default: - throw GsmException(_("unknown time period format"), SMSFormatError); - break; - } - return result; -} - -SMSDecoder::~SMSDecoder() -{ - delete _p; -} - -// SMSEncoder members - -SMSEncoder::SMSEncoder() : _bi(0), _op(_p) -{ - memset((void*)_p, 0, sizeof(_p)); -} - -void SMSEncoder::alignOctet() -{ - if (_bi != 0) - { - _bi = 0; - ++_op; - } -} - -void SMSEncoder::alignSeptet() -{ - while (((_op - _septetStart) * 8 + _bi) % 7 != 0) setBit(); -} - -void SMSEncoder::set2Bits(unsigned char twoBits) -{ - setBit(twoBits & 1); - setBit((twoBits & 2) == 2); -} - -void SMSEncoder::setOctet(unsigned char octet) -{ - alignOctet(); - *_op++ = octet; -} - -void SMSEncoder::setOctets(const unsigned char* octets, unsigned short length) -{ - alignOctet(); - for (unsigned short i = 0; i < length; ++i) - *_op++ = octets[i]; -} - -void SMSEncoder::setSemiOctets(string semiOctets) -{ - alignOctet(); - for (unsigned int i = 0; i < semiOctets.length(); ++i) - { - if (_bi == 0) - { - *_op = semiOctets[i] - '0'; - _bi = 4; - } - else - { - *_op++ |= (semiOctets[i] - '0') << 4; - _bi = 0; - } - } - if (_bi == 4) - *_op++ |= 0xf0; - _bi = 0; -} - -void SMSEncoder::setSemiOctetsInteger(unsigned long intValue, - unsigned short length) -{ - ostrstream os; - os << intValue << ends; - char *ss = os.str(); - string s(ss); - delete[] ss; - assert(s.length() <= length); - while (s.length() < length) s = '0' + s; - setSemiOctets(s); -} - -void SMSEncoder::setTimeZone(bool negativeTimeZone, unsigned long timeZone) -{ - setSemiOctetsInteger(timeZone / 15, 2); - if (!negativeTimeZone) - *(_op - 1) |= 8; -} - -void SMSEncoder::setInteger(unsigned long intvalue, unsigned short length) -{ - for (unsigned short i = 0; i < length; ++i) - setBit((intvalue & (1 << i)) != 0); -} - -void SMSEncoder::setString(string stringValue) -{ - alignSeptet(); - for (unsigned int i = 0; i < stringValue.length(); ++i) - { - unsigned char c = stringValue[i]; - for (unsigned short j = 0; j < 7; ++j) - setBit(((1 << j) & c) != 0); - } -} - -void SMSEncoder::setAddress(Address &address, bool scAddressFormat) -{ - alignOctet(); - if (scAddressFormat) - { - unsigned int numberLen = address._number.length(); - if (numberLen == 0) - { - setOctet(0); // special case: use default SC address - return; // (set by +CSCA=) - } - setOctet(numberLen / 2 + numberLen % 2 + 1); - // not supported for SCA format - assert(address._type != Address::Alphanumeric); - } - else - if (address._type == Address::Alphanumeric) - // address in GSM default encoding, see also comment in getAddress() - setOctet((address._number.length() * 7 + 6) / 8 * 2); - else - setOctet(address._number.length()); - - setInteger(address._plan, 4); - setInteger(address._type, 3); - setBit(1); - - if (address._number.length() > 0) - if (address._type == Address::Alphanumeric) - { - markSeptet(); - setString(latin1ToGsm(address._number)); - } - else - setSemiOctets(address._number); - alignOctet(); -} - -void SMSEncoder::setTimestamp(Timestamp timestamp) -{ - setSemiOctetsInteger(timestamp._year, 2); - setSemiOctetsInteger(timestamp._month, 2); - setSemiOctetsInteger(timestamp._day, 2); - setSemiOctetsInteger(timestamp._hour, 2); - setSemiOctetsInteger(timestamp._minute, 2); - setSemiOctetsInteger(timestamp._seconds, 2); - setTimeZone(timestamp._negativeTimeZone, timestamp._timeZoneMinutes); -} - -void SMSEncoder::setTimePeriod(TimePeriod period) -{ - switch (period._format) - { - case TimePeriod::NotPresent: - break; - case TimePeriod::Relative: - setOctet(period._relativeTime); - break; - case TimePeriod::Absolute: - setTimestamp(period._absoluteTime); - break; - default: - assert(0); - break; - } -} - -string SMSEncoder::getHexString() -{ - short bi = _bi; - unsigned char *op = _op; - alignOctet(); - string result = bufToHex(_p, _op - _p); - _bi = bi; - _op = op; - return result; -} - -unsigned int SMSEncoder::getLength() -{ - short bi = _bi; - unsigned char *op = _op; - alignOctet(); - unsigned int result = _op - _p; - _bi = bi; - _op = op; - return result; -} - -// UserDataHeader members - -void UserDataHeader::encode(SMSEncoder &e) -{ - e.setOctet(_udh.length()); - e.setOctets((unsigned char*)_udh.data(), _udh.length()); -} - -void UserDataHeader::decode(SMSDecoder &d) -{ - unsigned char udhLen = d.getOctet(); - unsigned char *s = - (unsigned char*)alloca(sizeof(unsigned char) * udhLen); - d.getOctets(s, udhLen); - string ss((char*)s, (unsigned int)udhLen); - _udh = ss; -} - -string UserDataHeader::getIE(unsigned char id) -{ - int udhl, pos = 0; - - udhl = _udh.length(); - while (pos < udhl) - { - unsigned char iei = _udh[pos++]; - unsigned char ieidl = _udh[pos++]; - if (iei == id) return _udh.substr(pos, ieidl); - pos += ieidl; - } - return ""; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.h deleted file mode 100644 index 692b424561..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_codec.h +++ /dev/null @@ -1,329 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sms_codec.h -// * -// * Purpose: Coder and Encoder for SMS TPDUs -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 16.5.1999 -// ************************************************************************* - -#ifndef GSM_SMS_CODEC_H -#define GSM_SMS_CODEC_H - -#include -#include - -using namespace std; - -namespace gsmlib -{ - // this struct represents a telephone number - // usually _type == Unknown or International - // and _number == ISDN_Telephone - struct Address - { - enum Type {Unknown = 0, International = 1, National = 2, - NetworkSpecific = 3, Subscriber = 4, - Alphanumeric = 5, Abbreviated = 6, Reserved = 7}; - enum NumberingPlan {UnknownPlan = 0, ISDN_Telephone = 1, - Data = 3, Telex = 4, NationalPlan = 8, - PrivatePlan = 9, Ermes = 10, ReservedPlan = 15}; - Type _type; - NumberingPlan _plan; - string _number; - - Address() : _type(Unknown), _plan(UnknownPlan) {} - // the constructor sets _type and _plan to defaults - // _plan == ISDN_Telephone - // _type == International if number starts with "+" - // _type == unknown otherwise - // number must be of the form "+123456" or "123456" - Address(string number); - - // return string representation - string toString() const; - - friend bool operator<(const Address &x, const Address &y); - friend bool operator==(const Address &x, const Address &y); - }; - - // compare two addresses - extern bool operator<(const Address &x, const Address &y); - extern bool operator==(const Address &x, const Address &y); - - // representation of a SMS timestamp - struct Timestamp - { - short _year, _month, _day, _hour, _minute, _seconds, _timeZoneMinutes; - bool _negativeTimeZone; - - Timestamp() : _year(0), _month(0), _day(0), _hour(0), - _minute(0), _seconds(0), _timeZoneMinutes(0), _negativeTimeZone(false) {} - - // return true if the time stamp is empty (ie. contains only zeroes) - bool empty() const; - - // return string representation - string toString(bool appendTimeZone = true) const; - - friend bool operator<(const Timestamp &x, const Timestamp &y); - friend bool operator==(const Timestamp &x, const Timestamp &y); - }; - - // compare two timestamps - extern bool operator<(const Timestamp &x, const Timestamp &y); - extern bool operator==(const Timestamp &x, const Timestamp &y); - - // representation of time period - struct TimePeriod - { - // possible values for validity period format - enum Format {NotPresent = 0, Relative = 2, Absolute = 3}; - Format _format; - Timestamp _absoluteTime; - unsigned char _relativeTime; - - TimePeriod() : _format(NotPresent), _relativeTime(0) {} - - // return string representation (already translated) - string toString() const; - }; - - // representation of DataCodingScheme - // the data coding scheme is described in detail in ETSI GSM 03.38, section 4 - const unsigned char DCS_COMPRESSED = 0x20; // bit 5 - - const unsigned char DCS_DEFAULT_ALPHABET = 0 << 2; // bit 2..3 == 0 - const unsigned char DCS_EIGHT_BIT_ALPHABET = 1 << 2; // bit 2..3 == 01 - const unsigned char DCS_SIXTEEN_BIT_ALPHABET = 2 << 2; // bit 2..3 == 10 - const unsigned char DCS_RESERVED_ALPHABET = 3 << 2; // bit 2..3 == 11 - - const unsigned char DCS_MESSAGE_WAITING_INDICATION = 0xc0; // bit 7..6 == 11 - const unsigned char DCS_VOICEMAIL_MESSAGE_WAITING = 0; - const unsigned char DCS_FAX_MESSAGE_WAITING = 1; - const unsigned char DCS_ELECTRONIC_MAIL_MESSAGE_WAITING = 2; - const unsigned char DCS_OTHER_MESSAGE_WAITING = 3; - - class DataCodingScheme - { - private: - unsigned char _dcs; - - public: - // initialize with data coding scheme octet - DataCodingScheme(unsigned char dcs) : _dcs(dcs) {} - - // set to default values (no message waiting, no message class indication, - // default 7-bit alphabet) - DataCodingScheme() : _dcs(DCS_DEFAULT_ALPHABET) {} - - // return type of alphabet used (if messageWaitingIndication == false) - unsigned char getAlphabet() const {return _dcs & (3 << 2);} - - // return true if message compressed - // (if messageWaitingIndication == false) - bool compressed() const {return _dcs & DCS_COMPRESSED == DCS_COMPRESSED;} - - // return true if message waiting indication - bool messageWaitingIndication() const - {return _dcs & DCS_MESSAGE_WAITING_INDICATION == - DCS_MESSAGE_WAITING_INDICATION;} - - // return type of waiting message (if messageWaitingIndication == true) - unsigned char getMessageWaitingType() const {return _dcs & 3;} - - // return string representation (already translated) - string toString() const; - - operator unsigned char() const {return _dcs;} - }; - - // utility class facilitate SMS TPDU decoding - class SMSDecoder - { - private: - unsigned char *_p; // buffer to hold pdu - short _bi; // bit index (0..7) - unsigned char *_op; // current octet pointer - unsigned char *_septetStart; // start of septet string - - unsigned char *_maxop; // pointer to last byte after _p - - public: - // initialize with a hexadecimal octet string containing SMS TPDU - SMSDecoder(string pdu); - - // align to octet border - void alignOctet(); - - // remember starting point of septets (important for alignSeptet()) - void markSeptet() {alignOctet(); _septetStart = _op;} - - // align to septet border - void alignSeptet(); - - // get single bit - bool getBit() - { - assert(_op < _maxop); - bool result = ((*_op >> _bi) & 1); - if (_bi == 7) - { - _bi = 0; - ++_op; - } - else - ++_bi; - return result; - } - - // get two bits - unsigned char get2Bits(); - - // get one octet - unsigned char getOctet(); - - // get string of octets of specified length - void getOctets(unsigned char* octets, unsigned short length); - - // get length semi-octets (bcd-coded number) as ASCII string of numbers - string getSemiOctets(unsigned short length); - - // get length semi-octets (bcd-coded number) as integer - unsigned long getSemiOctetsInteger(unsigned short length); - - // get time zone (in minutes) and time zone sign - unsigned long getTimeZone(bool &negativeTimeZone); - - // get integer with length number of bits - unsigned long getInteger(unsigned short length); - - // get length number of alphanumeric 7-bit characters - // markSeptet() must be called before this function - string getString(unsigned short length); - - // get address/telephone number - // service centre address has special format - Address getAddress(bool scAddressFormat = false); - - // get Timestamp - Timestamp getTimestamp(); - - // get TimePeriod of given format - TimePeriod getTimePeriod(TimePeriod::Format format); - - // destructor - ~SMSDecoder(); - }; - - // utility class for SMS TPDU encoding - class SMSEncoder - { - private: - unsigned char _p[2000]; // buffer to hold pdu (2000 should be enough) - short _bi; // bit index (0..7) - unsigned char *_op; // current octet pointer - unsigned char *_septetStart; // start of septet string - - public: - // constructor - SMSEncoder(); - - // align to octet border - void alignOctet(); - - // remember starting point of septets (important for alignSeptet()) - void markSeptet() {alignOctet(); _septetStart = _op;} - - // align to septet border - void alignSeptet(); - - // set single bit - void setBit(bool bit = false) - { - if (bit) - *_op |= (1 << _bi); - if (_bi == 7) - { - _bi = 0; - ++_op; - } - else - ++_bi; - } - - // set two bits - void set2Bits(unsigned char twoBits); - - // set one octet - void setOctet(unsigned char octet); - - // set string of octets of specified length - void setOctets(const unsigned char* octets, unsigned short length); - - // set semi-octets semiOctets (given as ASCII string of numbers) - void setSemiOctets(string semiOctets); - - // set semi-octets (given as integer) - void setSemiOctetsInteger(unsigned long intValue, unsigned short length); - - // set time zone (in minutes) and time zone sign - void setTimeZone(bool negativeTimeZone, unsigned long timeZone); - - // set integer with length number of bits - void setInteger(unsigned long intvalue, unsigned short length); - - // set alphanumeric 7-bit characters - void setString(string stringValue); - - // set address/telephone number - // service centre address has special format - void setAddress(Address &address, bool scAddressFormat = false); - - // set Timestamp - void setTimestamp(Timestamp timestamp); - - // set TimePeriod - void setTimePeriod(TimePeriod period); - - // return constructed TPDU as hex-encoded string - string getHexString(); - - // return current length of TPDU - unsigned int getLength(); - }; - - // class to handle user data header - class UserDataHeader - { - private: - string _udh; - - public: - // empty user data header - UserDataHeader() {} - - // initialize with user data header - UserDataHeader (string udh) : _udh(udh) {} - - // encode header - void encode(SMSEncoder &e); - - // decode header - void decode(SMSDecoder &d); - - // return a given information element, if present, or an empty string - string getIE(unsigned char id); - - // return the size of the header - unsigned int length() const {return _udh.length();} - - // return user data header as octet string - operator string() const {return _udh;} - }; -}; - -#endif // GSM_SMS_CODEC_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.cc deleted file mode 100644 index 91e15ce3a8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.cc +++ /dev/null @@ -1,489 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sms_store.cc -// * -// * Purpose: SMS functions, SMS store -// * (ETSI GSM 07.05) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 20.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// SMSStoreEntry members - -SMSStoreEntry::SMSStoreEntry() : - _status(Unknown), _cached(false), _mySMSStore(NULL), _index(0) -{ -} - - -SMSMessageRef SMSStoreEntry::message() const throw(GsmException) -{ - if (! cached()) - { - assert(_mySMSStore != NULL); - // these operations are at least "logically const" - SMSStoreEntry *thisEntry = const_cast(this); - _mySMSStore->readEntry(_index, thisEntry->_message, thisEntry->_status); - thisEntry->_cached = true; - } - return _message; -} - -CBMessageRef SMSStoreEntry::cbMessage() const throw(GsmException) -{ - assert(_mySMSStore != NULL); - - // these operations are at least "logically const" - SMSStoreEntry *thisEntry = const_cast(this); - // don't cache CB message for now - thisEntry->_cached = false; - - CBMessageRef result; - _mySMSStore->readEntry(_index, result); - return result; -} - -SMSStoreEntry::SMSMemoryStatus SMSStoreEntry::status() const - throw(GsmException) -{ - if (! cached()) - { - assert(_mySMSStore != NULL); - // these operations are at least "logically const" - SMSStoreEntry *thisEntry = const_cast(this); - _mySMSStore->readEntry(_index, thisEntry->_message, thisEntry->_status); - thisEntry->_cached = true; - } - return _status; -} - -bool SMSStoreEntry::empty() const throw(GsmException) -{ - return message().isnull(); -} - -unsigned char SMSStoreEntry::send(Ref &ackPdu) - throw(GsmException) -{ - return _mySMSStore->send(_index, ackPdu); -} - -unsigned char SMSStoreEntry::send() throw(GsmException) -{ - SMSMessageRef mref; - return send(mref); -} - -bool SMSStoreEntry::cached() const -{ - if (_mySMSStore == NULL) - return _cached; - else - return _cached && _mySMSStore->_useCache; -} - -Ref SMSStoreEntry::clone() -{ - Ref result = new SMSStoreEntry(_message->clone()); - result->_status = _status; - result->_index = _index; - return result; -} - -bool SMSStoreEntry::operator==(const SMSStoreEntry &e) const -{ - if (_message.isnull() || e._message.isnull()) - return _message.isnull() && e._message.isnull(); - else - return _message->encode() == e._message->encode(); -} - -SMSStoreEntry::SMSStoreEntry(const SMSStoreEntry &e) -{ - _message = e._message; - _status = e._status; - _cached = e._cached; - _mySMSStore = e._mySMSStore; - _index = e._index; -} - -SMSStoreEntry &SMSStoreEntry::operator=(const SMSStoreEntry &e) -{ - _message = e._message; - _status = e._status; - _cached = e._cached; - _mySMSStore = e._mySMSStore; - _index = e._index; - return *this; -} - -// iterator members - -SMSStoreEntry &SMSStoreIterator::operator*() -{ - return (*_store)[_index]; -} - -SMSStoreEntry *SMSStoreIterator::operator->() -{ - return &(*_store)[_index]; -} - -SMSStoreIterator::operator SMSStoreEntry*() -{ - return &(*_store)[_index]; -} - -SMSStoreIterator &SMSStoreIterator::operator=(const SMSStoreIterator &i) -{ - _index = i._index; - _store = i._store; - return *this; -} - -const SMSStoreEntry &SMSStoreConstIterator::operator*() -{ - return (*_store)[_index]; -} - -const SMSStoreEntry *SMSStoreConstIterator::operator->() -{ - return &(*_store)[_index]; -} - -// SMSStore members - -void SMSStore::readEntry(int index, SMSMessageRef &message, - SMSStoreEntry::SMSMemoryStatus &status) - throw(GsmException) -{ - // select SMS store - _meTa.setSMSStore(_storeName, 1); - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Reading SMS entry " << index << endl; -#endif // NDEBUG - - string pdu; - Ref p; - try - { - p = new Parser(_at->chat("+CMGR=" + intToStr(index + 1), "+CMGR:", - pdu, false, true, true)); - } - catch (GsmException &ge) - { - if (ge.getErrorCode() != SMS_INVALID_MEMORY_INDEX) - throw ge; - else - { - message = SMSMessageRef(); - status = SMSStoreEntry::Unknown; - return; - } - } - - if (pdu.length() == 0) - { - message = SMSMessageRef(); - status = SMSStoreEntry::Unknown; - } - else - { - // add missing service centre address if required by ME - if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix) - pdu = "00" + pdu; - - status = (SMSStoreEntry::SMSMemoryStatus)p->parseInt(); - - // ignore the rest of the line - message = SMSMessageRef( - SMSMessage::decode(pdu, - !(status == SMSStoreEntry::StoredUnsent || - status == SMSStoreEntry::StoredSent), - _at.getptr())); - } -} - -void SMSStore::readEntry(int index, CBMessageRef &message) - throw(GsmException) -{ - // select SMS store - _meTa.setSMSStore(_storeName, 1); - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Reading CB entry " << index << endl; -#endif // NDEBUG - - string pdu; - Ref p; - try - { - // this is just one row splitted in two part - // (msvc6 fail with internal compiler error) - string s = _at->chat("+CMGR=" + intToStr(index + 1), "+CMGR:", - pdu, false, true, true); - p = new Parser(s); - } - catch (GsmException &ge) - { - if (ge.getErrorCode() != SMS_INVALID_MEMORY_INDEX) - throw ge; - else - { - message = CBMessageRef(); - return; - } - } - - if (pdu.length() == 0) - message = CBMessageRef(); - else - message = CBMessageRef(new CBMessage(pdu)); -} - -void SMSStore::writeEntry(int &index, SMSMessageRef message) - throw(GsmException) -{ - // select SMS store - _meTa.setSMSStore(_storeName, 2); - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Writing SMS entry " << index << endl; -#endif - - // compute length of pdu - string pdu = message->encode(); - - // set message status to "RECEIVED READ" for SMS_DELIVER, SMS_STATUS_REPORT - string statusString; - - // Normally the ",1" sets the message status to "REC READ" (received read) - // which is appropriate for all non-submit messages - // Motorola Timeport 260 does not like this code, though - // DELIVER messages are magically recognized anyway - if (message->messageType() != SMSMessage::SMS_SUBMIT && - ! _at->getMeTa().getCapabilities()._wrongSMSStatusCode) - statusString = ",1"; - - Parser p(_at->sendPdu("+CMGW=" + - intToStr(pdu.length() / 2 - - message->getSCAddressLen()) + statusString, - "+CMGW:", pdu)); - index = p.parseInt() - 1; -} - -void SMSStore::eraseEntry(int index) throw(GsmException) -{ - // Select SMS store - _meTa.setSMSStore(_storeName, 1); - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "*** Erasing SMS entry " << index << endl; -#endif - - _at->chat("+CMGD=" + intToStr(index + 1)); -} - -unsigned char SMSStore::send(int index, Ref &ackPdu) - throw(GsmException) -{ - Parser p(_at->chat("+CMSS=" + intToStr(index + 1), "+CMSS:")); - unsigned char messageReference = p.parseInt(); - - if (p.parseComma(true)) - { - string pdu = p.parseEol(); - - // add missing service centre address if required by ME - if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix) - pdu = "00" + pdu; - - ackPdu = SMSMessage::decode(pdu); - } - else - ackPdu = SMSMessageRef(); - - return messageReference; -} - -int SMSStore::doInsert(SMSMessageRef message) - throw(GsmException) -{ - int index; - writeEntry(index, message); - // it is safer to force reading back the SMS from the ME - resizeStore(index + 1); - _store[index]->_cached = false; - return index; -} - -SMSStore::SMSStore(string storeName, Ref at, MeTa &meTa) - throw(GsmException) : - _storeName(storeName), _at(at), _meTa(meTa), _useCache(true) -{ - // select SMS store - Parser p(_meTa.setSMSStore(_storeName, true, true)); - - p.parseInt(); // skip number of used mems - p.parseComma(); - - resizeStore(p.parseInt()); // ignore rest of line -} - -void SMSStore::resizeStore(int newSize) -{ - int oldSize = _store.size(); - if (newSize > oldSize) - { - // cout << "*** Resizing from " << oldSize << " to " << newSize << endl; - _store.resize(newSize); - - // initialize store entries - for (int i = oldSize; i < newSize; i++) - { - _store[i] = new SMSStoreEntry(); - _store[i]->_index = i; - _store[i]->_cached = false; - _store[i]->_mySMSStore = this; - } - } -} - -SMSStore::iterator SMSStore::begin() -{ - return SMSStoreIterator(0, this); -} - -SMSStore::const_iterator SMSStore::begin() const -{ - return SMSStoreConstIterator(0, this); -} - -SMSStore::iterator SMSStore::end() -{ - return SMSStoreIterator(_store.size(), this); -} - -SMSStore::const_iterator SMSStore::end() const -{ - return SMSStoreConstIterator(_store.size(), this); -} - -SMSStore::reference SMSStore::operator[](int n) -{ - resizeStore(n + 1); - return *_store[n]; -} - -SMSStore::const_reference SMSStore::operator[](int n) const -{ - const_cast(this)->resizeStore(n + 1); - return *_store[n]; -} - -SMSStore::reference SMSStore::front() -{ - return *_store[0]; -} - -SMSStore::const_reference SMSStore::front() const -{ - return *_store[0]; -} - -SMSStore::reference SMSStore::back() -{ - return *_store.back(); -} - -SMSStore::const_reference SMSStore::back() const -{ - return *_store.back(); -} - -int SMSStore::size() const throw(GsmException) -{ - // select SMS store - Parser p(_meTa.setSMSStore(_storeName, 1, true)); - - return p.parseInt(); -} - -SMSStore::iterator SMSStore::insert(iterator position, - const SMSStoreEntry& x) - throw(GsmException) -{ - int index = doInsert(x.message()); - return SMSStoreIterator(index, this); -} - -SMSStore::iterator SMSStore::insert(const SMSStoreEntry& x) - throw(GsmException) -{ - int index = doInsert(x.message()); - return SMSStoreIterator(index, this); -} - -void SMSStore::insert (iterator pos, int n, const SMSStoreEntry& x) - throw(GsmException) -{ - for (int i = 0; i < n; i++) - doInsert(x.message()); -} - -void SMSStore::insert (iterator pos, long n, const SMSStoreEntry& x) - throw(GsmException) -{ - for (long i = 0; i < n; i++) - doInsert(x.message()); -} - -SMSStore::iterator SMSStore::erase(iterator position) - throw(GsmException) -{ - eraseEntry(position->_index); - position->_cached = false; - return position + 1; -} - -SMSStore::iterator SMSStore::erase(iterator first, iterator last) - throw(GsmException) -{ - iterator i(0, this); - for (i = first; i != last; ++i) - erase(i); - return i; -} - -void SMSStore::clear() throw(GsmException) -{ - for (iterator i = begin(); i != end(); ++i) - erase(i); -} - -SMSStore::~SMSStore() -{ - for (vector::iterator i = _store.begin(); - i != _store.end(); ++i) - delete *i; -} - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.h deleted file mode 100644 index 59d0ec8eac..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sms_store.h +++ /dev/null @@ -1,295 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sms_store.h -// * -// * Purpose: SMS functions, SMS store -// * (ETSI GSM 07.05) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 20.5.1999 -// ************************************************************************* - -#ifndef GSM_SMS_STORE_H -#define GSM_SMS_STORE_H - -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // forward declarations - class SMSStore; - class MeTa; - - // a single entry in the SMS store - - class SMSStoreEntry : public RefBase - { - public: - // status in ME memory - enum SMSMemoryStatus {ReceivedUnread = 0, ReceivedRead = 1, - StoredUnsent = 2, StoredSent = 3, - All = 4, Unknown = 5}; - - private: - SMSMessageRef _message; - SMSMemoryStatus _status; - bool _cached; - SMSStore *_mySMSStore; - int _index; - - public: - // this constructor is only used by SMSStore - SMSStoreEntry(); - - // create new entry given a SMS message - SMSStoreEntry(SMSMessageRef message) : - _message(message), _status(Unknown), _cached(true), _mySMSStore(NULL), - _index(0) {} - - // create new entry given a SMS message and an index - // only to be used for file-based stores (see gsm_sorted_sms_store) - SMSStoreEntry(SMSMessageRef message, int index) : - _message(message), _status(Unknown), _cached(true), _mySMSStore(NULL), - _index(index) {} - - // clear cached flag - void clearCached() { _cached = false; } - - // return SMS message stored in the entry - SMSMessageRef message() const throw(GsmException); - - // return CB message stored in the entry - CBMessageRef cbMessage() const throw(GsmException); - - // return message status in store - SMSMemoryStatus status() const throw(GsmException); - - // return true if empty, ie. no SMS in this entry - bool empty() const throw(GsmException); - - // send this PDU from store - // returns message reference and ACK-PDU (if requested) - // only applicate to SMS-SUBMIT and SMS-COMMAND - unsigned char send(Ref &ackPdu) throw(GsmException); - - // same as above, but ACK-PDU is discarded - unsigned char send() throw(GsmException); - - // return index (guaranteed to be unique, - // can be used for identification in store) - int index() const {return _index;} - - // return true if entry is cached (and caching is enabled) - bool cached() const; - - // return deep copy of this entry - Ref clone(); - - // equality operator - bool operator==(const SMSStoreEntry &e) const; - - // return store reference - SMSStore *getStore() {return _mySMSStore;} - - // copy constructor and assignment - SMSStoreEntry(const SMSStoreEntry &e); - SMSStoreEntry &operator=(const SMSStoreEntry &e); - - friend class SMSStore; - }; - - // iterator for the SMSStore class - -#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 - class SMSStoreIterator : public random_access_iterator -#else - class SMSStoreIterator : public iterator -#endif - { - int _index; - SMSStore *_store; - - SMSStoreIterator(int index, SMSStore *store) : - _index(index), _store(store) {} - - public: - SMSStoreIterator(SMSStoreEntry *entry) : - _index(entry->index()), _store(entry->getStore()) {} - - SMSStoreEntry &operator*(); - SMSStoreEntry *operator->(); - SMSStoreIterator &operator+(int i) - {_index += i; return *this;} - operator SMSStoreEntry*(); - SMSStoreIterator &operator=(const SMSStoreIterator &i); - SMSStoreIterator &operator++() - {++_index; return *this;} - SMSStoreIterator &operator--() - {--_index; return *this;} - SMSStoreIterator &operator++(int i) - {_index += i; return *this;} - SMSStoreIterator &operator--(int i) - {_index -= i; return *this;} - bool operator<(SMSStoreIterator &i) - {return _index < i._index;} - bool operator==(const SMSStoreIterator &i) const - {return _index == i._index;} - bool operator!=(const SMSStoreIterator &i) const - {return _index != i._index;} - - friend class SMSStore; - }; - -#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 - class SMSStoreConstIterator : public random_access_iterator -#else - class SMSStoreConstIterator : public iterator -#endif - { - int _index; - const SMSStore *_store; - - SMSStoreConstIterator(int index, const SMSStore *store) : - _index(index), _store(store) {} - - public: - const SMSStoreEntry &operator*(); - const SMSStoreEntry *operator->(); - SMSStoreConstIterator &operator++() - {++_index; return *this;} - SMSStoreConstIterator &operator--() - {--_index; return *this;} - SMSStoreConstIterator &operator++(int i) - {_index += i; return *this;} - SMSStoreConstIterator &operator--(int i) - {_index -= i; return *this;} - bool operator<(SMSStoreConstIterator &i) - {return _index < i._index;} - bool operator==(const SMSStoreConstIterator &i) const - {return _index == i._index;} - - friend class SMSStore; - }; - - // this class corresponds to a SMS store in the ME - // all functions directly update storage in the ME - // if the ME is exchanged, the storage may become corrupted because - // of internal buffering in the SMSStore class - - class SMSStore : public RefBase, public NoCopy - { - private: - vector _store; // vector of store entries - string _storeName; // name of the store, 2-byte like "SM" - Ref _at; // my GsmAt class - MeTa &_meTa; // my MeTa class - bool _useCache; // true if entries should be cached - - // internal access functions - // read/write entry from/to ME - void readEntry(int index, SMSMessageRef &message, - SMSStoreEntry::SMSMemoryStatus &status) throw(GsmException); - void readEntry(int index, CBMessageRef &message) throw(GsmException); - void writeEntry(int &index, SMSMessageRef message) - throw(GsmException); - // erase entry - void eraseEntry(int index) throw(GsmException); - // send PDU index from store - // returns message reference and ACK-PDU (if requested) - // only applicate to SMS-SUBMIT and SMS-COMMAND - unsigned char send(int index, Ref &ackPdu) throw(GsmException); - - - // do the actual insertion, return index of new element - int doInsert(SMSMessageRef message) throw(GsmException); - - // used by class MeTa - SMSStore(string storeName, Ref at, MeTa &meTa) throw(GsmException); - - // resize store entry vector if necessary - void resizeStore(int newSize); - - public: - // iterator defs - typedef SMSStoreIterator iterator; - typedef SMSStoreConstIterator const_iterator; - typedef SMSStoreEntry &reference; - typedef const SMSStoreEntry &const_reference; - - // set cache mode on or off - void setCaching(bool useCache) {_useCache = useCache;} - - // return name of this store (2-character string) - string name() const {return _storeName;} - - // SMS store traversal commands - // these are suitable to use stdc++ lib algorithms and iterators - // ME have fixed storage space implemented as memory slots - // that may either be empty or used - - // traversal commands - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - reference operator[](int n); - const_reference operator[](int n) const; - - // The size macros return the number of used entries - // Warning: indices may be _larger_ than size() because of this - // (perhaps this should be changed, because it is unexpected behavior) - - int size() const throw(GsmException); - int max_size() const {return _store.size();} - int capacity() const {return _store.size();} - bool empty() const throw(GsmException) {return size() == 0;} - - // insert iterators insert into the first empty cell regardless of position - // existing iterators may be invalidated after an insert operation - // return position - // insert only writes to available positions - // warning: insert fails silently if size() == max_size() - iterator insert(iterator position, const SMSStoreEntry& x) - throw(GsmException); - iterator insert(const SMSStoreEntry& x) throw(GsmException); - - // insert n times, same procedure as above - void insert (iterator pos, int n, const SMSStoreEntry& x) - throw(GsmException); - void insert (iterator pos, long n, const SMSStoreEntry& x) - throw(GsmException); - - // erase operators set used slots to "empty" - iterator erase(iterator position) throw(GsmException); - iterator erase(iterator first, iterator last) throw(GsmException); - void clear() throw(GsmException); - - // destructor - ~SMSStore(); - - friend class SMSStoreEntry; - friend class MeTa; - }; - - typedef Ref SMSStoreRef; - -}; - -#endif // GSM_SMS_STORE_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.cc deleted file mode 100644 index e1b265c3f7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.cc +++ /dev/null @@ -1,503 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sorted_phonebook.cc -// * -// * Purpose: Alphabetically sorted phonebook -// * (residing in files or in the ME) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 25.6.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -const int MAX_LINE_SIZE = 1000; - -using namespace std; -using namespace gsmlib; - -string SortedPhonebook::escapeString(string s) -{ - string result; - - for (const char *pp = s.c_str(); *pp != 0; ++pp) - { - if (*pp == CR) - result += "\\r"; - else if (*pp == LF) - result += "\\n"; - else if (*pp == '\\') - result += "\\\\"; - else if (*pp == '|') - result += "\\|"; - else - result += *pp; - } - return result; -} - -string SortedPhonebook::unescapeString(char *line, unsigned int &pos) -{ - string result; - bool escaped = false; - - while (! (line[pos] == '|' && ! escaped) && line[pos] != 0 && - line[pos] != CR && line[pos] != LF) - { - if (escaped) - { - escaped = false; - if (line[pos] == 'r') - result += CR; - else if (line[pos] == 'n') - result += LF; - else if (line[pos] == '\\') - result += '\\'; - else if (line[pos] == '|') - result += '|'; - else - result += line[pos]; - } - else - if (line[pos] == '\\') - escaped = true; - else - result += line[pos]; - - ++pos; - } - return result; -} - -void SortedPhonebook::readPhonebookFile(istream &pbs, string filename) - throw(GsmException) -{ - // read entries - while (! pbs.eof()) - { - char line[MAX_LINE_SIZE]; - pbs.getline(line, MAX_LINE_SIZE); - - if (strlen(line) == 0) - continue; // skip empty lines - - if (pbs.bad()) - throw GsmException(stringPrintf(_("error reading from file '%s"), - filename.c_str()), - OSError); - - // convert line to newEntry (line format : [index] '|' text '|' number - string text, telephone; - unsigned int pos = 0; - - // parse index - string indexS = unescapeString(line, pos); - int index = -1; - if (indexS.length() == 0) - { - if (_useIndices) - throw GsmException(stringPrintf(_("entry '%s' lacks index"), line), - ParserError); - } - else - { - index = checkNumber(indexS); - _useIndices = true; - } - if (line[pos++] != '|') - throw GsmException(stringPrintf(_("line '%s' has invalid format"), line), - ParserError); - - // parse text - text = unescapeString(line, pos); - if (line[pos++] != '|') - throw GsmException(stringPrintf(_("line '%s' has invalid format"), line), - ParserError); - - // parse telephone number - telephone = unescapeString(line, pos); - - insert(PhonebookEntryBase(telephone, text, index)); - } -} - -void SortedPhonebook::sync(bool fromDestructor) throw(GsmException) -{ - // if not in file it already is stored in ME/TA - if (! _fromFile) return; - - // if writing to stdout and not called from destructor ignore - // (avoids writing to stdout multiple times) - if (_filename == "" && ! fromDestructor) return; - - // find out if any of the entries have been updated - if (! _changed) // only look if we're not writing the file anyway - for (iterator i = begin(); i != end(); i++) - if (i->changed()) - { - _changed = true; - break; - } - - if (_changed) - { - checkReadonly(); - // create backup file - but only once - if (! _madeBackupFile && _filename != "") // don't make backup of stdout - { - renameToBackupFile(_filename); - _madeBackupFile = true; - } - - // open stream - ostream *pbs = NULL; - try - { - if (_filename == "") - pbs = &cout; - else - pbs = new ofstream(_filename.c_str()); - - if (pbs->bad()) - throw GsmException( - stringPrintf(_("error opening file '%s' for writing"), - (_filename == "" ? _("") : - _filename.c_str())), - OSError); - - // and write the entries - for (PhonebookMap::iterator i = _sortedPhonebook.begin(); - i != _sortedPhonebook.end(); ++i) - { - // convert entry to output line - string line = - (_useIndices ? intToStr(i->second->index()) : "") + "|" + - escapeString(i->second->text()) + "|" + - escapeString(i->second->telephone()); - - // write out the line - *pbs << line << endl; - if (pbs->bad()) - throw GsmException( - stringPrintf(_("error writing to file '%s'"), - (_filename == "" ? _("") : - _filename.c_str())), - OSError); - } - } - catch(GsmException &e) - { - if (pbs != &cout) delete pbs; - throw; - } - // close file - if (pbs != &cout) delete pbs; - - // reset all changed states - _changed = false; - for (iterator j = begin(); j != end(); j++) - j->resetChanged(); - } -} - -void SortedPhonebook::checkReadonly() throw(GsmException) -{ - if (_readonly) throw GsmException( - _("attempt to change phonebook read from "), - ParameterError); -} - -SortedPhonebook::SortedPhonebook(string filename, bool useIndices) - throw(GsmException) : - _changed(false), _fromFile(true), _madeBackupFile(false), - _sortOrder(ByIndex), _useIndices(useIndices), _readonly(false), - _filename(filename) -{ - // open the file - ifstream pbs(filename.c_str()); - if (pbs.bad()) - throw GsmException(stringPrintf(_("cannot open file '%s'"), - filename.c_str()), - OSError); - // and read the file - readPhonebookFile(pbs, filename); -} - -SortedPhonebook::SortedPhonebook(bool fromStdin, bool useIndices) - throw(GsmException) : - _changed(false), _fromFile(true), _madeBackupFile(false), - _sortOrder(ByIndex), _useIndices(useIndices), _readonly(fromStdin) - // _filename is "" - this means stdout -{ - // read from stdin - if (fromStdin) - readPhonebookFile(cin, (string)_("")); -} - -SortedPhonebook::SortedPhonebook(PhonebookRef mePhonebook) - throw(GsmException) : - _changed(false), _fromFile(false), _madeBackupFile(false), - _sortOrder(ByIndex), _readonly(false), _mePhonebook(mePhonebook) -{ - int entriesRead = 0; - reportProgress(0, _mePhonebook->end() - _mePhonebook->begin()); - - for (Phonebook::iterator i = _mePhonebook->begin(); - i != _mePhonebook->end(); ++i) - { - if (! i->empty()) - { - _sortedPhonebook.insert( - PhonebookMap::value_type(PhoneMapKey(*this, lowercase(i->text())), i)); - ++entriesRead; - if (entriesRead == _mePhonebook->size()) - return; // ready - } - reportProgress(i - _mePhonebook->begin()); - } -} - -void SortedPhonebook::setSortOrder(SortOrder newOrder) -{ - if (newOrder == _sortOrder) return; // nothing to do - - PhonebookMap savedPhonebook = _sortedPhonebook; // save phonebook - _sortedPhonebook = PhonebookMap(); // empty old phonebook - _sortOrder = newOrder; - - // re-insert entries - switch (newOrder) - { - case ByTelephone: - { - for (PhonebookMap::iterator i = savedPhonebook.begin(); - i != savedPhonebook.end(); ++i) - _sortedPhonebook. - insert(PhonebookMap::value_type( - PhoneMapKey(*this, lowercase(i->second->telephone())), i->second)); - break; - } - case ByText: - { - for (PhonebookMap::iterator i = savedPhonebook.begin(); - i != savedPhonebook.end(); ++i) - _sortedPhonebook. - insert(PhonebookMap::value_type( - PhoneMapKey(*this, lowercase(i->second->text())), i->second)); - break; - } - case ByIndex: - { - for (PhonebookMap::iterator i = savedPhonebook.begin(); - i != savedPhonebook.end(); ++i) - _sortedPhonebook. - insert(PhonebookMap::value_type( - PhoneMapKey(*this, i->second->index()), i->second)); - break; - } - default: - assert(0); - break; - } -} - -unsigned int SortedPhonebook::getMaxTelephoneLen() const -{ - if (_fromFile) - return UINT_MAX; - else - return _mePhonebook->getMaxTelephoneLen(); -} - -unsigned int SortedPhonebook::getMaxTextLen() const -{ - if (_fromFile) - return UINT_MAX; - else - return _mePhonebook->getMaxTextLen(); -} - -int SortedPhonebook::max_size() const -{ - if (_fromFile) - return _sortedPhonebook.max_size(); - else - return _mePhonebook->max_size(); -} - -int SortedPhonebook::capacity() const -{ - if (_fromFile) - return _sortedPhonebook.max_size(); - else - return _mePhonebook->capacity(); -} - -SortedPhonebook::iterator -SortedPhonebook::insert(const PhonebookEntryBase& x) throw(GsmException) -{ - checkReadonly(); - _changed = true; - PhonebookEntryBase *newEntry; - - if (_fromFile) - if (_useIndices) - { - if (x.index() != -1) // check that index is unique - { - for (PhonebookMap::iterator i = _sortedPhonebook.begin(); - i != _sortedPhonebook.end(); ++i) - if (i->second->index() == x.index()) - throw GsmException(_("indices must be unique in phonebook"), - ParameterError); - newEntry = new PhonebookEntryBase(x); - } - else // set index - { - SortOrder saveSortOrder = _sortOrder; - setSortOrder(ByIndex); - int index = 0; - for (PhonebookMap::iterator i = _sortedPhonebook.begin(); - i != _sortedPhonebook.end(); ++i, ++index) - if (i->second->index() != index) - break; - setSortOrder(saveSortOrder); - newEntry = new PhonebookEntryBase(); - newEntry->set(x.telephone(), x.text(), index, true); - } - } - else // index info in x is ignored - newEntry = new PhonebookEntryBase(x); - else - { - PhonebookEntry newMEEntry(x); - newEntry = _mePhonebook->insert((PhonebookEntry*)NULL, newMEEntry); - } - switch (_sortOrder) - { - case ByTelephone: - return - _sortedPhonebook. - insert(PhonebookMap::value_type( - PhoneMapKey(*this, lowercase(newEntry->telephone())), newEntry)); - case ByText: - return - _sortedPhonebook. - insert(PhonebookMap::value_type( - PhoneMapKey(*this, lowercase(newEntry->text())), newEntry)); - case ByIndex: - return - _sortedPhonebook. - insert(PhonebookMap::value_type( - PhoneMapKey(*this, newEntry->index()), newEntry)); - default: - assert(0); - break; - } - return SortedPhonebook::iterator(); -} - -SortedPhonebook::iterator -SortedPhonebook::insert(iterator position, const PhonebookEntryBase& x) - throw(GsmException) -{ - return insert(x); -} - -SortedPhonebook::size_type SortedPhonebook::erase(string &key) - throw(GsmException) -{ - // deallocate memory or remove from underlying ME phonebook - for (PhonebookMap::iterator i = - _sortedPhonebook.find(PhoneMapKey(*this, lowercase(key))); - i != _sortedPhonebook.end() && - i->first == PhoneMapKey(*this, lowercase(key)); - ++i) - { - checkReadonly(); - _changed = true; - if (_fromFile) - delete i->second; - else - _mePhonebook->erase((Phonebook::iterator)i->second); - } - - return _sortedPhonebook.erase(PhoneMapKey(*this, lowercase(key))); -} - -SortedPhonebook::size_type SortedPhonebook::erase(int key) - throw(GsmException) -{ - // deallocate memory or remove from underlying ME phonebook - for (PhonebookMap::iterator i = - _sortedPhonebook.find(PhoneMapKey(*this, key)); - i != _sortedPhonebook.end() && i->first == PhoneMapKey(*this, key); - ++i) - { - checkReadonly(); - _changed = true; - if (_fromFile) - delete i->second; - else - _mePhonebook->erase((Phonebook::iterator)i->second); - } - - return _sortedPhonebook.erase(PhoneMapKey(*this, key)); -} - -void SortedPhonebook::erase(iterator position) - throw(GsmException) -{ - checkReadonly(); - _changed = true; - // deallocate memory or remove from underlying ME phonebook - if (_fromFile) - delete ((PhonebookMap::iterator)position)->second; - else - _mePhonebook->erase((Phonebook::iterator) - ((PhonebookMap::iterator)position)->second); - _sortedPhonebook.erase(position); -} - -void SortedPhonebook::erase(iterator first, iterator last) - throw(GsmException) -{ - checkReadonly(); - _changed = true; - for (PhonebookMap::iterator i = first; i != last; ++i) - if (_fromFile) - delete i->second; - else - _mePhonebook->erase((Phonebook::iterator)i->second); - _sortedPhonebook.erase(first, last); -} - -void SortedPhonebook::clear() throw(GsmException) -{ - checkReadonly(); - _changed = true; - for (iterator i = begin(); i != end(); i++) - erase(i); -} - -SortedPhonebook::~SortedPhonebook() -{ - if (_fromFile) - { - sync(true); - for (PhonebookMap::iterator i = _sortedPhonebook.begin(); - i != _sortedPhonebook.end(); ++i) - delete i->second; - } -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.h deleted file mode 100644 index c0d3b787fe..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook.h +++ /dev/null @@ -1,159 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sorted_phonebook.h -// * -// * Purpose: Alphabetically sorted phonebook -// * (residing in files or in the ME) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 25.6.1999 -// ************************************************************************* - -#ifndef GSM_SORTED_PHONEBOOK_H -#define GSM_SORTED_PHONEBOOK_H - -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - - // The class SortedPhonebook makes the phonebook more manageable: - // - empty slots in the ME phonebook are hidden by the API - // - the class transparently handles phonebooks that reside in files - - class SortedPhonebook : public SortedPhonebookBase - { - private: - bool _changed; // true if file has changed after last save - bool _fromFile; // true if phonebook read from file - bool _madeBackupFile; // true if backup file was created - SortOrder _sortOrder; // sort order for the phonebook - bool _useIndices; // if phonebook from file: input file had - // indices; will write indices, too - bool _readonly; // =true if read from stdin - string _filename; // name of the file if phonebook from file - PhonebookMap _sortedPhonebook; // phonebook from file - PhonebookRef _mePhonebook; // phonebook if from ME - - // convert CR and LF in string to "\r" and "\n" respectively - string escapeString(string s); - - // convert "\r" and "\n" to CR and LF respectively - // start parsing with pos, stop when CR, LF, 0, or '|' is encountered - string unescapeString(char *line, unsigned int &pos); - - // initial read of phonebook file - void readPhonebookFile(istream &pbs, string filename) throw(GsmException); - - // synchronize SortedPhonebook with file (no action if in ME) - void sync(bool fromDestructor) throw(GsmException); - - // throw an exception if _readonly is set - void checkReadonly() throw(GsmException); - - public: - // iterator defs - typedef SortedPhonebookIterator iterator; - typedef PhonebookMap::size_type size_type; - - // constructor for file-based phonebook - // expect indices in file if useIndices == true - // read from file - SortedPhonebook(string filename, bool useIndices) - throw(GsmException); - // read from stdin or start empty and write to stdout - SortedPhonebook(bool fromStdin, bool useIndices) - throw(GsmException); - - // constructor for ME-based phonebook - SortedPhonebook(PhonebookRef mePhonebook) throw(GsmException); - - // return maximum telephone number length - unsigned int getMaxTelephoneLen() const; - - // return maximum entry description length - unsigned int getMaxTextLen() const; - - // handle sorting - void setSortOrder(SortOrder newOrder); - SortOrder sortOrder() const {return _sortOrder;} - - // phonebook traversal commands - // these are suitable to use stdc++ lib algorithms and iterators - // ME have fixed storage space implemented as memory slots - // that may either be empty or used - - // traversal commands - iterator begin() {return _sortedPhonebook.begin();} - iterator end() {return _sortedPhonebook.end();} - - // the size macros return the number of used entries - int size() const {return _sortedPhonebook.size();} - int max_size() const; - int capacity() const; - bool empty() const throw(GsmException) {return size() == 0;} - - // existing iterators remain valid after an insert or erase operation - // note: inserting many entries in indexed mode is inefficient - // if the sort order is not set to indexed before - - // return position - // insert only writes to available positions - // warning: insert fails silently if size() == max_size() - iterator insert(const PhonebookEntryBase& x) throw(GsmException); - iterator insert(iterator position, const PhonebookEntryBase& x) - throw(GsmException); - - PhonebookMap::size_type count(string &key) - {return _sortedPhonebook.count(PhoneMapKey(*this, lowercase(key)));} - iterator find(string &key) - {return _sortedPhonebook.find(PhoneMapKey(*this, lowercase(key)));} - iterator lower_bound(string &key) - {return _sortedPhonebook.lower_bound(PhoneMapKey(*this, - lowercase(key)));} - iterator upper_bound(string &key) - {return _sortedPhonebook.upper_bound(PhoneMapKey(*this, - lowercase(key)));} - pair equal_range(string &key) - {return _sortedPhonebook.equal_range(PhoneMapKey(*this, - lowercase(key)));} - - PhonebookMap::size_type count(int key) - {return _sortedPhonebook.count(PhoneMapKey(*this, key));} - iterator find(int key) - {return _sortedPhonebook.find(PhoneMapKey(*this, key));} - iterator lower_bound(int key) - {return _sortedPhonebook.lower_bound(PhoneMapKey(*this, key));} - iterator upper_bound(int key) - {return _sortedPhonebook.upper_bound(PhoneMapKey(*this, key));} - pair equal_range(int key) - {return _sortedPhonebook.equal_range(PhoneMapKey(*this, key));} - - size_type erase(string &key) throw(GsmException); - size_type erase(int key) throw(GsmException); - void erase(iterator position) throw(GsmException); - void erase(iterator first, iterator last) throw(GsmException); - void clear() throw(GsmException); - - // synchronize SortedPhonebook with file (no action if in ME) - void sync() throw(GsmException) {sync(false);} - - // destructor - // writes back change to file if phonebook is in file - virtual ~SortedPhonebook(); - }; - - // typedef Ref SortedPhonebookRef; -}; - -#endif // GSM_SORTED_PHONEBOOK_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.cc deleted file mode 100644 index 1061dc60b9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.cc +++ /dev/null @@ -1,115 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sorted_phonebook_base.cc -// * -// * Purpose: Virtual base class for alphabetically sorted phonebook -// * The infrastructure in this module allows custom backends for -// * storing phonebook entries to be integrated into gsmlib -// * (eg. LDAP- or RDBMS-based phonebook stores). -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 5.6.2000 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#include - -using namespace std; -using namespace gsmlib; - -// PhonebookEntryBase members - -void PhonebookEntryBase::set(string telephone, string text, int index, - bool useIndex) - throw(GsmException) -{ - checkTextAndTelephone(text, telephone); - - _changed = true; - _telephone = telephone; - _text = text; - _useIndex = useIndex; - if (index != -1) - _index = index; -} - -bool PhonebookEntryBase::operator==(const PhonebookEntryBase &e) const -{ - assert(! ((_useIndex || e._useIndex) && - (_index == -1 || e._index == -1))); - return _telephone == e._telephone && _text == e._text && - (! (_useIndex || e._useIndex) || _index == e._index); -} - -string PhonebookEntryBase::text() const throw(GsmException) -{ - return _text; -} - -string PhonebookEntryBase::telephone() const throw(GsmException) -{ - return _telephone; -} - -bool PhonebookEntryBase::empty() const throw(GsmException) -{ - return (text() == "") && (telephone() == ""); -} - -Ref PhonebookEntryBase::clone() -{ - Ref result = new PhonebookEntryBase(*this); - return result; -} - -PhonebookEntryBase::PhonebookEntryBase(const PhonebookEntryBase &e) - throw(GsmException) -{ - set(e._telephone, e._text, e._index, e._useIndex); -} - -PhonebookEntryBase &PhonebookEntryBase::operator=(const PhonebookEntryBase &e) - throw(GsmException) -{ - set(e._telephone, e._text, e._index, e._useIndex); - return *this; -} - -// CustomPhonebookRegistry members - -map -*CustomPhonebookRegistry::_factoryList = NULL; - -void CustomPhonebookRegistry:: -registerCustomPhonebookFactory(string backendName, - CustomPhonebookFactory *factory) - throw(GsmException) -{ - if (_factoryList == NULL) - _factoryList = new map; - backendName = lowercase(backendName); - if (_factoryList->find(backendName) != _factoryList->end()) - throw GsmException(stringPrintf(_("backend '%s' already registered"), - backendName.c_str()), ParameterError); -} - -SortedPhonebookRef CustomPhonebookRegistry:: -createPhonebook(string backendName, string source) throw(GsmException) -{ - if (_factoryList == NULL) - _factoryList = new map; - backendName = lowercase(backendName); - if (_factoryList->find(backendName) == _factoryList->end()) - throw GsmException(stringPrintf(_("backend '%s' not registered"), - backendName.c_str()), ParameterError); - return (*_factoryList)[backendName]->createPhonebook(source); -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.h deleted file mode 100644 index 166f81f45a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_phonebook_base.h +++ /dev/null @@ -1,220 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sorted_phonebook_base.h -// * -// * Purpose: Virtual base class for alphabetically sorted phonebook -// * The infrastructure in this module allows custom backends for -// * storing phonebook entries to be integrated into gsmlib -// * (eg. LDAP- or RDBMS-based phonebook stores). -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 5.6.2000 -// ************************************************************************* - -#ifndef GSM_SORTED_PHONEBOOK_BASE_H -#define GSM_SORTED_PHONEBOOK_BASE_H - -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // a single entry in a phonebook - - class PhonebookEntryBase : public RefBase - { - protected: - bool _changed; // set to true if _telephone or _text changed - string _telephone; - string _text; - int _index; // my position in the phonebook - // == -1 if not used (can only happen if - // phonebook is read from file) - bool _useIndex; // compare indices in operator==, - // use _index for inserting into - // Phonebook - - public: - PhonebookEntryBase() : - _changed(false), _index(-1), _useIndex(false) {} - - // convenience constructor - PhonebookEntryBase(string telephone, string text, int index = -1) : - _changed(false), _telephone(telephone), _text(text), - _index(index), _useIndex(false) {} - - // accessor functions - virtual void set(string telephone, string text, int index = -1, - bool useIndex = false) - throw(GsmException); - virtual string text() const throw(GsmException); - virtual string telephone() const throw(GsmException); - - // return true if both telephone and text are empty - bool empty() const throw(GsmException); - - // set to true if operator== should compare the _index as well - void setUseIndex(bool useIndex) - {_useIndex = useIndex;} - bool useIndex() const {return _useIndex;} - - // equality operator - // if one of the operands has _useIndex == true - // takes _index and e._index into account - bool operator==(const PhonebookEntryBase &e) const; - - // return index - int index() const {return _index;} - - // return true if entry changed - bool changed() const {return _changed;} - - // reset the changed status (ie. if synced to file) - void resetChanged() {_changed = false;} - - // return deep copy of this entry - virtual Ref clone(); - - PhonebookEntryBase(const PhonebookEntryBase &e) throw(GsmException); - PhonebookEntryBase &operator=(const PhonebookEntryBase &e) - throw(GsmException); - - virtual ~PhonebookEntryBase() {} - }; - - // MapKey for sortedPhonebook - - class SortedPhonebookBase; - typedef MapKey PhoneMapKey; - - // maps text or telephone to entry - - typedef multimap PhonebookMap; - - // iterator for SortedPhonebook that hides the "second" member of the map - - typedef PhonebookMap::iterator PhonebookMapIterator; - class SortedPhonebookIterator : public PhonebookMapIterator - { - public: - SortedPhonebookIterator() {} - SortedPhonebookIterator(PhonebookMap::iterator i) : - PhonebookMapIterator(i) {} - - PhonebookEntryBase &operator*() - {return *((PhonebookMap::iterator)*this)->second;} - - PhonebookEntryBase *operator->() - {return ((PhonebookMap::iterator)*this)->second;} - }; - - // virtual base class for sorted phonebooks - - class SortedPhonebookBase : public RefBase, public NoCopy - { - public: - // iterator defs - typedef SortedPhonebookIterator iterator; - typedef PhonebookMap::size_type size_type; - - // return maximum telephone number length - virtual unsigned int getMaxTelephoneLen() const = 0; - - // return maximum entry description length - virtual unsigned int getMaxTextLen() const = 0; - - // handle sorting - virtual void setSortOrder(SortOrder newOrder) = 0; - virtual SortOrder sortOrder() const = 0; - - // phonebook traversal commands - // these are suitable to use stdc++ lib algorithms and iterators - - // traversal commands - virtual iterator begin() = 0; - virtual iterator end() = 0; - - // the size macros return the number of used entries - virtual int size() const = 0; - virtual int max_size() const = 0; - virtual int capacity() const = 0; - virtual bool empty() const throw(GsmException) = 0; - - // existing iterators remain valid after an insert or erase operation - - // return position - // insert only writes to available positions - // warning: insert fails silently if size() == max_size() - virtual iterator insert(const PhonebookEntryBase& x) throw(GsmException) - = 0; - virtual iterator insert(iterator position, const PhonebookEntryBase& x) - throw(GsmException) = 0; - - virtual PhonebookMap::size_type count(string &key) = 0; - virtual iterator find(string &key) = 0; - virtual iterator lower_bound(string &key) = 0; - virtual iterator upper_bound(string &key) = 0; - virtual pair equal_range(string &key) = 0; - - virtual PhonebookMap::size_type count(int key) = 0; - virtual iterator find(int key) = 0; - virtual iterator lower_bound(int key) = 0; - virtual iterator upper_bound(int key) = 0; - virtual pair equal_range(int key) = 0; - - virtual size_type erase(string &key) throw(GsmException) = 0; - virtual size_type erase(int key) throw(GsmException) = 0; - virtual void erase(iterator position) throw(GsmException) = 0; - virtual void erase(iterator first, iterator last) throw(GsmException) = 0; - virtual void clear() throw(GsmException) = 0; - - // synchronize SortedPhonebookBase with storage - virtual void sync() throw(GsmException) = 0; - - virtual ~SortedPhonebookBase() {} - }; - - typedef Ref SortedPhonebookRef; - - - // base factory class for custom backends - class CustomPhonebookFactory - { - public: - // return sorted phonebook object given the source specification - // (eg. database name, URL, etc.) - virtual SortedPhonebookRef createPhonebook(string source) - throw(GsmException) = 0; - }; - - // registry for custom backends - - class CustomPhonebookRegistry - { - // registered factories - static map *_factoryList; - - public: - // register a factory class for a specific backend - // (case does not matter for backend name) - static void registerCustomPhonebookFactory(string backendName, - CustomPhonebookFactory *factory) - throw(GsmException); - - - // return a phonebook object given the backend name and the source - // specification - static SortedPhonebookRef - createPhonebook(string backendName, string source) throw(GsmException); - }; - -}; - -#endif // GSM_SORTED_PHONEBOOK_BASE_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.cc deleted file mode 100644 index 7ca9f9f160..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.cc +++ /dev/null @@ -1,499 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sorted_sms_store.cc -// * -// * Purpose: Sorted SMS store (residing in files or in the ME) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 14.8.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_NETINET_IN_H -#include -#endif - -using namespace std; -using namespace gsmlib; - -// SMS message file format: -// version number of file format, unsigned short int, 2 bytes in network byte -// order -// then comes the message: -// 1. length of PDU (see 4. below): unsigned short int, -// 2 bytes in network byte order -// 2. index of message, unique for this file: unsigned long, -// 4 bytes in network byte order -// 3. MessageType (1 byte), any of: -// 0 SMS_DELIVER -// 1 SMS_SUBMIT -// 2 SMS_STATUS_REPORT -// 4. PDU in hexadecimal format - -static const unsigned short int SMS_STORE_FILE_FORMAT_VERSION = 1; - -// SortedSMSStore members - -// aux function read bytes with error handling -// return false if EOF -static bool readnbytes(string &filename, - istream &is, int len, char *buf, - bool eofIsError = true) throw(GsmException) -{ - is.read(buf, len); - if (is.bad() || (is.eof() && eofIsError)) - throw GsmException(stringPrintf(_("error reading from file '%s'"), - (filename == "" ? _("") : - filename.c_str())), OSError); - return ! is.eof(); -} - -// aux function write bytes with error handling -static void writenbytes(string &filename, ostream &os, - int len, const char *buf) throw(GsmException) -{ - os.write(buf, len); - if (os.bad()) - throw GsmException(stringPrintf(_("error writing to file '%s'"), - (filename == "" ? _("") : - filename.c_str())), OSError); -} - -void SortedSMSStore::readSMSFile(istream &pbs, string filename) - throw(GsmException) -{ - char numberBuf[4]; - - // check the version - try - { - readnbytes(filename, pbs, 2, numberBuf); - } - catch (GsmException &ge) - { - // ignore error, file might be empty initially - } - unsigned_int_2 version = ntohs(*((unsigned_int_2*)numberBuf)); - if (! pbs.eof() && version != SMS_STORE_FILE_FORMAT_VERSION) - throw GsmException(stringPrintf(_("file '%s' has wrong version"), - filename.c_str()), ParameterError); - - // read entries - while (1) - { - // read PDU length and exit loop if EOF - if (! readnbytes(filename, pbs, 2, numberBuf, false)) - break; - - unsigned_int_2 pduLen = ntohs(*((unsigned_int_2*)numberBuf)); - if (pduLen > 500) - throw GsmException(stringPrintf(_("corrupt SMS store file '%s'"), - filename.c_str()), ParameterError); - - // read reserved integer field of message (was formerly index) - readnbytes(filename, pbs, 4, numberBuf); - //unsigned_int_4 reserved = ntohl(*((unsigned_int_4*)numberBuf)); - - // read message type - readnbytes(filename, pbs, 1, numberBuf); - SMSMessage::MessageType messageType = - (SMSMessage::MessageType)numberBuf[0]; - if (messageType > 2) - throw GsmException(stringPrintf(_("corrupt SMS store file '%s'"), - filename.c_str()), ParameterError); - - char *pduBuf = (char*)alloca(sizeof(char) * pduLen); - - // read pdu - readnbytes(filename, pbs, pduLen, pduBuf); - SMSMessageRef message = - SMSMessage::decode(string(pduBuf, pduLen), - (messageType != SMSMessage::SMS_SUBMIT)); - - SMSStoreEntry *newEntry = new SMSStoreEntry(message, _nextIndex++); - _sortedSMSStore.insert( - SMSStoreMap::value_type( - SMSMapKey(*this, message->serviceCentreTimestamp()), - newEntry) - ); - } -} - -void SortedSMSStore::sync(bool fromDestructor) throw(GsmException) -{ - if (_fromFile && _changed) - { - checkReadonly(); - - // if writing to stdout and not called from destructor ignore - // (avoids writing to stdout multiple times) - if (_filename == "" && ! fromDestructor) return; - - // create backup file - but only once - if (! _madeBackupFile && _filename != "") // don't make backup of stdout - { - renameToBackupFile(_filename); - _madeBackupFile = true; - } - - // open stream - ostream *pbs = NULL; - try - { - if (_filename == "") - pbs = &cout; - else - pbs = new ofstream(_filename.c_str(), ios::out | ios::binary); - - if (pbs->bad()) - throw GsmException( - stringPrintf(_("error opening file '%s' for writing"), - (_filename == "" ? _("") : - _filename.c_str())), - OSError); - - // write version number - unsigned_int_2 version = htons(SMS_STORE_FILE_FORMAT_VERSION); - writenbytes(_filename, *pbs, 2, (char*)&version); - - // and write the entries - for (SMSStoreMap::iterator i = _sortedSMSStore.begin(); - i != _sortedSMSStore.end(); ++i) - { - // create PDU and write length - string pdu = i->second->message()->encode(); - unsigned_int_2 pduLen = htons(pdu.length()); - writenbytes(_filename, *pbs, 2, (char*)&pduLen); - - // write reserved field (was formerly index) - unsigned_int_4 reserved = htonl(0); - writenbytes(_filename, *pbs, 4, (char*)&reserved); - - // write message type - char messageType = i->second->message()->messageType(); - writenbytes(_filename, *pbs, 1, (char*)&messageType); - - // write PDU - writenbytes(_filename, *pbs, pdu.length(), pdu.data()); - } - } - catch(GsmException &e) - { - if (pbs != &cout) delete pbs; - throw; - } - // close file - if (pbs != &cout) delete pbs; - - _changed = false; - } -} - -void SortedSMSStore::checkReadonly() throw(GsmException) -{ - if (_readonly) throw GsmException( - _("attempt to change SMS store read from "), - ParameterError); -} - -SortedSMSStore::SortedSMSStore(string filename) throw(GsmException) : - _changed(false), _fromFile(true), _madeBackupFile(false), - _sortOrder(ByDate), _readonly(false), _filename(filename), _nextIndex(0) -{ - // open the file - ifstream pbs(filename.c_str(), ios::in | ios::binary); - if (pbs.bad()) - throw GsmException(stringPrintf(_("cannot open file '%s'"), - filename.c_str()), OSError); - // and read the file - readSMSFile(pbs, filename); -} - -SortedSMSStore::SortedSMSStore(bool fromStdin) throw(GsmException) : - _changed(false), _fromFile(true), _madeBackupFile(false), - _sortOrder(ByDate), _readonly(fromStdin), _nextIndex(0) - // _filename is "" - this means stdout -{ - // read from stdin - if (fromStdin) - readSMSFile(cin, (string)_("")); -} - -SortedSMSStore::SortedSMSStore(SMSStoreRef meSMSStore) - throw(GsmException) : - _changed(false), _fromFile(false), _madeBackupFile(false), - _sortOrder(ByDate), _readonly(false), _meSMSStore(meSMSStore) -{ - // It is necessary to count the entries read because - // the maximum index into the SMS store may be larger than smsStore.size() - int entriesRead = 0; - reportProgress(0, _meSMSStore->size()); - - for (int i = 0;; ++i) - { - if (entriesRead == _meSMSStore->size()) - break; // ready - if (! _meSMSStore()[i].empty()) - { - _sortedSMSStore.insert( - SMSStoreMap::value_type( - SMSMapKey(*this, - _meSMSStore()[i].message()->serviceCentreTimestamp()), - &_meSMSStore()[i]) - ); - ++entriesRead; - reportProgress(entriesRead); - } - } -} - -void SortedSMSStore::setSortOrder(SortOrder newOrder) -{ - if (_sortOrder == newOrder) return; // nothing to be done - - SMSStoreMap savedSMSStore = _sortedSMSStore; - _sortedSMSStore = SMSStoreMap(); - _sortOrder = newOrder; - - switch (newOrder) - { - case ByIndex: - { - for (SMSStoreMap::iterator i = savedSMSStore.begin(); - i != savedSMSStore.end(); ++i) - _sortedSMSStore.insert( - SMSStoreMap::value_type(SMSMapKey(*this, (i->second->index())), - i->second)); - break; - } - case ByDate: - { - for (SMSStoreMap::iterator i = savedSMSStore.begin(); - i != savedSMSStore.end(); ++i) - _sortedSMSStore.insert( - SMSStoreMap::value_type( - SMSMapKey(*this, (i->second->message()->serviceCentreTimestamp())), - i->second)); - break; - } - case ByAddress: - { - for (SMSStoreMap::iterator i = savedSMSStore.begin(); - i != savedSMSStore.end(); ++i) - _sortedSMSStore.insert( - SMSStoreMap::value_type( - SMSMapKey(*this, (i->second->message()->address())), - i->second)); - break; - } - case ByType: - { - for (SMSStoreMap::iterator i = savedSMSStore.begin(); - i != savedSMSStore.end(); ++i) - _sortedSMSStore.insert( - SMSStoreMap::value_type( - SMSMapKey(*this, (i->second->message()->messageType())), - i->second)); - break; - } - default: - assert(0); - break; - } -} - -int SortedSMSStore::max_size() const -{ - if (_fromFile) - return _sortedSMSStore.max_size(); - else - return _meSMSStore->max_size(); -} - -int SortedSMSStore::capacity() const -{ - if (_fromFile) - return _sortedSMSStore.max_size(); - else - return _meSMSStore->capacity(); -} - -SortedSMSStore::iterator -SortedSMSStore::insert(const SMSStoreEntry& x) throw(GsmException) -{ - checkReadonly(); - _changed = true; - SMSStoreEntry *newEntry; - - if (_fromFile) - newEntry = new SMSStoreEntry(x.message(), _nextIndex++); - else - { - SMSStoreEntry newMEEntry(x.message()); - newEntry = _meSMSStore->insert(newMEEntry); - } - - switch (_sortOrder) - { - case ByIndex: - return - _sortedSMSStore. - insert(SMSStoreMap::value_type(SMSMapKey(*this, newEntry->index()), - newEntry)); - break; - case ByDate: - return - _sortedSMSStore. - insert(SMSStoreMap::value_type( - SMSMapKey(*this, newEntry->message()->serviceCentreTimestamp()), - newEntry)); - break; - case ByAddress: - return - _sortedSMSStore. - insert(SMSStoreMap::value_type( - SMSMapKey(*this, newEntry->message()->address()), - newEntry)); - break; - case ByType: - return - _sortedSMSStore. - insert(SMSStoreMap::value_type( - SMSMapKey(*this, newEntry->message()->messageType()), - newEntry)); - break; - default: - assert(0); - break; - } - return SortedSMSStore::iterator(); -} - -SortedSMSStore::iterator -SortedSMSStore::insert(iterator position, const SMSStoreEntry& x) - throw(GsmException) -{ - return insert(x); -} - -SortedSMSStore::size_type SortedSMSStore::erase(Address &key) - throw(GsmException) -{ - assert(_sortOrder == ByAddress); - - SMSMapKey mapKey(*this, key); - - // deallocate memory or remove from underlying ME SMS store - for (SMSStoreMap::iterator i = _sortedSMSStore.find(mapKey); - i != _sortedSMSStore.end() && i->first == mapKey; ++i) - { - checkReadonly(); - _changed = true; - if (_fromFile) - delete i->second; - else - _meSMSStore->erase((SMSStore::iterator)i->second); - } - - return _sortedSMSStore.erase(mapKey); -} - -SortedSMSStore::size_type SortedSMSStore::erase(int key) - throw(GsmException) -{ - assert(_sortOrder == ByIndex || _sortOrder == ByType); - - SMSMapKey mapKey(*this, key); - - // deallocate memory or remove from underlying ME SMS store - for (SMSStoreMap::iterator i = _sortedSMSStore.find(mapKey); - i != _sortedSMSStore.end() && i->first == mapKey; ++i) - { - checkReadonly(); - _changed = true; - if (_fromFile) - delete i->second; - else - _meSMSStore->erase((SMSStore::iterator)i->second); - } - - return _sortedSMSStore.erase(mapKey); -} - -SortedSMSStore::size_type SortedSMSStore::erase(Timestamp &key) - throw(GsmException) -{ - assert(_sortOrder == ByDate); - - SMSMapKey mapKey(*this, key); - - // deallocate memory or remove from underlying ME SMS store - for (SMSStoreMap::iterator i = _sortedSMSStore.find(mapKey); - i != _sortedSMSStore.end() && i->first == mapKey; ++i) - { - checkReadonly(); - _changed = true; - if (_fromFile) - delete i->second; - else - _meSMSStore->erase((SMSStore::iterator)i->second); - } - - return _sortedSMSStore.erase(mapKey); -} - -void SortedSMSStore::erase(iterator position) - throw(GsmException) -{ - checkReadonly(); - _changed = true; - // deallocate memory or remove from underlying ME SMS store - if (_fromFile) - delete ((SMSStoreMap::iterator)position)->second; - else - _meSMSStore->erase((SMSStore::iterator) - ((SMSStoreMap::iterator)position)->second); - _sortedSMSStore.erase(position); -} - -void SortedSMSStore::erase(iterator first, iterator last) - throw(GsmException) -{ - checkReadonly(); - _changed = true; - for (SMSStoreMap::iterator i = first; i != last; ++i) - if (_fromFile) - delete i->second; - else - _meSMSStore->erase((SMSStore::iterator)i->second); - _sortedSMSStore.erase(first, last); -} - -void SortedSMSStore::clear() throw(GsmException) -{ - checkReadonly(); - _changed = true; - for (iterator i = begin(); i != end(); i++) - erase(i); -} - -SortedSMSStore::~SortedSMSStore() -{ - if (_fromFile) - { - sync(true); - for (SMSStoreMap::iterator i = _sortedSMSStore.begin(); - i != _sortedSMSStore.end(); ++i) - delete i->second; - } -} - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.h deleted file mode 100644 index 126c5856bd..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sorted_sms_store.h +++ /dev/null @@ -1,217 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sorted_sms_store.h -// * -// * Purpose: Sorted SMS store (residing in files or in the ME) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 14.8.1999 -// ************************************************************************* - -#ifndef GSM_SORTED_SMS_STORE_H -#define GSM_SORTED_SMS_STORE_H - -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - // MapKey for SortedSMSStore - - class SortedSMSStore; - typedef MapKey SMSMapKey; - - // maps key (see SortedSMSStore::SortOrder) to entry - - typedef multimap SMSStoreMap; - - // iterator for SortedSMSStore that hides the "second" member of the map - - typedef SMSStoreMap::iterator SMSStoreMapIterator; - class SortedSMSStoreIterator : public SMSStoreMapIterator - { - public: - SortedSMSStoreIterator() {} - SortedSMSStoreIterator(SMSStoreMap::iterator i) : - SMSStoreMapIterator(i) {} - - SMSStoreEntry &operator*() - {return *((SMSStoreMap::iterator)*this)->second;} - - SMSStoreEntry *operator->() - {return ((SMSStoreMap::iterator)*this)->second;} - }; - - // The class SortedSMSStore makes the SMS store more manageable: - // - empty slots in the ME phonebook are hidden by the API - // - the class transparently handles stores that reside in files - - class SortedSMSStore : public RefBase, public NoCopy - { - private: - - bool _changed; // true if file has changed after last save - bool _fromFile; // true if store read from file - bool _madeBackupFile; // true if backup file was created - SortOrder _sortOrder; // sort order of the _sortedSMSStore - // (default is ByDate) - bool _readonly; // =true if read from stdin - string _filename; // name of the file if store from file - SMSStoreMap _sortedSMSStore; // store from file - SMSStoreRef _meSMSStore; // store if from ME - - unsigned int _nextIndex; // next index to use for file-based store - - // initial read of SMS file - void readSMSFile(istream &pbs, string filename) throw(GsmException); - - // synchronize SortedSMSStore with file (no action if in ME) - void sync(bool fromDestructor) throw(GsmException); - - // throw an exception if _readonly is set - void checkReadonly() throw(GsmException); - - public: - // iterator defs - typedef SortedSMSStoreIterator iterator; - typedef SMSStoreMap::size_type size_type; - - // constructor for file-based store - // read from file - SortedSMSStore(string filename) throw(GsmException); - // read from stdin or start empty and write to stdout - SortedSMSStore(bool fromStdin) throw(GsmException); - - // constructor for ME-based store - SortedSMSStore(SMSStoreRef meSMSStore) throw(GsmException); - - // handle sorting - void setSortOrder(SortOrder newOrder); - SortOrder sortOrder() const {return _sortOrder;} - - // store traversal commands - // these are suitable to use stdc++ lib algorithms and iterators - - // traversal commands - iterator begin() {return _sortedSMSStore.begin();} - iterator end() {return _sortedSMSStore.end();} - - // the size macros return the number of used entries - int size() const {return _sortedSMSStore.size();} - int max_size() const; - int capacity() const; - bool empty() const throw(GsmException) {return size() == 0;} - - // existing iterators may be invalidated after an insert operation - // return position - // insert only writes to available positions - // warning: insert fails silently if size() == max_size() - iterator insert(const SMSStoreEntry& x) throw(GsmException); - iterator insert(iterator position, const SMSStoreEntry& x) - throw(GsmException); - - SMSStoreMap::size_type count(Address &key) - { - assert(_sortOrder == ByAddress); - return _sortedSMSStore.count(SMSMapKey(*this, key)); - } - iterator find(Address &key) - { - assert(_sortOrder == ByAddress); - return _sortedSMSStore.find(SMSMapKey(*this, key)); - } - iterator lower_bound(Address &key) - { - assert(_sortOrder == ByAddress); - return _sortedSMSStore.lower_bound(SMSMapKey(*this, key)); - } - iterator upper_bound(Address &key) - { - assert(_sortOrder == ByAddress); - return _sortedSMSStore.upper_bound(SMSMapKey(*this, key)); - } - pair equal_range(Address &key) - { - assert(_sortOrder == ByAddress); - return _sortedSMSStore.equal_range(SMSMapKey(*this, key)); - } - - SMSStoreMap::size_type count(Timestamp &key) - { - assert(_sortOrder == ByDate); - return _sortedSMSStore.count(SMSMapKey(*this, key)); - } - iterator find(Timestamp &key) - { - assert(_sortOrder == ByDate); - return _sortedSMSStore.find(SMSMapKey(*this, key)); - } - iterator lower_bound(Timestamp &key) - { - assert(_sortOrder == ByDate); - return _sortedSMSStore.lower_bound(SMSMapKey(*this, key)); - } - iterator upper_bound(Timestamp &key) - { - assert(_sortOrder == ByDate); - return _sortedSMSStore.upper_bound(SMSMapKey(*this, key)); - } - pair equal_range(Timestamp &key) - { - assert(_sortOrder == ByDate); - return _sortedSMSStore.equal_range(SMSMapKey(*this, key)); - } - - SMSStoreMap::size_type count(int key) - { - assert(_sortOrder == ByIndex || _sortOrder == ByType); - return _sortedSMSStore.count(SMSMapKey(*this, key)); - } - iterator find(int key) - { - assert(_sortOrder == ByIndex || _sortOrder == ByType); - return _sortedSMSStore.find(SMSMapKey(*this, key)); - } - iterator lower_bound(int key) - { - assert(_sortOrder == ByIndex || _sortOrder == ByType); - return _sortedSMSStore.lower_bound(SMSMapKey(*this, key)); - } - iterator upper_bound(int key) - { - assert(_sortOrder == ByIndex || _sortOrder == ByType); - return _sortedSMSStore.upper_bound(SMSMapKey(*this, key)); - } - pair equal_range(int key) - { - assert(_sortOrder == ByIndex || _sortOrder == ByType); - return _sortedSMSStore.equal_range(SMSMapKey(*this, key)); - } - - size_type erase(Address &key) throw(GsmException); - size_type erase(int key) throw(GsmException); - size_type erase(Timestamp &key) throw(GsmException); - void erase(iterator position) throw(GsmException); - void erase(iterator first, iterator last) throw(GsmException); - void clear() throw(GsmException); - - // synchronize SortedPhonebook with file (no action if in ME) - void sync() throw(GsmException) {sync(false);} - - // destructor - // writes back change to file if store is in file - ~SortedSMSStore(); - }; - - typedef Ref SortedSMSStoreRef; -}; - -#endif // GSM_SORTED_SMS_STORE_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sysdep.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sysdep.h deleted file mode 100644 index 864fcf99ff..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_sysdep.h +++ /dev/null @@ -1,83 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_sysdep.h -// * -// * Purpose: Some magic to make alloca work on different platforms plus -// * other system-dependent stuff -// * -// * Warning: Only include this header from gsmlib .cc-files -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 28.10.1999 -// ************************************************************************* - -#ifndef GSM_SYSDEP_H -#define GSM_SYSDEP_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -extern "C" { - - // this is mostly taken from the autoconf documentation (WIN32 added) - -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifdef WIN32 -# include -# define alloca _alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -} - -// Windows-specific stuff -#if defined(WIN32) && ! defined(__GNUC__) -#define NOMINMAX -#include -#include - -#ifdef _MSC_VER -#define min __min -#endif - -#define S_ISREG(mode) (((mode) & _S_IFREG) == _S_IFREG) -#define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) - -#define read _read -#endif - -// define common data types with fixed sizes - -#if SIZEOF_UNSIGNED_SHORT_INT == 2 - typedef unsigned short int unsigned_int_2; -#else -#error "no suitable 2 byte unsigned int available" -#endif -#if SIZEOF_UNSIGNED_LONG_INT == 4 - typedef unsigned long int unsigned_int_4; -#else -#if SIZEOF_UNSIGNED_INT == 4 - typedef unsigned int unsigned_int_4; -#else -#error "no suitable 4 byte unsigned int available" -#endif -#endif - -#endif // GSM_SYSDEP_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.cc deleted file mode 100644 index feea2a24d9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.cc +++ /dev/null @@ -1,456 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_unix_port.cc -// * -// * Purpose: UNIX serial port implementation -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 10.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -static const int holdoff[] = {2000000, 1000000, 400000}; -static const int holdoffArraySize = sizeof(holdoff)/sizeof(int); - -// alarm handling for socket read/write -// the timerMtx is necessary since several threads cannot use the -// timer indepently of each other - -static pthread_mutex_t timerMtx = PTHREAD_MUTEX_INITIALIZER; - -// for non-GNU systems, define alarm() -#ifndef HAVE_ALARM -unsigned int alarm(unsigned int seconds) -{ - struct itimerval old, newt; - newt.it_interval.tv_usec = 0; - newt.it_interval.tv_sec = 0; - newt.it_value.tv_usec = 0; - newt.it_value.tv_sec = (long int)seconds; - if (setitimer(ITIMER_REAL, &newt, &old) < 0) - return 0; - else - return old.it_value.tv_sec; -} -#endif - -// this routine is called in case of a timeout -static void catchAlarm(int) -{ - // do nothing -} - -// start timer -static void startTimer() -{ - pthread_mutex_lock(&timerMtx); - struct sigaction newAction; - newAction.sa_handler = catchAlarm; - newAction.sa_flags = 0; - sigaction(SIGALRM, &newAction, NULL); - alarm(1); -} - -// reset timer -static void stopTimer() -{ - alarm(0); - sigaction(SIGALRM, NULL, NULL); - pthread_mutex_unlock(&timerMtx); -} - -// UnixSerialPort members - -void UnixSerialPort::throwModemException(string message) throw(GsmException) -{ - ostrstream os; - os << message << " (errno: " << errno << "/" << strerror(errno) << ")" - << ends; - char *ss = os.str(); - string s(ss); - delete[] ss; - throw GsmException(s, OSError, errno); -} - -void UnixSerialPort::putBack(unsigned char c) -{ - assert(_oldChar == -1); - _oldChar = c; -} - -int UnixSerialPort::readByte() throw(GsmException) -{ - if (_oldChar != -1) - { - int result = _oldChar; - _oldChar = -1; - return result; - } - - unsigned char c; - int timeElapsed = 0; - struct timeval oneSecond; - bool readDone = false; - - while (! readDone && timeElapsed < _timeoutVal) - { - if (interrupted()) - throwModemException(_("interrupted when reading from TA")); - - // setup fd_set data structure for select() - fd_set fdSet; - oneSecond.tv_sec = 1; - oneSecond.tv_usec = 0; - FD_ZERO(&fdSet); - FD_SET(_fd, &fdSet); - - switch (select(FD_SETSIZE, &fdSet, NULL, NULL, &oneSecond)) - { - case 1: - { - int res = read(_fd, &c, 1); - if (res != 1) - throwModemException(_("end of file when reading from TA")); - else - readDone = true; - break; - } - case 0: - ++timeElapsed; - break; - default: - if (errno != EINTR) - throwModemException(_("reading from TA")); - break; - } - } - if (! readDone) - throwModemException(_("timeout when reading from TA")); - -#ifndef NDEBUG - if (debugLevel() >= 2) - { - // some useful debugging code - if (c == LF) - cerr << ""; - else if (c == CR) - cerr << ""; - else cerr << "<'" << (char) c << "'>"; - cerr.flush(); - } -#endif - return c; -} - -UnixSerialPort::UnixSerialPort(string device, speed_t lineSpeed, - string initString, bool swHandshake) - throw(GsmException) : - _oldChar(-1), _timeoutVal(TIMEOUT_SECS) -{ - struct termios t; - - // open device - _fd = open(device.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); - if (_fd == -1) - throwModemException(stringPrintf(_("opening device '%s'"), - device.c_str())); - - // switch off non-blocking mode - int fdFlags; - if ((fdFlags = fcntl(_fd, F_GETFL)) == -1) { - close(_fd); - throwModemException(_("getting file status flags failed")); - } - fdFlags &= ~O_NONBLOCK; - if (fcntl(_fd, F_SETFL, fdFlags) == -1) { - close(_fd); - throwModemException(_("switching of non-blocking mode failed")); - } - - long int saveTimeoutVal = _timeoutVal; - _timeoutVal = 3; - int initTries = holdoffArraySize; - while (initTries-- > 0) - { - // flush all pending output - tcflush(_fd, TCOFLUSH); - - // toggle DTR to reset modem - int mctl = TIOCM_DTR; - if (ioctl(_fd, TIOCMBIC, &mctl) < 0) { - close(_fd); - throwModemException(_("clearing DTR failed")); - } - // the waiting time for DTR toggling is increased with each loop - usleep(holdoff[initTries]); - if (ioctl(_fd, TIOCMBIS, &mctl) < 0) { - close(_fd); - throwModemException(_("setting DTR failed")); - } - // get line modes - if (tcgetattr(_fd, &t) < 0) { - close(_fd); - throwModemException(stringPrintf(_("tcgetattr device '%s'"), - device.c_str())); - } - - // set line speed - cfsetispeed(&t, lineSpeed); - cfsetospeed(&t, lineSpeed); - - // set the device to a sane state - t.c_iflag |= IGNPAR | (swHandshake ? IXON | IXOFF : 0); - t.c_iflag &= ~(INPCK | ISTRIP | IMAXBEL | - (swHandshake ? 0 : IXON | IXOFF) - | IXANY | IGNCR | ICRNL | IMAXBEL | INLCR | IGNBRK); - t.c_oflag &= ~(OPOST); - // be careful, only touch "known" flags - t.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | - (swHandshake ? CRTSCTS : 0 )); - t.c_cflag |= CS8 | CREAD | HUPCL | (swHandshake ? 0 : CRTSCTS) | CLOCAL; - t.c_lflag &= ~(ECHO | ECHOE | ECHOPRT | ECHOK | ECHOKE | ECHONL | - ECHOCTL | ISIG | IEXTEN | TOSTOP | FLUSHO | ICANON); - t.c_lflag |= NOFLSH; - t.c_cc[VMIN] = 1; - t.c_cc[VTIME] = 0; - - t.c_cc[VSUSP] = 0; - - // write back - if(tcsetattr (_fd, TCSANOW, &t) < 0) { - close(_fd); - throwModemException(stringPrintf(_("tcsetattr device '%s'"), - device.c_str())); - } - // the waiting time for writing to the ME/TA is increased with each loop - usleep(holdoff[initTries]); - - // flush all pending input - tcflush(_fd, TCIFLUSH); - - try - { - // reset modem - putLine("ATZ"); - bool foundOK = false; - int readTries = 5; - while (readTries-- > 0) - { - // for the first call getLine() waits only 3 seconds - // because of _timeoutVal = 3 - string s = getLine(); - if (s.find("OK") != string::npos || - s.find("CABLE: GSM") != string::npos) - { - foundOK = true; - readTries = 0; // found OK, exit loop - } - else if (s.find("ERROR") != string::npos) - readTries = 0; // error, exit loop - } - - // set getLine/putLine timeout back to old value - _timeoutVal = saveTimeoutVal; - - if (foundOK) - { - // init modem - readTries = 5; - putLine("AT" + initString); - while (readTries-- > 0) - { - string s = getLine(); - if (s.find("OK") != string::npos || - s.find("CABLE: GSM") != string::npos) - return; // found OK, return - } - } - } - catch (GsmException &e) - { - _timeoutVal = saveTimeoutVal; - if (initTries == 0) { - close(_fd); - throw e; - } - } - } - // no response after 3 tries - close(_fd); - throw GsmException(stringPrintf(_("reset modem failed '%s'"), - device.c_str()), OtherError); -} - -string UnixSerialPort::getLine() throw(GsmException) -{ - string result; - int c; - while ((c = readByte()) >= 0) - { - while (c == CR) - { - c = readByte(); - } - if (c == LF) - break; - result += c; - } - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "<-- " << result << endl; -#endif - - return result; -} - -void UnixSerialPort::putLine(string line, - bool carriageReturn) throw(GsmException) -{ -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "--> " << line << endl; -#endif - - if (carriageReturn) line += CR; - const char *l = line.c_str(); - - int timeElapsed = 0; - struct timeval oneSecond; - - ssize_t bytesWritten = 0; - while (bytesWritten < (ssize_t)line.length() && timeElapsed < _timeoutVal) - { - if (interrupted()) - throwModemException(_("interrupted when writing to TA")); - - // setup fd_set data structure for select() - fd_set fdSet; - oneSecond.tv_sec = 1; - oneSecond.tv_usec = 0; - FD_ZERO(&fdSet); - FD_SET(_fd, &fdSet); - - switch (select(FD_SETSIZE, NULL, &fdSet, NULL, &oneSecond)) - { - case 1: - { - ssize_t bw = write(_fd, l + bytesWritten, line.length() - bytesWritten); - if (bw < 0) - throwModemException(_("writing to TA")); - bytesWritten += bw; - break; - } - case 0: - ++timeElapsed; - break; - default: - if (errno != EINTR) - throwModemException(_("writing to TA")); - break; - } - } - - while (timeElapsed < _timeoutVal) - { - if (interrupted()) - throwModemException(_("interrupted when writing to TA")); - startTimer(); - int res = tcdrain(_fd); // wait for output to be read by TA - stopTimer(); - if (res == 0) - break; - else - { - assert(errno == EINTR); - ++timeElapsed; - } - } - if (timeElapsed >= _timeoutVal) - throwModemException(_("timeout when writing to TA")); - - // echo CR LF must be removed by higher layer functions in gsm_at because - // in order to properly handle unsolicited result codes from the ME/TA -} - -bool UnixSerialPort::wait(GsmTime timeout) throw(GsmException) -{ - fd_set fds; - FD_ZERO(&fds); - FD_SET(_fd, &fds); - return select(FD_SETSIZE, &fds, NULL, NULL, timeout) != 0; -} - -// set timeout for read or write in seconds. -void UnixSerialPort::setTimeOut(unsigned int timeout) -{ - _timeoutVal = timeout; -} - -UnixSerialPort::~UnixSerialPort() -{ - if (_fd != -1) - close(_fd); -} - -speed_t gsmlib::baudRateStrToSpeed(string baudrate) throw(GsmException) -{ - if (baudrate == "300") - return B300; - else if (baudrate == "600") - return B600; - else if (baudrate == "1200") - return B1200; - else if (baudrate == "2400") - return B2400; - else if (baudrate == "4800") - return B4800; - else if (baudrate == "9600") - return B9600; - else if (baudrate == "19200") - return B19200; - else if (baudrate == "38400") - return B38400; -#ifdef B57600 - else if (baudrate == "57600") - return B57600; -#endif -#ifdef B115200 - else if (baudrate == "115200") - return B115200; -#endif -#ifdef B230400 - else if (baudrate == "230400") - return B230400; -#endif -#ifdef B460800 - else if (baudrate == "460800") - return B460800; -#endif - else - throw GsmException(stringPrintf(_("unknown baudrate '%s'"), - baudrate.c_str()), ParameterError); -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.h deleted file mode 100644 index 29b1800b6c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_unix_serial.h +++ /dev/null @@ -1,62 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_unix_port.h -// * -// * Purpose: UNIX serial port implementation -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.5.1999 -// ************************************************************************* - -#ifndef GSM_UNIX_SERIAL_H -#define GSM_UNIX_SERIAL_H - -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace gsmlib -{ - class UnixSerialPort : public Port - { - private: - int _fd; // file descriptor for device - int _debug; // debug level (set by environment variable - // GSM_DEBUG - int _oldChar; // character set by putBack() (-1 == none) - long int _timeoutVal; // timeout for getLine/readByte - - // throw GsmException include UNIX errno - void throwModemException(string message) throw(GsmException); - - public: - // create Port given the UNIX device name - UnixSerialPort(string device, speed_t lineSpeed = DEFAULT_BAUD_RATE, - string initString = DEFAULT_INIT_STRING, - bool swHandshake = false) - throw(GsmException); - - // inherited from Port - void putBack(unsigned char c); - int readByte() throw(GsmException); - string getLine() throw(GsmException); - void putLine(string line, - bool carriageReturn = true) throw(GsmException); - bool wait(GsmTime timeout) throw(GsmException); - void setTimeOut(unsigned int timeout); - - virtual ~UnixSerialPort(); - }; - - // convert baudrate string ("300" .. "460800") to speed_t - extern speed_t baudRateStrToSpeed(string baudrate) throw(GsmException); -}; - -#endif // GSM_UNIX_SERIAL_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.cc deleted file mode 100755 index bfcb4e9858..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.cc +++ /dev/null @@ -1,381 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_util.h -// * -// * Purpose: Various utilities -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if !defined(HAVE_CONFIG_H) || defined(HAVE_UNISTD_H) -#include -#endif -#if !defined(HAVE_CONFIG_H) || defined(HAVE_MALLOC_H) -#include -#endif -#include -#ifdef HAVE_VSNPRINTF -// switch on vsnprintf() prototype in stdio.h -#define __USE_GNU -#define _GNU_SOURCE -#endif -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -// Latin-1 undefined character (code 172 (Latin-1 boolean not, "")) -const int NOP = 172; - -// GSM undefined character (code 16 (GSM Delta)) -const int GSM_NOP = 16; - -// conversion tables, Latin1 to GSM and GSM to Latin1 - -static unsigned char gsmToLatin1Table[] = -{ - // 0 '@', '', '$', '', '', '', '', '', - '@', 163, '$', 165, 232, 233, 249, 236, - // 8 '', '', LF, '', '', CR, '', '', - 242, 199, 10, 216, 248, 13, 197, 229, - // 16 '', '_', '', '', '', '', '', '', - NOP, '_', NOP, NOP, NOP, NOP, NOP, NOP, - // 24 '', '', '', '', '', '', '', '', - NOP, NOP, NOP, NOP, 198, 230, 223, 201, - // 32 ' ', '!', '"', '#', '', '%', '&', ''', - ' ', '!', '"', '#', 164, '%', '&', '\'', - // 40 '(', ')', '*', '+', ',', '-', '.', '/', - '(', ')', '*', '+', ',', '-', '.', '/', - // 48 '0', '1', '2', '3', '4', '5', '6', '7', - '0', '1', '2', '3', '4', '5', '6', '7', - // 56 '8', '9', ':', ';', '<', '=', '>', '?', - '8', '9', ':', ';', '<', '=', '>', '?', - // 64 '', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', - // 72 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - // 80 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - // 88 'X', 'Y', 'Z', '', '', '', '', '', - 'X', 'Y', 'Z', 196, 214, 209, 220, 167, - // 96 '', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', - // 104 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - // 112 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - // 120 'x', 'y', 'z', '', '', '', '', '', - 'x', 'y', 'z', 228, 246, 241, 252, 224 -}; - -static unsigned char latin1ToGsmTable[256]; - -static class Latin1ToGsmTableInit -{ -public: - Latin1ToGsmTableInit() - { - memset((void*)latin1ToGsmTable, GSM_NOP, 256); - for (int i = 0; i < 128; i++) - if (gsmToLatin1Table[i] != NOP) - latin1ToGsmTable[gsmToLatin1Table[i]] = i; - } -} latin1ToGsmTableInit; - -string gsmlib::gsmToLatin1(string s) -{ - string result(s.length(), 0); - for (string::size_type i = 0; i < s.length(); i++) - result[i] = (unsigned char)s[i] > 127 ? NOP : gsmToLatin1Table[s[i]]; - return result; -} - -string gsmlib::latin1ToGsm(string s) -{ - string result(s.length(), 0); - for (string::size_type i = 0; i < s.length(); i++) - result[i] = latin1ToGsmTable[(unsigned char)s[i]]; - return result; -} - -static unsigned char byteToHex[] = -{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; - -string gsmlib::bufToHex(const unsigned char *buf, unsigned long length) -{ - const unsigned char *bb = buf; - string result; - result.reserve(length * 2); - - for (unsigned long i = 0; i < length; ++i) - { - result += byteToHex[*bb >> 4]; - result += byteToHex[*bb++ & 0xf]; - } - return result; -} - -bool gsmlib::hexToBuf(const string &hexString, unsigned char *buf) -{ - if (hexString.length() % 2 != 0) - return false; - - unsigned char *bb = buf; - for (unsigned int i = 0; i < hexString.length(); i += 2) - { - unsigned char c = hexString[i]; - if (! isdigit(c) && ! ('a' <= c && c <= 'f') && ! ('A' <= c && c <= 'F')) - return false; - *bb = (isdigit(c) ? c - '0' : - ((('a' <= c && c <= 'f') ? c - 'a' : c - 'A')) + 10) << 4; - c = hexString[i + 1]; - if (! isdigit(c) && ! ('a' <= c && c <= 'f') && ! ('A' <= c && c <= 'F')) - return false; - *bb++ |= isdigit(c) ? c - '0' : - ((('a' <= c && c <= 'f') ? c - 'a' : c - 'A') + 10); - } - return true; -} - -string gsmlib::intToStr(int i) -{ - ostrstream os; - os << i << ends; - char *ss = os.str(); - string s(ss); - delete[] ss; - return s; -} - -string gsmlib::removeWhiteSpace(string s) -{ - string result; - for (unsigned int i = 0; i < s.length(); ++i) - if (! isspace(s[i])) - result += s[i]; - return result; -} - -#ifdef WIN32 - -// helper routine, find out whether filename starts with "COM" -static bool isCom(string filename) -{ - filename = removeWhiteSpace(lowercase(filename)); - // remove UNC begin - if ( filename.compare(0, 4, "\\\\.\\") == 0 ) - filename.erase(0, 4); - return filename.length() < 3 || filename.substr(0, 3) == "com"; -} -#endif - -bool gsmlib::isFile(string filename) -{ -#ifdef WIN32 - // stat does not work reliably under Win32 to indicate devices - if (isCom(filename)) - return false; -#endif - - struct stat statBuf; - int retries = 0; - - while (retries < 10) - { - if (stat(filename.c_str(), &statBuf) != 0) - throw GsmException( - stringPrintf(_("error when calling stat('%s') (errno: %d/%s)"), - filename.c_str(), errno, strerror(errno)), - OSError); - -#ifndef WIN32 - if (S_ISLNK(statBuf.st_mode)) - { - int size = 100; - while (1) - { - char *buffer = (char*)malloc(size); - int nchars = readlink(filename.c_str(), buffer, size); - if (nchars < size) - { - filename.assign(buffer, nchars); - free(buffer); - break; - } - free(buffer); - size *= 2; - } - ++retries; - } - else if (S_ISCHR(statBuf.st_mode)) - return false; - else -#endif - if (S_ISREG(statBuf.st_mode)) - return true; - else - throw GsmException( - stringPrintf(_("file '%s' is neither file nor character device"), - filename.c_str()), - ParameterError); - } - throw GsmException(_("maxmimum number of symbolic links exceeded"), - ParameterError); -} - -void gsmlib::renameToBackupFile(string filename) throw(GsmException) -{ - string backupFilename = filename + "~"; - unlink(backupFilename.c_str()); - if (rename(filename.c_str(), backupFilename.c_str()) < 0) - throw GsmException( - stringPrintf(_("error renaming '%s' to '%s'"), - filename.c_str(), backupFilename.c_str()), - OSError, errno); -} - -// NoCopy members - -#ifndef NDEBUG - -NoCopy::NoCopy(NoCopy &n) -{ - cerr << "ABORT: NoCopy copy constructor used" << endl; - abort(); -} - -NoCopy &NoCopy::operator=(NoCopy &n) -{ - cerr << "ABORT: NoCopy::operator= used" << endl; - abort(); -#ifdef WIN32 - return n; -#endif //WIN32 -} - -#endif // NDEBUG - -string gsmlib::lowercase(string s) -{ - string result; - for (unsigned int i = 0; i < s.length(); ++i) - result += tolower(s[i]); - return result; -} - -int gsmlib::checkNumber(string s) throw(GsmException) -{ - for (unsigned int i = 0; i < s.length(); ++i) - if (! isdigit(s[i])) - throw GsmException(stringPrintf(_("expected number, got '%s'"), - s.c_str()), ParameterError); - int result; - istrstream is(s.c_str()); - is >> result; - return result; -} - -#ifdef HAVE_VSNPRINTF -string gsmlib::stringPrintf(const char *format, ...) -{ - va_list args; - va_start(args, format); - int size = 1024; - while (1) - { - char *buf = (char*)alloca(sizeof(char) * size); - int nchars = vsnprintf(buf, size, format, args); - if (nchars < size) - { - va_end(args); - return string(buf, nchars); - } - size *= 2; - } - return ""; -} - -#else -char gsmlib::__s[20000]; // buffer for the replacement macro -#endif // HAVE_VSNPRINTF - -#ifndef NDEBUG -int gsmlib::debugLevel() -{ - char *s = getenv("GSMLIB_DEBUG"); - if (s == NULL) return 0; - return checkNumber(s); -} -#endif - -// interrupt interface - -namespace gsmlib -{ - static InterruptBase *interruptObject = NULL; -} - -void gsmlib::setInterruptObject(InterruptBase *intObject) -{ - interruptObject = intObject; -} - -bool gsmlib::interrupted() -{ - return interruptObject != NULL && interruptObject->interrupted(); -} - -void gsmlib::checkTextAndTelephone(string text, string telephone) - throw(GsmException) -{ - if (text.find('"') != string::npos) - throw GsmException( - stringPrintf(_("text '%s' contains illegal character '\"'"), - text.c_str()), - ParameterError); - - for (unsigned int i = 0; i < telephone.length(); ++i) - if (! isdigit(telephone[i]) && ! (telephone[i] == '+') && - ! (telephone[i] == '*') && ! (telephone[i] == '#') && - ! (telephone[i] == 'p') && ! (telephone[i] == 'w') && - ! (telephone[i] == 'P') && ! (telephone[i] == 'W')) - throw GsmException( - stringPrintf(_("illegal character in telephone number '%s'"), - telephone.c_str()), ParameterError); -} - -// progress interface - -namespace gsmlib -{ - static ProgressBase *progressObject = NULL; -} - -void gsmlib::setProgressObject(ProgressBase *progObject) -{ - progressObject = progObject; -} - -void gsmlib::reportProgress(int part, int total) -{ - if (progressObject != NULL) - progressObject->reportProgress(part, total); -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.h deleted file mode 100644 index e4cee34372..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_util.h +++ /dev/null @@ -1,233 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_util.h -// * -// * Purpose: Various utilities -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 4.5.1999 -// ************************************************************************* - -#ifndef GSM_UTIL_H -#define GSM_UTIL_H - -#include -#include -#include -#include -#ifndef WIN32 -#include -#endif -#include - -using namespace std; - -namespace gsmlib -{ - // time type - typedef struct timeval *GsmTime; - - // some constants - const char CR = 13; // ASCII carriage return - const char LF = 10; // ASCII line feed - - // common number formats - const unsigned int UnknownNumberFormat = 129; - const unsigned int InternationalNumberFormat = 145; - - // convert gsm to Latin-1 - // characters that have no counterpart in Latin-1 are converted to - // code 172 (Latin-1 boolean not, "") - string gsmToLatin1(string s); - - // convert Latin-1 to gsm - // characters that have no counterpart in GSM are converted to - // code 16 (GSM Delta) - string latin1ToGsm(string s); - - // convert byte buffer of length to hexadecimal string - string bufToHex(const unsigned char *buf, unsigned long length); - - // convert hexString to byte buffer, return false if no hexString - bool hexToBuf(const string &hexString, unsigned char *buf); - - // indicate that a value is not set - const int NOT_SET = -1; - - // An integer range - struct IntRange - { - int _high, _low; - - IntRange() : _high(NOT_SET), _low(NOT_SET) {} - }; - - // A valid integer range for a given parameter - struct ParameterRange - { - string _parameter; - IntRange _range; - }; - - // *** general-purpose pointer wrapper with reference counting - - class RefBase - { - private: - int _refCount; - - public: - RefBase() : _refCount(0) {} - int ref() {return _refCount++;} - int unref() {return --_refCount;} - int refCount() const {return _refCount;} - }; - - template - class Ref - { - private: - T *_rep; - public: - T *operator->() const {return _rep;} - T &operator()() {return *_rep;} - T *getptr() {return _rep;} - bool isnull() const {return _rep == (T*)NULL;} - Ref() : _rep((T*)NULL) {} - Ref(T *pp) : _rep(pp) {if (pp != (T*)NULL) pp->ref();} - Ref(const Ref &r); - Ref &operator=(const Ref &r); - ~Ref(); - bool operator==(const Ref &r) const - { - return _rep == r._rep; - } - }; - - template - Ref::Ref(const Ref &r) : _rep(r._rep) - { - if (_rep != (T*)NULL) _rep->ref(); - } - - template - Ref &Ref::operator=(const Ref &r) - { - if (r._rep != (T*)NULL) r._rep->ref(); - if (_rep != (T*)NULL && _rep->unref() == 0) delete _rep; - _rep = r._rep; - return *this; - } - - template - Ref::~Ref() - { - if (_rep != (T*)NULL && _rep->unref() == 0) delete _rep; - } - - // utility function return string given an int - string intToStr(int i); - - // remove white space from the string - string removeWhiteSpace(string s); - - // return true if bit is set in vector - inline bool isSet(vector &b, unsigned int bit) - { - return b.size() > bit && b[bit]; - } - - // return true if filename refers to a file - // throws exception if filename is neither file nor device - bool isFile(string filename); - - // make backup file adequate for this operating system - void renameToBackupFile(string filename) throw(GsmException); - - // Base class for class for which copying is not allow - // only used for debugging - - class NoCopy - { - public: - NoCopy() {} - -#ifndef NDEBUG - NoCopy(NoCopy &n); - - NoCopy &operator=(NoCopy &n); -#endif - }; - - // convert string to lower case - string lowercase(string s); - - // convert string to number and check for all digits - int checkNumber(string s) throw(GsmException); - - // like printf, but return C++ string -#ifdef HAVE_VSNPRINTF - string stringPrintf(const char *format, ...) -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) - __attribute__((format (printf, 1, 2))) -#endif - ; -#else - // WARNING: This replacement code is - // - not threadsafe - // - subject to buffer overruns -#define stringPrintf(format, args...) \ - (sprintf(__s, format, ## args), string(__s)) - - extern char __s[]; -#endif // HAVE_VSNPRINTF - - // return debug level -#ifndef NDEBUG - extern int debugLevel(); -#endif - - // interface for interrupting gsmlib activity - - class InterruptBase - { - public: - // this member should return true if gsmlib is to be interrupted - virtual bool interrupted() = 0; - }; - - // set global interrupt object - extern void setInterruptObject(InterruptBase *intObject); - - // return true if interrupted - extern bool interrupted(); - - // interface for reporting progress - - class ProgressBase - { - public: - // override this to receive progress reports - virtual void reportProgress(int part, int total) = 0; - }; - - // set global progress object - extern void setProgressObject(ProgressBase *progObject); - - // report progress (part/total * 100 is meant to be the percentage) - // this function is called by - // - GsmAt::chatv() without arguments, used by Phonebook::Phonebook() - // - Phonebook::Phonebook() - // - SortedPhonebook::SortedPhonebook() - // - SortedSMSStore::SortedSMSStore() - extern void reportProgress(int part = -1, int total = -1); - - // check for valid text and telephone number - // throw exception if error - extern void checkTextAndTelephone(string text, string telephone) - throw(GsmException); -}; - -#endif // GSM_UTIL_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.cc deleted file mode 100644 index dda1d74587..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.cc +++ /dev/null @@ -1,507 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_win32_port.cc -// * -// * Purpose: WIN32 serial port implementation -// * -// * Author: Frediano Ziglio (freddy77@angelfire.com) -// * -// * Created: 25.10.2000 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -static long int timeoutVal = TIMEOUT_SECS; - -struct ExceptionSafeOverlapped: public OVERLAPPED -{ - ExceptionSafeOverlapped() - { - memset((OVERLAPPED*)this,0,sizeof(OVERLAPPED)); - hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - if (hEvent == INVALID_HANDLE_VALUE) - throw GsmException(_("error creating event"),OSError,GetLastError()); - } - ~ExceptionSafeOverlapped() - { CloseHandle(hEvent); } -}; - -typedef BOOL (WINAPI *TCancelIoProc)(HANDLE file); -TCancelIoProc CancelIoProc = NULL; -BOOL CancelIoHook(HANDLE file) -{ - if (CancelIoProc) - return CancelIoProc(file); - - HMODULE hmodule = GetModuleHandle("KERNEL32"); - if (hmodule) - { - CancelIoProc = (TCancelIoProc)GetProcAddress(hmodule,"CancelIo"); - if (CancelIoProc) - return CancelIoProc(file); - } - - return TRUE; -} -#define CancelIo CancelIoHook - -// Win32SerialPort members - -void Win32SerialPort::throwModemException(string message) throw(GsmException) -{ - ostrstream os; - os << message << " (errno: " << errno << "/" << strerror(errno) << ")" - << ends; - char *ss = os.str(); - string s(ss); - delete[] ss; - throw GsmException(s, OSError, errno); -} - -void Win32SerialPort::putBack(unsigned char c) -{ - assert(_oldChar == -1); - _oldChar = c; -} - -int Win32SerialPort::readByte() throw(GsmException) -{ - if (_oldChar != -1) - { - int result = _oldChar; - _oldChar = -1; - return result; - } - - unsigned char c; - int timeElapsed = 0; - bool readDone = true; - ExceptionSafeOverlapped over; - - DWORD initTime = GetTickCount(); - DWORD dwReaded; - if (!ReadFile(_file,&c,1,&dwReaded,&over)) - { - readDone = false; - if (GetLastError() != ERROR_IO_PENDING) - { - throwModemException(_("reading from TA")); - } - - while(!readDone) - { - if (interrupted()) - throwModemException(_("interrupted when reading from TA")); - - // wait another second - switch(WaitForSingleObject(over.hEvent,1000)) - { - case WAIT_TIMEOUT: - break; - case WAIT_OBJECT_0: - case WAIT_ABANDONED: - // !!! do a infinite loop if (bytesWritten < lenght) ? - GetOverlappedResult(_file,&over,&dwReaded,TRUE); - readDone = true; - break; - case WAIT_FAILED: - throwModemException(_("reading from TA")); - } - - timeElapsed = (GetTickCount() - initTime)/1000U; - - // timeout elapsed ? - if (timeElapsed >= timeoutVal) - { - CancelIo(_file); - break; - } - - } - } - - if (! readDone) - throwModemException(_("timeout when reading from TA")); - -#ifndef NDEBUG - if (debugLevel() >= 2) - { - // some useful debugging code - if (c == LF) - cerr << ""; - else if (c == CR) - cerr << ""; - else cerr << "<'" << (char) c << "'>"; - cerr.flush(); - } -#endif - return c; -} - -Win32SerialPort::Win32SerialPort(string device, int lineSpeed, - string initString, bool swHandshake) - throw(GsmException) : - _oldChar(-1) -{ - try - { - int holdoff[] = {2000, 1000, 400}; - - // open device - _file = CreateFile(device.c_str(),GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); - if (_file == INVALID_HANDLE_VALUE) - throwModemException(stringPrintf(_("opening device '%s'"), - device.c_str())); - - int initTries = 3; - while (initTries-- > 0) - { - // flush all pending output - FlushFileBuffers(_file); - - // toggle DTR to reset modem - if (!EscapeCommFunction(_file,CLRDTR)) - throwModemException(_("clearing DTR failed")); - Sleep(holdoff[initTries]); - if (!EscapeCommFunction(_file,SETDTR)) - throwModemException(_("setting DTR failed")); - - DCB dcb; - // get line modes - if (!GetCommState(_file,&dcb)) - throwModemException(stringPrintf(_("GetCommState device '%s'"), - device.c_str())); - -// if (tcgetattr(_fd, &t) < 0) -// throwModemException(stringPrintf(_("tcgetattr device '%s'"), -// device.c_str())); - - // set the device to a sane state - dcb.fBinary = TRUE; - dcb.BaudRate = lineSpeed; - - // n,8,1 - dcb.fParity = FALSE; - dcb.Parity = 0; - dcb.ByteSize = 8; - dcb.StopBits = 0; - - if (!swHandshake) - { - dcb.fInX = FALSE; - dcb.fOutX = FALSE; - dcb.fOutxDsrFlow = FALSE; - dcb.fOutxCtsFlow = FALSE; - } - else - { - dcb.fInX = TRUE; - dcb.fOutX = TRUE; - dcb.fOutxDsrFlow = FALSE; - dcb.fOutxCtsFlow = FALSE; - } - dcb.fDtrControl = DTR_CONTROL_ENABLE; - dcb.fRtsControl = RTS_CONTROL_ENABLE; - -// t.c_iflag |= IGNPAR; -// t.c_iflag &= ~(INPCK | ISTRIP | IMAXBEL | -// (swHandshake ? CRTSCTS : IXON | IXOFF) -// | IXANY | IGNCR | ICRNL | IMAXBEL | INLCR | IGNBRK); -// t.c_oflag &= ~(OPOST); -// // be careful, only touch "known" flags -// t.c_cflag&= ~(CSIZE | CSTOPB | PARENB | PARODD); -// t.c_cflag|= CS8 | CREAD | HUPCL | -// (swHandshake ? IXON | IXOFF : CRTSCTS) | -// CLOCAL; -// t.c_lflag &= ~(ECHO | ECHOE | ECHOPRT | ECHOK | ECHOKE | ECHONL | -// ECHOCTL | ISIG | IEXTEN | TOSTOP | FLUSHO | ICANON); -// t.c_lflag |= NOFLSH; -// -// t.c_cc[VMIN] = 1; -// t.c_cc[VTIME] = 0; -// -// t.c_cc[VSUSP] = 0; - - // write back - if (!SetCommState(_file,&dcb)) - throwModemException(stringPrintf(_("SetCommState device '%s'"), - device.c_str())); - - Sleep(holdoff[initTries]); - - if (!SetupComm(_file,1024,1024)) - throwModemException(stringPrintf(_("SetupComm device '%s'"), - device.c_str())); - - - // flush all pending input - PurgeComm(_file,PURGE_RXABORT|PURGE_RXCLEAR); - - try - { - // reset modem - putLine("ATZ"); - bool foundOK = false; - int readTries = 5; - while (readTries-- > 0) - { - string s = getLine(); - if (s.find("OK") != string::npos || - s.find("CABLE: GSM") != string::npos) - { - foundOK = true; - readTries = 0; // found OK, exit loop - } - } - - if (foundOK) - { - // init modem - readTries = 5; - // !!! no not declare this in loop, compiler error on Visual C++ - // (without SP and with SP4) - string s; - putLine("AT" + initString); - do - { - s = getLine(); - if (s.find("OK") != string::npos || - s.find("CABLE: GSM") != string::npos) - return; // found OK, return - } while(--readTries); - } - } - catch (GsmException &e) - { - if (initTries == 0) - throw e; - } - } - // no response after 3 tries - throw GsmException(stringPrintf(_("reset modem failed '%s'"), - device.c_str()), OtherError); - } - catch (GsmException &e) - { - if ( _file != INVALID_HANDLE_VALUE) - CloseHandle(_file); - throw e; - } -} - -string Win32SerialPort::getLine() throw(GsmException) -{ - string result; - int c; - while ((c = readByte()) > 0) - { - while (c == CR) - { - c = readByte(); - } - if (c == LF) - break; - result += c; - } - -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "<-- " << result << endl; -#endif - - return result; -} - -void Win32SerialPort::putLine(string line, - bool carriageReturn) throw(GsmException) -{ -#ifndef NDEBUG - if (debugLevel() >= 1) - cerr << "--> " << line << endl; -#endif - - if (carriageReturn) line += CR; - // !!! BUG, mantain this pointer isn't corrent, use iterator !!! - const char *l = line.c_str(); - - FlushFileBuffers(_file); // flush all pending input and output - - int timeElapsed = 0; - - DWORD bytesWritten = 0; - - ExceptionSafeOverlapped over; - - DWORD initTime = GetTickCount(); - if (!WriteFile(_file,l,line.length(),&bytesWritten,&over)) - { - if (GetLastError() != ERROR_IO_PENDING) - { - throwModemException(_("writing to TA")); - } - - while(bytesWritten < (DWORD)line.length()) - { - if (interrupted()) - throwModemException(_("interrupted when writing to TA")); - - // wait another second - switch(WaitForSingleObject(over.hEvent,1000)) - { - case WAIT_TIMEOUT: - break; - case WAIT_OBJECT_0: - case WAIT_ABANDONED: - // !!! do a infinite loop if (bytesWritten < lenght) ? - GetOverlappedResult(_file,&over,&bytesWritten,TRUE); - break; - case WAIT_FAILED: - throwModemException(_("writing to TA")); - } - - timeElapsed = (GetTickCount() - initTime)/1000U; - - // timeout elapsed ? - if (timeElapsed >= timeoutVal) - { - CancelIo(_file); - throwModemException(_("timeout when writing to TA")); - } - - } - } - - return; -/* - // empty buffer - SetCommMask(_file,EV_TXEMPTY); - DWORD dwEvent; - ResetEvent(over.hEvent); - if( WaitCommEvent(_file,&dwEvent,&over) ) - return; // already empty - - // check true errors - if (GetLastError() != ERROR_IO_PENDING) - throwModemException(_("error comm waiting")); - - while(timeElapsed < timeoutVal) - { - if (interrupted()) - throwModemException(_("interrupted when flushing to TA")); - - switch( WaitForSingleObject( over.hEvent, 1000 ) ) - { - case WAIT_TIMEOUT: - break; - - // successfully flushed - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - return; - - default: - throwModemException(_("error waiting")); - } - timeElapsed = (GetTickCount() - initTime)/1000U; - } - - CancelIo(_file); - throwModemException(_("timeout when writing to TA")); -*/ - - // echo CR LF must be removed by higher layer functions in gsm_at because - // in order to properly handle unsolicited result codes from the ME/TA -} - -bool Win32SerialPort::wait(GsmTime timeout) throw(GsmException) -{ - // See differences from UNIX - // Why do I use Windows ? - DWORD dwEvent; - SetCommMask(_file,EV_RXCHAR); - if (!timeout) - { - if( !WaitCommEvent(_file,&dwEvent,NULL) ) - throwModemException(_("error comm waiting")); - return true; - } - - ExceptionSafeOverlapped over; - if( !WaitCommEvent(_file,&dwEvent,&over) ) - { - // check true errors - if (GetLastError() != ERROR_IO_PENDING) - throwModemException(_("error comm waiting")); - - switch( WaitForSingleObject( over.hEvent, timeout->tv_sec*1000U+(timeout->tv_usec/1000U) ) ) - { - case WAIT_TIMEOUT: - CancelIo(_file); - return false; - - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - return true; - - default: - throwModemException(_("error waiting")); - } - } - - return true; -} - -void Win32SerialPort::setTimeOut(unsigned int timeout) -{ - timeoutVal = timeout; -} - -Win32SerialPort::~Win32SerialPort() -{ - if ( _file != INVALID_HANDLE_VALUE) - CloseHandle(_file); -} - -int gsmlib::baudRateStrToSpeed(string baudrate) throw(GsmException) -{ - if (baudrate == "300") - return 300; - else if (baudrate == "600") - return 600; - else if (baudrate == "1200") - return 1200; - else if (baudrate == "2400") - return 2400; - else if (baudrate == "4800") - return 4800; - else if (baudrate == "9600") - return 9600; - else if (baudrate == "19200") - return 19200; - else if (baudrate == "38400") - return 38400; - else if (baudrate == "57600") - return 57600; - else if (baudrate == "115200") - return 115200; - else - throw GsmException(stringPrintf(_("unknown baudrate '%s'"), - baudrate.c_str()), ParameterError); -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.h deleted file mode 100644 index 627bd09354..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/gsmlib/gsm_win32_serial.h +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: gsm_win32_port.h -// * -// * Purpose: WIN32 serial port implementation -// * -// * Author: Frediano Ziglio (freddy77@angelfire.com) -// * -// * Created: 25.10.2000 -// ************************************************************************* - -#ifndef GSM_WIN32_SERIAL_H -#define GSM_WIN32_SERIAL_H - -#include -#include -#include -#include -#define WIN32_MEAN_AND_LEAN -#include - -using namespace std; - -namespace gsmlib -{ - class Win32SerialPort : public Port - { - private: - HANDLE _file; // file handle for device - int _oldChar; // character set by putBack() (-1 == none) -// OVERLAPPED _overIn; // overlapped structure for wait - - // throw GsmException include UNIX errno - void throwModemException(string message) throw(GsmException); - - public: - // create Port given the UNIX device name - Win32SerialPort(string device, int lineSpeed = DEFAULT_BAUD_RATE, - string initString = DEFAULT_INIT_STRING, - bool swHandshake = false) - throw(GsmException); - - // inherited from Port - void putBack(unsigned char c); - int readByte() throw(GsmException); - string getLine() throw(GsmException); - void putLine(string line, - bool carriageReturn = true) throw(GsmException); - bool wait(GsmTime timeout) throw(GsmException); - void setTimeOut(unsigned int timeout); - - virtual ~Win32SerialPort(); - }; - - // convert baudrate string ("300" .. "460800") to speed_t - extern int baudRateStrToSpeed(string baudrate) throw(GsmException); -}; - -#endif // GSM_UNIX_SERIAL_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/ChangeLog b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/ChangeLog deleted file mode 100644 index 198950159d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/ChangeLog +++ /dev/null @@ -1,1086 +0,0 @@ -1998-04-29 Ulrich Drepper - - * intl/localealias.c (read_alias_file): Use unsigned char for - local variables. Remove unused variable tp. - * intl/l10nflist.c (_nl_normalize_codeset): Use unsigned char * - for type of codeset. For loosing Solaris systems. - * intl/loadinfo.h: Adapt prototype of _nl_normalize_codeset. - * intl/bindtextdom.c (BINDTEXTDOMAIN): Don't define local variable - len if not needed. - Patches by Jim Meyering. - -1998-04-28 Ulrich Drepper - - * loadmsgcat.c (_nl_load_domain): Don't assign the element use_mmap if - mmap is not supported. - - * hash-string.h: Don't include . - -1998-04-27 Ulrich Drepper - - * textdomain.c: Use strdup is available. - - * localealias.c: Define HAVE_MEMPCPY so that we can use this - function. Define and use semapahores to protect modfication of - global objects when compiling for glibc. Add code to allow - freeing alias table. - - * l10nflist.c: Don't assume stpcpy not being a macro. - - * gettextP.h: Define internal_function macri if not already done. - Use glibc byte-swap macros instead of defining SWAP when compiled - for glibc. - (struct loaded_domain): Add elements to allow unloading. - - * Makefile.in (distclean): Don't remove libintl.h here. - - * bindtextdomain.c: Carry over changes from glibc. Use strdup if - available. - - * dcgettext.c: Don't assume stpcpy not being a macro. Mark internal - functions. Add memory freeing code for glibc. - - * dgettext.c: Update copyright. - - * explodename.c: Include stdlib.h and string.h only if they exist. - Use strings.h eventually. - - * finddomain.c: Mark internal functions. Use strdup if available. - Add memory freeing code for glibc. - -1997-10-10 20:00 Ulrich Drepper - - * libgettext.h: Fix dummy textdomain and bindtextdomain macros. - They should return reasonable values. - Reported by Tom Tromey . - -1997-09-16 03:33 Ulrich Drepper - - * libgettext.h: Define PARAMS also to `args' if __cplusplus is defined. - * intlh.inst.in: Likewise. - Reported by Jean-Marc Lasgouttes . - - * libintl.glibc: Update from current glibc version. - -1997-09-06 02:10 Ulrich Drepper - - * intlh.inst.in: Reformat copyright. - -1997-08-19 15:22 Ulrich Drepper - - * dcgettext.c (DCGETTEXT): Remove wrong comment. - -1997-08-16 00:13 Ulrich Drepper - - * Makefile.in (install-data): Don't change directory to install. - -1997-08-01 14:30 Ulrich Drepper - - * cat-compat.c: Fix copyright. - - * localealias.c: Don't define strchr unless !HAVE_STRCHR. - - * loadmsgcat.c: Update copyright. Fix typos. - - * l10nflist.c: Don't define strchr unless !HAVE_STRCHR. - (_nl_make_l10nflist): Handle sponsor and revision correctly. - - * gettext.c: Update copyright. - * gettext.h: Likewise. - * hash-string.h: Likewise. - - * finddomain.c: Remoave dead code. Define strchr only if - !HAVE_STRCHR. - - * explodename.c: Include . - - * explodename.c: Reformat copyright text. - (_nl_explode_name): Fix typo. - - * dcgettext.c: Define and use __set_errno. - (guess_category_value): Don't use setlocale if HAVE_LC_MESSAGES is - not defined. - - * bindtextdom.c: Pretty printing. - -1997-05-01 02:25 Ulrich Drepper - - * dcgettext.c (guess_category_value): Don't depend on - HAVE_LC_MESSAGES. We don't need the macro here. - Patch by Bruno Haible . - - * cat-compat.c (textdomain): DoN't refer to HAVE_SETLOCALE_NULL - macro. Instead use HAVE_LOCALE_NULL and define it when using - glibc, as in dcgettext.c. - Patch by Bruno Haible . - - * Makefile.in (CPPFLAGS): New variable. Reported by Franc,ois - Pinard. - -Mon Mar 10 06:51:17 1997 Ulrich Drepper - - * Makefile.in: Implement handling of libtool. - - * gettextP.h: Change data structures for use of generic lowlevel - i18n file handling. - -Wed Dec 4 20:21:18 1996 Ulrich Drepper - - * textdomain.c: Put parentheses around arguments of memcpy macro - definition. - * localealias.c: Likewise. - * l10nflist.c: Likewise. - * finddomain.c: Likewise. - * bindtextdom.c: Likewise. - Reported by Thomas Esken. - -Mon Nov 25 22:57:51 1996 Ulrich Drepper - - * textdomain.c: Move definition of `memcpy` macro to right - position. - -Fri Nov 22 04:01:58 1996 Ulrich Drepper - - * finddomain.c [!HAVE_STRING_H && !_LIBC]: Define memcpy using - bcopy if not already defined. Reported by Thomas Esken. - * bindtextdom.c: Likewise. - * l10nflist.c: Likewise. - * localealias.c: Likewise. - * textdomain.c: Likewise. - -Tue Oct 29 11:10:27 1996 Ulrich Drepper - - * Makefile.in (libdir): Change to use exec_prefix instead of - prefix. Reported by Knut-HvardAksnes . - -Sat Aug 31 03:07:09 1996 Ulrich Drepper - - * l10nflist.c (_nl_normalize_codeset): We convert to lower case, - so don't prepend uppercase `ISO' for only numeric arg. - -Fri Jul 19 00:15:46 1996 Ulrich Drepper - - * l10nflist.c: Move inclusion of argz.h, ctype.h, stdlib.h after - definition of _GNU_SOURCE. Patch by Roland McGrath. - - * Makefile.in (uninstall): Fix another bug with `for' loop and - empty arguments. Patch by Jim Meyering. Correct name os - uninstalled files: no intl- prefix anymore. - - * Makefile.in (install-data): Again work around shells which - cannot handle mpty for list. Reported by Jim Meyering. - -Sat Jul 13 18:11:35 1996 Ulrich Drepper - - * Makefile.in (install): Split goal. Now depend on install-exec - and install-data. - (install-exec, install-data): New goals. Created from former - install goal. - Reported by Karl Berry. - -Sat Jun 22 04:58:14 1996 Ulrich Drepper - - * Makefile.in (MKINSTALLDIRS): New variable. Path to - mkinstalldirs script. - (install): use MKINSTALLDIRS variable or if the script is not present - try to find it in the $top_scrdir). - -Wed Jun 19 02:56:56 1996 Ulrich Drepper - - * l10nflist.c: Linux libc *partly* includes the argz_* functions. - Grr. Work around by renaming the static version and use macros - for renaming. - -Tue Jun 18 20:11:17 1996 Ulrich Drepper - - * l10nflist.c: Correct presence test macros of __argz_* functions. - - * l10nflist.c: Include based on test of it instead when - __argz_* functions are available. - Reported by Andreas Schwab. - -Thu Jun 13 15:17:44 1996 Ulrich Drepper - - * explodename.c, l10nflist.c: Define NULL for dumb systems. - -Tue Jun 11 17:05:13 1996 Ulrich Drepper - - * intlh.inst.in, libgettext.h (dcgettext): Rename local variable - result to __result to prevent name clash. - - * l10nflist.c, localealias.c, dcgettext.c: Define _GNU_SOURCE to - get prototype for stpcpy and strcasecmp. - - * intlh.inst.in, libgettext.h: Move declaration of - `_nl_msg_cat_cntr' outside __extension__ block to prevent warning - from gcc's -Wnested-extern option. - -Fri Jun 7 01:58:00 1996 Ulrich Drepper - - * Makefile.in (install): Remove comment. - -Thu Jun 6 17:28:17 1996 Ulrich Drepper - - * Makefile.in (install): Work around for another Buglix stupidity. - Always use an `else' close for `if's. Reported by Nelson Beebe. - - * Makefile.in (intlh.inst): Correct typo in phony rule. - Reported by Nelson Beebe. - -Thu Jun 6 01:49:52 1996 Ulrich Drepper - - * dcgettext.c (read_alias_file): Rename variable alloca_list to - block_list as the macro calls assume. - Patch by Eric Backus. - - * localealias.c [!HAVE_ALLOCA]: Define alloca as macro using - malloc. - (read_alias_file): Rename varriabe alloca_list to block_list as the - macro calls assume. - Patch by Eric Backus. - - * l10nflist.c: Correct conditional for inclusion. - Reported by Roland McGrath. - - * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not - all-@USE_NLS@. - - * Makefile.in (install): intlh.inst comes from local dir, not - $(srcdir). - - * Makefile.in (intlh.inst): Special handling of this goal. If - used in gettext, this is really a rul to construct this file. If - used in any other package it is defined as a .PHONY rule with - empty body. - - * finddomain.c: Extract locale file information handling into - l10nfile.c. Rename local stpcpy__ function to stpcpy. - - * dcgettext.c (stpcpy): Add local definition. - - * l10nflist.c: Solve some portability problems. Patches partly by - Thomas Esken. Add local definition of stpcpy. - -Tue Jun 4 02:47:49 1996 Ulrich Drepper - - * intlh.inst.in: Don't depend including on - HAVE_LOCALE_H. Instead configure must rewrite this fiile - depending on the result of the configure run. - - * Makefile.in (install): libintl.inst is now called intlh.inst. - Add rules for updating intlh.inst from intlh.inst.in. - - * libintl.inst: Renamed to intlh.inst.in. - - * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1 - because gcc has __buitlin_alloca. - Reported by Roland McGrath. - -Mon Jun 3 00:32:16 1996 Ulrich Drepper - - * Makefile.in (installcheck): New goal to fulfill needs of - automake's distcheck. - - * Makefile.in (install): Reorder commands so that VERSION is - found. - - * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in - @datadir@/gettext. - (COMSRCS): Add l10nfile.c. - (OBJECTS): Add l10nfile.o. - (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common). - (DISTFILE.gettext): Remove $(DISTFILES.common). - (all-gettext): Remove goal. - (install): If $(PACKAGE) = gettext install, otherwose do nothing. No - package but gettext itself should install libintl.h + headers. - (dist): Extend goal to work for gettext, too. - (dist-gettext): Remove goal. - - * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc. - -Sun Jun 2 17:33:06 1996 Ulrich Drepper - - * loadmsgcat.c (_nl_load_domain): Parameter is now comes from - find_l10nfile. - -Sat Jun 1 02:23:03 1996 Ulrich Drepper - - * l10nflist.c (__argz_next): Add definition. - - * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca - code. Use new l10nfile handling. - - * localealias.c [!HAVE_ALLOCA]: Add code for handling missing - alloca code. - - * l10nflist.c: Initial revision. - -Tue Apr 2 18:51:18 1996 Ulrich Drepper - - * Makefile.in (all-gettext): New goal. Same as all-yes. - -Thu Mar 28 23:01:22 1996 Karl Eichwalder - - * Makefile.in (gettextsrcdir): Define using @datadir@. - -Tue Mar 26 12:39:14 1996 Ulrich Drepper - - * finddomain.c: Include . Reported by Roland McGrath. - -Sat Mar 23 02:00:35 1996 Ulrich Drepper - - * finddomain.c (stpcpy): Rename to stpcpy__ to prevent clashing - with external declaration. - -Sat Mar 2 00:47:09 1996 Ulrich Drepper - - * Makefile.in (all-no): Rename from all_no. - -Sat Feb 17 00:25:59 1996 Ulrich Drepper - - * gettextP.h [loaded_domain]: Array `successor' must now contain up - to 63 elements (because of codeset name normalization). - - * finddomain.c: Implement codeset name normalization. - -Thu Feb 15 04:39:09 1996 Ulrich Drepper - - * Makefile.in (all): Define to `all-@USE_NLS@'. - (all-yes, all_no): New goals. `all-no' is noop, `all-yes' - is former all. - -Mon Jan 15 21:46:01 1996 Howard Gayle - - * localealias.c (alias_compare): Increment string pointers in loop - of strcasecmp replacement. - -Fri Dec 29 21:16:34 1995 Ulrich Drepper - - * Makefile.in (install-src): Who commented this goal out ? :-) - -Fri Dec 29 15:08:16 1995 Ulrich Drepper - - * dcgettext.c (DCGETTEXT): Save `errno'. Failing system calls - should not effect it because a missing catalog is no error. - Reported by Harald Knig . - -Tue Dec 19 22:09:13 1995 Ulrich Drepper - - * Makefile.in (Makefile): Explicitly use $(SHELL) for running - shell scripts. - -Fri Dec 15 17:34:59 1995 Andreas Schwab - - * Makefile.in (install-src): Only install library and header when - we use the own implementation. Don't do it when using the - system's gettext or catgets functions. - - * dcgettext.c (find_msg): Must not swap domain->hash_size here. - -Sat Dec 9 16:24:37 1995 Ulrich Drepper - - * localealias.c, libintl.inst, libgettext.h, hash-string.h, - gettextP.h, finddomain.c, dcgettext.c, cat-compat.c: - Use PARAMS instead of __P. Suggested by Roland McGrath. - -Tue Dec 5 11:39:14 1995 Larry Schwimmer - - * libgettext.h: Use `#if !defined (_LIBINTL_H)' instead of `#if - !_LIBINTL_H' because Solaris defines _LIBINTL_H as empty. - -Mon Dec 4 15:42:07 1995 Ulrich Drepper - - * Makefile.in (install-src): - Install libintl.inst instead of libintl.h.install. - -Sat Dec 2 22:51:38 1995 Marcus Daniels - - * cat-compat.c (textdomain): - Reverse order in which files are tried you load. First - try local file, when this failed absolute path. - -Wed Nov 29 02:03:53 1995 Nelson H. F. Beebe - - * cat-compat.c (bindtextdomain): Add missing { }. - -Sun Nov 26 18:21:41 1995 Ulrich Drepper - - * libintl.inst: Add missing __P definition. Reported by Nelson Beebe. - - * Makefile.in: - Add dummy `all' and `dvi' goals. Reported by Tom Tromey. - -Sat Nov 25 16:12:01 1995 Franc,ois Pinard - - * hash-string.h: Capitalize arguments of macros. - -Sat Nov 25 12:01:36 1995 Ulrich Drepper - - * Makefile.in (DISTFILES): Prevent files names longer than 13 - characters. libintl.h.glibc->libintl.glibc, - libintl.h.install->libintl.inst. Reported by Joshua R. Poulson. - -Sat Nov 25 11:31:12 1995 Eric Backus - - * dcgettext.c: Fix bug in preprocessor conditionals. - -Sat Nov 25 02:35:27 1995 Nelson H. F. Beebe - - * libgettext.h: Solaris cc does not understand - #if !SYMBOL1 && !SYMBOL2. Sad but true. - -Thu Nov 23 16:22:14 1995 Ulrich Drepper - - * hash-string.h (hash_string): - Fix for machine with >32 bit `unsigned long's. - - * dcgettext.c (DCGETTEXT): - Fix horrible bug in loop for alternative translation. - -Thu Nov 23 01:45:29 1995 Ulrich Drepper - - * po2tbl.sed.in, linux-msg.sed, xopen-msg.sed: - Some further simplifications in message number generation. - -Mon Nov 20 21:08:43 1995 Ulrich Drepper - - * libintl.h.glibc: Use __const instead of const in prototypes. - - * Makefile.in (install-src): - Install libintl.h.install instead of libintl.h. This - is a stripped-down version. Suggested by Peter Miller. - - * libintl.h.install, libintl.h.glibc: Initial revision. - - * localealias.c (_nl_expand_alias, read_alias_file): - Protect prototypes in type casts by __P. - -Tue Nov 14 16:43:58 1995 Ulrich Drepper - - * hash-string.h: Correct prototype for hash_string. - -Sun Nov 12 12:42:30 1995 Ulrich Drepper - - * hash-string.h (hash_string): Add prototype. - - * gettextP.h: Fix copyright. - (SWAP): Add prototype. - -Wed Nov 8 22:56:33 1995 Ulrich Drepper - - * localealias.c (read_alias_file): Forgot sizeof. - Avoid calling *printf function. This introduces a big overhead. - Patch by Roland McGrath. - -Tue Nov 7 14:21:08 1995 Ulrich Drepper - - * finddomain.c, cat-compat.c: Wrong indentation in #if for stpcpy. - - * finddomain.c (stpcpy): - Define substitution function local. The macro was to flaky. - - * cat-compat.c: Fix typo. - - * xopen-msg.sed, linux-msg.sed: - While bringing message number to right place only accept digits. - - * linux-msg.sed, xopen-msg.sed: Now that the counter does not have - leading 0s we don't need to remove them. Reported by Marcus - Daniels. - - * Makefile.in (../po/cat-id-tbl.o): Use $(top_srdir) in - dependency. Reported by Marcus Daniels. - - * cat-compat.c: (stpcpy) [!_LIBC && !HAVE_STPCPY]: Define replacement. - Generally cleanup using #if instead of #ifndef. - - * Makefile.in: Correct typos in comment. By Franc,ois Pinard. - -Mon Nov 6 00:27:02 1995 Ulrich Drepper - - * Makefile.in (install-src): Don't install libintl.h and libintl.a - if we use an available gettext implementation. - -Sun Nov 5 22:02:08 1995 Ulrich Drepper - - * libgettext.h: Fix typo: HAVE_CATGETTS -> HAVE_CATGETS. Reported - by Franc,ois Pinard. - - * libgettext.h: Use #if instead of #ifdef/#ifndef. - - * finddomain.c: - Comments describing what has to be done should start with FIXME. - -Sun Nov 5 19:38:01 1995 Ulrich Drepper - - * Makefile.in (DISTFILES): Split. Use DISTFILES with normal meaning. - DISTFILES.common names the files common to both dist goals. - DISTFILES.gettext are the files only distributed in GNU gettext. - -Sun Nov 5 17:32:54 1995 Ulrich Drepper - - * dcgettext.c (DCGETTEXT): Correct searching in derived locales. - This was necessary since a change in _nl_find_msg several weeks - ago. I really don't know this is still not fixed. - -Sun Nov 5 12:43:12 1995 Ulrich Drepper - - * loadmsgcat.c (_nl_load_domain): Test for FILENAME == NULL. This - might mark a special condition. - - * finddomain.c (make_entry_rec): Don't make illegal entry as decided. - - * Makefile.in (dist): Suppress error message when ln failed. - Get files from $(srcdir) explicitly. - - * libgettext.h (gettext_const): Rename to gettext_noop. - -Fri Nov 3 07:36:50 1995 Ulrich Drepper - - * finddomain.c (make_entry_rec): - Protect against wrong locale names by testing mask. - - * libgettext.h (gettext_const): Add macro definition. - Capitalize macro arguments. - -Thu Nov 2 23:15:51 1995 Ulrich Drepper - - * finddomain.c (_nl_find_domain): - Test for pointer != NULL before accessing value. - Reported by Tom Tromey. - - * gettext.c (NULL): - Define as (void*)0 instad of 0. Reported by Franc,ois Pinard. - -Mon Oct 30 21:28:52 1995 Ulrich Drepper - - * po2tbl.sed.in: Serious typo bug fixed by Jim Meyering. - -Sat Oct 28 23:20:47 1995 Ulrich Drepper - - * libgettext.h: Disable dcgettext optimization for Solaris 2.3. - - * localealias.c (alias_compare): - Peter Miller reported that tolower in some systems is - even dumber than I thought. Protect call by `isupper'. - -Fri Oct 27 22:22:51 1995 Ulrich Drepper - - * Makefile.in (libdir, includedir): New variables. - (install-src): Install libintl.a and libintl.h in correct dirs. - -Fri Oct 27 22:07:29 1995 Ulrich Drepper - - * Makefile.in (SOURCES): Fix typo: intrl.compat.c -> intl-compat.c. - - * po2tbl.sed.in: Patch for buggy SEDs by Christian von Roques. - - * localealias.c: - Fix typo and superflous test. Reported by Christian von Roques. - -Fri Oct 6 11:52:05 1995 Ulrich Drepper - - * finddomain.c (_nl_find_domain): - Correct some remainder from the pre-CEN syntax. Now - we don't have a constant number of successors anymore. - -Wed Sep 27 21:41:13 1995 Ulrich Drepper - - * Makefile.in (DISTFILES): Add libintl.h.glibc. - - * Makefile.in (dist-libc): Add goal for packing sources for glibc. - (COMSRCS, COMHDRS): Splitted to separate sources shared with glibc. - - * loadmsgcat.c: Forget to continue #if line. - - * localealias.c: - [_LIBC]: Rename strcasecmp to __strcasecmp to keep ANSI C name - space clean. - - * dcgettext.c, finddomain.c: Better comment to last change. - - * loadmsgcat.c: - [_LIBC]: Rename fstat, open, close, read, mmap, and munmap to - __fstat, __open, __close, __read, __mmap, and __munmap resp - to keep ANSI C name space clean. - - * finddomain.c: - [_LIBC]: Rename stpcpy to __stpcpy to keep ANSI C name space clean. - - * dcgettext.c: - [_LIBC]: Rename getced and stpcpy to __getcwd and __stpcpy resp to - keep ANSI C name space clean. - - * libgettext.h: - Include sys/types.h for those old SysV systems out there. - Reported by Francesco Potorti`. - - * loadmsgcat.c (use_mmap): Define if compiled for glibc. - - * bindtextdom.c: Include all those standard headers - unconditionally if _LIBC is defined. - - * finddomain.c: Fix 2 times defiend -> defined. - - * textdomain.c: Include libintl.h instead of libgettext.h when - compiling for glibc. Include all those standard headers - unconditionally if _LIBC is defined. - - * localealias.c, loadmsgcat.c: Prepare to be compiled in glibc. - - * gettext.c: - Include libintl.h instead of libgettext.h when compiling for glibc. - Get NULL from stddef.h if we compile for glibc. - - * finddomain.c: Include libintl.h instead of libgettext.h when - compiling for glibc. Include all those standard headers - unconditionally if _LIBC is defined. - - * dcgettext.c: Include all those standard headers unconditionally - if _LIBC is defined. - - * dgettext.c: If compiled in glibc include libintl.h instead of - libgettext.h. - (locale.h): Don't rely on HAVE_LOCALE_H when compiling for glibc. - - * dcgettext.c: If compiled in glibc include libintl.h instead of - libgettext.h. - (getcwd): Don't rely on HAVE_GETCWD when compiling for glibc. - - * bindtextdom.c: - If compiled in glibc include libintl.h instead of libgettext.h. - -Mon Sep 25 22:23:06 1995 Ulrich Drepper - - * localealias.c (_nl_expand_alias): Don't call bsearch if NMAP <= 0. - Reported by Marcus Daniels. - - * cat-compat.c (bindtextdomain): - String used in putenv must not be recycled. - Reported by Marcus Daniels. - - * libgettext.h (__USE_GNU_GETTEXT): - Additional symbol to signal that we use GNU gettext - library. - - * cat-compat.c (bindtextdomain): - Fix bug with the strange stpcpy replacement. - Reported by Nelson Beebe. - -Sat Sep 23 08:23:51 1995 Ulrich Drepper - - * cat-compat.c: Include for stpcpy prototype. - - * localealias.c (read_alias_file): - While expand strdup code temporary variable `cp' hided - higher level variable with same name. Rename to `tp'. - - * textdomain.c (textdomain): - Avoid warning by using temporary variable in strdup code. - - * finddomain.c (_nl_find_domain): Remove unused variable `application'. - -Thu Sep 21 15:51:44 1995 Ulrich Drepper - - * localealias.c (alias_compare): - Use strcasecmp() only if available. Else use - implementation in place. - - * intl-compat.c: - Wrapper functions now call *__ functions instead of __*. - - * libgettext.h: Declare prototypes for *__ functions instead for __*. - - * cat-compat.c, loadmsgcat.c: - Don't use xmalloc, xstrdup, and stpcpy. These functions are not part - of the standard libc and so prevent libintl.a from being used - standalone. - - * bindtextdom.c: - Don't use xmalloc, xstrdup, and stpcpy. These functions are not part - of the standard libc and so prevent libintl.a from being used - standalone. - Rename to bindtextdomain__ if not used in GNU C Library. - - * dgettext.c: - Rename function to dgettext__ if not used in GNU C Library. - - * gettext.c: - Don't use xmalloc, xstrdup, and stpcpy. These functions are not part - of the standard libc and so prevent libintl.a from being used - standalone. - Functions now called gettext__ if not used in GNU C Library. - - * dcgettext.c, localealias.c, textdomain.c, finddomain.c: - Don't use xmalloc, xstrdup, and stpcpy. These functions are not part - of the standard libc and so prevent libintl.a from being used - standalone. - -Sun Sep 17 23:14:49 1995 Ulrich Drepper - - * finddomain.c: Correct some bugs in handling of CEN standard - locale definitions. - -Thu Sep 7 01:49:28 1995 Ulrich Drepper - - * finddomain.c: Implement CEN syntax. - - * gettextP.h (loaded_domain): Extend number of successors to 31. - -Sat Aug 19 19:25:29 1995 Ulrich Drepper - - * Makefile.in (aliaspath): Remove path to X11 locale dir. - - * Makefile.in: Make install-src depend on install. This helps - gettext to install the sources and other packages can use the - install goal. - -Sat Aug 19 15:19:33 1995 Ulrich Drepper - - * Makefile.in (uninstall): Remove stuff installed by install-src. - -Tue Aug 15 13:13:53 1995 Ulrich Drepper - - * VERSION.in: Initial revision. - - * Makefile.in (DISTFILES): - Add VERSION file. This is not necessary for gettext, but - for other packages using this library. - -Tue Aug 15 06:16:44 1995 Ulrich Drepper - - * gettextP.h (_nl_find_domain): - New prototype after changing search strategy. - - * finddomain.c (_nl_find_domain): - We now try only to find a specified catalog. Fall back to other - catalogs listed in the locale list is now done in __dcgettext. - - * dcgettext.c (__dcgettext): - Now we provide message fall back even to different languages. - I.e. if a message is not available in one language all the other - in the locale list a tried. Formerly fall back was only possible - within one language. Implemented by moving one loop from - _nl_find_domain to here. - -Mon Aug 14 23:45:50 1995 Ulrich Drepper - - * Makefile.in (gettextsrcdir): - Directory where source of GNU gettext library are made - available. - (INSTALL, INSTALL_DATA): Programs used for installing sources. - (gettext-src): New. Rule to install GNU gettext sources for use in - gettextize shell script. - -Sun Aug 13 14:40:48 1995 Ulrich Drepper - - * loadmsgcat.c (_nl_load_domain): - Use mmap for loading only when munmap function is - also available. - - * Makefile.in (install): Depend on `all' goal. - -Wed Aug 9 11:04:33 1995 Ulrich Drepper - - * localealias.c (read_alias_file): - Do not overwrite '\n' when terminating alias value string. - - * localealias.c (read_alias_file): - Handle long lines. Ignore the rest not fitting in - the buffer after the initial `fgets' call. - -Wed Aug 9 00:54:29 1995 Ulrich Drepper - - * gettextP.h (_nl_load_domain): - Add prototype, replacing prototype for _nl_load_msg_cat. - - * finddomain.c (_nl_find_domain): - Remove unneeded variable filename and filename_len. - (expand_alias): Remove prototype because functions does not - exist anymore. - - * localealias.c (read_alias_file): - Change type of fname_len parameter to int. - (xmalloc): Add prototype. - - * loadmsgcat.c: Better prototypes for xmalloc. - -Tue Aug 8 22:30:39 1995 Ulrich Drepper - - * finddomain.c (_nl_find_domain): - Allow alias name to be constructed from the four components. - - * Makefile.in (aliaspath): New variable. Set to preliminary value. - (SOURCES): Add localealias.c. - (OBJECTS): Add localealias.o. - - * gettextP.h: Add prototype for _nl_expand_alias. - - * finddomain.c: Aliasing handled in intl/localealias.c. - - * localealias.c: Aliasing for locale names. - - * bindtextdom.c: Better prototypes for xmalloc and xstrdup. - -Mon Aug 7 23:47:42 1995 Ulrich Drepper - - * Makefile.in (DISTFILES): gettext.perl is now found in misc/. - - * cat-compat.c (bindtextdomain): - Correct implementation. dirname parameter was not used. - Reported by Marcus Daniels. - - * gettextP.h (loaded_domain): - New fields `successor' and `decided' for oo, lazy - message handling implementation. - - * dcgettext.c: - Adopt for oo, lazy message handliing. - Now we can inherit translations from less specific locales. - (find_msg): New function. - - * loadmsgcat.c, finddomain.c: - Complete rewrite. Implement oo, lazy message handling :-). - We now have an additional environment variable `LANGUAGE' with - a higher priority than LC_ALL for the LC_MESSAGE locale. - Here we can set a colon separated list of specifications each - of the form `language[_territory[.codeset]][@modifier]'. - -Sat Aug 5 09:55:42 1995 Ulrich Drepper - - * finddomain.c (unistd.h): - Include to get _PC_PATH_MAX defined on system having it. - -Fri Aug 4 22:42:00 1995 Ulrich Drepper - - * finddomain.c (stpcpy): Include prototype. - - * Makefile.in (dist): Remove `copying instead' message. - -Wed Aug 2 18:52:03 1995 Ulrich Drepper - - * Makefile.in (ID, TAGS): Do not use $^. - -Tue Aug 1 20:07:11 1995 Ulrich Drepper - - * Makefile.in (TAGS, ID): Use $^ as command argument. - (TAGS): Give etags -o option t write to current directory, - not $(srcdir). - (ID): Use $(srcdir) instead os $(top_srcdir)/src. - (distclean): Remove ID. - -Sun Jul 30 11:51:46 1995 Ulrich Drepper - - * Makefile.in (gnulocaledir): - New variable, always using share/ for data directory. - (DEFS): Add GNULOCALEDIR, used in finddomain.c. - - * finddomain.c (_nl_default_dirname): - Set to GNULOCALEDIR, because it always has to point - to the directory where GNU gettext Library writes it to. - - * intl-compat.c (textdomain, bindtextdomain): - Undefine macros before function definition. - -Sat Jul 22 01:10:02 1995 Ulrich Drepper - - * libgettext.h (_LIBINTL_H): - Protect definition in case where this file is included as - libgettext.h on Solaris machines. Add comment about this. - -Wed Jul 19 02:36:42 1995 Ulrich Drepper - - * intl-compat.c (textdomain): Correct typo. - -Wed Jul 19 01:51:35 1995 Ulrich Drepper - - * dcgettext.c (dcgettext): Function now called __dcgettext. - - * dgettext.c (dgettext): Now called __dgettext and calls - __dcgettext. - - * gettext.c (gettext): - Function now called __gettext and calls __dgettext. - - * textdomain.c (textdomain): Function now called __textdomain. - - * bindtextdom.c (bindtextdomain): Function now called - __bindtextdomain. - - * intl-compat.c: Initial revision. - - * Makefile.in (SOURCES): Add intl-compat.c. - (OBJECTS): We always compile the GNU gettext library functions. - OBJECTS contains all objects but cat-compat.o, ../po/cat-if-tbl.o, - and intl-compat.o. - (GETTOBJS): Contains now only intl-compat.o. - - * libgettext.h: - Re-include protection matches dualistic character of libgettext.h. - For all functions in GNU gettext library define __ counter part. - - * finddomain.c (strchr): Define as index if not found in C library. - (_nl_find_domain): For relative paths paste / in between. - -Tue Jul 18 16:37:45 1995 Ulrich Drepper - - * loadmsgcat.c, finddomain.c: Add inclusion of sys/types.h. - - * xopen-msg.sed: Fix bug with `msgstr ""' lines. - A little bit better comments. - -Tue Jul 18 01:18:27 1995 Ulrich Drepper - - * Makefile.in: - po-mode.el, makelinks, combine-sh are now found in ../misc. - - * po-mode.el, makelinks, combine-sh, elisp-comp: - Moved to ../misc/. - - * libgettext.h, gettextP.h, gettext.h: Uniform test for __STDC__. - -Sun Jul 16 22:33:02 1995 Ulrich Drepper - - * Makefile.in (INSTALL, INSTALL_DATA): New variables. - (install-data, uninstall): Install/uninstall .elc file. - - * po-mode.el (Installation comment): - Add .pox as possible extension of .po files. - -Sun Jul 16 13:23:27 1995 Ulrich Drepper - - * elisp-comp: Complete new version by Franc,ois: This does not - fail when not compiling in the source directory. - -Sun Jul 16 00:12:17 1995 Ulrich Drepper - - * Makefile.in (../po/cat-id-tbl.o): - Use $(MAKE) instead of make for recursive make. - - * Makefile.in (.el.elc): Use $(SHELL) instead of /bin/sh. - (install-exec): Add missing dummy goal. - (install-data, uninstall): @ in multi-line shell command at - beginning, not in front of echo. Reported by Eric Backus. - -Sat Jul 15 00:21:28 1995 Ulrich Drepper - - * Makefile.in (DISTFILES): - Rename libgettext.perl to gettext.perl to fit in 14 chars - file systems. - - * gettext.perl: - Rename to gettext.perl to fit in 14 chars file systems. - -Thu Jul 13 23:17:20 1995 Ulrich Drepper - - * cat-compat.c: If !STDC_HEADERS try to include malloc.h. - -Thu Jul 13 20:55:02 1995 Ulrich Drepper - - * po2tbl.sed.in: Pretty printing. - - * linux-msg.sed, xopen-msg.sed: - Correct bugs with handling substitute flags in branches. - - * hash-string.h (hash_string): - Old K&R compilers don't under stand `unsigned char'. - - * gettext.h (nls_uint32): - Some old K&R compilers (eg HP) don't understand `unsigned int'. - - * cat-compat.c (msg_to_cat_id): De-ANSI-fy prototypes. - -Thu Jul 13 01:34:33 1995 Ulrich Drepper - - * Makefile.in (ELCFILES): New variable. - (DISTFILES): Add elisp-comp. - Add implicit rule for .el -> .elc compilation. - (install-data): install $ELCFILES - (clean): renamed po-to-tbl and po-to-msg to po2tbl and po2msg resp. - - * elisp-comp: Initial revision - -Wed Jul 12 16:14:52 1995 Ulrich Drepper - - * Makefile.in: - cat-id-tbl.c is now found in po/. This enables us to use an identical - intl/ directory in all packages. - - * dcgettext.c (dcgettext): hashing does not work for table size <= 2. - - * textdomain.c: fix typo (#if def -> #if defined) - -Tue Jul 11 18:44:43 1995 Ulrich Drepper - - * Makefile.in (stamp-cat-id): use top_srcdir to address source files - (DISTFILES,distclean): move tupdate.perl to src/ - - * po-to-tbl.sed.in: - add additional jump to clear change flag to recognize multiline strings - -Tue Jul 11 01:32:50 1995 Ulrich Drepper - - * textdomain.c: Protect inclusion of stdlib.h and string.h. - - * loadmsgcat.c: Protect inclusion of stdlib.h. - - * libgettext.h: Protect inclusion of locale.h. - Allow use in C++ programs. - Define NULL is not happened already. - - * Makefile.in (DISTFILES): ship po-to-tbl.sed.in instead of - po-to-tbl.sed. - (distclean): remove po-to-tbl.sed and tupdate.perl. - - * tupdate.perl.in: Substitute Perl path even in exec line. - Don't include entries without translation from old .po file. - -Tue Jul 4 00:41:51 1995 Ulrich Drepper - - * tupdate.perl.in: use "Updated: " in msgid "". - - * cat-compat.c: Fix typo (LOCALDIR -> LOCALEDIR). - Define getenv if !__STDC__. - - * bindtextdom.c: Protect stdlib.h and string.h inclusion. - Define free if !__STDC__. - - * finddomain.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. - Define free if !__STDC__. - - * cat-compat.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. - -Mon Jul 3 23:56:30 1995 Ulrich Drepper - - * Makefile.in: Use LOCALEDIR instead of DEF_MSG_DOM_DIR. - Remove unneeded $(srcdir) from Makefile.in dependency. - - * makelinks: Add copyright and short description. - - * po-mode.el: Last version for 0.7. - - * tupdate.perl.in: Fix die message. - - * dcgettext.c: Protect include of string.h. - - * gettext.c: Protect include of stdlib.h and further tries to get NULL. - - * finddomain.c: Some corrections in includes. - - * Makefile.in (INCLUDES): Prune list correct path to Makefile.in. - - * po-to-tbl.sed: Adopt for new .po file format. - - * linux-msg.sed, xopen-msg.sed: Adopt for new .po file format. - -Sun Jul 2 23:55:03 1995 Ulrich Drepper - - * tupdate.perl.in: Complete rewrite for new .po file format. - -Sun Jul 2 02:06:50 1995 Ulrich Drepper - - * First official release. This directory contains all the code - needed to internationalize own packages. It provides functions - which allow to use the X/Open catgets function with an interface - like the Uniforum gettext function. For system which does not - have neither of those a complete implementation is provided. diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile deleted file mode 100644 index 37585e769e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile +++ /dev/null @@ -1,214 +0,0 @@ -# Makefile for directory with message catalog handling in GNU NLS Utilities. -# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -PACKAGE = gsmlib -VERSION = 1.10 - -SHELL = /bin/sh - -srcdir = . -top_srcdir = .. -top_builddir = .. - - -prefix = /usr -exec_prefix = ${prefix} -transform = s,x,x, -libdir = $(exec_prefix)/lib -includedir = $(prefix)/include -datadir = $(prefix)/share -localedir = $(datadir)/locale -gnulocaledir = $(prefix)/share/locale -gettextsrcdir = ${prefix}/share/gettext/intl -aliaspath = $(localedir):. -subdir = intl - -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -MKINSTALLDIRS = $(top_builddir)/scripts/mkinstalldirs - -l = @l@ - -AR = ar -CC = i486-linux-gnu-gcc -LIBTOOL = $(SHELL) $(top_builddir)/libtool -RANLIB = ranlib - -DEFS = -DGNULOCALEDIR=\"$(gnulocaledir)\" \ --DLOCALE_ALIAS_PATH=\"$(aliaspath)\" -DHAVE_CONFIG_H -CPPFLAGS = -CFLAGS = -D_REENTRANT -g -O2 -LDFLAGS = - -COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) - -HEADERS = $(COMHDRS) libgettext.h loadinfo.h -COMHDRS = gettext.h gettextP.h hash-string.h -SOURCES = $(COMSRCS) intl-compat.c cat-compat.c -COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ -finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ -explodename.c -OBJECTS = bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ -finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ -explodename.$lo -CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo -GETTOBJS = intl-compat.$lo -DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \ -xopen-msg.sed $(HEADERS) $(SOURCES) -DISTFILES.normal = VERSION -DISTFILES.gettext = libintl.glibc intlh.inst.in - -.SUFFIXES: -.SUFFIXES: .c .o .lo -.c.o: - $(COMPILE) $< -.c.lo: - $(LIBTOOL) --mode=compile $(COMPILE) $< - -INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib - -all: all-no - -all-yes: libintl.$la intlh.inst -all-no: - -libintl.a: $(OBJECTS) - rm -f $@ - $(AR) cru $@ $(OBJECTS) - $(RANLIB) $@ - -libintl.la: $(OBJECTS) - $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \ - -version-info 1:0 -rpath $(libdir) - -../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot - cd ../po && $(MAKE) cat-id-tbl.$lo - -check: all - -# This installation goal is only used in GNU gettext. Packages which -# only use the library should use install instead. - -# We must not install the libintl.h/libintl.a files if we are on a -# system which has the gettext() function in its C library or in a -# separate library or use the catgets interface. A special case is -# where configure found a previously installed GNU gettext library. -# If you want to use the one which comes with this version of the -# package, you have to use `configure --with-included-gettext'. -install: install-exec install-data -install-exec: all - if test "$(PACKAGE)" = "gettext" \ - && test '' = '$(GETTOBJS)'; then \ - if test -r $(MKINSTALLDIRS); then \ - $(MKINSTALLDIRS) $(libdir) $(includedir); \ - else \ - $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \ - fi; \ - $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \ - $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \ - else \ - : ; \ - fi -install-data: all - if test "$(PACKAGE)" = "gettext"; then \ - if test -r $(MKINSTALLDIRS); then \ - $(MKINSTALLDIRS) $(gettextsrcdir); \ - else \ - $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ - fi; \ - $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \ - dists="$(DISTFILES.common)"; \ - for file in $$dists; do \ - $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: - dists="$(DISTFILES.common)"; \ - for file in $$dists; do \ - rm -f $(gettextsrcdir)/$$file; \ - done - -info dvi: - -$(OBJECTS): ../gsm_config.h libgettext.h -bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h -dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h - -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) - -id: ID - -ID: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) - - -mostlyclean: - rm -f *.a *.o *.lo core core.* - -clean: mostlyclean - -distclean: clean - rm -f Makefile ID TAGS po2msg.sed po2tbl.sed - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - - -# GNU gettext needs not contain the file `VERSION' but contains some -# other files which should not be distributed in other packages. -distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: Makefile $(DISTFILES) - if test "$(PACKAGE)" = gettext; then \ - additional="$(DISTFILES.gettext)"; \ - else \ - additional="$(DISTFILES.normal)"; \ - fi; \ - for file in $(DISTFILES.common) $$additional; do \ - ln $(srcdir)/$$file $(distdir) 2> /dev/null \ - || cp -p $(srcdir)/$$file $(distdir); \ - done - -dist-libc: - tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc - -Makefile: Makefile.in ../config.status - cd .. \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# The dependency for intlh.inst is different in gettext and all other -# packages. Because we cannot you GNU make features we have to solve -# the problem while rewriting Makefile.in. -@GT_YES@intlh.inst: intlh.inst.in ../config.status -@GT_YES@ cd .. \ -@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \ -@GT_YES@ $(SHELL) ./config.status -@GT_NO@.PHONY: intlh.inst -@GT_NO@intlh.inst: - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile.in deleted file mode 100644 index fc1e9e3ff1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/Makefile.in +++ /dev/null @@ -1,214 +0,0 @@ -# Makefile for directory with message catalog handling in GNU NLS Utilities. -# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -SHELL = /bin/sh - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -top_builddir = .. -VPATH = @srcdir@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -transform = @program_transform_name@ -libdir = $(exec_prefix)/lib -includedir = $(prefix)/include -datadir = $(prefix)/@DATADIRNAME@ -localedir = $(datadir)/locale -gnulocaledir = $(prefix)/share/locale -gettextsrcdir = @datadir@/gettext/intl -aliaspath = $(localedir):. -subdir = intl - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = @MKINSTALLDIRS@ - -l = @l@ - -AR = ar -CC = @CC@ -LIBTOOL = @LIBTOOL@ -RANLIB = @RANLIB@ - -DEFS = -DGNULOCALEDIR=\"$(gnulocaledir)\" \ --DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@ -CPPFLAGS = @CPPFLAGS@ -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ - -COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) - -HEADERS = $(COMHDRS) libgettext.h loadinfo.h -COMHDRS = gettext.h gettextP.h hash-string.h -SOURCES = $(COMSRCS) intl-compat.c cat-compat.c -COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ -finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ -explodename.c -OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ -finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ -explodename.$lo -CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo -GETTOBJS = intl-compat.$lo -DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \ -xopen-msg.sed $(HEADERS) $(SOURCES) -DISTFILES.normal = VERSION -DISTFILES.gettext = libintl.glibc intlh.inst.in - -.SUFFIXES: -.SUFFIXES: .c .o .lo -.c.o: - $(COMPILE) $< -.c.lo: - $(LIBTOOL) --mode=compile $(COMPILE) $< - -INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib - -all: all-@USE_INCLUDED_LIBINTL@ - -all-yes: libintl.$la intlh.inst -all-no: - -libintl.a: $(OBJECTS) - rm -f $@ - $(AR) cru $@ $(OBJECTS) - $(RANLIB) $@ - -libintl.la: $(OBJECTS) - $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \ - -version-info 1:0 -rpath $(libdir) - -../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot - cd ../po && $(MAKE) cat-id-tbl.$lo - -check: all - -# This installation goal is only used in GNU gettext. Packages which -# only use the library should use install instead. - -# We must not install the libintl.h/libintl.a files if we are on a -# system which has the gettext() function in its C library or in a -# separate library or use the catgets interface. A special case is -# where configure found a previously installed GNU gettext library. -# If you want to use the one which comes with this version of the -# package, you have to use `configure --with-included-gettext'. -install: install-exec install-data -install-exec: all - if test "$(PACKAGE)" = "gettext" \ - && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ - if test -r $(MKINSTALLDIRS); then \ - $(MKINSTALLDIRS) $(libdir) $(includedir); \ - else \ - $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \ - fi; \ - $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \ - $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \ - else \ - : ; \ - fi -install-data: all - if test "$(PACKAGE)" = "gettext"; then \ - if test -r $(MKINSTALLDIRS); then \ - $(MKINSTALLDIRS) $(gettextsrcdir); \ - else \ - $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ - fi; \ - $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \ - dists="$(DISTFILES.common)"; \ - for file in $$dists; do \ - $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: - dists="$(DISTFILES.common)"; \ - for file in $$dists; do \ - rm -f $(gettextsrcdir)/$$file; \ - done - -info dvi: - -$(OBJECTS): ../gsm_config.h libgettext.h -bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h -dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h - -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) - -id: ID - -ID: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) - - -mostlyclean: - rm -f *.a *.o *.lo core core.* - -clean: mostlyclean - -distclean: clean - rm -f Makefile ID TAGS po2msg.sed po2tbl.sed - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - - -# GNU gettext needs not contain the file `VERSION' but contains some -# other files which should not be distributed in other packages. -distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: Makefile $(DISTFILES) - if test "$(PACKAGE)" = gettext; then \ - additional="$(DISTFILES.gettext)"; \ - else \ - additional="$(DISTFILES.normal)"; \ - fi; \ - for file in $(DISTFILES.common) $$additional; do \ - ln $(srcdir)/$$file $(distdir) 2> /dev/null \ - || cp -p $(srcdir)/$$file $(distdir); \ - done - -dist-libc: - tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc - -Makefile: Makefile.in ../config.status - cd .. \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# The dependency for intlh.inst is different in gettext and all other -# packages. Because we cannot you GNU make features we have to solve -# the problem while rewriting Makefile.in. -@GT_YES@intlh.inst: intlh.inst.in ../config.status -@GT_YES@ cd .. \ -@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \ -@GT_YES@ $(SHELL) ./config.status -@GT_NO@.PHONY: intlh.inst -@GT_NO@intlh.inst: - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/VERSION b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/VERSION deleted file mode 100644 index ee66b0612b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/VERSION +++ /dev/null @@ -1 +0,0 @@ -GNU gettext library from gettext-0.10.35 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/bindtextdom.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/bindtextdom.c deleted file mode 100644 index 42b11aaddb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/bindtextdom.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Implementation of the bindtextdomain(3) function - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined STDC_HEADERS || defined _LIBC -# include -#else -# ifdef HAVE_MALLOC_H -# include -# else -void free (); -# endif -#endif - -#if defined HAVE_STRING_H || defined _LIBC -# include -#else -# include -# ifndef memcpy -# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) -# endif -#endif - -#ifdef _LIBC -# include -#else -# include "libgettext.h" -#endif -#include "gettext.h" -#include "gettextP.h" - -/* @@ end of prolog @@ */ - -/* Contains the default location of the message catalogs. */ -extern const char _nl_default_dirname[]; - -/* List with bindings of specific domains. */ -extern struct binding *_nl_domain_bindings; - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define BINDTEXTDOMAIN __bindtextdomain -# ifndef strdup -# define strdup(str) __strdup (str) -# endif -#else -# define BINDTEXTDOMAIN bindtextdomain__ -#endif - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -char * -BINDTEXTDOMAIN (domainname, dirname) - const char *domainname; - const char *dirname; -{ - struct binding *binding; - - /* Some sanity checks. */ - if (domainname == NULL || domainname[0] == '\0') - return NULL; - - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (dirname == NULL) - /* The current binding has be to returned. */ - return binding == NULL ? (char *) _nl_default_dirname : binding->dirname; - - if (binding != NULL) - { - /* The domain is already bound. If the new value and the old - one are equal we simply do nothing. Otherwise replace the - old binding. */ - if (strcmp (dirname, binding->dirname) != 0) - { - char *new_dirname; - - if (strcmp (dirname, _nl_default_dirname) == 0) - new_dirname = (char *) _nl_default_dirname; - else - { -#if defined _LIBC || defined HAVE_STRDUP - new_dirname = strdup (dirname); - if (new_dirname == NULL) - return NULL; -#else - size_t len = strlen (dirname) + 1; - new_dirname = (char *) malloc (len); - if (new_dirname == NULL) - return NULL; - - memcpy (new_dirname, dirname, len); -#endif - } - - if (binding->dirname != _nl_default_dirname) - free (binding->dirname); - - binding->dirname = new_dirname; - } - } - else - { - /* We have to create a new binding. */ -#if !defined _LIBC && !defined HAVE_STRDUP - size_t len; -#endif - struct binding *new_binding = - (struct binding *) malloc (sizeof (*new_binding)); - - if (new_binding == NULL) - return NULL; - -#if defined _LIBC || defined HAVE_STRDUP - new_binding->domainname = strdup (domainname); - if (new_binding->domainname == NULL) - return NULL; -#else - len = strlen (domainname) + 1; - new_binding->domainname = (char *) malloc (len); - if (new_binding->domainname == NULL) - return NULL; - memcpy (new_binding->domainname, domainname, len); -#endif - - if (strcmp (dirname, _nl_default_dirname) == 0) - new_binding->dirname = (char *) _nl_default_dirname; - else - { -#if defined _LIBC || defined HAVE_STRDUP - new_binding->dirname = strdup (dirname); - if (new_binding->dirname == NULL) - return NULL; -#else - len = strlen (dirname) + 1; - new_binding->dirname = (char *) malloc (len); - if (new_binding->dirname == NULL) - return NULL; - memcpy (new_binding->dirname, dirname, len); -#endif - } - - /* Now enqueue it. */ - if (_nl_domain_bindings == NULL - || strcmp (domainname, _nl_domain_bindings->domainname) < 0) - { - new_binding->next = _nl_domain_bindings; - _nl_domain_bindings = new_binding; - } - else - { - binding = _nl_domain_bindings; - while (binding->next != NULL - && strcmp (domainname, binding->next->domainname) > 0) - binding = binding->next; - - new_binding->next = binding->next; - binding->next = new_binding; - } - - binding = new_binding; - } - - return binding->dirname; -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__bindtextdomain, bindtextdomain); -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/cat-compat.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/cat-compat.c deleted file mode 100644 index 4eb0e068f1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/cat-compat.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Compatibility code for gettext-using-catgets interface. - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef STDC_HEADERS -# include -# include -#else -char *getenv (); -# ifdef HAVE_MALLOC_H -# include -# endif -#endif - -#ifdef HAVE_NL_TYPES_H -# include -#endif - -#include "libgettext.h" - -/* @@ end of prolog @@ */ - -/* XPG3 defines the result of `setlocale (category, NULL)' as: - ``Directs `setlocale()' to query `category' and return the current - setting of `local'.'' - However it does not specify the exact format. And even worse: POSIX - defines this not at all. So we can use this feature only on selected - system (e.g. those using GNU C Library). */ -#ifdef _LIBC -# define HAVE_LOCALE_NULL -#endif - -/* The catalog descriptor. */ -static nl_catd catalog = (nl_catd) -1; - -/* Name of the default catalog. */ -static const char default_catalog_name[] = "messages"; - -/* Name of currently used catalog. */ -static const char *catalog_name = default_catalog_name; - -/* Get ID for given string. If not found return -1. */ -static int msg_to_cat_id PARAMS ((const char *msg)); - -/* Substitution for systems lacking this function in their C library. */ -#if !_LIBC && !HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -#endif - - -/* Set currently used domain/catalog. */ -char * -textdomain (domainname) - const char *domainname; -{ - nl_catd new_catalog; - char *new_name; - size_t new_name_len; - char *lang; - -#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \ - && defined HAVE_LOCALE_NULL - lang = setlocale (LC_MESSAGES, NULL); -#else - lang = getenv ("LC_ALL"); - if (lang == NULL || lang[0] == '\0') - { - lang = getenv ("LC_MESSAGES"); - if (lang == NULL || lang[0] == '\0') - lang = getenv ("LANG"); - } -#endif - if (lang == NULL || lang[0] == '\0') - lang = "C"; - - /* See whether name of currently used domain is asked. */ - if (domainname == NULL) - return (char *) catalog_name; - - if (domainname[0] == '\0') - domainname = default_catalog_name; - - /* Compute length of added path element. */ - new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang) - + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1 - + sizeof (".cat"); - - new_name = (char *) malloc (new_name_len); - if (new_name == NULL) - return NULL; - - strcpy (new_name, PACKAGE); - new_catalog = catopen (new_name, 0); - - if (new_catalog == (nl_catd) -1) - { - /* NLSPATH search didn't work, try absolute path */ - sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang, - PACKAGE); - new_catalog = catopen (new_name, 0); - - if (new_catalog == (nl_catd) -1) - { - free (new_name); - return (char *) catalog_name; - } - } - - /* Close old catalog. */ - if (catalog != (nl_catd) -1) - catclose (catalog); - if (catalog_name != default_catalog_name) - free ((char *) catalog_name); - - catalog = new_catalog; - catalog_name = new_name; - - return (char *) catalog_name; -} - -char * -bindtextdomain (domainname, dirname) - const char *domainname; - const char *dirname; -{ -#if HAVE_SETENV || HAVE_PUTENV - char *old_val, *new_val, *cp; - size_t new_val_len; - - /* This does not make much sense here but to be compatible do it. */ - if (domainname == NULL) - return NULL; - - /* Compute length of added path element. If we use setenv we don't need - the first byts for NLSPATH=, but why complicate the code for this - peanuts. */ - new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname) - + sizeof ("/%L/LC_MESSAGES/%N.cat"); - - old_val = getenv ("NLSPATH"); - if (old_val == NULL || old_val[0] == '\0') - { - old_val = NULL; - new_val_len += 1 + sizeof (LOCALEDIR) - 1 - + sizeof ("/%L/LC_MESSAGES/%N.cat"); - } - else - new_val_len += strlen (old_val); - - new_val = (char *) malloc (new_val_len); - if (new_val == NULL) - return NULL; - -# if HAVE_SETENV - cp = new_val; -# else - cp = stpcpy (new_val, "NLSPATH="); -# endif - - cp = stpcpy (cp, dirname); - cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:"); - - if (old_val == NULL) - { -# if __STDC__ - stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); -# else - - cp = stpcpy (cp, LOCALEDIR); - stpcpy (cp, "/%L/LC_MESSAGES/%N.cat"); -# endif - } - else - stpcpy (cp, old_val); - -# if HAVE_SETENV - setenv ("NLSPATH", new_val, 1); - free (new_val); -# else - putenv (new_val); - /* Do *not* free the environment entry we just entered. It is used - from now on. */ -# endif - -#endif - - return (char *) domainname; -} - -#undef gettext -char * -gettext (msg) - const char *msg; -{ - int msgid; - - if (msg == NULL || catalog == (nl_catd) -1) - return (char *) msg; - - /* Get the message from the catalog. We always use set number 1. - The message ID is computed by the function `msg_to_cat_id' - which works on the table generated by `po-to-tbl'. */ - msgid = msg_to_cat_id (msg); - if (msgid == -1) - return (char *) msg; - - return catgets (catalog, 1, msgid, (char *) msg); -} - -/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries - for the one equal to msg. If it is found return the ID. In case when - the string is not found return -1. */ -static int -msg_to_cat_id (msg) - const char *msg; -{ - int cnt; - - for (cnt = 0; cnt < _msg_tbl_length; ++cnt) - if (strcmp (msg, _msg_tbl[cnt]._msg) == 0) - return _msg_tbl[cnt]._msg_number; - - return -1; -} - - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dcgettext.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dcgettext.c deleted file mode 100644 index ed697f371b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dcgettext.c +++ /dev/null @@ -1,624 +0,0 @@ -/* Implementation of the dcgettext(3) function. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef __GNUC__ -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -#endif - -#include -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -#if defined STDC_HEADERS || defined _LIBC -# include -#else -char *getenv (); -# ifdef HAVE_MALLOC_H -# include -# else -void free (); -# endif -#endif - -#if defined HAVE_STRING_H || defined _LIBC -# ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -# endif -# include -#else -# include -#endif -#if !HAVE_STRCHR && !defined _LIBC -# ifndef strchr -# define strchr index -# endif -#endif - -#if defined HAVE_UNISTD_H || defined _LIBC -# include -#endif - -#include "gettext.h" -#include "gettextP.h" -#ifdef _LIBC -# include -#else -# include "libgettext.h" -#endif -#include "hash-string.h" - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# define getcwd __getcwd -# ifndef stpcpy -# define stpcpy __stpcpy -# endif -#else -# if !defined HAVE_GETCWD -char *getwd (); -# define getcwd(buf, max) getwd (buf) -# else -char *getcwd (); -# endif -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -#endif - -/* Amount to increase buffer size by in each try. */ -#define PATH_INCR 32 - -/* The following is from pathmax.h. */ -/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define - PATH_MAX but might cause redefinition warnings when sys/param.h is - later included (as on MORE/BSD 4.3). */ -#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__)) -# include -#endif - -#ifndef _POSIX_PATH_MAX -# define _POSIX_PATH_MAX 255 -#endif - -#if !defined(PATH_MAX) && defined(_PC_PATH_MAX) -# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) -#endif - -/* Don't include sys/param.h if it already has been. */ -#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN) -# include -#endif - -#if !defined(PATH_MAX) && defined(MAXPATHLEN) -# define PATH_MAX MAXPATHLEN -#endif - -#ifndef PATH_MAX -# define PATH_MAX _POSIX_PATH_MAX -#endif - -/* XPG3 defines the result of `setlocale (category, NULL)' as: - ``Directs `setlocale()' to query `category' and return the current - setting of `local'.'' - However it does not specify the exact format. And even worse: POSIX - defines this not at all. So we can use this feature only on selected - system (e.g. those using GNU C Library). */ -#ifdef _LIBC -# define HAVE_LOCALE_NULL -#endif - -/* Name of the default domain used for gettext(3) prior any call to - textdomain(3). The default value for this is "messages". */ -const char _nl_default_default_domain[] = "messages"; - -/* Value used as the default domain for gettext(3). */ -const char *_nl_current_default_domain = _nl_default_default_domain; - -/* Contains the default location of the message catalogs. */ -const char _nl_default_dirname[] = GNULOCALEDIR; - -/* List with bindings of specific domains created by bindtextdomain() - calls. */ -struct binding *_nl_domain_bindings; - -/* Prototypes for local functions. */ -static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file, - const char *msgid)) internal_function; -static const char *category_to_name PARAMS ((int category)) internal_function; -static const char *guess_category_value PARAMS ((int category, - const char *categoryname)) - internal_function; - - -/* For those loosing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -/* Nothing has to be done. */ -# define ADD_BLOCK(list, address) /* nothing */ -# define FREE_BLOCKS(list) /* nothing */ -#else -struct block_list -{ - void *address; - struct block_list *next; -}; -# define ADD_BLOCK(list, addr) \ - do { \ - struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ - /* If we cannot get a free block we cannot add the new element to \ - the list. */ \ - if (newp != NULL) { \ - newp->address = (addr); \ - newp->next = (list); \ - (list) = newp; \ - } \ - } while (0) -# define FREE_BLOCKS(list) \ - do { \ - while (list != NULL) { \ - struct block_list *old = list; \ - list = list->next; \ - free (old); \ - } \ - } while (0) -# undef alloca -# define alloca(size) (malloc (size)) -#endif /* have alloca */ - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCGETTEXT __dcgettext -#else -# define DCGETTEXT dcgettext__ -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -char * -DCGETTEXT (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; -{ -#ifndef HAVE_ALLOCA - struct block_list *block_list = NULL; -#endif - struct loaded_l10nfile *domain; - struct binding *binding; - const char *categoryname; - const char *categoryvalue; - char *dirname, *xdomainname; - char *single_locale; - char *retval; - int saved_errno = errno; - - /* If no real MSGID is given return NULL. */ - if (msgid == NULL) - return NULL; - - /* If DOMAINNAME is NULL, we are interested in the default domain. If - CATEGORY is not LC_MESSAGES this might not make much sense but the - defintion left this undefined. */ - if (domainname == NULL) - domainname = _nl_current_default_domain; - - /* First find matching binding. */ - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (binding == NULL) - dirname = (char *) _nl_default_dirname; - else if (binding->dirname[0] == '/') - dirname = binding->dirname; - else - { - /* We have a relative path. Make it absolute now. */ - size_t dirname_len = strlen (binding->dirname) + 1; - size_t path_max; - char *ret; - - path_max = (unsigned) PATH_MAX; - path_max += 2; /* The getcwd docs say to do this. */ - - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); - - __set_errno (0); - while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE) - { - path_max += PATH_INCR; - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); - __set_errno (0); - } - - if (ret == NULL) - { - /* We cannot get the current working directory. Don't signal an - error but simply return the default string. */ - FREE_BLOCKS (block_list); - __set_errno (saved_errno); - return (char *) msgid; - } - - stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); - } - - /* Now determine the symbolic name of CATEGORY and its value. */ - categoryname = category_to_name (category); - categoryvalue = guess_category_value (category, categoryname); - - xdomainname = (char *) alloca (strlen (categoryname) - + strlen (domainname) + 5); - ADD_BLOCK (block_list, xdomainname); - - stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), - domainname), - ".mo"); - - /* Creating working area. */ - single_locale = (char *) alloca (strlen (categoryvalue) + 1); - ADD_BLOCK (block_list, single_locale); - - - /* Search for the given string. This is a loop because we perhaps - got an ordered list of languages to consider for th translation. */ - while (1) - { - /* Make CATEGORYVALUE point to the next element of the list. */ - while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') - ++categoryvalue; - if (categoryvalue[0] == '\0') - { - /* The whole contents of CATEGORYVALUE has been searched but - no valid entry has been found. We solve this situation - by implicitly appending a "C" entry, i.e. no translation - will take place. */ - single_locale[0] = 'C'; - single_locale[1] = '\0'; - } - else - { - char *cp = single_locale; - while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') - *cp++ = *categoryvalue++; - *cp = '\0'; - } - - /* If the current locale value is C (or POSIX) we don't load a - domain. Return the MSGID. */ - if (strcmp (single_locale, "C") == 0 - || strcmp (single_locale, "POSIX") == 0) - { - FREE_BLOCKS (block_list); - __set_errno (saved_errno); - return (char *) msgid; - } - - - /* Find structure describing the message catalog matching the - DOMAINNAME and CATEGORY. */ - domain = _nl_find_domain (dirname, single_locale, xdomainname); - - if (domain != NULL) - { - retval = find_msg (domain, msgid); - - if (retval == NULL) - { - int cnt; - - for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) - { - retval = find_msg (domain->successor[cnt], msgid); - - if (retval != NULL) - break; - } - } - - if (retval != NULL) - { - FREE_BLOCKS (block_list); - __set_errno (saved_errno); - return retval; - } - } - } - /* NOTREACHED */ -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dcgettext, dcgettext); -#endif - - -static char * -internal_function -find_msg (domain_file, msgid) - struct loaded_l10nfile *domain_file; - const char *msgid; -{ - size_t top, act, bottom; - struct loaded_domain *domain; - - if (domain_file->decided == 0) - _nl_load_domain (domain_file); - - if (domain_file->data == NULL) - return NULL; - - domain = (struct loaded_domain *) domain_file->data; - - /* Locate the MSGID and its translation. */ - if (domain->hash_size > 2 && domain->hash_tab != NULL) - { - /* Use the hashing table. */ - nls_uint32 len = strlen (msgid); - nls_uint32 hash_val = hash_string (msgid); - nls_uint32 idx = hash_val % domain->hash_size; - nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); - nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]); - - if (nstr == 0) - /* Hash table entry is empty. */ - return NULL; - - if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len - && strcmp (msgid, - domain->data + W (domain->must_swap, - domain->orig_tab[nstr - 1].offset)) == 0) - return (char *) domain->data + W (domain->must_swap, - domain->trans_tab[nstr - 1].offset); - - while (1) - { - if (idx >= domain->hash_size - incr) - idx -= domain->hash_size - incr; - else - idx += incr; - - nstr = W (domain->must_swap, domain->hash_tab[idx]); - if (nstr == 0) - /* Hash table entry is empty. */ - return NULL; - - if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len - && strcmp (msgid, - domain->data + W (domain->must_swap, - domain->orig_tab[nstr - 1].offset)) - == 0) - return (char *) domain->data - + W (domain->must_swap, domain->trans_tab[nstr - 1].offset); - } - /* NOTREACHED */ - } - - /* Now we try the default method: binary search in the sorted - array of messages. */ - bottom = 0; - top = domain->nstrings; - while (bottom < top) - { - int cmp_val; - - act = (bottom + top) / 2; - cmp_val = strcmp (msgid, domain->data - + W (domain->must_swap, - domain->orig_tab[act].offset)); - if (cmp_val < 0) - top = act; - else if (cmp_val > 0) - bottom = act + 1; - else - break; - } - - /* If an translation is found return this. */ - return bottom >= top ? NULL : (char *) domain->data - + W (domain->must_swap, - domain->trans_tab[act].offset); -} - - -/* Return string representation of locale CATEGORY. */ -static const char * -internal_function -category_to_name (category) - int category; -{ - const char *retval; - - switch (category) - { -#ifdef LC_COLLATE - case LC_COLLATE: - retval = "LC_COLLATE"; - break; -#endif -#ifdef LC_CTYPE - case LC_CTYPE: - retval = "LC_CTYPE"; - break; -#endif -#ifdef LC_MONETARY - case LC_MONETARY: - retval = "LC_MONETARY"; - break; -#endif -#ifdef LC_NUMERIC - case LC_NUMERIC: - retval = "LC_NUMERIC"; - break; -#endif -#ifdef LC_TIME - case LC_TIME: - retval = "LC_TIME"; - break; -#endif -#ifdef LC_MESSAGES - case LC_MESSAGES: - retval = "LC_MESSAGES"; - break; -#endif -#ifdef LC_RESPONSE - case LC_RESPONSE: - retval = "LC_RESPONSE"; - break; -#endif -#ifdef LC_ALL - case LC_ALL: - /* This might not make sense but is perhaps better than any other - value. */ - retval = "LC_ALL"; - break; -#endif - default: - /* If you have a better idea for a default value let me know. */ - retval = "LC_XXX"; - } - - return retval; -} - -/* Guess value of current locale from value of the environment variables. */ -static const char * -internal_function -guess_category_value (category, categoryname) - int category; - const char *categoryname; -{ - const char *retval; - - /* The highest priority value is the `LANGUAGE' environment - variable. This is a GNU extension. */ - retval = getenv ("LANGUAGE"); - if (retval != NULL && retval[0] != '\0') - return retval; - - /* `LANGUAGE' is not set. So we have to proceed with the POSIX - methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some - systems this can be done by the `setlocale' function itself. */ -#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL - return setlocale (category, NULL); -#else - /* Setting of LC_ALL overwrites all other. */ - retval = getenv ("LC_ALL"); - if (retval != NULL && retval[0] != '\0') - return retval; - - /* Next comes the name of the desired category. */ - retval = getenv (categoryname); - if (retval != NULL && retval[0] != '\0') - return retval; - - /* Last possibility is the LANG environment variable. */ - retval = getenv ("LANG"); - if (retval != NULL && retval[0] != '\0') - return retval; - - /* We use C as the default domain. POSIX says this is implementation - defined. */ - return "C"; -#endif -} - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif - - -#ifdef _LIBC -/* If we want to free all resources we have to do some work at - program's end. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - struct binding *runp; - - for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next) - { - free (runp->domainname); - if (runp->dirname != _nl_default_dirname) - /* Yes, this is a pointer comparison. */ - free (runp->dirname); - } - - if (_nl_current_default_domain != _nl_default_default_domain) - /* Yes, again a pointer comparison. */ - free ((char *) _nl_current_default_domain); -} - -text_set_element (__libc_subfreeres, free_mem); -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dgettext.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dgettext.c deleted file mode 100644 index 6525d83293..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/dgettext.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Implementation of the dgettext(3) function - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined HAVE_LOCALE_H || defined _LIBC -# include -#endif - -#ifdef _LIBC -# include -#else -# include "libgettext.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DGETTEXT __dgettext -# define DCGETTEXT __dcgettext -#else -# define DGETTEXT dgettext__ -# define DCGETTEXT dcgettext__ -#endif - -/* Look up MSGID in the DOMAINNAME message catalog of the current - LC_MESSAGES locale. */ -char * -DGETTEXT (domainname, msgid) - const char *domainname; - const char *msgid; -{ - return DCGETTEXT (domainname, msgid, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dgettext, dgettext); -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/explodename.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/explodename.c deleted file mode 100644 index b80aa79ae2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/explodename.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Ulrich Drepper , 1995. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined STDC_HEADERS || defined _LIBC -# include -#endif - -#if defined HAVE_STRING_H || defined _LIBC -# include -#else -# include -#endif -#include - -#include "loadinfo.h" - -/* On some strange systems still no definition of NULL is found. Sigh! */ -#ifndef NULL -# if defined __STDC__ && __STDC__ -# define NULL ((void *) 0) -# else -# define NULL 0 -# endif -#endif - -/* @@ end of prolog @@ */ - -int -_nl_explode_name (name, language, modifier, territory, codeset, - normalized_codeset, special, sponsor, revision) - char *name; - const char **language; - const char **modifier; - const char **territory; - const char **codeset; - const char **normalized_codeset; - const char **special; - const char **sponsor; - const char **revision; -{ - enum { undecided, xpg, cen } syntax; - char *cp; - int mask; - - *modifier = NULL; - *territory = NULL; - *codeset = NULL; - *normalized_codeset = NULL; - *special = NULL; - *sponsor = NULL; - *revision = NULL; - - /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ - mask = 0; - syntax = undecided; - *language = cp = name; - while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@' - && cp[0] != '+' && cp[0] != ',') - ++cp; - - if (*language == cp) - /* This does not make sense: language has to be specified. Use - this entry as it is without exploding. Perhaps it is an alias. */ - cp = strchr (*language, '\0'); - else if (cp[0] == '_') - { - /* Next is the territory. */ - cp[0] = '\0'; - *territory = ++cp; - - while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' - && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= TERRITORY; - - if (cp[0] == '.') - { - /* Next is the codeset. */ - syntax = xpg; - cp[0] = '\0'; - *codeset = ++cp; - - while (cp[0] != '\0' && cp[0] != '@') - ++cp; - - mask |= XPG_CODESET; - - if (*codeset != cp && (*codeset)[0] != '\0') - { - *normalized_codeset = _nl_normalize_codeset (*codeset, - cp - *codeset); - if (strcmp (*codeset, *normalized_codeset) == 0) - free ((char *) *normalized_codeset); - else - mask |= XPG_NORM_CODESET; - } - } - } - - if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) - { - /* Next is the modifier. */ - syntax = cp[0] == '@' ? xpg : cen; - cp[0] = '\0'; - *modifier = ++cp; - - while (syntax == cen && cp[0] != '\0' && cp[0] != '+' - && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= XPG_MODIFIER | CEN_AUDIENCE; - } - - if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) - { - syntax = cen; - - if (cp[0] == '+') - { - /* Next is special application (CEN syntax). */ - cp[0] = '\0'; - *special = ++cp; - - while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= CEN_SPECIAL; - } - - if (cp[0] == ',') - { - /* Next is sponsor (CEN syntax). */ - cp[0] = '\0'; - *sponsor = ++cp; - - while (cp[0] != '\0' && cp[0] != '_') - ++cp; - - mask |= CEN_SPONSOR; - } - - if (cp[0] == '_') - { - /* Next is revision (CEN syntax). */ - cp[0] = '\0'; - *revision = ++cp; - - mask |= CEN_REVISION; - } - } - - /* For CEN syntax values it might be important to have the - separator character in the file name, not for XPG syntax. */ - if (syntax == xpg) - { - if (*territory != NULL && (*territory)[0] == '\0') - mask &= ~TERRITORY; - - if (*codeset != NULL && (*codeset)[0] == '\0') - mask &= ~XPG_CODESET; - - if (*modifier != NULL && (*modifier)[0] == '\0') - mask &= ~XPG_MODIFIER; - } - - return mask; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/finddomain.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/finddomain.c deleted file mode 100644 index 9588532f3d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/finddomain.c +++ /dev/null @@ -1,216 +0,0 @@ -/* Handle list of needed message catalogs - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Written by Ulrich Drepper , 1995. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#if defined STDC_HEADERS || defined _LIBC -# include -#else -# ifdef HAVE_MALLOC_H -# include -# else -void free (); -# endif -#endif - -#if defined HAVE_STRING_H || defined _LIBC -# include -#else -# include -# ifndef memcpy -# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) -# endif -#endif -#if !HAVE_STRCHR && !defined _LIBC -# ifndef strchr -# define strchr index -# endif -#endif - -#if defined HAVE_UNISTD_H || defined _LIBC -# include -#endif - -#include "gettext.h" -#include "gettextP.h" -#ifdef _LIBC -# include -#else -# include "libgettext.h" -#endif - -/* @@ end of prolog @@ */ -/* List of already loaded domains. */ -static struct loaded_l10nfile *_nl_loaded_domains; - - -/* Return a data structure describing the message catalog described by - the DOMAINNAME and CATEGORY parameters with respect to the currently - established bindings. */ -struct loaded_l10nfile * -internal_function -_nl_find_domain (dirname, locale, domainname) - const char *dirname; - char *locale; - const char *domainname; -{ - struct loaded_l10nfile *retval; - const char *language; - const char *modifier; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *special; - const char *sponsor; - const char *revision; - const char *alias_value; - int mask; - - /* LOCALE can consist of up to four recognized parts for the XPG syntax: - - language[_territory[.codeset]][@modifier] - - and six parts for the CEN syntax: - - language[_territory][+audience][+special][,[sponsor][_revision]] - - Beside the first part all of them are allowed to be missing. If - the full specified locale is not found, the less specific one are - looked for. The various parts will be stripped off according to - the following order: - (1) revision - (2) sponsor - (3) special - (4) codeset - (5) normalized codeset - (6) territory - (7) audience/modifier - */ - - /* If we have already tested for this locale entry there has to - be one data set in the list of loaded domains. */ - retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, - strlen (dirname) + 1, 0, locale, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, domainname, 0); - if (retval != NULL) - { - /* We know something about this locale. */ - int cnt; - - if (retval->decided == 0) - _nl_load_domain (retval); - - if (retval->data != NULL) - return retval; - - for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) - { - if (retval->successor[cnt]->decided == 0) - _nl_load_domain (retval->successor[cnt]); - - if (retval->successor[cnt]->data != NULL) - break; - } - return cnt >= 0 ? retval : NULL; - /* NOTREACHED */ - } - - /* See whether the locale value is an alias. If yes its value - *overwrites* the alias name. No test for the original value is - done. */ - alias_value = _nl_expand_alias (locale); - if (alias_value != NULL) - { -#if defined _LIBC || defined HAVE_STRDUP - locale = strdup (alias_value); - if (locale == NULL) - return NULL; -#else - size_t len = strlen (alias_value) + 1; - locale = (char *) malloc (len); - if (locale == NULL) - return NULL; - - memcpy (locale, alias_value, len); -#endif - } - - /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ - mask = _nl_explode_name (locale, &language, &modifier, &territory, - &codeset, &normalized_codeset, &special, - &sponsor, &revision); - - /* Create all possible locale entries which might be interested in - generalization. */ - retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, - strlen (dirname) + 1, mask, language, territory, - codeset, normalized_codeset, modifier, special, - sponsor, revision, domainname, 1); - if (retval == NULL) - /* This means we are out of core. */ - return NULL; - - if (retval->decided == 0) - _nl_load_domain (retval); - if (retval->data == NULL) - { - int cnt; - for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) - { - if (retval->successor[cnt]->decided == 0) - _nl_load_domain (retval->successor[cnt]); - if (retval->successor[cnt]->data != NULL) - break; - } - } - - /* The room for an alias was dynamically allocated. Free it now. */ - if (alias_value != NULL) - free (locale); - - return retval; -} - - -#ifdef _LIBC -static void __attribute__ ((unused)) -free_mem (void) -{ - struct loaded_l10nfile *runp = _nl_loaded_domains; - - while (runp != NULL) - { - struct loaded_l10nfile *here = runp; - if (runp->data != NULL) - _nl_unload_domain ((struct loaded_domain *) runp->data); - runp = runp->next; - free (here); - } -} - -text_set_element (__libc_subfreeres, free_mem); -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.c deleted file mode 100644 index c3c64bf8c5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Implementation of gettext(3) function. - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef _LIBC -# define __need_NULL -# include -#else -# ifdef STDC_HEADERS -# include /* Just for NULL. */ -# else -# ifdef HAVE_STRING_H -# include -# else -# define NULL ((void *) 0) -# endif -# endif -#endif - -#ifdef _LIBC -# include -#else -# include "libgettext.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define GETTEXT __gettext -# define DGETTEXT __dgettext -#else -# define GETTEXT gettext__ -# define DGETTEXT dgettext__ -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -char * -GETTEXT (msgid) - const char *msgid; -{ - return DGETTEXT (NULL, msgid); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__gettext, gettext); -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.h deleted file mode 100644 index 3cd23d7d6a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettext.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Internal header for GNU gettext internationalization functions. - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef _GETTEXT_H -#define _GETTEXT_H 1 - -#include - -#if HAVE_LIMITS_H || _LIBC -# include -#endif - -/* @@ end of prolog @@ */ - -/* The magic number of the GNU message catalog format. */ -#define _MAGIC 0x950412de -#define _MAGIC_SWAPPED 0xde120495 - -/* Revision number of the currently used .mo (binary) file format. */ -#define MO_REVISION_NUMBER 0 - -/* The following contortions are an attempt to use the C preprocessor - to determine an unsigned integral type that is 32 bits wide. An - alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but - doing that would require that the configure script compile and *run* - the resulting executable. Locally running cross-compiled executables - is usually not possible. */ - -#if __STDC__ -# define UINT_MAX_32_BITS 4294967295U -#else -# define UINT_MAX_32_BITS 0xFFFFFFFF -#endif - -/* If UINT_MAX isn't defined, assume it's a 32-bit type. - This should be valid for all systems GNU cares about because - that doesn't include 16-bit systems, and only modern systems - (that certainly have ) have 64+-bit integral types. */ - -#ifndef UINT_MAX -# define UINT_MAX UINT_MAX_32_BITS -#endif - -#if UINT_MAX == UINT_MAX_32_BITS -typedef unsigned nls_uint32; -#else -# if USHRT_MAX == UINT_MAX_32_BITS -typedef unsigned short nls_uint32; -# else -# if ULONG_MAX == UINT_MAX_32_BITS -typedef unsigned long nls_uint32; -# else - /* The following line is intended to throw an error. Using #error is - not portable enough. */ - "Cannot determine unsigned 32-bit data type." -# endif -# endif -#endif - - -/* Header for binary .mo file format. */ -struct mo_file_header -{ - /* The magic number. */ - nls_uint32 magic; - /* The revision number of the file format. */ - nls_uint32 revision; - /* The number of strings pairs. */ - nls_uint32 nstrings; - /* Offset of table with start offsets of original strings. */ - nls_uint32 orig_tab_offset; - /* Offset of table with start offsets of translation strings. */ - nls_uint32 trans_tab_offset; - /* Size of hashing table. */ - nls_uint32 hash_tab_size; - /* Offset of first hashing entry. */ - nls_uint32 hash_tab_offset; -}; - -struct string_desc -{ - /* Length of addressed string. */ - nls_uint32 length; - /* Offset of string in file. */ - nls_uint32 offset; -}; - -/* @@ begin of epilog @@ */ - -#endif /* gettext.h */ diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettextP.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettextP.h deleted file mode 100644 index 00c5203197..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/gettextP.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Header describing internals of gettext library - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Written by Ulrich Drepper , 1995. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _GETTEXTP_H -#define _GETTEXTP_H - -#include "loadinfo.h" - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -#ifndef W -# define W(flag, data) ((flag) ? SWAP (data) : (data)) -#endif - - -#ifdef _LIBC -# include -# define SWAP(i) bswap_32 (i) -#else -static nls_uint32 SWAP PARAMS ((nls_uint32 i)); - -static inline nls_uint32 -SWAP (i) - nls_uint32 i; -{ - return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); -} -#endif - - -struct loaded_domain -{ - const char *data; - int use_mmap; - size_t mmap_size; - int must_swap; - nls_uint32 nstrings; - struct string_desc *orig_tab; - struct string_desc *trans_tab; - nls_uint32 hash_size; - nls_uint32 *hash_tab; -}; - -struct binding -{ - struct binding *next; - char *domainname; - char *dirname; -}; - -struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, - char *__locale, - const char *__domainname)) - internal_function; -void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain)) - internal_function; -void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) - internal_function; - -/* @@ begin of epilog @@ */ - -#endif /* gettextP.h */ diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/hash-string.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/hash-string.h deleted file mode 100644 index cacb38e479..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/hash-string.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Implements a string hashing function. - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -/* We assume to have `unsigned long int' value with at least 32 bits. */ -#define HASHWORDBITS 32 - - -/* Defines the so called `hashpjw' function by P.J. Weinberger - [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, - 1986, 1987 Bell Telephone Laboratories, Inc.] */ -static unsigned long hash_string PARAMS ((const char *__str_param)); - -static inline unsigned long -hash_string (str_param) - const char *str_param; -{ - unsigned long int hval, g; - const char *str = str_param; - - /* Compute the hash value for the given string. */ - hval = 0; - while (*str != '\0') - { - hval <<= 4; - hval += (unsigned long) *str++; - g = hval & ((unsigned long) 0xf << (HASHWORDBITS - 4)); - if (g != 0) - { - hval ^= g >> (HASHWORDBITS - 8); - hval ^= g; - } - } - return hval; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/intl-compat.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/intl-compat.c deleted file mode 100644 index 21ffc60c19..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/intl-compat.c +++ /dev/null @@ -1,76 +0,0 @@ -/* intl-compat.c - Stub functions to call gettext functions from GNU gettext - Library. - Copyright (C) 1995 Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "libgettext.h" - -/* @@ end of prolog @@ */ - - -#undef gettext -#undef dgettext -#undef dcgettext -#undef textdomain -#undef bindtextdomain - - -char * -bindtextdomain (domainname, dirname) - const char *domainname; - const char *dirname; -{ - return bindtextdomain__ (domainname, dirname); -} - - -char * -dcgettext (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; -{ - return dcgettext__ (domainname, msgid, category); -} - - -char * -dgettext (domainname, msgid) - const char *domainname; - const char *msgid; -{ - return dgettext__ (domainname, msgid); -} - - -char * -gettext (msgid) - const char *msgid; -{ - return gettext__ (msgid); -} - - -char * -textdomain (domainname) - const char *domainname; -{ - return textdomain__ (domainname); -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/l10nflist.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/l10nflist.c deleted file mode 100644 index 174794201c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/l10nflist.c +++ /dev/null @@ -1,411 +0,0 @@ -/* Handle list of needed message catalogs - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Ulrich Drepper , 1995. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#if defined HAVE_STRING_H || defined _LIBC -# ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -# endif -# include -#else -# include -# ifndef memcpy -# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) -# endif -#endif -#if !HAVE_STRCHR && !defined _LIBC -# ifndef strchr -# define strchr index -# endif -#endif - -#if defined _LIBC || defined HAVE_ARGZ_H -# include -#endif -#include -#include - -#if defined STDC_HEADERS || defined _LIBC -# include -#endif - -#include "loadinfo.h" - -/* On some strange systems still no definition of NULL is found. Sigh! */ -#ifndef NULL -# if defined __STDC__ && __STDC__ -# define NULL ((void *) 0) -# else -# define NULL 0 -# endif -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# ifndef stpcpy -# define stpcpy(dest, src) __stpcpy(dest, src) -# endif -#else -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -#endif - -/* Define function which are usually not available. */ - -#if !defined _LIBC && !defined HAVE___ARGZ_COUNT -/* Returns the number of strings in ARGZ. */ -static size_t argz_count__ PARAMS ((const char *argz, size_t len)); - -static size_t -argz_count__ (argz, len) - const char *argz; - size_t len; -{ - size_t count = 0; - while (len > 0) - { - size_t part_len = strlen (argz); - argz += part_len + 1; - len -= part_len + 1; - count++; - } - return count; -} -# undef __argz_count -# define __argz_count(argz, len) argz_count__ (argz, len) -#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ - -#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY -/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's - except the last into the character SEP. */ -static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); - -static void -argz_stringify__ (argz, len, sep) - char *argz; - size_t len; - int sep; -{ - while (len > 0) - { - size_t part_len = strlen (argz); - argz += part_len; - len -= part_len + 1; - if (len > 0) - *argz++ = sep; - } -} -# undef __argz_stringify -# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) -#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ - -#if !defined _LIBC && !defined HAVE___ARGZ_NEXT -static char *argz_next__ PARAMS ((char *argz, size_t argz_len, - const char *entry)); - -static char * -argz_next__ (argz, argz_len, entry) - char *argz; - size_t argz_len; - const char *entry; -{ - if (entry) - { - if (entry < argz + argz_len) - entry = strchr (entry, '\0') + 1; - - return entry >= argz + argz_len ? NULL : (char *) entry; - } - else - if (argz_len > 0) - return argz; - else - return 0; -} -# undef __argz_next -# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) -#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ - - -/* Return number of bits set in X. */ -static int pop PARAMS ((int x)); - -static inline int -pop (x) - int x; -{ - /* We assume that no more than 16 bits are used. */ - x = ((x & ~0x5555) >> 1) + (x & 0x5555); - x = ((x & ~0x3333) >> 2) + (x & 0x3333); - x = ((x >> 4) + x) & 0x0f0f; - x = ((x >> 8) + x) & 0xff; - - return x; -} - - -struct loaded_l10nfile * -_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, - territory, codeset, normalized_codeset, modifier, special, - sponsor, revision, filename, do_allocate) - struct loaded_l10nfile **l10nfile_list; - const char *dirlist; - size_t dirlist_len; - int mask; - const char *language; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *modifier; - const char *special; - const char *sponsor; - const char *revision; - const char *filename; - int do_allocate; -{ - char *abs_filename; - struct loaded_l10nfile *last = NULL; - struct loaded_l10nfile *retval; - char *cp; - size_t entries; - int cnt; - - /* Allocate room for the full file name. */ - abs_filename = (char *) malloc (dirlist_len - + strlen (language) - + ((mask & TERRITORY) != 0 - ? strlen (territory) + 1 : 0) - + ((mask & XPG_CODESET) != 0 - ? strlen (codeset) + 1 : 0) - + ((mask & XPG_NORM_CODESET) != 0 - ? strlen (normalized_codeset) + 1 : 0) - + (((mask & XPG_MODIFIER) != 0 - || (mask & CEN_AUDIENCE) != 0) - ? strlen (modifier) + 1 : 0) - + ((mask & CEN_SPECIAL) != 0 - ? strlen (special) + 1 : 0) - + (((mask & CEN_SPONSOR) != 0 - || (mask & CEN_REVISION) != 0) - ? (1 + ((mask & CEN_SPONSOR) != 0 - ? strlen (sponsor) + 1 : 0) - + ((mask & CEN_REVISION) != 0 - ? strlen (revision) + 1 : 0)) : 0) - + 1 + strlen (filename) + 1); - - if (abs_filename == NULL) - return NULL; - - retval = NULL; - last = NULL; - - /* Construct file name. */ - memcpy (abs_filename, dirlist, dirlist_len); - __argz_stringify (abs_filename, dirlist_len, ':'); - cp = abs_filename + (dirlist_len - 1); - *cp++ = '/'; - cp = stpcpy (cp, language); - - if ((mask & TERRITORY) != 0) - { - *cp++ = '_'; - cp = stpcpy (cp, territory); - } - if ((mask & XPG_CODESET) != 0) - { - *cp++ = '.'; - cp = stpcpy (cp, codeset); - } - if ((mask & XPG_NORM_CODESET) != 0) - { - *cp++ = '.'; - cp = stpcpy (cp, normalized_codeset); - } - if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) - { - /* This component can be part of both syntaces but has different - leading characters. For CEN we use `+', else `@'. */ - *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; - cp = stpcpy (cp, modifier); - } - if ((mask & CEN_SPECIAL) != 0) - { - *cp++ = '+'; - cp = stpcpy (cp, special); - } - if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) - { - *cp++ = ','; - if ((mask & CEN_SPONSOR) != 0) - cp = stpcpy (cp, sponsor); - if ((mask & CEN_REVISION) != 0) - { - *cp++ = '_'; - cp = stpcpy (cp, revision); - } - } - - *cp++ = '/'; - stpcpy (cp, filename); - - /* Look in list of already loaded domains whether it is already - available. */ - last = NULL; - for (retval = *l10nfile_list; retval != NULL; retval = retval->next) - if (retval->filename != NULL) - { - int compare = strcmp (retval->filename, abs_filename); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It's not in the list. */ - retval = NULL; - break; - } - - last = retval; - } - - if (retval != NULL || do_allocate == 0) - { - free (abs_filename); - return retval; - } - - retval = (struct loaded_l10nfile *) - malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len) - * (1 << pop (mask)) - * sizeof (struct loaded_l10nfile *))); - if (retval == NULL) - return NULL; - - retval->filename = abs_filename; - retval->decided = (__argz_count (dirlist, dirlist_len) != 1 - || ((mask & XPG_CODESET) != 0 - && (mask & XPG_NORM_CODESET) != 0)); - retval->data = NULL; - - if (last == NULL) - { - retval->next = *l10nfile_list; - *l10nfile_list = retval; - } - else - { - retval->next = last->next; - last->next = retval; - } - - entries = 0; - /* If the DIRLIST is a real list the RETVAL entry corresponds not to - a real file. So we have to use the DIRLIST separation mechanism - of the inner loop. */ - cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask; - for (; cnt >= 0; --cnt) - if ((cnt & ~mask) == 0 - && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) - && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) - { - /* Iterate over all elements of the DIRLIST. */ - char *dir = NULL; - - while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) - != NULL) - retval->successor[entries++] - = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt, - language, territory, codeset, - normalized_codeset, modifier, special, - sponsor, revision, filename, 1); - } - retval->successor[entries] = NULL; - - return retval; -} - -/* Normalize codeset name. There is no standard for the codeset - names. Normalization allows the user to use any of the common - names. */ -const char * -_nl_normalize_codeset (codeset, name_len) - const unsigned char *codeset; - size_t name_len; -{ - int len = 0; - int only_digit = 1; - char *retval; - char *wp; - size_t cnt; - - for (cnt = 0; cnt < name_len; ++cnt) - if (isalnum (codeset[cnt])) - { - ++len; - - if (isalpha (codeset[cnt])) - only_digit = 0; - } - - retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); - - if (retval != NULL) - { - if (only_digit) - wp = stpcpy (retval, "iso"); - else - wp = retval; - - for (cnt = 0; cnt < name_len; ++cnt) - if (isalpha (codeset[cnt])) - *wp++ = tolower (codeset[cnt]); - else if (isdigit (codeset[cnt])) - *wp++ = codeset[cnt]; - - *wp = '\0'; - } - - return (const char *) retval; -} - - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/libgettext.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/libgettext.h deleted file mode 100644 index 3a92960ae3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/libgettext.h +++ /dev/null @@ -1,182 +0,0 @@ -/* Message catalogs for internationalization. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Because on some systems (e.g. Solaris) we sometimes have to include - the systems libintl.h as well as this file we have more complex - include protection above. But the systems header might perhaps also - define _LIBINTL_H and therefore we have to protect the definition here. */ - -#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H -#ifndef _LIBINTL_H -# define _LIBINTL_H 1 -#endif -#define _LIBGETTEXT_H 1 - -/* We define an additional symbol to signal that we use the GNU - implementation of gettext. */ -#define __USE_GNU_GETTEXT 1 - -#include - -#if HAVE_LOCALE_H -# include -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ || defined __cplusplus -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef NULL -# if !defined __cplusplus || defined __GNUC__ -# define NULL ((void *) 0) -# else -# define NULL (0) -# endif -#endif - -#if !HAVE_LC_MESSAGES -/* This value determines the behaviour of the gettext() and dgettext() - function. But some system does not have this defined. Define it - to a default value. */ -# define LC_MESSAGES (-1) -#endif - - -/* Declarations for gettext-using-catgets interface. Derived from - Jim Meyering's libintl.h. */ -struct _msg_ent -{ - const char *_msg; - int _msg_number; -}; - - -#if HAVE_CATGETS -/* These two variables are defined in the automatically by po-to-tbl.sed - generated file `cat-id-tbl.c'. */ -extern const struct _msg_ent _msg_tbl[]; -extern int _msg_tbl_length; -#endif - - -/* For automatical extraction of messages sometimes no real - translation is needed. Instead the string itself is the result. */ -#define gettext_noop(Str) (Str) - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -extern char *gettext PARAMS ((const char *__msgid)); -extern char *gettext__ PARAMS ((const char *__msgid)); - -/* Look up MSGID in the DOMAINNAME message catalog for the current - LC_MESSAGES locale. */ -extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid)); -extern char *dgettext__ PARAMS ((const char *__domainname, - const char *__msgid)); - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid, - int __category)); -extern char *dcgettext__ PARAMS ((const char *__domainname, - const char *__msgid, int __category)); - - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -extern char *textdomain PARAMS ((const char *__domainname)); -extern char *textdomain__ PARAMS ((const char *__domainname)); - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -extern char *bindtextdomain PARAMS ((const char *__domainname, - const char *__dirname)); -extern char *bindtextdomain__ PARAMS ((const char *__domainname, - const char *__dirname)); - -#if ENABLE_NLS - -/* Solaris 2.3 has the gettext function but dcgettext is missing. - So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4 - has dcgettext. */ -# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT) - -# define gettext(Msgid) \ - dgettext (NULL, Msgid) - -# define dgettext(Domainname, Msgid) \ - dcgettext (Domainname, Msgid, LC_MESSAGES) - -# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7 -/* This global variable is defined in loadmsgcat.c. We need a sign, - whether a new catalog was loaded, which can be associated with all - translations. */ -extern int _nl_msg_cat_cntr; - -# define dcgettext(Domainname, Msgid, Category) \ - (__extension__ \ - ({ \ - char *__result; \ - if (__builtin_constant_p (Msgid)) \ - { \ - static char *__translation__; \ - static int __catalog_counter__; \ - if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \ - { \ - __translation__ = \ - dcgettext__ (Domainname, Msgid, Category); \ - __catalog_counter__ = _nl_msg_cat_cntr; \ - } \ - __result = __translation__; \ - } \ - else \ - __result = dcgettext__ (Domainname, Msgid, Category); \ - __result; \ - })) -# endif -# endif - -#else - -# define gettext(Msgid) (Msgid) -# define dgettext(Domainname, Msgid) (Msgid) -# define dcgettext(Domainname, Msgid, Category) (Msgid) -# define textdomain(Domainname) ((char *) Domainname) -# define bindtextdomain(Domainname, Dirname) ((char *) Dirname) - -#endif - -/* @@ begin of epilog @@ */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/linux-msg.sed b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/linux-msg.sed deleted file mode 100755 index 5918e720a9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/linux-msg.sed +++ /dev/null @@ -1,100 +0,0 @@ -# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file -# Copyright (C) 1995 Free Software Foundation, Inc. -# Ulrich Drepper , 1995. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# -# The first directive in the .msg should be the definition of the -# message set number. We use always set number 1. -# -1 { - i\ -$set 1 # Automatically created by po2msg.sed - h - s/.*/0/ - x -} -# -# Mitch's old catalog format does not allow comments. -# -# We copy the original message as a comment into the .msg file. -# -/^msgid/ { - s/msgid[ ]*"// -# -# This does not work now with the new format. -# /"$/! { -# s/\\$// -# s/$/ ... (more lines following)"/ -# } - x -# The following nice solution is by -# Bruno - td -# Increment a decimal number in pattern space. -# First hide trailing `9' digits. - :d - s/9\(_*\)$/_\1/ - td -# Assure at least one digit is available. - s/^\(_*\)$/0\1/ -# Increment the last digit. - s/8\(_*\)$/9\1/ - s/7\(_*\)$/8\1/ - s/6\(_*\)$/7\1/ - s/5\(_*\)$/6\1/ - s/4\(_*\)$/5\1/ - s/3\(_*\)$/4\1/ - s/2\(_*\)$/3\1/ - s/1\(_*\)$/2\1/ - s/0\(_*\)$/1\1/ -# Convert the hidden `9' digits to `0's. - s/_/0/g - x - G - s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p -} -# -# The .msg file contains, other then the .po file, only the translations -# but each given a unique ID. Starting from 1 and incrementing by 1 for -# each message we assign them to the messages. -# It is important that the .po file used to generate the cat-id-tbl.c file -# (with po-to-tbl) is the same as the one used here. (At least the order -# of declarations must not be changed.) -# -/^msgstr/ { - s/msgstr[ ]*"\(.*\)"/# \1/ -# Clear substitution flag. - tb -# Append the next line. - :b - N -# Look whether second part is continuation line. - s/\(.*\n\)"\(.*\)"/\1\2/ -# Yes, then branch. - ta - P - D -# Note that D includes a jump to the start!! -# We found a continuation line. But before printing insert '\'. - :a - s/\(.*\)\(\n.*\)/\1\\\2/ - P -# We cannot use D here. - s/.*\n\(.*\)/\1/ - tb -} -d diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadinfo.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadinfo.h deleted file mode 100644 index f4ebf6d811..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadinfo.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1996. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef PARAMS -# if __STDC__ -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -/* Encoding of locale name parts. */ -#define CEN_REVISION 1 -#define CEN_SPONSOR 2 -#define CEN_SPECIAL 4 -#define XPG_NORM_CODESET 8 -#define XPG_CODESET 16 -#define TERRITORY 32 -#define CEN_AUDIENCE 64 -#define XPG_MODIFIER 128 - -#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) -#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) - - -struct loaded_l10nfile -{ - const char *filename; - int decided; - - const void *data; - - struct loaded_l10nfile *next; - struct loaded_l10nfile *successor[1]; -}; - - -extern const char *_nl_normalize_codeset PARAMS ((const unsigned char *codeset, - size_t name_len)); - -extern struct loaded_l10nfile * -_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, - const char *dirlist, size_t dirlist_len, int mask, - const char *language, const char *territory, - const char *codeset, - const char *normalized_codeset, - const char *modifier, const char *special, - const char *sponsor, const char *revision, - const char *filename, int do_allocate)); - - -extern const char *_nl_expand_alias PARAMS ((const char *name)); - -extern int _nl_explode_name PARAMS ((char *name, const char **language, - const char **modifier, - const char **territory, - const char **codeset, - const char **normalized_codeset, - const char **special, - const char **sponsor, - const char **revision)); diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadmsgcat.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadmsgcat.c deleted file mode 100644 index e74a2f77f5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/loadmsgcat.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Load needed message catalogs. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#if defined STDC_HEADERS || defined _LIBC -# include -#endif - -#if defined HAVE_UNISTD_H || defined _LIBC -# include -#endif - -#if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC -# include -#endif - -#include "gettext.h" -#include "gettextP.h" - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ISO C functions. This is required by the standard - because some ISO C functions will require linking with this object - file and the name space must not be polluted. */ -# define open __open -# define close __close -# define read __read -# define mmap __mmap -# define munmap __munmap -#endif - -/* We need a sign, whether a new catalog was loaded, which can be associated - with all translations. This is important if the translations are - cached by one of GCC's features. */ -int _nl_msg_cat_cntr = 0; - - -/* Load the message catalogs specified by FILENAME. If it is no valid - message catalog do nothing. */ -void -internal_function -_nl_load_domain (domain_file) - struct loaded_l10nfile *domain_file; -{ - int fd; - size_t size; - struct stat st; - struct mo_file_header *data = (struct mo_file_header *) -1; -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || defined _LIBC - int use_mmap = 0; -#endif - struct loaded_domain *domain; - - domain_file->decided = 1; - domain_file->data = NULL; - - /* If the record does not represent a valid locale the FILENAME - might be NULL. This can happen when according to the given - specification the locale file name is different for XPG and CEN - syntax. */ - if (domain_file->filename == NULL) - return; - - /* Try to open the addressed file. */ - fd = open (domain_file->filename, O_RDONLY); - if (fd == -1) - return; - - /* We must know about the size of the file. */ - if (fstat (fd, &st) != 0 - || (size = (size_t) st.st_size) != st.st_size - || size < sizeof (struct mo_file_header)) - { - /* Something went wrong. */ - close (fd); - return; - } - -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || defined _LIBC - /* Now we are ready to load the file. If mmap() is available we try - this first. If not available or it failed we try to load it. */ - data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, - MAP_PRIVATE, fd, 0); - - if (data != (struct mo_file_header *) -1) - { - /* mmap() call was successful. */ - close (fd); - use_mmap = 1; - } -#endif - - /* If the data is not yet available (i.e. mmap'ed) we try to load - it manually. */ - if (data == (struct mo_file_header *) -1) - { - size_t to_read; - char *read_ptr; - - data = (struct mo_file_header *) malloc (size); - if (data == NULL) - return; - - to_read = size; - read_ptr = (char *) data; - do - { - long int nb = (long int) read (fd, read_ptr, to_read); - if (nb == -1) - { - close (fd); - return; - } - - read_ptr += nb; - to_read -= nb; - } - while (to_read > 0); - - close (fd); - } - - /* Using the magic number we can test whether it really is a message - catalog file. */ - if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED) - { - /* The magic number is wrong: not a message catalog file. */ -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || defined _LIBC - if (use_mmap) - munmap ((caddr_t) data, size); - else -#endif - free (data); - return; - } - - domain_file->data - = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); - if (domain_file->data == NULL) - return; - - domain = (struct loaded_domain *) domain_file->data; - domain->data = (char *) data; -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || defined _LIBC - domain->use_mmap = use_mmap; -#endif - domain->mmap_size = size; - domain->must_swap = data->magic != _MAGIC; - - /* Fill in the information about the available tables. */ - switch (W (domain->must_swap, data->revision)) - { - case 0: - domain->nstrings = W (domain->must_swap, data->nstrings); - domain->orig_tab = (struct string_desc *) - ((char *) data + W (domain->must_swap, data->orig_tab_offset)); - domain->trans_tab = (struct string_desc *) - ((char *) data + W (domain->must_swap, data->trans_tab_offset)); - domain->hash_size = W (domain->must_swap, data->hash_tab_size); - domain->hash_tab = (nls_uint32 *) - ((char *) data + W (domain->must_swap, data->hash_tab_offset)); - break; - default: - /* This is an illegal revision. */ -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || defined _LIBC - if (use_mmap) - munmap ((caddr_t) data, size); - else -#endif - free (data); - free (domain); - domain_file->data = NULL; - return; - } - - /* Show that one domain is changed. This might make some cached - translations invalid. */ - ++_nl_msg_cat_cntr; -} - - -#ifdef _LIBC -void -internal_function -_nl_unload_domain (domain) - struct loaded_domain *domain; -{ - if (domain->use_mmap) - munmap ((caddr_t) domain->data, domain->mmap_size); - else - free ((void *) domain->data); - - free (domain); -} -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/localealias.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/localealias.c deleted file mode 100644 index 18cc68886b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/localealias.c +++ /dev/null @@ -1,424 +0,0 @@ -/* Handle aliases for locale names. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Written by Ulrich Drepper , 1995. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#ifdef __GNUC__ -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -#endif - -#if defined STDC_HEADERS || defined _LIBC -# include -#else -char *getenv (); -# ifdef HAVE_MALLOC_H -# include -# else -void free (); -# endif -#endif - -#if defined HAVE_STRING_H || defined _LIBC -# ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -# endif -# include -#else -# include -# ifndef memcpy -# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) -# endif -#endif -#if !HAVE_STRCHR && !defined _LIBC -# ifndef strchr -# define strchr index -# endif -#endif - -#include "gettext.h" -#include "gettextP.h" - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# define strcasecmp __strcasecmp - -# define mempcpy __mempcpy -# define HAVE_MEMPCPY 1 - -/* We need locking here since we can be called from different places. */ -# include - -__libc_lock_define_initialized (static, lock); -#endif - - -/* For those loosing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -/* Nothing has to be done. */ -# define ADD_BLOCK(list, address) /* nothing */ -# define FREE_BLOCKS(list) /* nothing */ -#else -struct block_list -{ - void *address; - struct block_list *next; -}; -# define ADD_BLOCK(list, addr) \ - do { \ - struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ - /* If we cannot get a free block we cannot add the new element to \ - the list. */ \ - if (newp != NULL) { \ - newp->address = (addr); \ - newp->next = (list); \ - (list) = newp; \ - } \ - } while (0) -# define FREE_BLOCKS(list) \ - do { \ - while (list != NULL) { \ - struct block_list *old = list; \ - list = list->next; \ - free (old); \ - } \ - } while (0) -# undef alloca -# define alloca(size) (malloc (size)) -#endif /* have alloca */ - - -struct alias_map -{ - const char *alias; - const char *value; -}; - - -static char *string_space = NULL; -static size_t string_space_act = 0; -static size_t string_space_max = 0; -static struct alias_map *map; -static size_t nmap = 0; -static size_t maxmap = 0; - - -/* Prototypes for local functions. */ -static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) - internal_function; -static void extend_alias_table PARAMS ((void)); -static int alias_compare PARAMS ((const struct alias_map *map1, - const struct alias_map *map2)); - - -const char * -_nl_expand_alias (name) - const char *name; -{ - static const char *locale_alias_path = LOCALE_ALIAS_PATH; - struct alias_map *retval; - const char *result = NULL; - size_t added; - -#ifdef _LIBC - __libc_lock_lock (lock); -#endif - - do - { - struct alias_map item; - - item.alias = name; - - if (nmap > 0) - retval = (struct alias_map *) bsearch (&item, map, nmap, - sizeof (struct alias_map), - (int (*) PARAMS ((const void *, - const void *)) - ) alias_compare); - else - retval = NULL; - - /* We really found an alias. Return the value. */ - if (retval != NULL) - { - result = retval->value; - break; - } - - /* Perhaps we can find another alias file. */ - added = 0; - while (added == 0 && locale_alias_path[0] != '\0') - { - const char *start; - - while (locale_alias_path[0] == ':') - ++locale_alias_path; - start = locale_alias_path; - - while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':') - ++locale_alias_path; - - if (start < locale_alias_path) - added = read_alias_file (start, locale_alias_path - start); - } - } - while (added != 0); - -#ifdef _LIBC - __libc_lock_unlock (lock); -#endif - - return result; -} - - -static size_t -internal_function -read_alias_file (fname, fname_len) - const char *fname; - int fname_len; -{ -#ifndef HAVE_ALLOCA - struct block_list *block_list = NULL; -#endif - FILE *fp; - char *full_fname; - size_t added; - static const char aliasfile[] = "/locale.alias"; - - full_fname = (char *) alloca (fname_len + sizeof aliasfile); - ADD_BLOCK (block_list, full_fname); -#ifdef HAVE_MEMPCPY - mempcpy (mempcpy (full_fname, fname, fname_len), - aliasfile, sizeof aliasfile); -#else - memcpy (full_fname, fname, fname_len); - memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); -#endif - - fp = fopen (full_fname, "r"); - if (fp == NULL) - { - FREE_BLOCKS (block_list); - return 0; - } - - added = 0; - while (!feof (fp)) - { - /* It is a reasonable approach to use a fix buffer here because - a) we are only interested in the first two fields - b) these fields must be usable as file names and so must not - be that long - */ - unsigned char buf[BUFSIZ]; - unsigned char *alias; - unsigned char *value; - unsigned char *cp; - - if (fgets (buf, sizeof buf, fp) == NULL) - /* EOF reached. */ - break; - - /* Possibly not the whole line fits into the buffer. Ignore - the rest of the line. */ - if (strchr (buf, '\n') == NULL) - { - char altbuf[BUFSIZ]; - do - if (fgets (altbuf, sizeof altbuf, fp) == NULL) - /* Make sure the inner loop will be left. The outer loop - will exit at the `feof' test. */ - break; - while (strchr (altbuf, '\n') == NULL); - } - - cp = buf; - /* Ignore leading white space. */ - while (isspace (cp[0])) - ++cp; - - /* A leading '#' signals a comment line. */ - if (cp[0] != '\0' && cp[0] != '#') - { - alias = cp++; - while (cp[0] != '\0' && !isspace (cp[0])) - ++cp; - /* Terminate alias name. */ - if (cp[0] != '\0') - *cp++ = '\0'; - - /* Now look for the beginning of the value. */ - while (isspace (cp[0])) - ++cp; - - if (cp[0] != '\0') - { - size_t alias_len; - size_t value_len; - - value = cp++; - while (cp[0] != '\0' && !isspace (cp[0])) - ++cp; - /* Terminate value. */ - if (cp[0] == '\n') - { - /* This has to be done to make the following test - for the end of line possible. We are looking for - the terminating '\n' which do not overwrite here. */ - *cp++ = '\0'; - *cp = '\n'; - } - else if (cp[0] != '\0') - *cp++ = '\0'; - - if (nmap >= maxmap) - extend_alias_table (); - - alias_len = strlen (alias) + 1; - value_len = strlen (value) + 1; - - if (string_space_act + alias_len + value_len > string_space_max) - { - /* Increase size of memory pool. */ - size_t new_size = (string_space_max - + (alias_len + value_len > 1024 - ? alias_len + value_len : 1024)); - char *new_pool = (char *) realloc (string_space, new_size); - if (new_pool == NULL) - { - FREE_BLOCKS (block_list); - return added; - } - string_space = new_pool; - string_space_max = new_size; - } - - map[nmap].alias = memcpy (&string_space[string_space_act], - alias, alias_len); - string_space_act += alias_len; - - map[nmap].value = memcpy (&string_space[string_space_act], - value, value_len); - string_space_act += value_len; - - ++nmap; - ++added; - } - } - } - - /* Should we test for ferror()? I think we have to silently ignore - errors. --drepper */ - fclose (fp); - - if (added > 0) - qsort (map, nmap, sizeof (struct alias_map), - (int (*) PARAMS ((const void *, const void *))) alias_compare); - - FREE_BLOCKS (block_list); - return added; -} - - -static void -extend_alias_table () -{ - size_t new_size; - struct alias_map *new_map; - - new_size = maxmap == 0 ? 100 : 2 * maxmap; - new_map = (struct alias_map *) realloc (map, (new_size - * sizeof (struct alias_map))); - if (new_map == NULL) - /* Simply don't extend: we don't have any more core. */ - return; - - map = new_map; - maxmap = new_size; -} - - -#ifdef _LIBC -static void __attribute__ ((unused)) -free_mem (void) -{ - if (string_space != NULL) - free (string_space); - if (map != NULL) - free (map); -} -text_set_element (__libc_subfreeres, free_mem); -#endif - - -static int -alias_compare (map1, map2) - const struct alias_map *map1; - const struct alias_map *map2; -{ -#if defined _LIBC || defined HAVE_STRCASECMP - return strcasecmp (map1->alias, map2->alias); -#else - const unsigned char *p1 = (const unsigned char *) map1->alias; - const unsigned char *p2 = (const unsigned char *) map2->alias; - unsigned char c1, c2; - - if (p1 == p2) - return 0; - - do - { - /* I know this seems to be odd but the tolower() function in - some systems libc cannot handle nonalpha characters. */ - c1 = isupper (*p1) ? tolower (*p1) : *p1; - c2 = isupper (*p2) ? tolower (*p2) : *p2; - if (c1 == '\0') - break; - ++p1; - ++p2; - } - while (c1 == c2); - - return c1 - c2; -#endif -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/po2tbl.sed.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/po2tbl.sed.in deleted file mode 100755 index b3bcca4d73..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/po2tbl.sed.in +++ /dev/null @@ -1,102 +0,0 @@ -# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets -# Copyright (C) 1995 Free Software Foundation, Inc. -# Ulrich Drepper , 1995. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -1 { - i\ -/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\ -\ -#if HAVE_CONFIG_H\ -# include \ -#endif\ -\ -#include "libgettext.h"\ -\ -const struct _msg_ent _msg_tbl[] = { - h - s/.*/0/ - x -} -# -# Write msgid entries in C array form. -# -/^msgid/ { - s/msgid[ ]*\(".*"\)/ {\1/ - tb -# Append the next line - :b - N -# Look whether second part is continuation line. - s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/ -# Yes, then branch. - ta -# Because we assume that the input file correctly formed the line -# just read cannot be again be a msgid line. So it's safe to ignore -# it. - s/\(.*\)\n.*/\1/ - bc -# We found a continuation line. But before printing insert '\'. - :a - s/\(.*\)\(\n.*\)/\1\\\2/ - P -# We cannot use D here. - s/.*\n\(.*\)/\1/ -# Some buggy seds do not clear the `successful substitution since last ``t''' -# flag on `N', so we do a `t' here to clear it. - tb -# Not reached - :c - x -# The following nice solution is by -# Bruno - td -# Increment a decimal number in pattern space. -# First hide trailing `9' digits. - :d - s/9\(_*\)$/_\1/ - td -# Assure at least one digit is available. - s/^\(_*\)$/0\1/ -# Increment the last digit. - s/8\(_*\)$/9\1/ - s/7\(_*\)$/8\1/ - s/6\(_*\)$/7\1/ - s/5\(_*\)$/6\1/ - s/4\(_*\)$/5\1/ - s/3\(_*\)$/4\1/ - s/2\(_*\)$/3\1/ - s/1\(_*\)$/2\1/ - s/0\(_*\)$/1\1/ -# Convert the hidden `9' digits to `0's. - s/_/0/g - x - G - s/\(.*\)\n\([0-9]*\)/\1, \2},/ - s/\(.*\)"$/\1/ - p -} -# -# Last line. -# -$ { - i\ -};\ - - g - s/0*\(.*\)/int _msg_tbl_length = \1;/p -} -d diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/textdomain.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/textdomain.c deleted file mode 100644 index 2e8facb1f8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/textdomain.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Implementation of the textdomain(3) function. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Written by Ulrich Drepper , 1995. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined STDC_HEADERS || defined _LIBC -# include -#endif - -#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC -# include -#else -# include -# ifndef memcpy -# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) -# endif -#endif - -#ifdef _LIBC -# include -#else -# include "libgettext.h" -#endif - -/* @@ end of prolog @@ */ - -/* Name of the default text domain. */ -extern const char _nl_default_default_domain[]; - -/* Default text domain in which entries for gettext(3) are to be found. */ -extern const char *_nl_current_default_domain; - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define TEXTDOMAIN __textdomain -# ifndef strdup -# define strdup(str) __strdup (str) -# endif -#else -# define TEXTDOMAIN textdomain__ -#endif - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -char * -TEXTDOMAIN (domainname) - const char *domainname; -{ - char *old; - - /* A NULL pointer requests the current setting. */ - if (domainname == NULL) - return (char *) _nl_current_default_domain; - - old = (char *) _nl_current_default_domain; - - /* If domain name is the null string set to default domain "messages". */ - if (domainname[0] == '\0' - || strcmp (domainname, _nl_default_default_domain) == 0) - _nl_current_default_domain = _nl_default_default_domain; - else - { - /* If the following malloc fails `_nl_current_default_domain' - will be NULL. This value will be returned and so signals we - are out of core. */ -#if defined _LIBC || defined HAVE_STRDUP - _nl_current_default_domain = strdup (domainname); -#else - size_t len = strlen (domainname) + 1; - char *cp = (char *) malloc (len); - if (cp != NULL) - memcpy (cp, domainname, len); - _nl_current_default_domain = cp; -#endif - } - - if (old != _nl_default_default_domain) - free (old); - - return (char *) _nl_current_default_domain; -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__textdomain, textdomain); -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/xopen-msg.sed b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/xopen-msg.sed deleted file mode 100755 index b19c0bbd0e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/intl/xopen-msg.sed +++ /dev/null @@ -1,104 +0,0 @@ -# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file -# Copyright (C) 1995 Free Software Foundation, Inc. -# Ulrich Drepper , 1995. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# -# The first directive in the .msg should be the definition of the -# message set number. We use always set number 1. -# -1 { - i\ -$set 1 # Automatically created by po2msg.sed - h - s/.*/0/ - x -} -# -# We copy all comments into the .msg file. Perhaps they can help. -# -/^#/ s/^#[ ]*/$ /p -# -# We copy the original message as a comment into the .msg file. -# -/^msgid/ { -# Does not work now -# /"$/! { -# s/\\$// -# s/$/ ... (more lines following)"/ -# } - s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/ - p -} -# -# The .msg file contains, other then the .po file, only the translations -# but each given a unique ID. Starting from 1 and incrementing by 1 for -# each message we assign them to the messages. -# It is important that the .po file used to generate the cat-id-tbl.c file -# (with po-to-tbl) is the same as the one used here. (At least the order -# of declarations must not be changed.) -# -/^msgstr/ { - s/msgstr[ ]*"\(.*\)"/\1/ - x -# The following nice solution is by -# Bruno - td -# Increment a decimal number in pattern space. -# First hide trailing `9' digits. - :d - s/9\(_*\)$/_\1/ - td -# Assure at least one digit is available. - s/^\(_*\)$/0\1/ -# Increment the last digit. - s/8\(_*\)$/9\1/ - s/7\(_*\)$/8\1/ - s/6\(_*\)$/7\1/ - s/5\(_*\)$/6\1/ - s/4\(_*\)$/5\1/ - s/3\(_*\)$/4\1/ - s/2\(_*\)$/3\1/ - s/1\(_*\)$/2\1/ - s/0\(_*\)$/1\1/ -# Convert the hidden `9' digits to `0's. - s/_/0/g - x -# Bring the line in the format ` ' - G - s/^[^\n]*$/& / - s/\(.*\)\n\([0-9]*\)/\2 \1/ -# Clear flag from last substitution. - tb -# Append the next line. - :b - N -# Look whether second part is a continuation line. - s/\(.*\n\)"\(.*\)"/\1\2/ -# Yes, then branch. - ta - P - D -# Note that `D' includes a jump to the start!! -# We found a continuation line. But before printing insert '\'. - :a - s/\(.*\)\(\n.*\)/\1\\\2/ - P -# We cannot use the sed command `D' here - s/.*\n\(.*\)/\1/ - tb -} -d diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/Makefile.in.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/Makefile.in.in deleted file mode 100644 index 629f3d4b46..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/Makefile.in.in +++ /dev/null @@ -1,250 +0,0 @@ -# Makefile for program source directory in GNU NLS utilities package. -# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper -# -# This file file be copied and used freely without restrictions. It can -# be used in projects which are not available under the GNU Public License -# but which still want to provide support for the GNU gettext functionality. -# Please note that the actual code is *not* freely available. - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -DESTDIR = - -SHELL = /bin/sh -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ - -prefix = $(DESTDIR)@prefix@ -exec_prefix = @exec_prefix@ -datadir = $(prefix)/@DATADIRNAME@ -localedir = $(datadir)/locale -gnulocaledir = $(prefix)/share/locale -gettextsrcdir = $(prefix)/share/gettext/po -subdir = po - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = ../scripts/mkinstalldirs - -CC = @CC@ -GENCAT = @GENCAT@ -GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ -MSGFMT = @MSGFMT@ -XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ -MSGMERGE = PATH=../src:$$PATH msgmerge - -DEFS = @DEFS@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ - -INCLUDES = -I.. -I$(top_srcdir)/intl - -COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) - -SOURCES = cat-id-tbl.c -POFILES = @POFILES@ -GMOFILES = @GMOFILES@ -DISTFILES = Makefile.in.in POTFILES.in $(PACKAGE).pot \ -stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) - -POTFILES = \ - -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ -INSTOBJEXT = @INSTOBJEXT@ - -.SUFFIXES: -.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat - -.c.o: - $(COMPILE) $< - -.po.pox: - $(MAKE) $(PACKAGE).pot - $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox - -.po.mo: - $(MSGFMT) -o $@ $< - -.po.gmo: - file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ - && rm -f $$file && $(GMSGFMT) -o $$file $< - -.po.cat: - sed -f ../intl/po2msg.sed < $< > $*.msg \ - && rm -f $@ && $(GENCAT) $@ $*.msg - - -all: all-@USE_NLS@ - -all-yes: cat-id-tbl.c $(CATALOGS) -all-no: - -$(srcdir)/$(PACKAGE).pot: $(POTFILES) - $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ - --add-comments --keyword=_ --keyword=N_ \ - --files-from=$(srcdir)/POTFILES.in \ - && test ! -f $(PACKAGE).po \ - || ( rm -f $(srcdir)/$(PACKAGE).pot \ - && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) - -$(srcdir)/cat-id-tbl.c: stamp-cat-id; @: -$(srcdir)/stamp-cat-id: $(PACKAGE).pot - rm -f cat-id-tbl.tmp - sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ - | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp - if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \ - rm cat-id-tbl.tmp; \ - else \ - echo cat-id-tbl.c changed; \ - rm -f $(srcdir)/cat-id-tbl.c; \ - mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \ - fi - cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id - - -install: install-exec install-data -install-exec: -install-data: install-data-@USE_NLS@ -install-data-no: all -install-data-yes: all - if test -r "$(MKINSTALLDIRS)"; then \ - $(MKINSTALLDIRS) $(datadir); \ - else \ - $(SHELL) ../scripts/mkinstalldirs $(datadir); \ - fi - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - case "$$cat" in \ - *.gmo) destdir=$(gnulocaledir);; \ - *) destdir=$(localedir);; \ - esac; \ - lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ - dir=$$destdir/$$lang/LC_MESSAGES; \ - if test -r "$(MKINSTALLDIRS)"; then \ - $(MKINSTALLDIRS) $$dir; \ - else \ - $(SHELL) ../scripts/mkinstalldirs $$dir; \ - fi; \ - if test -r $$cat; then \ - $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ - echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ - else \ - $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ - echo "installing $(srcdir)/$$cat as" \ - "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ - fi; \ - if test -r $$cat.m; then \ - $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ - echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ - else \ - if test -r $(srcdir)/$$cat.m ; then \ - $(INSTALL_DATA) $(srcdir)/$$cat.m \ - $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ - echo "installing $(srcdir)/$$cat as" \ - "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ - else \ - true; \ - fi; \ - fi; \ - done - if test "$(PACKAGE)" = "gettext"; then \ - if test -r "$(MKINSTALLDIRS)"; then \ - $(MKINSTALLDIRS) $(gettextsrcdir); \ - else \ - $(SHELL) ../scripts/mkinstalldirs $(gettextsrcdir); \ - fi; \ - $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ - $(gettextsrcdir)/Makefile.in.in; \ - else \ - : ; \ - fi - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: - catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ - rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ - rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ - rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ - rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ - done - rm -f $(gettextsrcdir)/po-Makefile.in.in - -check: all - -cat-id-tbl.o: ../intl/libgettext.h - -dvi info tags TAGS ID: - -mostlyclean: - rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp - rm -fr *.o - -clean: mostlyclean - -distclean: clean - rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - rm -f $(GMOFILES) - -distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: update-po $(DISTFILES) - dists="$(DISTFILES)"; \ - for file in $$dists; do \ - ln $(srcdir)/$$file $(distdir) 2> /dev/null \ - || cp -p $(srcdir)/$$file $(distdir) || echo ignore; \ - done - -update-po: Makefile - $(MAKE) $(PACKAGE).pot - PATH=`pwd`/../src:$$PATH; \ - cd $(srcdir); \ - catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ - mv $$lang.po $$lang.old.po; \ - echo "$$lang:"; \ - if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ - rm -f $$lang.old.po; \ - else \ - echo "msgmerge for $$cat failed!"; \ - rm -f $$lang.po; \ - mv $$lang.old.po $$lang.po; \ - fi; \ - done - -POTFILES: POTFILES.in - ( if test 'x$(srcdir)' != 'x.'; then \ - posrcprefix='$(top_srcdir)/'; \ - else \ - posrcprefix="../"; \ - fi; \ - rm -f $@-t $@ \ - && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ - -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ - | sed -e '$$s/\\$$//') > $@-t \ - && chmod a-w $@-t \ - && mv $@-t $@ ) - -Makefile: Makefile.in.in ../config.status POTFILES - cd .. \ - && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ - $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/POTFILES.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/POTFILES.in deleted file mode 100644 index 8b9106da56..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/POTFILES.in +++ /dev/null @@ -1,19 +0,0 @@ -apps/gsmsmsd.cc -apps/gsmsendsms.cc -apps/gsmpb.cc -apps/gsmctl.cc -apps/gsmsmsstore.cc -gsmlib/gsm_at.cc -gsmlib/gsm_error.cc -gsmlib/gsm_event.cc -gsmlib/gsm_me_ta.cc -gsmlib/gsm_nls.cc -gsmlib/gsm_parser.cc -gsmlib/gsm_phonebook.cc -gsmlib/gsm_sms.cc -gsmlib/gsm_sms_codec.cc -gsmlib/gsm_sms_store.cc -gsmlib/gsm_unix_serial.cc -gsmlib/gsm_util.cc -gsmlib/gsm_sorted_phonebook.cc -gsmlib/gsm_sorted_sms_store.cc diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/cat-id-tbl.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/cat-id-tbl.c deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/de.gmo b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/de.gmo deleted file mode 100644 index 7ac755ac73d7810320dafa6fbb64875a20636f6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34591 zcmb`P34moqb@wkI0t3n>t0I?yVR~fVY`_4++B4Gw4bwBjbPpoqC~vvl@6oT{Yu++T zi*bvID;kx!izdXl;gUp+iTh_34M+?oYBbRg=hMWvB+-aOO!E7ms=D{Sr2#+lpyq#X z-C9qbI_K1>s{Y3l9(PB?uYE`qJq7%uqoe4@Ja0Wku~BsDnNc(fo(5h3?glRgUk$DT zKkwgv2Cn6OZ5&1Cfn`wNUj-`PC&4w~kHHpr&RJ1Z1z!(d2}Vm@x~sqqymrC$;0M74 z@VnqGVCig^?_Th7-q)Yw>g|9dyuTA%4&DbU|AXKGaMiLXS^>TbY=VCSt^_xp8$|`M z2^PV(f@<%7gS){CC`{>I4bFg{0B6BvRHpdf0xtwV3Em0*1bjUBIx0IHd^7k&@Ezch z;0M9uz>k5)f?oiS0RJ959ee=%8u$xP<$vXA&Ro=Hjwf7ejZf%Z-FZB=b+kg3`9N#JQX}1Tn18QbP;$ySOrf7-{Rjt44%gO zKZ9z|VI&frPXW&W*Mn-`6!--2*&ss@&4Fsqo4_Z79|AQG?*-MK$HTNIf~SB=e;%lM zZuHm!W8Pl@o(bL!s$KW`_wRsK4$Q2ne+nr2tp=Y2UJ0H6PJuBv1FHO&`0u|1s=Xft zHI9D*)f-(4fQ1!k8ycYZjsQw)SbDj*I1d8q} zL8eG_35bY@D&Se*Z~FIlgKF13pv^N-fet+r91u-$45&+m3KL)er)malc4f7K-GIY zDE|0eQ29R#s-O3RyTG4<>hIPKj&2Q5`CkQ!Uq1kz27UoN1w06fza9oPK1W>Yp_)M21WN5fy)1SQ29Opo(g^z)V%q+fBzY%bjM%j;#Yv`#}@E(a5t#@dqMU4 zrJ&0BZBX@p02CcR1ByO>1!~;B3?f>hZ+KjS@RwY?7*zT_9%n$+b1NwM^a@bvJ_2f9 zd>uq2MMqxYbnhm3it;9{$Wu4 z`4TAlNLj0&t3cJe8#H==qW3F6&4)LF>d)_kqW_(^A$}jRC_-N*1&tf>%sM7j-D?8r3Zfx z)VRG5RQo>xiZ1^IYQ8@RsvU=Iar9XVs@`>=+CK%J3C@BVrcK}(|h2C@x>T;B)H4tvp~(?8Bp~f z0M*~$0>xiQBYv0yx6^tHJBQkAdp{;k>Aw zBcR%SIVgU=3A_mGf~xOsQ00CORDZt*ivCA#b@iMBYTj%BHJ&q|`tefm2=E=C+VgHu z^!pU3^6mxC27m0|PnmG-x*Sx!H-oBgA1M0X0jhm>fhzw~;L+e$K(+td;5lHl&CRQ2 zp!j79d;-`2pLz�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\n" -"Language-Team: Peter Hofmann\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-15\n" -"Content-Transfer-Encoding: 8bit\n" - -# , c-format -#: apps/gsmsmsd.cc:164 -#, c-format -msgid "could not execute '%s'" -msgstr "konnte '%s' nicht ausfhren" - -# , c-format -#: apps/gsmsmsd.cc:168 -#, c-format -msgid "error writing to '%s'" -msgstr "Fehler beim Schreiben zu '%s'" - -# , c-format -#: apps/gsmsmsd.cc:196 -#, c-format -msgid "error when calling opendir('%s')(errno: %d/%s)" -msgstr "Fehler beim Aufruf von opendir('%s') (errno: %d/%s)" - -# , c-format -#: apps/gsmsmsd.cc:225 -#, c-format -msgid "count not open SMS spool file %s" -msgstr "kann SMS Spool-Datei '%s' nicht ffnen" - -# , c-format -#: apps/gsmsmsd.cc:341 apps/gsmsendsms.cc:144 apps/gsmpb.cc:311 -#: apps/gsmctl.cc:380 apps/gsmsmsstore.cc:179 -#, c-format -msgid ": version %s [compiled %s]" -msgstr ": Version %s [kompiliert am %s]" - -#: apps/gsmsmsd.cc:346 -msgid "" -": [-a action][-b baudrate][-C sca][-d device][-f][-h][-I init string]\n" -" [-s spool dir][-t][-v]{sms_type}" -msgstr "" -": [-a Aktion][-b Baud-Rate][-C sca][-d Gert][-f][-h][-I Init String]\n" -" [-s Spoolverzeichnis][-t][-v]{SMS-Typ}" - -#: apps/gsmsmsd.cc:350 -msgid "" -" -a, --action the action to execute when an SMS arrives\n" -" (SMS is send to stdin of action)" -msgstr "" -" -a, --action die auszufhrende Aktion, wenn eine SMS eintrifft\n" -" (Kurznachricht wird zur Standardeingabe der Aktion\n" -" geschrieben)" - -#: apps/gsmsmsd.cc:354 apps/gsmsendsms.cc:153 apps/gsmpb.cc:322 -#: apps/gsmctl.cc:389 apps/gsmsmsstore.cc:194 -msgid " -b, --baudrate baudrate to use for device (default: 38400)" -msgstr "" -" -b, --baudrate fr das Gert zu verwendende Baud-Rate\n" -" (Voreinstellung: 38400)" - -#: apps/gsmsmsd.cc:357 -msgid " -c, --concatenate start ID for concatenated SMS messages" -msgstr " -c, --concatenate Start-ID fr verbundene SMS-Nachrichten" - -#: apps/gsmsmsd.cc:359 apps/gsmsendsms.cc:158 apps/gsmsmsstore.cc:200 -msgid " -C, --sca SMS service centre address" -msgstr " -C, --sca SMS service centre address" - -#: apps/gsmsmsd.cc:360 -msgid " -d, --device sets the device to connect to" -msgstr " -d, --device stellt das Ziel-Gert ein" - -#: apps/gsmsmsd.cc:361 -msgid " -D, --direct enable direct routing of SMSs" -msgstr "" -" -D, --direct direkte Weiterleitung von SMSs ohne Zwischenspeicherung" - -#: apps/gsmsmsd.cc:362 -msgid " -f, --flush flush SMS from store" -msgstr " -f, --flush lsche und bearbeite SMS im Speicher" - -#: apps/gsmsmsd.cc:363 apps/gsmsendsms.cc:161 apps/gsmpb.cc:332 -#: apps/gsmctl.cc:394 apps/gsmsmsstore.cc:204 -msgid " -h, --help prints this message" -msgstr " -h, --help gibt diesen Hilfetext aus" - -#: apps/gsmsmsd.cc:364 apps/gsmsendsms.cc:162 apps/gsmpb.cc:335 -#: apps/gsmctl.cc:395 apps/gsmsmsstore.cc:205 -msgid " -I, --init device AT init sequence" -msgstr " -I, --init AT-Initialisierungssequenz" - -#: apps/gsmsmsd.cc:365 apps/gsmsendsms.cc:163 -msgid " -r, --requeststat request SMS status report" -msgstr " -r, --requeststat fordert SMS-Statusreport an" - -#: apps/gsmsmsd.cc:366 -msgid " -s, --spool spool directory for outgoing SMS" -msgstr " -s, --spool Spool-Verzeichnis fr zu sendende SMS" - -#: apps/gsmsmsd.cc:368 -msgid "" -" -t, --store name of SMS store to use for flush\n" -" and/or temporary SMS storage" -msgstr "" -" -t, --store gibt den zu verwendenden SMS-Speicher an (fr flush-\n" -" Option und/oder temporren SMS-Speicher)" - -#: apps/gsmsmsd.cc:371 apps/gsmsendsms.cc:167 apps/gsmpb.cc:343 -#: apps/gsmctl.cc:399 apps/gsmsmsstore.cc:213 -msgid " -v, --version prints version and exits" -msgstr " -v, --version gibt Versionsnummer aus und terminiert" - -#: apps/gsmsmsd.cc:372 apps/gsmsendsms.cc:169 apps/gsmpb.cc:346 -#: apps/gsmctl.cc:400 apps/gsmsmsstore.cc:218 -msgid " -X, --xonxoff switch on software handshake" -msgstr " -X, --xonxoff Software Handshake anschalten" - -#: apps/gsmsmsd.cc:374 -msgid " sms_type may be any combination of" -msgstr " SMS-Typ kann aus den folgenden Parametern kombiniert werden:" - -#: apps/gsmsmsd.cc:375 -msgid " sms, no_sms controls reception of normal SMS" -msgstr " sms, no_sms schaltet Empfang von normalen SMS an bzw. aus" - -#: apps/gsmsmsd.cc:377 -msgid " cb, no_cb controls reception of cell broadcast messages" -msgstr "" -" cb, no_cb schaltet Empfang von Zellen-weiten Nachrichten an bzw. " -"aus" - -#: apps/gsmsmsd.cc:379 -msgid " stat, no_stat controls reception of status reports" -msgstr " stat, no_stat schaltet Empfang von Status-Reports an bzw. aus" - -#: apps/gsmsmsd.cc:381 -msgid " default is \"sms cb stat\"" -msgstr " Die Voreinstellung ist \"sms cb stat\"." - -#: apps/gsmsmsd.cc:382 -msgid "If no action is given, the SMS is printed to stdout" -msgstr "" -"Wenn keine Aktion angegeben ist, wird die SMS auf der Standardausgabe\n" -"angezeigt." - -#: apps/gsmsmsd.cc:387 apps/gsmsendsms.cc:178 apps/gsmpb.cc:354 -#: apps/gsmctl.cc:414 apps/gsmsmsstore.cc:223 -msgid "unknown option" -msgstr "unbekannte Option" - -# , c-format -#: apps/gsmsmsd.cc:426 -#, c-format -msgid "error when calling sigaction() (errno: %d/%s)" -msgstr "Fehler beim Aufruf von sigaction() (errno: %d/%s)" - -#: apps/gsmsmsd.cc:446 -msgid "store name must be given for flush option" -msgstr "Speichername mu angegeben werden fr flush-Option" - -#. process the new message -#: apps/gsmsmsd.cc:454 apps/gsmsmsd.cc:522 -msgid "Type of message: " -msgstr "Typ der Nachricht: " - -#: apps/gsmsmsd.cc:458 apps/gsmsmsd.cc:526 -msgid "SMS message\n" -msgstr "SMS Nachricht\n" - -#: apps/gsmsmsd.cc:461 -msgid "submit report message\n" -msgstr "Submit-Report-Nachricht\n" - -#: apps/gsmsmsd.cc:464 apps/gsmsmsd.cc:532 -msgid "status report message\n" -msgstr "Status-Report-Nachricht\n" - -#: apps/gsmsmsd.cc:529 -msgid "cell broadcast message\n" -msgstr "Zellen-weite Nachricht\n" - -#: apps/gsmsmsd.cc:585 apps/gsmsmsd.cc:587 apps/gsmsendsms.cc:253 -#: apps/gsmpb.cc:503 apps/gsmctl.cc:631 apps/gsmsmsstore.cc:435 -msgid "[ERROR]: " -msgstr "[FEHLER]: " - -#: apps/gsmsmsd.cc:588 -msgid "(try setting sms_type, please refer to gsmsmsd manpage)" -msgstr "" -"(versuchen Sie, den sms_type zu setzen; siehe auch gsmsmsd Manual-Seite)" - -#: apps/gsmsendsms.cc:149 -msgid "" -": [-b baudrate][-c concatenatedID][-C sca][-d device][-h][-I init string]\n" -" [-t][-v][-X] phonenumber [text]" -msgstr "" -": [-b Baud-Rate][-c concatenatedID][-C sca][-d Gert][-h][-I Init String]\n" -" [-t][-v][-X] Telefonnummer [Text]" - -#: apps/gsmsendsms.cc:156 -msgid " -c, --concatenate ID for concatenated SMS messages" -msgstr " -c, --concatenate ID fr verbundene SMS-Nachrichten" - -#: apps/gsmsendsms.cc:159 apps/gsmctl.cc:392 -msgid " -d, --device sets the destination device to connect to" -msgstr " -d, --device stellt das Ziel-Gert ein" - -#: apps/gsmsendsms.cc:164 -msgid "" -" -t, --test convert text to GSM alphabet and vice\n" -" versa, no SMS message is sent" -msgstr "" -" -t, --test konvertiert den Text in das GSM-Alphabet und\n" -" wieder zurck. Es wird keine SMS-Nachricht versendet." - -#: apps/gsmsendsms.cc:171 -msgid " phonenumber recipient's phone number" -msgstr " Telefonummer die Telefonnummer des Empfngers" - -#: apps/gsmsendsms.cc:172 -msgid "" -" text optional text of the SMS message\n" -" if omitted: read from stdin" -msgstr "" -" text Text der SMS-Nachricht (optional),\n" -" wenn nicht angegeben: lese von der Standardeingabe" - -#: apps/gsmsendsms.cc:205 -msgid "phone number and text missing" -msgstr "weder Telefonnummer noch Text angegeben" - -#: apps/gsmsendsms.cc:208 apps/gsmsmsstore.cc:261 -msgid "more than two parameters given" -msgstr "mehr als zwei Parameter angegeben" - -#: apps/gsmsendsms.cc:224 -msgid "text is larger than 160 characters" -msgstr "der Text ist lnger als 160 Zeichen" - -# , c-format -#: apps/gsmpb.cc:102 apps/gsmpb.cc:491 -#, c-format -msgid "inserting '%s' tel# %s" -msgstr "fge ein '%s' Tel# %s" - -# , c-format -#: apps/gsmpb.cc:105 apps/gsmpb.cc:230 apps/gsmpb.cc:494 -#, c-format -msgid " (index #%d)" -msgstr " (Index #%d)" - -# , c-format -#: apps/gsmpb.cc:144 -#, c-format -msgid "updating '%s' tel# %s to new tel# %s" -msgstr "berschreibe '%s' Tel# %s mit neuer Tel# %s" - -# , c-format -#: apps/gsmpb.cc:177 -#, c-format -msgid "updating '%s' tel# %s to new tel# %s(index %d)" -msgstr "berschreibe '%s' Tel# %s mit neuer Tel# %s (Index %d)" - -# , c-format -#: apps/gsmpb.cc:227 -#, c-format -msgid "deleting '%s' tel# %s" -msgstr "lsche '%s' Tel# %s" - -#: apps/gsmpb.cc:316 -msgid "" -": [-b baudrate][-c][-d device or file][-h][-I init string]\n" -" [-p phonebook name][-s device or file][-t charset][-v][-V][-y][-X]" -msgstr "" -": [-b Baud-Rate][-c][-d Gert oder Datei][-h][-I Init String]\n" -" [-p Telefonbuchname][-s Gert oder Datei][-t Zeichensatz][-v][-V][-y][-X]" - -#: apps/gsmpb.cc:325 -msgid " -c, --copy copy source entries to destination" -msgstr " -c, --copy kopiere Quell-Eintrge zum Zielgert/-datei" - -#: apps/gsmpb.cc:327 -msgid "" -" -d, --destination sets the destination device to connect \n" -" to, or the file to write" -msgstr " -d, --destination setzt das Zielgert bzw. die Zieldatei" - -#: apps/gsmpb.cc:330 -msgid " -D, --destination-backend sets the destination backend" -msgstr " -D, --destination-backend stellt den Typ des Ziel-Backends ein" - -#: apps/gsmpb.cc:333 -msgid " -i, --index takes index positions into account" -msgstr " -i, --index bercksichtige die Indexpositionen der Eintrge" - -#: apps/gsmpb.cc:336 -msgid " -p, --phonebook name of phonebook to use" -msgstr " -p, --phonebook Name des zu verwendenden Telefonbuchs" - -#: apps/gsmpb.cc:337 apps/gsmsmsstore.cc:210 -msgid "" -" -s, --source sets the source device to connect to,\n" -" or the file to read" -msgstr " -s, --source setzt das Quellgert bzw. die Quelldatei" - -#: apps/gsmpb.cc:339 -msgid "" -" -t, --charset sets the character set to use for\n" -" phonebook entries" -msgstr " -t, --charset setzt den Zeichensatz fr Telefonbucheintrge" - -#: apps/gsmpb.cc:341 -msgid " -S, --source-backend sets the source backend" -msgstr " -S, --source-backend stellt den Typ des Ziel-Backends ein" - -#: apps/gsmpb.cc:344 apps/gsmsmsstore.cc:214 -msgid " -V, --verbose print detailed progress messages" -msgstr " -V, --verbose gibt detaillierte Fortschrittsmeldungen aus" - -#: apps/gsmpb.cc:347 -msgid "" -" -y, --synchronize synchronize destination with source\n" -" entries (destination is overwritten)\n" -" (see gsmpb(1) for details)" -msgstr "" -" -y, --synchronize synchronisiere das Zielgert/-datei mit der Quelle\n" -" (Zieleintrge werden eventuell berschrieben)\n" -" (siehe gsmpb(1) fr weitere Details)" - -#: apps/gsmpb.cc:360 -msgid "both source and destination must be given" -msgstr "sowohl Quellgert/-datei als auch Zielgert/-datei erforderlich" - -#: apps/gsmpb.cc:374 apps/gsmpb.cc:416 -msgid "phonebook name must be given" -msgstr "ein Telefonbuchname mu angegeben werden" - -# , c-format -#: apps/gsmpb.cc:441 -#, c-format -msgid "" -"text '%s' is too large to fit into destination (maximum size %d characters)" -msgstr "" -"Text '%s' ist zu gro fr das Zielgert (maximale Textlnge %d Zeichen)" - -# , c-format -#: apps/gsmpb.cc:447 -#, c-format -msgid "" -"phone number '%s' is too large to fit into destination (maximum size %d " -"characters)" -msgstr "" -"Telefonnummer '%s' ist zu gro fr das Zielgert (maximale Lnge %d Zeichen)" - -#: apps/gsmctl.cc:90 -msgid "active " -msgstr "aktiv" - -#: apps/gsmctl.cc:90 -msgid "inactive " -msgstr "inaktiv" - -#: apps/gsmctl.cc:91 -msgid "number: " -msgstr "Telefonnummer: " - -#: apps/gsmctl.cc:92 -msgid " subaddr: " -msgstr " Unteradresse: " - -#: apps/gsmctl.cc:93 -msgid " time: " -msgstr " Zeit: " - -#: apps/gsmctl.cc:105 -msgid " Manufacturer: " -msgstr " Hersteller: " - -#: apps/gsmctl.cc:106 -msgid " Model: " -msgstr " Modell: " - -#: apps/gsmctl.cc:107 -msgid " Revision: " -msgstr " Revision: " - -#: apps/gsmctl.cc:108 -msgid " Serial Number: " -msgstr " Seriennummer: " - -#: apps/gsmctl.cc:116 apps/gsmctl.cc:118 -msgid " Functionality Level: " -msgstr " Funktionalitts-Level: " - -#: apps/gsmctl.cc:118 -msgid "unsupported" -msgstr "Kommando nicht untersttzt" - -#: apps/gsmctl.cc:128 -msgid "> Status: " -msgstr "> Status: " - -#: apps/gsmctl.cc:131 gsmlib/gsm_error.cc:104 gsmlib/gsm_sms.cc:441 -#: gsmlib/gsm_sms_codec.cc:204 -msgid "unknown" -msgstr "unbekannt" - -#: apps/gsmctl.cc:132 -msgid "current" -msgstr "aktuell" - -#: apps/gsmctl.cc:133 -msgid "available" -msgstr "verfgbar" - -#: apps/gsmctl.cc:134 -msgid "forbidden" -msgstr "nicht whlbar" - -#: apps/gsmctl.cc:136 apps/gsmctl.cc:147 -msgid " Long name: '" -msgstr " Langname: '" - -#: apps/gsmctl.cc:137 apps/gsmctl.cc:148 -msgid " Short name: '" -msgstr " Kurzname: '" - -#: apps/gsmctl.cc:138 apps/gsmctl.cc:149 -msgid " Numeric name: " -msgstr " Numerischer Name: " - -#: apps/gsmctl.cc:150 -msgid " Mode: " -msgstr " Modus: " - -#: apps/gsmctl.cc:153 -msgid "automatic" -msgstr "automatisch" - -#: apps/gsmctl.cc:154 -msgid "manual" -msgstr "manuell" - -#: apps/gsmctl.cc:155 -msgid "deregister" -msgstr "abmelden" - -#: apps/gsmctl.cc:156 -msgid "manual/automatic" -msgstr "manuell/automatisch" - -#: apps/gsmctl.cc:172 apps/gsmctl.cc:247 -msgid " Voice" -msgstr " Sprache" - -#: apps/gsmctl.cc:176 apps/gsmctl.cc:185 apps/gsmctl.cc:194 -msgid " unknown" -msgstr " unbekannt" - -#: apps/gsmctl.cc:181 apps/gsmctl.cc:249 -msgid " Data" -msgstr " Daten" - -#: apps/gsmctl.cc:190 apps/gsmctl.cc:251 -msgid " Fax" -msgstr " Fax" - -#: apps/gsmctl.cc:229 -msgid "on" -msgstr "an" - -#: apps/gsmctl.cc:229 -msgid "off" -msgstr "aus" - -#: apps/gsmctl.cc:239 -msgid "UnconditionalReason" -msgstr "\"Alle Anrufe\"" - -#: apps/gsmctl.cc:240 -msgid "MobileBusyReason" -msgstr "\"Mobiltelefon besetzt\"" - -#: apps/gsmctl.cc:241 -msgid "NoReplyReason" -msgstr "\"Keine Antwort\"" - -#: apps/gsmctl.cc:242 -msgid "NotReachableReason" -msgstr "\"Nicht erreichbar\"" - -#: apps/gsmctl.cc:261 -msgid "0 ME is powered by the battery" -msgstr "0 ME wird von der Batterie gespeist" - -#: apps/gsmctl.cc:262 -msgid "1 ME has a battery connected, but is not powered by it" -msgstr "1 ME-Batterie ist vorhanden, liefert aber keinen Strom" - -#: apps/gsmctl.cc:264 -msgid "2 ME does not have a battery connected" -msgstr "2 ME-Batterie nicht angeschlossen" - -#: apps/gsmctl.cc:266 -msgid "3 Recognized power fault, calls inhibited" -msgstr "3 Problem mit der Energieversorgung, keine Anrufe mglich" - -# , c-format -#: apps/gsmctl.cc:323 -#, c-format -msgid "unknown facility class parameter '%c'" -msgstr "unbekannter Dienstmerkmal-Parameter '%c'" - -# , c-format -#: apps/gsmctl.cc:336 -#, c-format -msgid "not enough parameters, minimum number of parameters is %d" -msgstr "nicht gengend Parameter, die Mindestanzahl der Parameter ist %d" - -# , c-format -#: apps/gsmctl.cc:340 -#, c-format -msgid "too many parameters, maximum number of parameters is %d" -msgstr "zu viele Parameter, die Maximalanzahl der Parameter ist %d" - -#: apps/gsmctl.cc:385 -msgid "" -": [-b baudrate][-d device][-h][-I init string][-o operation]\n" -" [-v][-X]{parameters}" -msgstr "" -": [-b Baud-Rate][-d Gert][-h][-I Init String][-o Operation]\n" -" [-v][-X]{Parameter}" - -#: apps/gsmctl.cc:396 -msgid "" -" -o, --operation operation to perform on the mobile \n" -" phone with the specified parameters" -msgstr "" -" -o, --operation gibt die Operation an, die auf dem Mobiltelefon\n" -" mit den angegebenen Parametern ausgefhrt werden soll" - -#: apps/gsmctl.cc:402 -msgid "" -" parameters parameters to use for the operation\n" -" (if an operation is given) or\n" -" a specification which kind of\n" -" information to read from the mobile phone" -msgstr "" -" Parameter die fr die Operation zu verwendenden Parameter\n" -" (wenn eine Operation ausgefhrt werden soll) oder\n" -" die Spezifikation der vom Mobiltelefon zu lesenden\n" -" Informationen" - -#: apps/gsmctl.cc:408 -msgid "" -"Refer to gsmctl(1) for details on the available parameters and operations." -msgstr "" -"Bitte beziehen Sie sich auf die Manual-Seite gsmctl(1) fr weitere Details\n" -"ber die untersttzten Parameter und Operationen." - -# , c-format -#: apps/gsmctl.cc:471 -#, c-format -msgid "unknown information parameter '%s'" -msgstr "unbekannter Informations-Parameter '%s'" - -# , c-format -#: apps/gsmctl.cc:520 -#, c-format -msgid "unknown opmode parameter '%s'" -msgstr "Unbekannter (Operations-)Modus-Parameter '%s'" - -# , c-format -#: apps/gsmctl.cc:588 -#, c-format -msgid "unknown forward reason parameter '%s'" -msgstr "unbekannter Weiterleitungsgrund-Parameter '%s'" - -# , c-format -#: apps/gsmctl.cc:604 -#, c-format -msgid "unknown forward mode parameter '%s'" -msgstr "unbekannter Weiterleitungs-Modus-Parameter '%s'" - -# , c-format -#: apps/gsmctl.cc:625 -#, c-format -msgid "unknown operation '%s'" -msgstr "unbekannte Operation '%s'" - -# , c-format -#: apps/gsmsmsstore.cc:91 apps/gsmsmsstore.cc:363 apps/gsmsmsstore.cc:380 -#, c-format -msgid "inserting entry #%d from source into destination" -msgstr "fge Eintrag #%d von Quellgert/-datei in Zielgert/-datei ein" - -# , c-format -#: apps/gsmsmsstore.cc:102 -#, c-format -msgid "incompatible options '%c' and '%c'" -msgstr "inkompatible Optionen '%c' und '%c'" - -#: apps/gsmsmsstore.cc:184 -msgid "" -": [-a][-b baudrate][-c][-C sca][-d device or file]\n" -" [-h][-I init string][-k][-l][-s device or file][-t SMS store name]\n" -" [-v][-V][-x][-X]{indices}|[phonenumber text]" -msgstr "" -": [-a][-b Baud-Rate][-c][-C sca][-d Gert oder Datei]\n" -" [-h][-I Init String][-k][-l][-s Gert oder Datei][-t SMS Speichername]\n" -" [-v][-V][-x][-X]{Indices}|[Telefonnummer Text]" - -#: apps/gsmsmsstore.cc:191 -msgid "" -" -a, --add add new SMS submit message\n" -" (phonenumber and text) to destination" -msgstr "" -" -a, --add fge neue SMS-Submit-Nachricht (Telefonnummer und\n" -" Text) in das Zielgert/-datei ein" - -#: apps/gsmsmsstore.cc:197 -msgid "" -" -c, --copy copy source entries to destination\n" -" (if indices are given, copy only these entries)" -msgstr "" -" -c, --copy kopiere Quell-Eintrge in das Zielgert/-datei\n" -" (wenn Indices angegeben sind, kopiere nur diese Eintrge)" - -#: apps/gsmsmsstore.cc:201 -msgid "" -" -d, --destination sets the destination device to\n" -" connect to, or the file to write to" -msgstr " -d, --destination setzt das Zielgert bzw. die Zieldatei" - -#: apps/gsmsmsstore.cc:206 -msgid "" -" -k, --backup backup new entries to destination\n" -" (if indices are given, copy only these entries)" -msgstr "" -" -k, --backup sichert alle neuen Eintrge in die Zieldatei/-gert\n" -" (wenn Indices angegeben sind, sichere nur diese Eintrge)" - -#: apps/gsmsmsstore.cc:209 -msgid " -l, --list list source to stdout" -msgstr "" -" -l, --list schreibe Liste der Quelleintrge auf die Standardausgabe" - -#: apps/gsmsmsstore.cc:212 -msgid " -t, --store name of SMS store to use" -msgstr " -t, --store gibt den zu verwendenden SMS-Speicher an" - -#: apps/gsmsmsstore.cc:216 -msgid " -x, --delete delete entries denoted by indices" -msgstr "" -" -x, --delete lsche die durch die Indices spezifizierten Eintrge" - -#: apps/gsmsmsstore.cc:229 -msgid "no operation option given" -msgstr "keine Operations-Option angegeben" - -#: apps/gsmsmsstore.cc:232 -msgid "both source and destination required" -msgstr "sowohl Quellgert/-datei als auch Zielgert/-datei erforderlich" - -#: apps/gsmsmsstore.cc:237 -msgid "destination must not be given" -msgstr "Zielgert/-datei darf nicht angegeben werden" - -#: apps/gsmsmsstore.cc:239 -msgid "source required" -msgstr "Quellgert/-datei erforderlich" - -#: apps/gsmsmsstore.cc:244 -msgid "source must not be given" -msgstr "Quellgert/-datei darf nicht angegeben werden" - -#: apps/gsmsmsstore.cc:246 -msgid "destination required" -msgstr "Zielgert/-datei erforderlich" - -# , c-format -#: apps/gsmsmsstore.cc:254 gsmlib/gsm_util.cc:285 -#, c-format -msgid "expected number, got '%s'" -msgstr "Zahl erwartet, nicht '%s'" - -#: apps/gsmsmsstore.cc:264 -msgid "not enough parameters given" -msgstr "nicht gengend Parameter angegeben" - -#: apps/gsmsmsstore.cc:269 -msgid "unexpected parameters" -msgstr "unerwartete Parameter" - -#: apps/gsmsmsstore.cc:280 apps/gsmsmsstore.cc:317 -msgid "store name must be given" -msgstr "Speichername mu angegeben werden" - -# , c-format -#: apps/gsmsmsstore.cc:344 apps/gsmsmsstore.cc:377 -#, c-format -msgid "no index '%s' in source" -msgstr "kein Index '%s' in der Quelldatei/-gert" - -# , c-format -#: apps/gsmsmsstore.cc:392 -#, c-format -msgid "index #%d" -msgstr "Index #%d" - -#: apps/gsmsmsstore.cc:406 -msgid "inserting new entry into destination" -msgstr "fge neuen Eintrag in das Zielgert/-datei ein" - -# , c-format -#: apps/gsmsmsstore.cc:421 -#, c-format -msgid "deleting entry #%d from destination" -msgstr "lsche Eintrag #%d von Zielgert/-datei" - -# , c-format -#: apps/gsmsmsstore.cc:426 -#, c-format -msgid "no index '%s' in destination" -msgstr "kein Index '%s' in Zielgert/-datei" - -#: gsmlib/gsm_at.cc:66 -msgid "unspecified ME/TA error" -msgstr "unspezifizierter ME/TA-Fehler" - -#: gsmlib/gsm_at.cc:76 -msgid "ME/TA error '" -msgstr "ME/TA-Fehler '" - -# , c-format -#: gsmlib/gsm_at.cc:80 -#, c-format -msgid "(code %s)" -msgstr "(Code %s)" - -#: gsmlib/gsm_at.cc:125 gsmlib/gsm_at.cc:215 gsmlib/gsm_at.cc:344 -msgid "ME/TA error '' (code not known)" -msgstr "ME/TA-Fehler '' (Code nicht bekannt)" - -# , c-format -#: gsmlib/gsm_at.cc:184 gsmlib/gsm_at.cc:365 -#, c-format -msgid "unexpected response '%s' when sending 'AT%s'" -msgstr "unerwartete Antwort '%s' beim Senden von 'AT%s'" - -#: gsmlib/gsm_at.cc:318 -msgid "unexpected character in PDU handshake" -msgstr "unerwartetes Zeichen im PDU-Handshake" - -#: gsmlib/gsm_error.cc:29 -msgid "phone failure" -msgstr "Telefon-Fehler" - -#: gsmlib/gsm_error.cc:32 -msgid "no connection to phone" -msgstr "keine Verbindung zum Telefon" - -#: gsmlib/gsm_error.cc:35 -msgid "phone adaptor link reserved" -msgstr "Telefonadapter-Verbindung reserviert" - -#: gsmlib/gsm_error.cc:38 gsmlib/gsm_error.cc:259 -msgid "operation not allowed" -msgstr "Operation nicht erlaubt" - -#: gsmlib/gsm_error.cc:41 gsmlib/gsm_error.cc:262 -msgid "operation not supported" -msgstr "Operation nicht untersttzt" - -#: gsmlib/gsm_error.cc:44 -msgid "ph SIM PIN required" -msgstr "ph SIM PIN erforderlich" - -#: gsmlib/gsm_error.cc:47 gsmlib/gsm_error.cc:271 -msgid "SIM not inserted" -msgstr "SIM nicht eingesteckt" - -#: gsmlib/gsm_error.cc:50 gsmlib/gsm_error.cc:274 -msgid "SIM PIN required" -msgstr "SIM PIN erforderlich" - -#: gsmlib/gsm_error.cc:53 gsmlib/gsm_error.cc:289 -msgid "SIM PUK required" -msgstr "SIM PUK erforderlich" - -#: gsmlib/gsm_error.cc:56 gsmlib/gsm_error.cc:280 -msgid "SIM failure" -msgstr "SIM-Fehler" - -#: gsmlib/gsm_error.cc:59 gsmlib/gsm_error.cc:283 -msgid "SIM busy" -msgstr "SIM beschftigt" - -#: gsmlib/gsm_error.cc:62 gsmlib/gsm_error.cc:286 -msgid "SIM wrong" -msgstr "falsche SIM" - -#: gsmlib/gsm_error.cc:65 -msgid "incorrect password" -msgstr "falsches Pawort" - -#: gsmlib/gsm_error.cc:68 gsmlib/gsm_error.cc:292 -msgid "SIM PIN2 required" -msgstr "SIM PIN2 erforderlich" - -#: gsmlib/gsm_error.cc:71 gsmlib/gsm_error.cc:295 -msgid "SIM PUK2 required" -msgstr "SIM PUK2 erforderlich" - -#: gsmlib/gsm_error.cc:74 gsmlib/gsm_error.cc:304 -msgid "memory full" -msgstr "Speicher voll" - -#: gsmlib/gsm_error.cc:77 -msgid "invalid index" -msgstr "ungltiger Index" - -#: gsmlib/gsm_error.cc:80 -msgid "not found" -msgstr "nicht gefunden" - -#: gsmlib/gsm_error.cc:83 gsmlib/gsm_error.cc:298 -msgid "memory failure" -msgstr "Speicher-Fehler" - -#: gsmlib/gsm_error.cc:86 -msgid "text string too long" -msgstr "Zeichenkette zu lang" - -#: gsmlib/gsm_error.cc:89 -msgid "invalid characters in text string" -msgstr "ungltige Zeichen in der Zeichenkette" - -#: gsmlib/gsm_error.cc:92 -msgid "dial string too long" -msgstr "zu whlende Telefonnummer zu lang" - -#: gsmlib/gsm_error.cc:95 -msgid "invalid characters in dial string" -msgstr "ungltige Zeichen in zu whlender Telefonnummer" - -#: gsmlib/gsm_error.cc:98 gsmlib/gsm_error.cc:310 -msgid "no network service" -msgstr "kein Netz" - -#: gsmlib/gsm_error.cc:101 gsmlib/gsm_error.cc:313 -msgid "network timeout" -msgstr "Netz-Zeitberschreitung" - -# , c-format -#: gsmlib/gsm_error.cc:107 -#, c-format -msgid "invalid ME error %d" -msgstr "ungltiger ME-Fehler %d" - -#: gsmlib/gsm_error.cc:117 -msgid "Unassigned (unallocated) number" -msgstr "nicht zugewiesene Nummer" - -#: gsmlib/gsm_error.cc:120 -msgid "Operator determined barring" -msgstr "vom Operator geschaltete Sperre" - -#: gsmlib/gsm_error.cc:123 -msgid "Call barred" -msgstr "Rufsperre" - -#: gsmlib/gsm_error.cc:126 -msgid "Network failure" -msgstr "Netz-Fehler" - -#: gsmlib/gsm_error.cc:129 -msgid "Short message transfer rejected" -msgstr "Kurznachrichten-bertragung zurckgewiesen" - -#: gsmlib/gsm_error.cc:133 gsmlib/gsm_error.cc:355 -msgid "Congestion" -msgstr "Netzberlastung" - -#: gsmlib/gsm_error.cc:136 -msgid "Destination out of service" -msgstr "Ziel auer Betrieb" - -#: gsmlib/gsm_error.cc:139 -msgid "Unidentified subscriber" -msgstr "unidentifizierter Teilnehmer" - -#: gsmlib/gsm_error.cc:142 -msgid "Facility rejected" -msgstr "Dienstmerkmal zurckgewiesen" - -#: gsmlib/gsm_error.cc:145 -msgid "Unknown subscriber" -msgstr "unbekannter Teilnehmer" - -#: gsmlib/gsm_error.cc:148 -msgid "Network out of order" -msgstr "Netz auer Betrieb" - -#: gsmlib/gsm_error.cc:151 -msgid "Temporary failure" -msgstr "temporrer Fehler" - -#: gsmlib/gsm_error.cc:154 -msgid "Resources unavailable, unspecified" -msgstr "Ressourcen nicht verfgbar, nicht spezifiziert" - -#: gsmlib/gsm_error.cc:157 -msgid "Requested facility not subscribed" -msgstr "angefordertes Dienstmerkmal nicht freigeschaltet" - -#: gsmlib/gsm_error.cc:160 -msgid "Requested facility not implemented" -msgstr "angefordertes Dienstmerkmal nicht implementiert" - -#: gsmlib/gsm_error.cc:163 -msgid "Invalid Transaction Identifier" -msgstr "ungltiger Transaktionsbezeichner" - -#: gsmlib/gsm_error.cc:166 -msgid "Semantically incorrect message" -msgstr "semantisch fehlerhafte Nachricht" - -#: gsmlib/gsm_error.cc:169 -msgid "Invalid mandatory information" -msgstr "ungltige, obligatorische Information" - -#: gsmlib/gsm_error.cc:172 -msgid "Message type non-existent or not implemented" -msgstr "Nachrichtentyp nicht existent bzw. nicht implementiert" - -#: gsmlib/gsm_error.cc:175 -msgid "Message not compatible with short message protocol state" -msgstr "Nachricht nicht vereinbar mit Kurznachrichten-Protokollstatus" - -#: gsmlib/gsm_error.cc:178 -msgid "Information element non-existent or not implemented" -msgstr "Informationselement nicht existent oder nicht implementiert" - -#: gsmlib/gsm_error.cc:181 -msgid "Protocol error, unspecified" -msgstr "Protokollfehler, nicht spezifiziert" - -#: gsmlib/gsm_error.cc:184 -msgid "Interworking, unspecified" -msgstr "Interworking, nicht spezifiziert" - -#: gsmlib/gsm_error.cc:187 -msgid "Telematic interworking not supported" -msgstr "Telematisches Interworking nicht untersttzt" - -#: gsmlib/gsm_error.cc:190 -msgid "Short message Type 0 not supported" -msgstr "Kurznachrichtentyp 0 nicht untersttzt" - -#: gsmlib/gsm_error.cc:193 -msgid "Cannot replace short message" -msgstr "kann Kurznachricht nicht ersetzen" - -#: gsmlib/gsm_error.cc:196 -msgid "Unspecified TP-PID error" -msgstr "unspezifizierter TP-PID-Fehler" - -#: gsmlib/gsm_error.cc:199 -msgid "Data coding scheme (alphabet) not supported" -msgstr "Datenkodierungsschema (Alphabet) nicht untersttzt" - -#: gsmlib/gsm_error.cc:202 -msgid "Message class not supported" -msgstr "Nachrichtenklasse nicht untersttzt" - -#: gsmlib/gsm_error.cc:205 -msgid "Unspecifiec TP-DCS error" -msgstr "unspezifizierter TP-DCS-Fehler" - -#: gsmlib/gsm_error.cc:208 -msgid "Command cannot be actioned" -msgstr "Kommando kann nicht ausgefhrt werden" - -#: gsmlib/gsm_error.cc:211 -msgid "Command unsupported" -msgstr "Kommando nicht untersttzt" - -#: gsmlib/gsm_error.cc:214 -msgid "Unspecified TP-Command error" -msgstr "unspezifizierter TP-Kommando-Fehler" - -#: gsmlib/gsm_error.cc:217 -msgid "TPDU not supported" -msgstr "TPDU nicht untersttzt" - -#: gsmlib/gsm_error.cc:220 -msgid "SC busy" -msgstr "SC besetzt" - -#: gsmlib/gsm_error.cc:223 -msgid "No SC subscription" -msgstr "SC nicht freigeschaltet" - -#: gsmlib/gsm_error.cc:226 -msgid "SC system failure" -msgstr "SC-Systemfehler" - -#: gsmlib/gsm_error.cc:229 -msgid "Invalid SME address" -msgstr "ungltige SME-Adresse" - -#: gsmlib/gsm_error.cc:232 -msgid "Destination SME barred" -msgstr "Ziel-SME gesperrt" - -#: gsmlib/gsm_error.cc:235 -msgid "SM Rejected-Duplicated SM" -msgstr "Kurznachricht zurckgewiesen - doppelte Kurznachricht" - -#: gsmlib/gsm_error.cc:238 -msgid "SIM SMS storage full" -msgstr "SIM-SMS-Speicher voll" - -#: gsmlib/gsm_error.cc:241 -msgid "No SMS storage capability in SIM" -msgstr "Keine SMS-Speicherfhigkeit in SIM" - -#: gsmlib/gsm_error.cc:244 -msgid "Error in MS" -msgstr "Fehler im MS" - -#: gsmlib/gsm_error.cc:247 -msgid "Memory Capacity Exceed" -msgstr "Speicherkapazitt berschritten" - -#: gsmlib/gsm_error.cc:250 -msgid "Unspecified error cause" -msgstr "unspezifizierter Fehlergrund" - -#: gsmlib/gsm_error.cc:253 -msgid "ME failure" -msgstr "ME-Fehler" - -#: gsmlib/gsm_error.cc:256 -msgid "SMS service of ME reserved" -msgstr "SMS-Dienst im ME reserviert" - -#: gsmlib/gsm_error.cc:265 -msgid "invalid PDU mode parameter" -msgstr "ungltiger PDU-Modus-Parameter" - -#: gsmlib/gsm_error.cc:268 -msgid "invalid text mode parameter" -msgstr "ungltiger Text-Modus-Parameter" - -#: gsmlib/gsm_error.cc:277 -msgid "PH-SIM PIN required" -msgstr "PH-SIM PIN erforderlich" - -#: gsmlib/gsm_error.cc:301 -msgid "invalid memory index" -msgstr "ungltiger Speicherindex" - -#: gsmlib/gsm_error.cc:307 -msgid "SMSC address unknown" -msgstr "SMSC-Adresse nicht bekannt" - -#: gsmlib/gsm_error.cc:316 -msgid "no +CNMA acknowledgement expected" -msgstr "keine +CNMA-Besttigung erwartet" - -#: gsmlib/gsm_error.cc:319 -msgid "unknown error" -msgstr "unbekannter Fehler" - -# , c-format -#: gsmlib/gsm_error.cc:322 -#, c-format -msgid "invalid SMS error %d" -msgstr "ungltiger SMS-Fehler %d" - -#: gsmlib/gsm_error.cc:335 -msgid "Short message received by the SME" -msgstr "Kurznachricht von der SME empfangen" - -#: gsmlib/gsm_error.cc:338 -msgid "" -"Short message forwarded by the SC to the SME but the SC is unable to confirm " -"delivery" -msgstr "" -"die Kurznachricht wurde vom SC zur SME weitergeleitet, aber das SC ist nicht " -"in der Lage, den Empfang zu besttigen" - -#: gsmlib/gsm_error.cc:342 -msgid "Short message replaced by the SC" -msgstr "Kurznachricht wurde vom SC ersetzt" - -#: gsmlib/gsm_error.cc:345 gsmlib/gsm_error.cc:373 gsmlib/gsm_error.cc:418 -msgid "reserved" -msgstr "reserviert" - -#: gsmlib/gsm_error.cc:358 -msgid "SME busy" -msgstr "SME besetzt" - -#: gsmlib/gsm_error.cc:361 -msgid "No response from SME" -msgstr "keine Antwort vom SME" - -#: gsmlib/gsm_error.cc:364 -msgid "Service rejected" -msgstr "Dienst zurckgewiesen" - -#: gsmlib/gsm_error.cc:367 gsmlib/gsm_error.cc:400 -msgid "Quality of service not available" -msgstr "Dienstqualitt nicht verfgbar" - -#: gsmlib/gsm_error.cc:370 -msgid "Error in SME" -msgstr "Fehler im SME" - -#: gsmlib/gsm_error.cc:377 -msgid " (Temporary error, SC is not making any more transfer attempts)" -msgstr " (temporrer Fehler, SC macht keine weiteren bertragungsversuche)" - -#: gsmlib/gsm_error.cc:380 -msgid " (Temporary error, SC still trying to transfer SM)" -msgstr " (temporrer Fehler, SC versucht weiterhin die SM zu bertragen)" - -#: gsmlib/gsm_error.cc:388 -msgid "Remote Procedure Error" -msgstr "Fern-Prozedur-Aufrufs-Fehler" - -#: gsmlib/gsm_error.cc:391 -msgid "Incompatible destination" -msgstr "inkompatibles Ziel" - -#: gsmlib/gsm_error.cc:394 -msgid "Connection rejected by SME" -msgstr "Verbindung vom SME zurckgewiesen" - -#: gsmlib/gsm_error.cc:397 -msgid "Not obtainable" -msgstr "nicht verfgbar" - -#: gsmlib/gsm_error.cc:403 -msgid "No interworking available" -msgstr "kein Interworking verfgbar" - -#: gsmlib/gsm_error.cc:406 -msgid "SM validity period expired" -msgstr "SM-Gltigkeitszeitraum berschritten" - -#: gsmlib/gsm_error.cc:409 -msgid "SM deleted by originating SME" -msgstr "SM von der sendenden SME gelscht" - -#: gsmlib/gsm_error.cc:412 -msgid "SM deleted by SC administration" -msgstr "SM von der SC-Administration gelscht" - -#: gsmlib/gsm_error.cc:415 -msgid "SM does not exit" -msgstr "SM macht keinen Exit" - -#: gsmlib/gsm_error.cc:421 -msgid " (Permanent Error, SC is not making any more transfer attempts)" -msgstr " (permanenter Fehler, SC macht keine weiteren bertragungsversuche)" - -# , c-format -#: gsmlib/gsm_event.cc:80 -#, c-format -msgid "unexpected number format %d" -msgstr "unerwartetes Telefonnummernformat %d" - -# , c-format -#: gsmlib/gsm_event.cc:100 -#, c-format -msgid "unexpected unsolicited event '%s'" -msgstr "unerwartetes asynchrones Ereignis '%s'" - -#: gsmlib/gsm_me_ta.cc:536 -msgid "unable to set operator" -msgstr "kann den Netzbetreiber nicht setzen" - -#: gsmlib/gsm_me_ta.cc:663 -msgid "call forward time must be in the range 0..30" -msgstr "Rufumleitungszeit muss im Bereich 0..30 sein" - -#: gsmlib/gsm_me_ta.cc:811 -msgid "Functionality Level commands not supported by ME" -msgstr "" -"Funktionalitts-Level-Kommandos werden vom Gert (ME) nicht untersttzt" - -#. If the number was just out of range, we get here. -#: gsmlib/gsm_me_ta.cc:830 -msgid "Requested Functionality Level out of range" -msgstr "Angeforderter Funktionalitts-Level auerhalb des erlaubten Bereichs" - -#: gsmlib/gsm_me_ta.cc:941 -msgid "unsupported alphabet for SMS" -msgstr "nicht untersttztes Alphabet fr SMS" - -#: gsmlib/gsm_me_ta.cc:950 -msgid "SMS text is larger than allowed" -msgstr "SMS-Text ist lnger als erlaubt" - -#: gsmlib/gsm_me_ta.cc:962 -msgid "not more than 255 concatenated SMSs allowed" -msgstr "nicht mehr als 255 verbundene SMSs erlaubt" - -#: gsmlib/gsm_me_ta.cc:995 -msgid "only serviceLevel 0 or 1 supported" -msgstr "nur Dienst-Level 0 oder 1 untersttzt" - -#: gsmlib/gsm_me_ta.cc:1108 gsmlib/gsm_me_ta.cc:1150 -msgid "cannot route SMS messages to TE" -msgstr "kann keine Kurznachrichten zum TE weiterleiten" - -#: gsmlib/gsm_me_ta.cc:1122 gsmlib/gsm_me_ta.cc:1164 -msgid "cannot route cell broadcast messages to TE" -msgstr "kann keine Zellen-weiten Nachrichten zum TE weiterleiten" - -#: gsmlib/gsm_me_ta.cc:1134 -msgid "cannot route status reports messages to TE" -msgstr "kann keine Status-Report-Nachrichten zum TE weiterleiten" - -#: gsmlib/gsm_me_ta.cc:1178 -msgid "cannot route status report messages to TE" -msgstr "kann keine Status-Report-Nachrichten zum TE weiterleiten" - -#: gsmlib/gsm_parser.cc:51 -msgid "expected parameter" -msgstr "Parameter erwartet" - -#: gsmlib/gsm_parser.cc:71 -msgid "expected '\"'" -msgstr "'\"' erwartet" - -#: gsmlib/gsm_parser.cc:109 -msgid "expected number" -msgstr "Zahl erwartet" - -# , c-format -#: gsmlib/gsm_parser.cc:120 -#, c-format -msgid "unexpected end of string '%s'" -msgstr "unerwartetes Ende der Zeichenkette '%s'" - -# , c-format -#: gsmlib/gsm_parser.cc:124 -#, c-format -msgid " (at position %d of string '%s')" -msgstr " (an Position %d der Zeichenkette '%s')" - -# , c-format -#: gsmlib/gsm_parser.cc:141 -#, c-format -msgid "expected '%c'" -msgstr "'%c' erwartet" - -#: gsmlib/gsm_parser.cc:165 -msgid "expected ')' or ','" -msgstr "')' oder ',' erwartet" - -#: gsmlib/gsm_parser.cc:251 -msgid "expected ')', ',' or '-'" -msgstr "')', ',' oder '-' erwartet" - -#: gsmlib/gsm_parser.cc:257 -msgid "range of the form a-b-c not allowed" -msgstr "Bereich der Form a-b-c nicht erlaubt" - -#: gsmlib/gsm_parser.cc:264 -msgid "range of the form a- no allowed" -msgstr "Bereich der Form a- nicht erlaubt" - -#: gsmlib/gsm_parser.cc:350 -msgid "expected comma" -msgstr "Komma erwartet" - -#: gsmlib/gsm_parser.cc:367 -msgid "expected end of line" -msgstr "Zeilenende erwartet" - -# , c-format -#: gsmlib/gsm_phonebook.cc:47 -#, c-format -msgid "" -"length of text '%s' exceeds maximum text length (%d characters) of phonebook " -"'%s'" -msgstr "" -"die Lnge des Texts '%s' berschreitet die maximale Textlnge (%d Zeichen) " -"des Telefonbuchs '%s'" - -# , c-format -#: gsmlib/gsm_phonebook.cc:55 -#, c-format -msgid "" -"length of telephone number '%s' exceeds maximum telephone number length (%d " -"characters) of phonebook '%s'" -msgstr "" -"die Lnge der Telefonnummer '%s' berschreitet die maximale " -"Telefonnummernlnge (%d Zeichen) des Telefonbuchs '%s'" - -#: gsmlib/gsm_phonebook.cc:275 -msgid "phonebook full" -msgstr "Telefonbuch voll" - -#: gsmlib/gsm_phonebook.cc:291 -msgid "attempt to overwrite phonebook entry" -msgstr "Versuch, einen Telefonbucheintrag zu berschreiben" - -#: gsmlib/gsm_phonebook.cc:569 -msgid "SIM card changed while accessing phonebook" -msgstr "SIM-Karte wurde gewechselt beim Zugriff auf Telefonbuch" - -#: gsmlib/gsm_sms.cc:66 gsmlib/gsm_sms.cc:85 gsmlib/gsm_sms.cc:175 -msgid "unhandled SMS TPDU type" -msgstr "unerwarteter SMS TPDU-Typ" - -#: gsmlib/gsm_sms.cc:107 -msgid "can only send SMS-SUBMIT and SMS-COMMAND TPDUs" -msgstr "kann nur SMS-SUBMIT und SMS-COMMAND TPDUs senden" - -#: gsmlib/gsm_sms.cc:111 -msgid "no device given for sending SMS" -msgstr "kein Gert zum Versenden von SMS angegeben" - -#: gsmlib/gsm_sms.cc:283 -msgid "Message type: SMS-DELIVER" -msgstr "Nachrichtentyp: SMS-DELIVER" - -#: gsmlib/gsm_sms.cc:284 gsmlib/gsm_sms.cc:426 gsmlib/gsm_sms.cc:531 -#: gsmlib/gsm_sms.cc:618 gsmlib/gsm_sms.cc:723 gsmlib/gsm_sms.cc:829 -msgid "SC address: '" -msgstr "SC-Adresse: '" - -#: gsmlib/gsm_sms.cc:285 gsmlib/gsm_sms.cc:532 -msgid "More messages to send: " -msgstr "Mehr Nachrichten zu versenden: " - -#: gsmlib/gsm_sms.cc:286 gsmlib/gsm_sms.cc:445 -msgid "Reply path: " -msgstr "Antwortpfad: " - -#: gsmlib/gsm_sms.cc:287 gsmlib/gsm_sms.cc:446 -msgid "User data header indicator: " -msgstr "Benutzerdatenvorspann (Indikation): " - -#: gsmlib/gsm_sms.cc:289 -msgid "Status report indication: " -msgstr "Status-Report-Indikation: " - -#: gsmlib/gsm_sms.cc:290 -msgid "Originating address: '" -msgstr "Senderadresse: '" - -#: gsmlib/gsm_sms.cc:292 gsmlib/gsm_sms.cc:452 gsmlib/gsm_sms.cc:621 -#: gsmlib/gsm_sms.cc:729 gsmlib/gsm_sms.cc:836 -msgid "Protocol identifier: 0x" -msgstr "Protokollbezeichner: 0x" - -#: gsmlib/gsm_sms.cc:294 gsmlib/gsm_sms.cc:454 gsmlib/gsm_sms.cc:733 -#: gsmlib/gsm_sms.cc:840 -msgid "Data coding scheme: " -msgstr "Datenkodierungsschema: " - -#: gsmlib/gsm_sms.cc:295 gsmlib/gsm_sms.cc:536 gsmlib/gsm_sms.cc:830 -msgid "SC timestamp: " -msgstr "SC-Zeitstempel: " - -#: gsmlib/gsm_sms.cc:296 gsmlib/gsm_sms.cc:456 gsmlib/gsm_sms.cc:735 -#: gsmlib/gsm_sms.cc:842 -msgid "User data length: " -msgstr "Benutzerdatenlnge: " - -#: gsmlib/gsm_sms.cc:297 gsmlib/gsm_sms.cc:457 -msgid "User data header: 0x" -msgstr "Benutzerdatenvorspann: 0x" - -#: gsmlib/gsm_sms.cc:302 gsmlib/gsm_sms.cc:461 gsmlib/gsm_sms.cc:736 -#: gsmlib/gsm_sms.cc:843 -msgid "User data: '" -msgstr "Benutzerdaten: '" - -#: gsmlib/gsm_sms.cc:425 -msgid "Message type: SMS-SUBMIT" -msgstr "Nachrichtentyp: SMS-SUBMIT" - -#: gsmlib/gsm_sms.cc:427 -msgid "Reject duplicates: " -msgstr "Duplikate zurckweisen: " - -#: gsmlib/gsm_sms.cc:428 -msgid "Validity period format: " -msgstr "Gltigkeitszeitraum-Format: " - -#: gsmlib/gsm_sms.cc:432 gsmlib/gsm_sms_codec.cc:183 -msgid "not present" -msgstr "nicht vorhanden" - -#: gsmlib/gsm_sms.cc:435 -msgid "relative" -msgstr "relativ" - -#: gsmlib/gsm_sms.cc:438 -msgid "absolute" -msgstr "absolut" - -#: gsmlib/gsm_sms.cc:448 gsmlib/gsm_sms.cc:620 -msgid "Status report request: " -msgstr "Status-Report-Anforderung: " - -#: gsmlib/gsm_sms.cc:449 gsmlib/gsm_sms.cc:534 gsmlib/gsm_sms.cc:619 -msgid "Message reference: " -msgstr "Nachrichtenreferenz: " - -#: gsmlib/gsm_sms.cc:450 gsmlib/gsm_sms.cc:626 -msgid "Destination address: '" -msgstr "Zieladresse: '" - -#: gsmlib/gsm_sms.cc:455 -msgid "Validity period: " -msgstr "Gltigkeitszeitraum: " - -#: gsmlib/gsm_sms.cc:530 -msgid "Message type: SMS-STATUS-REPORT" -msgstr "Nachrichtentyp: SMS-STATUS-REPORT" - -#: gsmlib/gsm_sms.cc:533 -msgid "Status report qualifier: " -msgstr "Status-Report-Attribut: " - -#: gsmlib/gsm_sms.cc:535 -msgid "Recipient address: '" -msgstr "Empfngeradresse: '" - -#: gsmlib/gsm_sms.cc:537 -msgid "Discharge time: " -msgstr "Aussendezeit: " - -#: gsmlib/gsm_sms.cc:538 -msgid "Status: 0x" -msgstr "Status: 0x" - -#: gsmlib/gsm_sms.cc:617 -msgid "Message type: SMS-COMMAND" -msgstr "Nachrichtentyp: SMS-COMMAND" - -#: gsmlib/gsm_sms.cc:623 -msgid "Command type: 0x" -msgstr "Kommandotyp: 0x" - -#: gsmlib/gsm_sms.cc:625 -msgid "Message number: " -msgstr "Nachrichtennummer: " - -#: gsmlib/gsm_sms.cc:628 -msgid "Command data length: " -msgstr "Kommandodatenlnge: " - -#: gsmlib/gsm_sms.cc:629 -msgid "Command data: '" -msgstr "Kommandodaten: '" - -#: gsmlib/gsm_sms.cc:722 -msgid "Message type: SMS-DELIVER-REPORT" -msgstr "Nachrichtentyp: SMS-DELIVER-REPORT" - -#: gsmlib/gsm_sms.cc:724 gsmlib/gsm_sms.cc:831 -msgid "Protocol identifier present: " -msgstr "Protokollbezeichner prsent: " - -#: gsmlib/gsm_sms.cc:726 gsmlib/gsm_sms.cc:833 -msgid "Data coding scheme present: " -msgstr "Datenkodierungsschema prsent: " - -#: gsmlib/gsm_sms.cc:727 gsmlib/gsm_sms.cc:834 -msgid "User data length present: " -msgstr "Benutzerdatenlnge prsent: " - -#: gsmlib/gsm_sms.cc:828 -msgid "Message type: SMS-SUBMIT-REPORT" -msgstr "Nachrichtentyp: SMS-SUBMIT-REPORT" - -#: gsmlib/gsm_sms_codec.cc:188 gsmlib/gsm_sms_codec.cc:190 -msgid " minutes" -msgstr " Minuten" - -#: gsmlib/gsm_sms_codec.cc:192 -msgid " days" -msgstr " Tage" - -#: gsmlib/gsm_sms_codec.cc:194 -msgid " weeks" -msgstr " Wochen" - -#: gsmlib/gsm_sms_codec.cc:213 -msgid "compressed " -msgstr "komprimiert " - -#: gsmlib/gsm_sms_codec.cc:218 -msgid "voicemail message waiting" -msgstr "Sprachnachricht abrufbar" - -#: gsmlib/gsm_sms_codec.cc:221 -msgid "fax message waiting" -msgstr "Faxnachricht abrufbar" - -#: gsmlib/gsm_sms_codec.cc:224 -msgid "electronic mail message waiting" -msgstr "E-Mail-Nachricht abrufbar" - -#: gsmlib/gsm_sms_codec.cc:227 -msgid "other message waiting" -msgstr "andere Nachricht abrufbar" - -#: gsmlib/gsm_sms_codec.cc:234 -msgid "default alphabet" -msgstr "Standardalphabet" - -#: gsmlib/gsm_sms_codec.cc:237 -msgid "8-bit alphabet" -msgstr "8-Bit Alphabet" - -#: gsmlib/gsm_sms_codec.cc:240 -msgid "16-bit alphabet" -msgstr "16-bit Alphabet" - -#: gsmlib/gsm_sms_codec.cc:243 -msgid "reserved alphabet" -msgstr "reserviertes Alphabet" - -#: gsmlib/gsm_sms_codec.cc:256 -msgid "bad hexadecimal PDU format" -msgstr "fehlerhaftes hexadezimales PDU-Format" - -#: gsmlib/gsm_sms_codec.cc:285 gsmlib/gsm_sms_codec.cc:295 -#: gsmlib/gsm_sms_codec.cc:310 gsmlib/gsm_sms_codec.cc:318 -#: gsmlib/gsm_sms_codec.cc:339 gsmlib/gsm_sms_codec.cc:347 -#: gsmlib/gsm_sms_codec.cc:368 gsmlib/gsm_sms_codec.cc:382 -msgid "premature end of PDU" -msgstr "Vorzeitiges Ende der PDU" - -#: gsmlib/gsm_sms_codec.cc:473 -msgid "unknown time period format" -msgstr "Unbekanntes Zeitperiodenformat" - -#: gsmlib/gsm_unix_serial.cc:119 -msgid "interrupted when reading from TA" -msgstr "Unterbrechung beim Lesen vom TA" - -#: gsmlib/gsm_unix_serial.cc:144 -msgid "reading from TA" -msgstr "beim Lesen vom TA" - -#: gsmlib/gsm_unix_serial.cc:149 -msgid "timeout when reading from TA" -msgstr "Zeitberschreitung beim Lesen vom TA" - -# , c-format -#: gsmlib/gsm_unix_serial.cc:176 -#, c-format -msgid "opening device '%s'" -msgstr "beim ffnen von Gert '%s'" - -#: gsmlib/gsm_unix_serial.cc:182 -msgid "getting file status flags failed" -msgstr "Lesen der Dateistatus-Flags fehlgeschlagen" - -#: gsmlib/gsm_unix_serial.cc:185 -msgid "switching of non-blocking mode failed" -msgstr "Abschalten des Non-Blocking Mode fehlgeschlagen" - -#: gsmlib/gsm_unix_serial.cc:198 -msgid "clearing DTR failed" -msgstr "Zurcksetzen von DTR fehlgeschlagen" - -#: gsmlib/gsm_unix_serial.cc:202 -msgid "setting DTR failed" -msgstr "Setzen von DTR fehlgeschlagen" - -# , c-format -#: gsmlib/gsm_unix_serial.cc:206 -#, c-format -msgid "tcgetattr device '%s'" -msgstr "tcgetattr Gert '%s'" - -# , c-format -#: gsmlib/gsm_unix_serial.cc:233 -#, c-format -msgid "tcsetattr device '%s'" -msgstr "tcsetattr Gert '%s'" - -# , c-format -#. no response after 3 tries -#: gsmlib/gsm_unix_serial.cc:287 -#, c-format -msgid "reset modem failed '%s'" -msgstr "Zurcksetzen des Modems '%s' fehlgeschlagen" - -#: gsmlib/gsm_unix_serial.cc:332 gsmlib/gsm_unix_serial.cc:364 -msgid "interrupted when writing to TA" -msgstr "Unterbrechnung beim Schreiben auf den TA" - -#: gsmlib/gsm_unix_serial.cc:347 gsmlib/gsm_unix_serial.cc:356 -msgid "writing to TA" -msgstr "beim Schreiben auf den TA" - -#: gsmlib/gsm_unix_serial.cc:377 -msgid "timeout when writing to TA" -msgstr "Zeitberschreitung beim Schreiben auf den TA" - -# , c-format -#: gsmlib/gsm_unix_serial.cc:438 -#, c-format -msgid "unknown baudrate '%s'" -msgstr "unbekannte Baud-Rate '%s'" - -# , c-format -#: gsmlib/gsm_util.cc:205 -#, c-format -msgid "error when calling stat('%s') (errno: %d/%s)" -msgstr "Fehler beim Aufruf von stat('%s') (errno: %d/%s)" - -# , c-format -#: gsmlib/gsm_util.cc:236 -#, c-format -msgid "file '%s' is neither file nor character device" -msgstr "Datei '%s' ist weder eine regulre Datei noch einen Zeichengert" - -#: gsmlib/gsm_util.cc:240 -msgid "maxmimum number of symbolic links exceeded" -msgstr "maximale Anzahl der symbolischen Links berschritten" - -# , c-format -#: gsmlib/gsm_util.cc:250 -#, c-format -msgid "error renaming '%s' to '%s'" -msgstr "Fehler beim Umbenennen von '%s' zu '%s'" - -# , c-format -#: gsmlib/gsm_util.cc:348 -#, c-format -msgid "text '%s' contains illegal character '\"'" -msgstr "der Text '%s' enthlt das illegale Zeichen '\"'" - -# , c-format -#: gsmlib/gsm_util.cc:358 -#, c-format -msgid "illegal character in telephone number '%s'" -msgstr "ungltiges Zeichen in der Telefonnummer '%s'" - -# , c-format -#: gsmlib/gsm_sorted_phonebook.cc:95 -#, c-format -msgid "error reading from file '%s" -msgstr "Fehler beim Lesen von Datei '%s'" - -# , c-format -#: gsmlib/gsm_sorted_phonebook.cc:109 -#, c-format -msgid "entry '%s' lacks index" -msgstr "Eintrag '%s' hat keinen Index" - -# , c-format -#: gsmlib/gsm_sorted_phonebook.cc:118 gsmlib/gsm_sorted_phonebook.cc:124 -#, c-format -msgid "line '%s' has invalid format" -msgstr "Zeile '%s' hat ungltiges Format" - -# , c-format -#: gsmlib/gsm_sorted_phonebook.cc:173 gsmlib/gsm_sorted_sms_store.cc:159 -#, c-format -msgid "error opening file '%s' for writing" -msgstr "Fehler beim ffnen der Datei '%s' zum Schreiben" - -#: gsmlib/gsm_sorted_phonebook.cc:174 gsmlib/gsm_sorted_phonebook.cc:193 -#: gsmlib/gsm_sorted_sms_store.cc:67 gsmlib/gsm_sorted_sms_store.cc:160 -msgid "" -msgstr "" - -# , c-format -#: gsmlib/gsm_sorted_phonebook.cc:192 gsmlib/gsm_sorted_sms_store.cc:66 -#, c-format -msgid "error writing to file '%s'" -msgstr "Fehler beim Schreiben in die Datei '%s'" - -#: gsmlib/gsm_sorted_phonebook.cc:216 -msgid "attempt to change phonebook read from " -msgstr "Versuch, von der Standardeingabe gelesenes Telefonbuch zu verndern" - -# , c-format -#: gsmlib/gsm_sorted_phonebook.cc:229 gsmlib/gsm_sorted_sms_store.cc:215 -#, c-format -msgid "cannot open file '%s'" -msgstr "kann Datei '%s' nicht ffnen" - -#: gsmlib/gsm_sorted_phonebook.cc:244 gsmlib/gsm_sorted_sms_store.cc:55 -#: gsmlib/gsm_sorted_sms_store.cc:228 -msgid "" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:361 -msgid "indices must be unique in phonebook" -msgstr "Indices im Telefonbuch mssen eindeutig sein" - -# , c-format -#: gsmlib/gsm_sorted_sms_store.cc:54 -#, c-format -msgid "error reading from file '%s'" -msgstr "Fehler beim Lesen aus der Datei '%s'" - -# , c-format -#: gsmlib/gsm_sorted_sms_store.cc:87 -#, c-format -msgid "file '%s' has wrong version" -msgstr "Datei '%s' hat die falsche Version" - -# , c-format -#: gsmlib/gsm_sorted_sms_store.cc:99 gsmlib/gsm_sorted_sms_store.cc:111 -#, c-format -msgid "corrupt SMS store file '%s'" -msgstr "beschdigte SMS-Speicherdatei '%s'" - -#: gsmlib/gsm_sorted_sms_store.cc:204 -msgid "attempt to change SMS store read from " -msgstr "" -"Versuch, SMS-Speicher zu verndern, der von der Standardeingabe gelesen wurde" - -#~ msgid "cannot read current network operator" -#~ msgstr "kann den aktuellen Netzbetreiber nicht lesen" - -#~ msgid "Message type: SMS" -#~ msgstr "Nachrichtentyp: SMS" - -#~ msgid "(no further information available)" -#~ msgstr "(keine weitere Information verfgbar)" diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/gsmlib.pot b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/gsmlib.pot deleted file mode 100644 index 1d0385cf4f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/gsmlib.pot +++ /dev/null @@ -1,1689 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-06 14:36+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: apps/gsmsmsd.cc:172 -#, c-format -msgid "could not execute '%s'" -msgstr "" - -#: apps/gsmsmsd.cc:176 -#, c-format -msgid "error writing to '%s'" -msgstr "" - -#: apps/gsmsmsd.cc:197 apps/gsmsmsd.cc:198 apps/gsmsmsd.cc:199 -#, c-format -msgid "%d" -msgstr "" - -#: apps/gsmsmsd.cc:216 -#, c-format -msgid "error when calling opendir('%s')(errno: %d/%s)" -msgstr "" - -#: apps/gsmsmsd.cc:260 -#, c-format -msgid "count not open SMS spool file %s" -msgstr "" - -#: apps/gsmsmsd.cc:439 apps/gsmsendsms.cc:144 apps/gsmpb.cc:311 -#: apps/gsmctl.cc:380 apps/gsmsmsstore.cc:179 -#, c-format -msgid ": version %s [compiled %s]" -msgstr "" - -#: apps/gsmsmsd.cc:444 -msgid "" -": [-a action][-b baudrate][-C sca][-d device][-f][-h][-I init string]\n" -" [-s spool dir][-t][-v]{sms_type}" -msgstr "" - -#: apps/gsmsmsd.cc:448 -msgid "" -" -a, --action the action to execute when an SMS arrives\n" -" (SMS is send to stdin of action)" -msgstr "" - -#: apps/gsmsmsd.cc:452 apps/gsmsendsms.cc:153 apps/gsmpb.cc:322 -#: apps/gsmctl.cc:389 apps/gsmsmsstore.cc:194 -msgid " -b, --baudrate baudrate to use for device (default: 38400)" -msgstr "" - -#: apps/gsmsmsd.cc:455 -msgid " -c, --concatenate start ID for concatenated SMS messages" -msgstr "" - -#: apps/gsmsmsd.cc:457 apps/gsmsendsms.cc:158 apps/gsmsmsstore.cc:200 -msgid " -C, --sca SMS service centre address" -msgstr "" - -#: apps/gsmsmsd.cc:458 -msgid " -d, --device sets the device to connect to" -msgstr "" - -#: apps/gsmsmsd.cc:459 -msgid " -D, --direct enable direct routing of SMSs" -msgstr "" - -#: apps/gsmsmsd.cc:460 -msgid " -f, --flush flush SMS from store" -msgstr "" - -#: apps/gsmsmsd.cc:461 -msgid " -F, --failed directory to move failed SMS to," -msgstr "" - -#: apps/gsmsmsd.cc:462 apps/gsmsmsd.cc:475 -msgid " if unset, the SMS will be deleted" -msgstr "" - -#: apps/gsmsmsd.cc:463 apps/gsmsendsms.cc:161 apps/gsmpb.cc:332 -#: apps/gsmctl.cc:394 apps/gsmsmsstore.cc:204 -msgid " -h, --help prints this message" -msgstr "" - -#: apps/gsmsmsd.cc:464 apps/gsmsendsms.cc:162 apps/gsmpb.cc:335 -#: apps/gsmctl.cc:395 apps/gsmsmsstore.cc:205 -msgid " -I, --init device AT init sequence" -msgstr "" - -#: apps/gsmsmsd.cc:466 -msgid " -L, --syslog log errors and information to syslog" -msgstr "" - -#: apps/gsmsmsd.cc:469 -msgid " -P, --priorities number of priority levels to use," -msgstr "" - -#: apps/gsmsmsd.cc:470 -msgid " (default: none)" -msgstr "" - -#: apps/gsmsmsd.cc:471 apps/gsmsendsms.cc:163 -msgid " -r, --requeststat request SMS status report" -msgstr "" - -#: apps/gsmsmsd.cc:472 -msgid " -s, --spool spool directory for outgoing SMS" -msgstr "" - -#: apps/gsmsmsd.cc:474 -msgid " -S, --sent directory to move sent SMS to," -msgstr "" - -#: apps/gsmsmsd.cc:476 -msgid "" -" -t, --store name of SMS store to use for flush\n" -" and/or temporary SMS storage" -msgstr "" - -#: apps/gsmsmsd.cc:479 apps/gsmsendsms.cc:167 apps/gsmpb.cc:343 -#: apps/gsmctl.cc:399 apps/gsmsmsstore.cc:213 -msgid " -v, --version prints version and exits" -msgstr "" - -#: apps/gsmsmsd.cc:480 apps/gsmsendsms.cc:169 apps/gsmpb.cc:346 -#: apps/gsmctl.cc:400 apps/gsmsmsstore.cc:218 -msgid " -X, --xonxoff switch on software handshake" -msgstr "" - -#: apps/gsmsmsd.cc:482 -msgid " sms_type may be any combination of" -msgstr "" - -#: apps/gsmsmsd.cc:483 -msgid " sms, no_sms controls reception of normal SMS" -msgstr "" - -#: apps/gsmsmsd.cc:485 -msgid " cb, no_cb controls reception of cell broadcast messages" -msgstr "" - -#: apps/gsmsmsd.cc:487 -msgid " stat, no_stat controls reception of status reports" -msgstr "" - -#: apps/gsmsmsd.cc:489 -msgid " default is \"sms cb stat\"" -msgstr "" - -#: apps/gsmsmsd.cc:490 -msgid "If no action is given, the SMS is printed to stdout" -msgstr "" - -#: apps/gsmsmsd.cc:492 -msgid "If -P is given, it activates the priority system and sets the" -msgstr "" - -#: apps/gsmsmsd.cc:493 -msgid "number or levels to use. For every level, there must be directories" -msgstr "" - -#: apps/gsmsmsd.cc:494 -msgid "named +." -msgstr "" - -#: apps/gsmsmsd.cc:495 -msgid "For example \"-P 2 -s queue -S send -F failed\" needs the following" -msgstr "" - -#: apps/gsmsmsd.cc:496 -msgid "directories: queue1/ queue2/ send1/ send2/ failed1/ failed2/" -msgstr "" - -#: apps/gsmsmsd.cc:497 -msgid "Before sending one SMS from queue2, all pending SMS from queue1" -msgstr "" - -#: apps/gsmsmsd.cc:498 -msgid "will be sent." -msgstr "" - -#: apps/gsmsmsd.cc:503 apps/gsmsendsms.cc:178 apps/gsmpb.cc:354 -#: apps/gsmctl.cc:414 apps/gsmsmsstore.cc:223 -msgid "unknown option" -msgstr "" - -#: apps/gsmsmsd.cc:542 -#, c-format -msgid "error when calling sigaction() (errno: %d/%s)" -msgstr "" - -#: apps/gsmsmsd.cc:562 -msgid "store name must be given for flush option" -msgstr "" - -#. process the new message -#: apps/gsmsmsd.cc:570 apps/gsmsmsd.cc:638 -msgid "Type of message: " -msgstr "" - -#: apps/gsmsmsd.cc:574 apps/gsmsmsd.cc:642 -msgid "SMS message\n" -msgstr "" - -#: apps/gsmsmsd.cc:577 -msgid "submit report message\n" -msgstr "" - -#: apps/gsmsmsd.cc:580 apps/gsmsmsd.cc:648 -msgid "status report message\n" -msgstr "" - -#: apps/gsmsmsd.cc:645 -msgid "cell broadcast message\n" -msgstr "" - -#: apps/gsmsmsd.cc:701 apps/gsmsmsd.cc:703 apps/gsmsendsms.cc:253 -#: apps/gsmpb.cc:503 apps/gsmctl.cc:631 apps/gsmsmsstore.cc:430 -msgid "[ERROR]: " -msgstr "" - -#: apps/gsmsmsd.cc:704 -msgid "(try setting sms_type, please refer to gsmsmsd manpage)" -msgstr "" - -#: apps/gsmsendsms.cc:149 -msgid "" -": [-b baudrate][-c concatenatedID][-C sca][-d device][-h][-I init string]\n" -" [-t][-v][-X] phonenumber [text]" -msgstr "" - -#: apps/gsmsendsms.cc:156 -msgid " -c, --concatenate ID for concatenated SMS messages" -msgstr "" - -#: apps/gsmsendsms.cc:159 apps/gsmctl.cc:392 -msgid " -d, --device sets the destination device to connect to" -msgstr "" - -#: apps/gsmsendsms.cc:164 -msgid "" -" -t, --test convert text to GSM alphabet and vice\n" -" versa, no SMS message is sent" -msgstr "" - -#: apps/gsmsendsms.cc:171 -msgid " phonenumber recipient's phone number" -msgstr "" - -#: apps/gsmsendsms.cc:172 -msgid "" -" text optional text of the SMS message\n" -" if omitted: read from stdin" -msgstr "" - -#: apps/gsmsendsms.cc:205 -msgid "phone number and text missing" -msgstr "" - -#: apps/gsmsendsms.cc:208 apps/gsmsmsstore.cc:261 -msgid "more than two parameters given" -msgstr "" - -#: apps/gsmsendsms.cc:224 -msgid "text is larger than 160 characters" -msgstr "" - -#: apps/gsmpb.cc:102 apps/gsmpb.cc:491 -#, c-format -msgid "inserting '%s' tel# %s" -msgstr "" - -#: apps/gsmpb.cc:105 apps/gsmpb.cc:230 apps/gsmpb.cc:494 -#, c-format -msgid " (index #%d)" -msgstr "" - -#: apps/gsmpb.cc:144 -#, c-format -msgid "updating '%s' tel# %s to new tel# %s" -msgstr "" - -#: apps/gsmpb.cc:177 -#, c-format -msgid "updating '%s' tel# %s to new tel# %s(index %d)" -msgstr "" - -#: apps/gsmpb.cc:227 -#, c-format -msgid "deleting '%s' tel# %s" -msgstr "" - -#: apps/gsmpb.cc:316 -msgid "" -": [-b baudrate][-c][-d device or file][-h][-I init string]\n" -" [-p phonebook name][-s device or file][-t charset][-v][-V][-y][-X]" -msgstr "" - -#: apps/gsmpb.cc:325 -msgid " -c, --copy copy source entries to destination" -msgstr "" - -#: apps/gsmpb.cc:327 -msgid "" -" -d, --destination sets the destination device to connect \n" -" to, or the file to write" -msgstr "" - -#: apps/gsmpb.cc:330 -msgid " -D, --destination-backend sets the destination backend" -msgstr "" - -#: apps/gsmpb.cc:333 -msgid " -i, --index takes index positions into account" -msgstr "" - -#: apps/gsmpb.cc:336 -msgid " -p, --phonebook name of phonebook to use" -msgstr "" - -#: apps/gsmpb.cc:337 apps/gsmsmsstore.cc:210 -msgid "" -" -s, --source sets the source device to connect to,\n" -" or the file to read" -msgstr "" - -#: apps/gsmpb.cc:339 -msgid "" -" -t, --charset sets the character set to use for\n" -" phonebook entries" -msgstr "" - -#: apps/gsmpb.cc:341 -msgid " -S, --source-backend sets the source backend" -msgstr "" - -#: apps/gsmpb.cc:344 apps/gsmsmsstore.cc:214 -msgid " -V, --verbose print detailed progress messages" -msgstr "" - -#: apps/gsmpb.cc:347 -msgid "" -" -y, --synchronize synchronize destination with source\n" -" entries (destination is overwritten)\n" -" (see gsmpb(1) for details)" -msgstr "" - -#: apps/gsmpb.cc:360 -msgid "both source and destination must be given" -msgstr "" - -#: apps/gsmpb.cc:374 apps/gsmpb.cc:416 -msgid "phonebook name must be given" -msgstr "" - -#: apps/gsmpb.cc:441 -#, c-format -msgid "" -"text '%s' is too large to fit into destination (maximum size %d characters)" -msgstr "" - -#: apps/gsmpb.cc:447 -#, c-format -msgid "" -"phone number '%s' is too large to fit into destination (maximum size %d " -"characters)" -msgstr "" - -#: apps/gsmctl.cc:90 -msgid "active " -msgstr "" - -#: apps/gsmctl.cc:90 -msgid "inactive " -msgstr "" - -#: apps/gsmctl.cc:91 -msgid "number: " -msgstr "" - -#: apps/gsmctl.cc:92 -msgid " subaddr: " -msgstr "" - -#: apps/gsmctl.cc:93 -msgid " time: " -msgstr "" - -#: apps/gsmctl.cc:105 -msgid " Manufacturer: " -msgstr "" - -#: apps/gsmctl.cc:106 -msgid " Model: " -msgstr "" - -#: apps/gsmctl.cc:107 -msgid " Revision: " -msgstr "" - -#: apps/gsmctl.cc:108 -msgid " Serial Number: " -msgstr "" - -#: apps/gsmctl.cc:116 apps/gsmctl.cc:118 -msgid " Functionality Level: " -msgstr "" - -#: apps/gsmctl.cc:118 -msgid "unsupported" -msgstr "" - -#: apps/gsmctl.cc:128 -msgid "> Status: " -msgstr "" - -#: apps/gsmctl.cc:131 gsmlib/gsm_error.cc:104 gsmlib/gsm_sms.cc:441 -#: gsmlib/gsm_sms_codec.cc:205 -msgid "unknown" -msgstr "" - -#: apps/gsmctl.cc:132 -msgid "current" -msgstr "" - -#: apps/gsmctl.cc:133 -msgid "available" -msgstr "" - -#: apps/gsmctl.cc:134 -msgid "forbidden" -msgstr "" - -#: apps/gsmctl.cc:136 apps/gsmctl.cc:147 -msgid " Long name: '" -msgstr "" - -#: apps/gsmctl.cc:137 apps/gsmctl.cc:148 -msgid " Short name: '" -msgstr "" - -#: apps/gsmctl.cc:138 apps/gsmctl.cc:149 -msgid " Numeric name: " -msgstr "" - -#: apps/gsmctl.cc:150 -msgid " Mode: " -msgstr "" - -#: apps/gsmctl.cc:153 -msgid "automatic" -msgstr "" - -#: apps/gsmctl.cc:154 -msgid "manual" -msgstr "" - -#: apps/gsmctl.cc:155 -msgid "deregister" -msgstr "" - -#: apps/gsmctl.cc:156 -msgid "manual/automatic" -msgstr "" - -#: apps/gsmctl.cc:172 apps/gsmctl.cc:247 -msgid " Voice" -msgstr "" - -#: apps/gsmctl.cc:176 apps/gsmctl.cc:185 apps/gsmctl.cc:194 -msgid " unknown" -msgstr "" - -#: apps/gsmctl.cc:181 apps/gsmctl.cc:249 -msgid " Data" -msgstr "" - -#: apps/gsmctl.cc:190 apps/gsmctl.cc:251 -msgid " Fax" -msgstr "" - -#: apps/gsmctl.cc:229 -msgid "on" -msgstr "" - -#: apps/gsmctl.cc:229 -msgid "off" -msgstr "" - -#: apps/gsmctl.cc:239 -msgid "UnconditionalReason" -msgstr "" - -#: apps/gsmctl.cc:240 -msgid "MobileBusyReason" -msgstr "" - -#: apps/gsmctl.cc:241 -msgid "NoReplyReason" -msgstr "" - -#: apps/gsmctl.cc:242 -msgid "NotReachableReason" -msgstr "" - -#: apps/gsmctl.cc:261 -msgid "0 ME is powered by the battery" -msgstr "" - -#: apps/gsmctl.cc:262 -msgid "1 ME has a battery connected, but is not powered by it" -msgstr "" - -#: apps/gsmctl.cc:264 -msgid "2 ME does not have a battery connected" -msgstr "" - -#: apps/gsmctl.cc:266 -msgid "3 Recognized power fault, calls inhibited" -msgstr "" - -#: apps/gsmctl.cc:323 -#, c-format -msgid "unknown facility class parameter '%c'" -msgstr "" - -#: apps/gsmctl.cc:336 -#, c-format -msgid "not enough parameters, minimum number of parameters is %d" -msgstr "" - -#: apps/gsmctl.cc:340 -#, c-format -msgid "too many parameters, maximum number of parameters is %d" -msgstr "" - -#: apps/gsmctl.cc:385 -msgid "" -": [-b baudrate][-d device][-h][-I init string][-o operation]\n" -" [-v][-X]{parameters}" -msgstr "" - -#: apps/gsmctl.cc:396 -msgid "" -" -o, --operation operation to perform on the mobile \n" -" phone with the specified parameters" -msgstr "" - -#: apps/gsmctl.cc:402 -msgid "" -" parameters parameters to use for the operation\n" -" (if an operation is given) or\n" -" a specification which kind of\n" -" information to read from the mobile phone" -msgstr "" - -#: apps/gsmctl.cc:408 -msgid "" -"Refer to gsmctl(1) for details on the available parameters and operations." -msgstr "" - -#: apps/gsmctl.cc:471 -#, c-format -msgid "unknown information parameter '%s'" -msgstr "" - -#: apps/gsmctl.cc:520 -#, c-format -msgid "unknown opmode parameter '%s'" -msgstr "" - -#: apps/gsmctl.cc:588 -#, c-format -msgid "unknown forward reason parameter '%s'" -msgstr "" - -#: apps/gsmctl.cc:604 -#, c-format -msgid "unknown forward mode parameter '%s'" -msgstr "" - -#: apps/gsmctl.cc:625 -#, c-format -msgid "unknown operation '%s'" -msgstr "" - -#: apps/gsmsmsstore.cc:91 apps/gsmsmsstore.cc:358 apps/gsmsmsstore.cc:375 -#, c-format -msgid "inserting entry #%d from source into destination" -msgstr "" - -#: apps/gsmsmsstore.cc:102 -#, c-format -msgid "incompatible options '%c' and '%c'" -msgstr "" - -#: apps/gsmsmsstore.cc:184 -msgid "" -": [-a][-b baudrate][-c][-C sca][-d device or file]\n" -" [-h][-I init string][-k][-l][-s device or file][-t SMS store name]\n" -" [-v][-V][-x][-X]{indices}|[phonenumber text]" -msgstr "" - -#: apps/gsmsmsstore.cc:191 -msgid "" -" -a, --add add new SMS submit message\n" -" (phonenumber and text) to destination" -msgstr "" - -#: apps/gsmsmsstore.cc:197 -msgid "" -" -c, --copy copy source entries to destination\n" -" (if indices are given, copy only these entries)" -msgstr "" - -#: apps/gsmsmsstore.cc:201 -msgid "" -" -d, --destination sets the destination device to\n" -" connect to, or the file to write to" -msgstr "" - -#: apps/gsmsmsstore.cc:206 -msgid "" -" -k, --backup backup new entries to destination\n" -" (if indices are given, copy only these entries)" -msgstr "" - -#: apps/gsmsmsstore.cc:209 -msgid " -l, --list list source to stdout" -msgstr "" - -#: apps/gsmsmsstore.cc:212 -msgid " -t, --store name of SMS store to use" -msgstr "" - -#: apps/gsmsmsstore.cc:216 -msgid " -x, --delete delete entries denoted by indices" -msgstr "" - -#: apps/gsmsmsstore.cc:229 -msgid "no operation option given" -msgstr "" - -#: apps/gsmsmsstore.cc:232 -msgid "both source and destination required" -msgstr "" - -#: apps/gsmsmsstore.cc:237 -msgid "destination must not be given" -msgstr "" - -#: apps/gsmsmsstore.cc:239 -msgid "source required" -msgstr "" - -#: apps/gsmsmsstore.cc:244 -msgid "source must not be given" -msgstr "" - -#: apps/gsmsmsstore.cc:246 -msgid "destination required" -msgstr "" - -#: apps/gsmsmsstore.cc:254 gsmlib/gsm_util.cc:286 -#, c-format -msgid "expected number, got '%s'" -msgstr "" - -#: apps/gsmsmsstore.cc:264 -msgid "not enough parameters given" -msgstr "" - -#: apps/gsmsmsstore.cc:269 -msgid "unexpected parameters" -msgstr "" - -#: apps/gsmsmsstore.cc:280 apps/gsmsmsstore.cc:312 -msgid "store name must be given" -msgstr "" - -#: apps/gsmsmsstore.cc:339 apps/gsmsmsstore.cc:372 -#, c-format -msgid "no index '%s' in source" -msgstr "" - -#: apps/gsmsmsstore.cc:387 -#, c-format -msgid "index #%d" -msgstr "" - -#: apps/gsmsmsstore.cc:401 -msgid "inserting new entry into destination" -msgstr "" - -#: apps/gsmsmsstore.cc:416 -#, c-format -msgid "deleting entry #%d from destination" -msgstr "" - -#: apps/gsmsmsstore.cc:421 -#, c-format -msgid "no index '%s' in destination" -msgstr "" - -#: gsmlib/gsm_at.cc:66 -msgid "unspecified ME/TA error" -msgstr "" - -#: gsmlib/gsm_at.cc:76 -msgid "ME/TA error '" -msgstr "" - -#: gsmlib/gsm_at.cc:80 -#, c-format -msgid "(code %s)" -msgstr "" - -#: gsmlib/gsm_at.cc:125 gsmlib/gsm_at.cc:215 gsmlib/gsm_at.cc:344 -msgid "ME/TA error '' (code not known)" -msgstr "" - -#: gsmlib/gsm_at.cc:184 gsmlib/gsm_at.cc:365 -#, c-format -msgid "unexpected response '%s' when sending 'AT%s'" -msgstr "" - -#: gsmlib/gsm_at.cc:318 -msgid "unexpected character in PDU handshake" -msgstr "" - -#: gsmlib/gsm_error.cc:29 -msgid "phone failure" -msgstr "" - -#: gsmlib/gsm_error.cc:32 -msgid "no connection to phone" -msgstr "" - -#: gsmlib/gsm_error.cc:35 -msgid "phone adaptor link reserved" -msgstr "" - -#: gsmlib/gsm_error.cc:38 gsmlib/gsm_error.cc:259 -msgid "operation not allowed" -msgstr "" - -#: gsmlib/gsm_error.cc:41 gsmlib/gsm_error.cc:262 -msgid "operation not supported" -msgstr "" - -#: gsmlib/gsm_error.cc:44 -msgid "ph SIM PIN required" -msgstr "" - -#: gsmlib/gsm_error.cc:47 gsmlib/gsm_error.cc:271 -msgid "SIM not inserted" -msgstr "" - -#: gsmlib/gsm_error.cc:50 gsmlib/gsm_error.cc:274 -msgid "SIM PIN required" -msgstr "" - -#: gsmlib/gsm_error.cc:53 gsmlib/gsm_error.cc:289 -msgid "SIM PUK required" -msgstr "" - -#: gsmlib/gsm_error.cc:56 gsmlib/gsm_error.cc:280 -msgid "SIM failure" -msgstr "" - -#: gsmlib/gsm_error.cc:59 gsmlib/gsm_error.cc:283 -msgid "SIM busy" -msgstr "" - -#: gsmlib/gsm_error.cc:62 gsmlib/gsm_error.cc:286 -msgid "SIM wrong" -msgstr "" - -#: gsmlib/gsm_error.cc:65 -msgid "incorrect password" -msgstr "" - -#: gsmlib/gsm_error.cc:68 gsmlib/gsm_error.cc:292 -msgid "SIM PIN2 required" -msgstr "" - -#: gsmlib/gsm_error.cc:71 gsmlib/gsm_error.cc:295 -msgid "SIM PUK2 required" -msgstr "" - -#: gsmlib/gsm_error.cc:74 gsmlib/gsm_error.cc:304 -msgid "memory full" -msgstr "" - -#: gsmlib/gsm_error.cc:77 -msgid "invalid index" -msgstr "" - -#: gsmlib/gsm_error.cc:80 -msgid "not found" -msgstr "" - -#: gsmlib/gsm_error.cc:83 gsmlib/gsm_error.cc:298 -msgid "memory failure" -msgstr "" - -#: gsmlib/gsm_error.cc:86 -msgid "text string too long" -msgstr "" - -#: gsmlib/gsm_error.cc:89 -msgid "invalid characters in text string" -msgstr "" - -#: gsmlib/gsm_error.cc:92 -msgid "dial string too long" -msgstr "" - -#: gsmlib/gsm_error.cc:95 -msgid "invalid characters in dial string" -msgstr "" - -#: gsmlib/gsm_error.cc:98 gsmlib/gsm_error.cc:310 -msgid "no network service" -msgstr "" - -#: gsmlib/gsm_error.cc:101 gsmlib/gsm_error.cc:313 -msgid "network timeout" -msgstr "" - -#: gsmlib/gsm_error.cc:107 -#, c-format -msgid "invalid ME error %d" -msgstr "" - -#: gsmlib/gsm_error.cc:117 -msgid "Unassigned (unallocated) number" -msgstr "" - -#: gsmlib/gsm_error.cc:120 -msgid "Operator determined barring" -msgstr "" - -#: gsmlib/gsm_error.cc:123 -msgid "Call barred" -msgstr "" - -#: gsmlib/gsm_error.cc:126 -msgid "Network failure" -msgstr "" - -#: gsmlib/gsm_error.cc:129 -msgid "Short message transfer rejected" -msgstr "" - -#: gsmlib/gsm_error.cc:133 gsmlib/gsm_error.cc:355 -msgid "Congestion" -msgstr "" - -#: gsmlib/gsm_error.cc:136 -msgid "Destination out of service" -msgstr "" - -#: gsmlib/gsm_error.cc:139 -msgid "Unidentified subscriber" -msgstr "" - -#: gsmlib/gsm_error.cc:142 -msgid "Facility rejected" -msgstr "" - -#: gsmlib/gsm_error.cc:145 -msgid "Unknown subscriber" -msgstr "" - -#: gsmlib/gsm_error.cc:148 -msgid "Network out of order" -msgstr "" - -#: gsmlib/gsm_error.cc:151 -msgid "Temporary failure" -msgstr "" - -#: gsmlib/gsm_error.cc:154 -msgid "Resources unavailable, unspecified" -msgstr "" - -#: gsmlib/gsm_error.cc:157 -msgid "Requested facility not subscribed" -msgstr "" - -#: gsmlib/gsm_error.cc:160 -msgid "Requested facility not implemented" -msgstr "" - -#: gsmlib/gsm_error.cc:163 -msgid "Invalid Transaction Identifier" -msgstr "" - -#: gsmlib/gsm_error.cc:166 -msgid "Semantically incorrect message" -msgstr "" - -#: gsmlib/gsm_error.cc:169 -msgid "Invalid mandatory information" -msgstr "" - -#: gsmlib/gsm_error.cc:172 -msgid "Message type non-existent or not implemented" -msgstr "" - -#: gsmlib/gsm_error.cc:175 -msgid "Message not compatible with short message protocol state" -msgstr "" - -#: gsmlib/gsm_error.cc:178 -msgid "Information element non-existent or not implemented" -msgstr "" - -#: gsmlib/gsm_error.cc:181 -msgid "Protocol error, unspecified" -msgstr "" - -#: gsmlib/gsm_error.cc:184 -msgid "Interworking, unspecified" -msgstr "" - -#: gsmlib/gsm_error.cc:187 -msgid "Telematic interworking not supported" -msgstr "" - -#: gsmlib/gsm_error.cc:190 -msgid "Short message Type 0 not supported" -msgstr "" - -#: gsmlib/gsm_error.cc:193 -msgid "Cannot replace short message" -msgstr "" - -#: gsmlib/gsm_error.cc:196 -msgid "Unspecified TP-PID error" -msgstr "" - -#: gsmlib/gsm_error.cc:199 -msgid "Data coding scheme (alphabet) not supported" -msgstr "" - -#: gsmlib/gsm_error.cc:202 -msgid "Message class not supported" -msgstr "" - -#: gsmlib/gsm_error.cc:205 -msgid "Unspecifiec TP-DCS error" -msgstr "" - -#: gsmlib/gsm_error.cc:208 -msgid "Command cannot be actioned" -msgstr "" - -#: gsmlib/gsm_error.cc:211 -msgid "Command unsupported" -msgstr "" - -#: gsmlib/gsm_error.cc:214 -msgid "Unspecified TP-Command error" -msgstr "" - -#: gsmlib/gsm_error.cc:217 -msgid "TPDU not supported" -msgstr "" - -#: gsmlib/gsm_error.cc:220 -msgid "SC busy" -msgstr "" - -#: gsmlib/gsm_error.cc:223 -msgid "No SC subscription" -msgstr "" - -#: gsmlib/gsm_error.cc:226 -msgid "SC system failure" -msgstr "" - -#: gsmlib/gsm_error.cc:229 -msgid "Invalid SME address" -msgstr "" - -#: gsmlib/gsm_error.cc:232 -msgid "Destination SME barred" -msgstr "" - -#: gsmlib/gsm_error.cc:235 -msgid "SM Rejected-Duplicated SM" -msgstr "" - -#: gsmlib/gsm_error.cc:238 -msgid "SIM SMS storage full" -msgstr "" - -#: gsmlib/gsm_error.cc:241 -msgid "No SMS storage capability in SIM" -msgstr "" - -#: gsmlib/gsm_error.cc:244 -msgid "Error in MS" -msgstr "" - -#: gsmlib/gsm_error.cc:247 -msgid "Memory Capacity Exceed" -msgstr "" - -#: gsmlib/gsm_error.cc:250 -msgid "Unspecified error cause" -msgstr "" - -#: gsmlib/gsm_error.cc:253 -msgid "ME failure" -msgstr "" - -#: gsmlib/gsm_error.cc:256 -msgid "SMS service of ME reserved" -msgstr "" - -#: gsmlib/gsm_error.cc:265 -msgid "invalid PDU mode parameter" -msgstr "" - -#: gsmlib/gsm_error.cc:268 -msgid "invalid text mode parameter" -msgstr "" - -#: gsmlib/gsm_error.cc:277 -msgid "PH-SIM PIN required" -msgstr "" - -#: gsmlib/gsm_error.cc:301 -msgid "invalid memory index" -msgstr "" - -#: gsmlib/gsm_error.cc:307 -msgid "SMSC address unknown" -msgstr "" - -#: gsmlib/gsm_error.cc:316 -msgid "no +CNMA acknowledgement expected" -msgstr "" - -#: gsmlib/gsm_error.cc:319 -msgid "unknown error" -msgstr "" - -#: gsmlib/gsm_error.cc:322 -#, c-format -msgid "invalid SMS error %d" -msgstr "" - -#: gsmlib/gsm_error.cc:335 -msgid "Short message received by the SME" -msgstr "" - -#: gsmlib/gsm_error.cc:338 -msgid "" -"Short message forwarded by the SC to the SME but the SC is unable to confirm " -"delivery" -msgstr "" - -#: gsmlib/gsm_error.cc:342 -msgid "Short message replaced by the SC" -msgstr "" - -#: gsmlib/gsm_error.cc:345 gsmlib/gsm_error.cc:373 gsmlib/gsm_error.cc:418 -msgid "reserved" -msgstr "" - -#: gsmlib/gsm_error.cc:358 -msgid "SME busy" -msgstr "" - -#: gsmlib/gsm_error.cc:361 -msgid "No response from SME" -msgstr "" - -#: gsmlib/gsm_error.cc:364 -msgid "Service rejected" -msgstr "" - -#: gsmlib/gsm_error.cc:367 gsmlib/gsm_error.cc:400 -msgid "Quality of service not available" -msgstr "" - -#: gsmlib/gsm_error.cc:370 -msgid "Error in SME" -msgstr "" - -#: gsmlib/gsm_error.cc:377 -msgid " (Temporary error, SC is not making any more transfer attempts)" -msgstr "" - -#: gsmlib/gsm_error.cc:380 -msgid " (Temporary error, SC still trying to transfer SM)" -msgstr "" - -#: gsmlib/gsm_error.cc:388 -msgid "Remote Procedure Error" -msgstr "" - -#: gsmlib/gsm_error.cc:391 -msgid "Incompatible destination" -msgstr "" - -#: gsmlib/gsm_error.cc:394 -msgid "Connection rejected by SME" -msgstr "" - -#: gsmlib/gsm_error.cc:397 -msgid "Not obtainable" -msgstr "" - -#: gsmlib/gsm_error.cc:403 -msgid "No interworking available" -msgstr "" - -#: gsmlib/gsm_error.cc:406 -msgid "SM validity period expired" -msgstr "" - -#: gsmlib/gsm_error.cc:409 -msgid "SM deleted by originating SME" -msgstr "" - -#: gsmlib/gsm_error.cc:412 -msgid "SM deleted by SC administration" -msgstr "" - -#: gsmlib/gsm_error.cc:415 -msgid "SM does not exit" -msgstr "" - -#: gsmlib/gsm_error.cc:421 -msgid " (Permanent Error, SC is not making any more transfer attempts)" -msgstr "" - -#: gsmlib/gsm_event.cc:80 -#, c-format -msgid "unexpected number format %d" -msgstr "" - -#: gsmlib/gsm_event.cc:100 -#, c-format -msgid "unexpected unsolicited event '%s'" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:538 -msgid "unable to set operator" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:665 -msgid "call forward time must be in the range 0..30" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:813 -msgid "Functionality Level commands not supported by ME" -msgstr "" - -#. If the number was just out of range, we get here. -#: gsmlib/gsm_me_ta.cc:832 -msgid "Requested Functionality Level out of range" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:943 -msgid "unsupported alphabet for SMS" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:952 -msgid "SMS text is larger than allowed" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:964 -msgid "not more than 255 concatenated SMSs allowed" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:997 -msgid "only serviceLevel 0 or 1 supported" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:1110 gsmlib/gsm_me_ta.cc:1152 -msgid "cannot route SMS messages to TE" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:1124 gsmlib/gsm_me_ta.cc:1166 -msgid "cannot route cell broadcast messages to TE" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:1136 -msgid "cannot route status reports messages to TE" -msgstr "" - -#: gsmlib/gsm_me_ta.cc:1180 -msgid "cannot route status report messages to TE" -msgstr "" - -#: gsmlib/gsm_parser.cc:51 -msgid "expected parameter" -msgstr "" - -#: gsmlib/gsm_parser.cc:71 -msgid "expected '\"'" -msgstr "" - -#: gsmlib/gsm_parser.cc:109 -msgid "expected number" -msgstr "" - -#: gsmlib/gsm_parser.cc:120 -#, c-format -msgid "unexpected end of string '%s'" -msgstr "" - -#: gsmlib/gsm_parser.cc:124 -#, c-format -msgid " (at position %d of string '%s')" -msgstr "" - -#: gsmlib/gsm_parser.cc:141 -#, c-format -msgid "expected '%c'" -msgstr "" - -#: gsmlib/gsm_parser.cc:165 -msgid "expected ')' or ','" -msgstr "" - -#: gsmlib/gsm_parser.cc:251 -msgid "expected ')', ',' or '-'" -msgstr "" - -#: gsmlib/gsm_parser.cc:257 -msgid "range of the form a-b-c not allowed" -msgstr "" - -#: gsmlib/gsm_parser.cc:264 -msgid "range of the form a- no allowed" -msgstr "" - -#: gsmlib/gsm_parser.cc:350 -msgid "expected comma" -msgstr "" - -#: gsmlib/gsm_parser.cc:367 -msgid "expected end of line" -msgstr "" - -#: gsmlib/gsm_phonebook.cc:47 -#, c-format -msgid "" -"length of text '%s' exceeds maximum text length (%d characters) of phonebook " -"'%s'" -msgstr "" - -#: gsmlib/gsm_phonebook.cc:55 -#, c-format -msgid "" -"length of telephone number '%s' exceeds maximum telephone number length (%d " -"characters) of phonebook '%s'" -msgstr "" - -#: gsmlib/gsm_phonebook.cc:275 -msgid "phonebook full" -msgstr "" - -#: gsmlib/gsm_phonebook.cc:291 -msgid "attempt to overwrite phonebook entry" -msgstr "" - -#: gsmlib/gsm_phonebook.cc:569 -msgid "SIM card changed while accessing phonebook" -msgstr "" - -#: gsmlib/gsm_sms.cc:66 gsmlib/gsm_sms.cc:85 gsmlib/gsm_sms.cc:175 -msgid "unhandled SMS TPDU type" -msgstr "" - -#: gsmlib/gsm_sms.cc:107 -msgid "can only send SMS-SUBMIT and SMS-COMMAND TPDUs" -msgstr "" - -#: gsmlib/gsm_sms.cc:111 -msgid "no device given for sending SMS" -msgstr "" - -#: gsmlib/gsm_sms.cc:283 -msgid "Message type: SMS-DELIVER" -msgstr "" - -#: gsmlib/gsm_sms.cc:284 gsmlib/gsm_sms.cc:426 gsmlib/gsm_sms.cc:531 -#: gsmlib/gsm_sms.cc:618 gsmlib/gsm_sms.cc:723 gsmlib/gsm_sms.cc:829 -msgid "SC address: '" -msgstr "" - -#: gsmlib/gsm_sms.cc:285 gsmlib/gsm_sms.cc:532 -msgid "More messages to send: " -msgstr "" - -#: gsmlib/gsm_sms.cc:286 gsmlib/gsm_sms.cc:445 -msgid "Reply path: " -msgstr "" - -#: gsmlib/gsm_sms.cc:287 gsmlib/gsm_sms.cc:446 -msgid "User data header indicator: " -msgstr "" - -#: gsmlib/gsm_sms.cc:289 -msgid "Status report indication: " -msgstr "" - -#: gsmlib/gsm_sms.cc:290 -msgid "Originating address: '" -msgstr "" - -#: gsmlib/gsm_sms.cc:292 gsmlib/gsm_sms.cc:452 gsmlib/gsm_sms.cc:621 -#: gsmlib/gsm_sms.cc:729 gsmlib/gsm_sms.cc:836 -msgid "Protocol identifier: 0x" -msgstr "" - -#: gsmlib/gsm_sms.cc:294 gsmlib/gsm_sms.cc:454 gsmlib/gsm_sms.cc:733 -#: gsmlib/gsm_sms.cc:840 -msgid "Data coding scheme: " -msgstr "" - -#: gsmlib/gsm_sms.cc:295 gsmlib/gsm_sms.cc:536 gsmlib/gsm_sms.cc:830 -msgid "SC timestamp: " -msgstr "" - -#: gsmlib/gsm_sms.cc:296 gsmlib/gsm_sms.cc:456 gsmlib/gsm_sms.cc:735 -#: gsmlib/gsm_sms.cc:842 -msgid "User data length: " -msgstr "" - -#: gsmlib/gsm_sms.cc:297 gsmlib/gsm_sms.cc:457 -msgid "User data header: 0x" -msgstr "" - -#: gsmlib/gsm_sms.cc:302 gsmlib/gsm_sms.cc:461 gsmlib/gsm_sms.cc:736 -#: gsmlib/gsm_sms.cc:843 -msgid "User data: '" -msgstr "" - -#: gsmlib/gsm_sms.cc:425 -msgid "Message type: SMS-SUBMIT" -msgstr "" - -#: gsmlib/gsm_sms.cc:427 -msgid "Reject duplicates: " -msgstr "" - -#: gsmlib/gsm_sms.cc:428 -msgid "Validity period format: " -msgstr "" - -#: gsmlib/gsm_sms.cc:432 gsmlib/gsm_sms_codec.cc:184 -msgid "not present" -msgstr "" - -#: gsmlib/gsm_sms.cc:435 -msgid "relative" -msgstr "" - -#: gsmlib/gsm_sms.cc:438 -msgid "absolute" -msgstr "" - -#: gsmlib/gsm_sms.cc:448 gsmlib/gsm_sms.cc:620 -msgid "Status report request: " -msgstr "" - -#: gsmlib/gsm_sms.cc:449 gsmlib/gsm_sms.cc:534 gsmlib/gsm_sms.cc:619 -msgid "Message reference: " -msgstr "" - -#: gsmlib/gsm_sms.cc:450 gsmlib/gsm_sms.cc:626 -msgid "Destination address: '" -msgstr "" - -#: gsmlib/gsm_sms.cc:455 -msgid "Validity period: " -msgstr "" - -#: gsmlib/gsm_sms.cc:530 -msgid "Message type: SMS-STATUS-REPORT" -msgstr "" - -#: gsmlib/gsm_sms.cc:533 -msgid "Status report qualifier: " -msgstr "" - -#: gsmlib/gsm_sms.cc:535 -msgid "Recipient address: '" -msgstr "" - -#: gsmlib/gsm_sms.cc:537 -msgid "Discharge time: " -msgstr "" - -#: gsmlib/gsm_sms.cc:538 -msgid "Status: 0x" -msgstr "" - -#: gsmlib/gsm_sms.cc:617 -msgid "Message type: SMS-COMMAND" -msgstr "" - -#: gsmlib/gsm_sms.cc:623 -msgid "Command type: 0x" -msgstr "" - -#: gsmlib/gsm_sms.cc:625 -msgid "Message number: " -msgstr "" - -#: gsmlib/gsm_sms.cc:628 -msgid "Command data length: " -msgstr "" - -#: gsmlib/gsm_sms.cc:629 -msgid "Command data: '" -msgstr "" - -#: gsmlib/gsm_sms.cc:722 -msgid "Message type: SMS-DELIVER-REPORT" -msgstr "" - -#: gsmlib/gsm_sms.cc:724 gsmlib/gsm_sms.cc:831 -msgid "Protocol identifier present: " -msgstr "" - -#: gsmlib/gsm_sms.cc:726 gsmlib/gsm_sms.cc:833 -msgid "Data coding scheme present: " -msgstr "" - -#: gsmlib/gsm_sms.cc:727 gsmlib/gsm_sms.cc:834 -msgid "User data length present: " -msgstr "" - -#: gsmlib/gsm_sms.cc:828 -msgid "Message type: SMS-SUBMIT-REPORT" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:189 gsmlib/gsm_sms_codec.cc:191 -msgid " minutes" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:193 -msgid " days" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:195 -msgid " weeks" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:214 -msgid "compressed " -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:219 -msgid "voicemail message waiting" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:222 -msgid "fax message waiting" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:225 -msgid "electronic mail message waiting" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:228 -msgid "other message waiting" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:235 -msgid "default alphabet" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:238 -msgid "8-bit alphabet" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:241 -msgid "16-bit alphabet" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:244 -msgid "reserved alphabet" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:257 -msgid "bad hexadecimal PDU format" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:286 gsmlib/gsm_sms_codec.cc:296 -#: gsmlib/gsm_sms_codec.cc:311 gsmlib/gsm_sms_codec.cc:319 -#: gsmlib/gsm_sms_codec.cc:340 gsmlib/gsm_sms_codec.cc:348 -#: gsmlib/gsm_sms_codec.cc:369 gsmlib/gsm_sms_codec.cc:383 -msgid "premature end of PDU" -msgstr "" - -#: gsmlib/gsm_sms_codec.cc:474 -msgid "unknown time period format" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:121 -msgid "interrupted when reading from TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:136 -msgid "end of file when reading from TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:146 -msgid "reading from TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:151 -msgid "timeout when reading from TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:178 -#, c-format -msgid "opening device '%s'" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:185 -msgid "getting file status flags failed" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:190 -msgid "switching of non-blocking mode failed" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:205 -msgid "clearing DTR failed" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:211 -msgid "setting DTR failed" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:216 -#, c-format -msgid "tcgetattr device '%s'" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:245 -#, c-format -msgid "tcsetattr device '%s'" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:303 -#, c-format -msgid "reset modem failed '%s'" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:348 gsmlib/gsm_unix_serial.cc:380 -msgid "interrupted when writing to TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:363 gsmlib/gsm_unix_serial.cc:372 -msgid "writing to TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:393 -msgid "timeout when writing to TA" -msgstr "" - -#: gsmlib/gsm_unix_serial.cc:454 -#, c-format -msgid "unknown baudrate '%s'" -msgstr "" - -#: gsmlib/gsm_util.cc:206 -#, c-format -msgid "error when calling stat('%s') (errno: %d/%s)" -msgstr "" - -#: gsmlib/gsm_util.cc:237 -#, c-format -msgid "file '%s' is neither file nor character device" -msgstr "" - -#: gsmlib/gsm_util.cc:241 -msgid "maxmimum number of symbolic links exceeded" -msgstr "" - -#: gsmlib/gsm_util.cc:251 -#, c-format -msgid "error renaming '%s' to '%s'" -msgstr "" - -#: gsmlib/gsm_util.cc:349 -#, c-format -msgid "text '%s' contains illegal character '\"'" -msgstr "" - -#: gsmlib/gsm_util.cc:359 -#, c-format -msgid "illegal character in telephone number '%s'" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:96 -#, c-format -msgid "error reading from file '%s" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:110 -#, c-format -msgid "entry '%s' lacks index" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:119 gsmlib/gsm_sorted_phonebook.cc:125 -#, c-format -msgid "line '%s' has invalid format" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:174 gsmlib/gsm_sorted_sms_store.cc:159 -#, c-format -msgid "error opening file '%s' for writing" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:175 gsmlib/gsm_sorted_phonebook.cc:194 -#: gsmlib/gsm_sorted_sms_store.cc:67 gsmlib/gsm_sorted_sms_store.cc:160 -msgid "" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:193 gsmlib/gsm_sorted_sms_store.cc:66 -#, c-format -msgid "error writing to file '%s'" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:217 -msgid "attempt to change phonebook read from " -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:230 gsmlib/gsm_sorted_sms_store.cc:215 -#, c-format -msgid "cannot open file '%s'" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:245 gsmlib/gsm_sorted_sms_store.cc:55 -#: gsmlib/gsm_sorted_sms_store.cc:228 -msgid "" -msgstr "" - -#: gsmlib/gsm_sorted_phonebook.cc:362 -msgid "indices must be unique in phonebook" -msgstr "" - -#: gsmlib/gsm_sorted_sms_store.cc:54 -#, c-format -msgid "error reading from file '%s'" -msgstr "" - -#: gsmlib/gsm_sorted_sms_store.cc:87 -#, c-format -msgid "file '%s' has wrong version" -msgstr "" - -#: gsmlib/gsm_sorted_sms_store.cc:99 gsmlib/gsm_sorted_sms_store.cc:111 -#, c-format -msgid "corrupt SMS store file '%s'" -msgstr "" - -#: gsmlib/gsm_sorted_sms_store.cc:204 -msgid "attempt to change SMS store read from " -msgstr "" diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/stamp-cat-id b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/stamp-cat-id deleted file mode 100644 index 9788f70238..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/po/stamp-cat-id +++ /dev/null @@ -1 +0,0 @@ -timestamp diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.am deleted file mode 100644 index 53f51ac19a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: scripts Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 5.6.1999 -# ************************************************************************* - -EXTRA_DIST = config.sub ltconfig missing \ - config.guess install-sh ltmain.sh mkinstalldirs debugconfig.sh diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.in deleted file mode 100644 index 6129036172..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/Makefile.in +++ /dev/null @@ -1,259 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: scripts Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 5.6.1999 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -EXTRA_DIST = config.sub ltconfig missing \ - config.guess install-sh ltmain.sh mkinstalldirs debugconfig.sh - -subdir = scripts -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -DIST_SOURCES = -DIST_COMMON = Makefile.am Makefile.in config.guess config.rpath \ - config.sub depcomp install-sh ltconfig ltmain.sh missing \ - mkinstalldirs -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu scripts/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -tags: TAGS -TAGS: - -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile - -installdirs: - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-generic distclean-libtool - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -uninstall-am: uninstall-info-am - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am info info-am install install-am install-data \ - install-data-am install-exec install-exec-am install-info \ - install-info-am install-man install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool uninstall uninstall-am uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.guess b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.guess deleted file mode 100755 index 1f5c50c0d1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.guess +++ /dev/null @@ -1,1420 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. - -timestamp='2014-03-23' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches with a ChangeLog entry to config-patches@gnu.org. - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -case "${UNAME_SYSTEM}" in -Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu - - eval $set_cc_for_build - cat <<-EOF > $dummy.c - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #else - LIBC=gnu - #endif - EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` - ;; -esac - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi - else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } - ;; - openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} - exit ;; - or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} - exit ;; - ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc - fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - fi - elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 - fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.rpath b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.rpath deleted file mode 100755 index 5ead7586a7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/config.rpath +++ /dev/null @@ -1,513 +0,0 @@ -#! /bin/sh -# Output a system dependent set of variables, describing how to set the -# run time search path of shared libraries in an executable. -# -# Copyright 1996-2002 Free Software Foundation, Inc. -# Taken from GNU libtool, 2001 -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld -# should be set by the caller. -# -# The set of defined variables is at the end of this script. - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -shlibext= - -host="$1" -host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -wl= -if test "$GCC" = yes; then - wl='-Wl,' -else - case "$host_os" in - aix3* | aix4* | aix5*) - wl='-Wl,' - ;; - hpux9* | hpux10* | hpux11*) - wl='-Wl,' - ;; - irix5* | irix6*) - wl='-Wl,' - ;; - linux*) - echo '__INTEL_COMPILER' > conftest.$ac_ext - if $CC -E conftest.$ac_ext >/dev/null | grep __INTEL_COMPILER >/dev/null - then - : - else - # Intel icc - wl='-Qoption,ld,' - fi - ;; - osf3* | osf4* | osf5*) - wl='-Wl,' - ;; - solaris*) - wl='-Wl,' - ;; - sunos4*) - wl='-Qoption ld ' - ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - if test "x$host_vendor" = xsni; then - wl='-LD' - else - wl='-Wl,' - fi - ;; - esac -fi - -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no - -case "$host_os" in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - case "$host_os" in - aix3* | aix4* | aix5*) - # On AIX, the GNU linker is very broken - ld_shlibs=no - ;; - amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - cygwin* | mingw* | pw32*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - ;; - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - sunos4*) - hardcode_direct=yes - ;; - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - esac - if test "$ld_shlibs" = yes; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - fi -else - case "$host_os" in - aix3*) - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - else - aix_use_runtimelinking=no - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - fi - hardcode_direct=yes - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - fi - if test "$aix_use_runtimelinking" = yes; then - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - else - hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' - fi - fi - ;; - amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - libext=lib - ;; - darwin* | rhapsody*) - hardcode_direct=yes - ;; - freebsd1*) - ld_shlibs=no - ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) - hardcode_direct=yes - hardcode_minus_L=yes - ;; - freebsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - hpux9* | hpux10* | hpux11*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_minus_L=yes # Not in the search PATH, but as the default - # location of the library. - ;; - irix5* | irix6*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - netbsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - newsos6) - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - openbsd*) - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - osf3*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - osf4* | osf5*) - if test "$GCC" = yes; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - # Both cc and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - sco3.2v5*) - ;; - solaris*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - sunos4*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - ;; - sysv4) - if test "x$host_vendor" = xsno; then - hardcode_direct=yes # is this really true??? - else - hardcode_direct=no # Motorola manual says yes, but my tests say they lie - fi - ;; - sysv4.3*) - ;; - sysv5*) - hardcode_libdir_flag_spec= - ;; - uts4*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - dgux*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - sysv4*MP*) - if test -d /usr/nec; then - ld_shlibs=yes - fi - ;; - sysv4.2uw2*) - hardcode_direct=yes - hardcode_minus_L=no - ;; - sysv5uw7* | unixware7*) - ;; - *) - ld_shlibs=no - ;; - esac -fi - -# Check dynamic linker characteristics -libname_spec='lib$name' -sys_lib_dlsearch_path_spec="/lib /usr/lib" -sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -case "$host_os" in - aix3*) - shlibext=so - ;; - aix4* | aix5*) - shlibext=so - ;; - amigaos*) - shlibext=ixlibrary - ;; - beos*) - shlibext=so - ;; - bsdi4*) - shlibext=so - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - ;; - cygwin* | mingw* | pw32*) - case $GCC,$host_os in - yes,cygwin*) - shlibext=dll.a - ;; - yes,mingw*) - shlibext=dll - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` - ;; - yes,pw32*) - shlibext=dll - ;; - *) - shlibext=dll - ;; - esac - ;; - darwin* | rhapsody*) - shlibext=dylib - ;; - freebsd1*) - ;; - freebsd*) - shlibext=so - ;; - gnu*) - shlibext=so - ;; - hpux9* | hpux10* | hpux11*) - shlibext=sl - ;; - irix5* | irix6*) - shlibext=so - case "$host_os" in - irix5*) - libsuff= shlibsuff= - ;; - *) - case $LD in - *-32|*"-32 ") libsuff= shlibsuff= ;; - *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 ;; - *-64|*"-64 ") libsuff=64 shlibsuff=64 ;; - *) libsuff= shlibsuff= ;; - esac - ;; - esac - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - ;; - linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) - ;; - linux-gnu*) - shlibext=so - ;; - netbsd*) - shlibext=so - ;; - newsos6) - shlibext=so - ;; - openbsd*) - shlibext=so - ;; - os2*) - libname_spec='$name' - shlibext=dll - ;; - osf3* | osf4* | osf5*) - shlibext=so - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - sco3.2v5*) - shlibext=so - ;; - solaris*) - shlibext=so - ;; - sunos4*) - shlibext=so - ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - shlibext=so - case "$host_vendor" in - motorola) - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - uts4*) - shlibext=so - ;; - dgux*) - shlibext=so - ;; - sysv4*MP*) - if test -d /usr/nec; then - shlibext=so - fi - ;; -esac - -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' -escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_sys_lib_search_path_spec=`echo "X$sys_lib_search_path_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_sys_lib_dlsearch_path_spec=`echo "X$sys_lib_dlsearch_path_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` - -sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches with a ChangeLog entry to config-patches@gnu.org. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright 1992-2014 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - c8051-*) - os=-elf - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/debugconfig.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/debugconfig.sh deleted file mode 100755 index c9f597fed4..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/debugconfig.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -CXXFLAGS="-g -Wall" ./configure --disable-shared diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/depcomp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/depcomp deleted file mode 100755 index 807b991f4a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/depcomp +++ /dev/null @@ -1,423 +0,0 @@ -#! /bin/sh - -# depcomp - compile a program generating dependencies as side-effects -# Copyright 1999, 2000 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi -# `libtool' can also be set to `yes' or `no'. - -if test -z "$depfile"; then - base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` - dir=`echo "$object" | sed 's,/.*$,/,'` - if test "$dir" = "$object"; then - dir= - fi - # FIXME: should be _deps on DOS. - depfile="$dir.deps/$base" -fi - -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. - "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. This file always lives in the current directory. - # Also, the AIX compiler puts `$object:' at the start of each line; - # $object doesn't have directory information. - stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" - outname="$stripped.o" - if test "$libtool" = yes; then - "$@" -Wc,-M - else - "$@" -M - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - tmpdepfile1="$dir.libs/$base.lo.d" - tmpdepfile2="$dir.libs/$base.d" - "$@" -Wc,-MD - else - tmpdepfile1="$dir$base.o.d" - tmpdepfile2="$dir$base.d" - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - if test -f "$tmpdepfile1"; then - tmpdepfile="$tmpdepfile1" - else - tmpdepfile="$tmpdepfile2" - fi - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a space and a tab in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. We will use -o /dev/null later, - # however we can't do the remplacement now because - # `-o $object' might simply not be used - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - -*) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/install-sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/install-sh deleted file mode 100755 index e8436696c1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/install-sh +++ /dev/null @@ -1,250 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltconfig b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltconfig deleted file mode 100755 index e3afc39777..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltconfig +++ /dev/null @@ -1,3115 +0,0 @@ -#! /bin/sh - -# ltconfig - Create a system-specific libtool. -# Copyright (C) 1996-1999 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A lot of this script is taken from autoconf-2.10. - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} -echo=echo -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec "$SHELL" "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null`} - case X$UNAME in - *-DOS) PATH_SEPARATOR=';' ;; - *) PATH_SEPARATOR=':' ;; - esac -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string="`eval $cmd`") 2>/dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || - test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH /usr/ucb; do - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running ltconfig again with it. - ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - echo='printf "%s\n"' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - # Cool, printf works - : - elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && - test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL $0 --fallback-echo" - elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && - test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - echo="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# The name of this program. -progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` - -# Constants: -PROGRAM=ltconfig -PACKAGE=libtool -VERSION=1.3.5 -TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)" -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -rm="rm -f" - -help="Try \`$progname --help' for more information." - -# Global variables: -default_ofile=libtool -can_build_shared=yes -enable_shared=yes -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -enable_static=yes -enable_fast_install=yes -enable_dlopen=unknown -enable_win32_dll=no -ltmain= -silent= -srcdir= -ac_config_guess= -ac_config_sub= -host= -nonopt= -ofile="$default_ofile" -verify_host=yes -with_gcc=no -with_gnu_ld=no -need_locks=yes -ac_ext=c -objext=o -libext=a -exeext= -cache_file= - -old_AR="$AR" -old_CC="$CC" -old_CFLAGS="$CFLAGS" -old_CPPFLAGS="$CPPFLAGS" -old_LDFLAGS="$LDFLAGS" -old_LD="$LD" -old_LN_S="$LN_S" -old_LIBS="$LIBS" -old_NM="$NM" -old_RANLIB="$RANLIB" -old_DLLTOOL="$DLLTOOL" -old_OBJDUMP="$OBJDUMP" -old_AS="$AS" - -# Parse the command line options. -args= -prev= -for option -do - case "$option" in - -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - eval "$prev=\$option" - prev= - continue - fi - - case "$option" in - --help) cat <&2 - echo "$help" 1>&2 - exit 1 - ;; - - *) - if test -z "$ltmain"; then - ltmain="$option" - elif test -z "$host"; then -# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 -# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then -# echo "$progname: warning \`$option' is not a valid host type" 1>&2 -# fi - host="$option" - else - echo "$progname: too many arguments" 1>&2 - echo "$help" 1>&2 - exit 1 - fi ;; - esac -done - -if test -z "$ltmain"; then - echo "$progname: you must specify a LTMAIN file" 1>&2 - echo "$help" 1>&2 - exit 1 -fi - -if test ! -f "$ltmain"; then - echo "$progname: \`$ltmain' does not exist" 1>&2 - echo "$help" 1>&2 - exit 1 -fi - -# Quote any args containing shell metacharacters. -ltconfig_args= -for arg -do - case "$arg" in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ltconfig_args="$ltconfig_args '$arg'" ;; - *) ltconfig_args="$ltconfig_args $arg" ;; - esac -done - -# A relevant subset of AC_INIT. - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 5 compiler messages saved in config.log -# 6 checking for... messages and results -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>>./config.log - -# NLS nuisances. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi -if test "X${LANG+set}" = Xset; then LANG=C; export LANG; fi - -if test -n "$cache_file" && test -r "$cache_file"; then - echo "loading cache $cache_file within ltconfig" - . $cache_file -fi - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - -if test -z "$srcdir"; then - # Assume the source directory is the same one as the path to LTMAIN. - srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` - test "$srcdir" = "$ltmain" && srcdir=. -fi - -trap "$rm conftest*; exit 1" 1 2 15 -if test "$verify_host" = yes; then - # Check for config.guess and config.sub. - ac_aux_dir= - for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/config.guess; then - ac_aux_dir=$ac_dir - break - fi - done - if test -z "$ac_aux_dir"; then - echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 - echo "$help" 1>&2 - exit 1 - fi - ac_config_guess=$ac_aux_dir/config.guess - ac_config_sub=$ac_aux_dir/config.sub - - # Make sure we can run config.sub. - if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : - else - echo "$progname: cannot run $ac_config_sub" 1>&2 - echo "$help" 1>&2 - exit 1 - fi - - echo $ac_n "checking host system type""... $ac_c" 1>&6 - - host_alias=$host - case "$host_alias" in - "") - if host_alias=`$SHELL $ac_config_guess`; then : - else - echo "$progname: cannot guess host type; you must specify one" 1>&2 - echo "$help" 1>&2 - exit 1 - fi ;; - esac - host=`$SHELL $ac_config_sub $host_alias` - echo "$ac_t$host" 1>&6 - - # Make sure the host verified. - test -z "$host" && exit 1 - -elif test -z "$host"; then - echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 - echo "$help" 1>&2 - exit 1 -else - host_alias=$host -fi - -# Transform linux* to *-*-linux-gnu*, to support old configure scripts. -case "$host_os" in -linux-gnu*) ;; -linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` -esac - -host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -case "$host_os" in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR cru $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -# Set a sane default for `AR'. -test -z "$AR" && AR=ar - -# Set a sane default for `OBJDUMP'. -test -z "$OBJDUMP" && OBJDUMP=objdump - -# If RANLIB is not set, then run the test. -if test "${RANLIB+set}" != "set"; then - result=no - - echo $ac_n "checking for ranlib... $ac_c" 1>&6 - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then - RANLIB="ranlib" - result="ranlib" - break - fi - done - IFS="$save_ifs" - - echo "$ac_t$result" 1>&6 -fi - -if test -n "$RANLIB"; then - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" -fi - -# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$AS" && AS=as - -# Check to see if we are using GCC. -if test "$with_gcc" != yes || test -z "$CC"; then - # If CC is not set, then try to find GCC or a usable CC. - if test -z "$CC"; then - echo $ac_n "checking for gcc... $ac_c" 1>&6 - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then - CC="gcc" - break - fi - done - IFS="$save_ifs" - - if test -n "$CC"; then - echo "$ac_t$CC" 1>&6 - else - echo "$ac_t"no 1>&6 - fi - fi - - # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". - if test -z "$CC"; then - echo $ac_n "checking for cc... $ac_c" 1>&6 - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - cc_rejected=no - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/cc || test -f $dir/cc$ac_exeext; then - if test "$dir/cc" = "/usr/ucb/cc"; then - cc_rejected=yes - continue - fi - CC="cc" - break - fi - done - IFS="$save_ifs" - if test $cc_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same name, so the bogon will be chosen - # first if we set CC to just the name; use the full file name. - shift - set dummy "$dir/cc" "$@" - shift - CC="$@" - fi - fi - - if test -n "$CC"; then - echo "$ac_t$CC" 1>&6 - else - echo "$ac_t"no 1>&6 - fi - - if test -z "$CC"; then - echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 - exit 1 - fi - fi - - # Now see if the compiler is really GCC. - with_gcc=no - echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 - echo "$progname:581: checking whether we are using GNU C" >&5 - - $rm conftest.c - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - with_gcc=yes - fi - $rm conftest.c - echo "$ac_t$with_gcc" 1>&6 -fi - -# Allow CC to be a program name with arguments. -set dummy $CC -compiler="$2" - -echo $ac_n "checking for object suffix... $ac_c" 1>&6 -$rm conftest* -echo 'int i = 1;' > conftest.c -echo "$progname:603: checking for object suffix" >& 5 -if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then - # Append any warnings to the config.log. - cat conftest.err 1>&5 - - for ac_file in conftest.*; do - case $ac_file in - *.c) ;; - *) objext=`echo $ac_file | sed -e s/conftest.//` ;; - esac - done -else - cat conftest.err 1>&5 - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 -fi -$rm conftest* -echo "$ac_t$objext" 1>&6 - -echo $ac_n "checking for executable suffix... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_cv_exeext="no" - $rm conftest* - echo 'main () { return 0; }' > conftest.c - echo "$progname:629: checking for executable suffix" >& 5 - if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then - # Append any warnings to the config.log. - cat conftest.err 1>&5 - - for ac_file in conftest.*; do - case $ac_file in - *.c | *.err | *.$objext ) ;; - *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; - esac - done - else - cat conftest.err 1>&5 - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 - fi - $rm conftest* -fi -if test "X$ac_cv_exeext" = Xno; then - exeext="" -else - exeext="$ac_cv_exeext" -fi -echo "$ac_t$ac_cv_exeext" 1>&6 - -echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 -pic_flag= -special_shlib_compile_flags= -wl= -link_static_flag= -no_builtin_flag= - -if test "$with_gcc" = yes; then - wl='-Wl,' - link_static_flag='-static' - - case "$host_os" in - beos* | irix5* | irix6* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - aix*) - # Below there is a dirty hack to force normal static linking with -ldl - # The problem is because libdl dynamically linked with both libc and - # libC (AIX C++ library), which obviously doesn't included in libraries - # list by gcc. This cause undefined symbols with -static flags. - # This hack allows C programs to be linked with "-static -ldl", but - # we not sure about C++ programs. - link_static_flag="$link_static_flag ${wl}-lC" - ;; - cygwin* | mingw* | os2*) - # We can build DLLs from non-PIC. - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - pic_flag='-m68020 -resident32 -malways-restore-a4' - ;; - sysv4*MP*) - if test -d /usr/nec; then - pic_flag=-Kconform_pic - fi - ;; - *) - pic_flag='-fPIC' - ;; - esac -else - # PORTME Check for PIC flags for the system compiler. - case "$host_os" in - aix3* | aix4*) - # All AIX code is PIC. - link_static_flag='-bnso -bI:/lib/syscalls.exp' - ;; - - hpux9* | hpux10* | hpux11*) - # Is there a better link_static_flag that works with the bundled CC? - wl='-Wl,' - link_static_flag="${wl}-a ${wl}archive" - pic_flag='+Z' - ;; - - irix5* | irix6*) - wl='-Wl,' - link_static_flag='-non_shared' - # PIC (with -KPIC) is the default. - ;; - - cygwin* | mingw* | os2*) - # We can build DLLs from non-PIC. - ;; - - osf3* | osf4* | osf5*) - # All OSF/1 code is PIC. - wl='-Wl,' - link_static_flag='-non_shared' - ;; - - sco3.2v5*) - pic_flag='-Kpic' - link_static_flag='-dn' - special_shlib_compile_flags='-belf' - ;; - - solaris*) - pic_flag='-KPIC' - link_static_flag='-Bstatic' - wl='-Wl,' - ;; - - sunos4*) - pic_flag='-PIC' - link_static_flag='-Bstatic' - wl='-Qoption ld ' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - pic_flag='-KPIC' - link_static_flag='-Bstatic' - wl='-Wl,' - ;; - - uts4*) - pic_flag='-pic' - link_static_flag='-Bstatic' - ;; - sysv4*MP*) - if test -d /usr/nec ;then - pic_flag='-Kconform_pic' - link_static_flag='-Bstatic' - fi - ;; - *) - can_build_shared=no - ;; - esac -fi - -if test -n "$pic_flag"; then - echo "$ac_t$pic_flag" 1>&6 - - # Check to make sure the pic_flag actually works. - echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 - $rm conftest* - echo "int some_variable = 0;" > conftest.c - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $pic_flag -DPIC" - echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 - if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then - # Append any warnings to the config.log. - cat conftest.err 1>&5 - - case "$host_os" in - hpux9* | hpux10* | hpux11*) - # On HP-UX, both CC and GCC only warn that PIC is supported... then they - # create non-PIC objects. So, if there were any warnings, we assume that - # PIC is not supported. - if test -s conftest.err; then - echo "$ac_t"no 1>&6 - can_build_shared=no - pic_flag= - else - echo "$ac_t"yes 1>&6 - pic_flag=" $pic_flag" - fi - ;; - *) - echo "$ac_t"yes 1>&6 - pic_flag=" $pic_flag" - ;; - esac - else - # Append any errors to the config.log. - cat conftest.err 1>&5 - can_build_shared=no - pic_flag= - echo "$ac_t"no 1>&6 - fi - CFLAGS="$save_CFLAGS" - $rm conftest* -else - echo "$ac_t"none 1>&6 -fi - -# Check to see if options -o and -c are simultaneously supported by compiler -echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 -$rm -r conftest 2>/dev/null -mkdir conftest -cd conftest -$rm conftest* -echo "int some_variable = 0;" > conftest.c -mkdir out -# According to Tom Tromey, Ian Lance Taylor reported there are C compilers -# that will create temporary files in the current directory regardless of -# the output directory. Thus, making CWD read-only will cause this test -# to fail, enabling locking or at least warning the user not to do parallel -# builds. -chmod -w . -save_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -o out/conftest2.o" -echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 -if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then - - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s out/conftest.err; then - echo "$ac_t"no 1>&6 - compiler_c_o=no - else - echo "$ac_t"yes 1>&6 - compiler_c_o=yes - fi -else - # Append any errors to the config.log. - cat out/conftest.err 1>&5 - compiler_c_o=no - echo "$ac_t"no 1>&6 -fi -CFLAGS="$save_CFLAGS" -chmod u+w . -$rm conftest* out/* -rmdir out -cd .. -rmdir conftest -$rm -r conftest 2>/dev/null - -if test x"$compiler_c_o" = x"yes"; then - # Check to see if we can write to a .lo - echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 - $rm conftest* - echo "int some_variable = 0;" > conftest.c - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -c -o conftest.lo" - echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 -if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then - - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - echo "$ac_t"no 1>&6 - compiler_o_lo=no - else - echo "$ac_t"yes 1>&6 - compiler_o_lo=yes - fi - else - # Append any errors to the config.log. - cat conftest.err 1>&5 - compiler_o_lo=no - echo "$ac_t"no 1>&6 - fi - CFLAGS="$save_CFLAGS" - $rm conftest* -else - compiler_o_lo=no -fi - -# Check to see if we can do hard links to lock some files if needed -hard_links="nottested" -if test "$compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$ac_t$hard_links" 1>&6 - $rm conftest* - if test "$hard_links" = no; then - echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 - need_locks=warn - fi -else - need_locks=no -fi - -if test "$with_gcc" = yes; then - # Check to see if options -fno-rtti -fno-exceptions are supported by compiler - echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 - $rm conftest* - echo "int some_variable = 0;" > conftest.c - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" - echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 - if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then - - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - echo "$ac_t"no 1>&6 - compiler_rtti_exceptions=no - else - echo "$ac_t"yes 1>&6 - compiler_rtti_exceptions=yes - fi - else - # Append any errors to the config.log. - cat conftest.err 1>&5 - compiler_rtti_exceptions=no - echo "$ac_t"no 1>&6 - fi - CFLAGS="$save_CFLAGS" - $rm conftest* - - if test "$compiler_rtti_exceptions" = "yes"; then - no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' - else - no_builtin_flag=' -fno-builtin' - fi - -fi - -# Check for any special shared library compilation flags. -if test -n "$special_shlib_compile_flags"; then - echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 - if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : - else - echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 - can_build_shared=no - fi -fi - -echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 -$rm conftest* -echo 'main(){return(0);}' > conftest.c -save_LDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS $link_static_flag" -echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 -if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - echo "$ac_t$link_static_flag" 1>&6 -else - echo "$ac_t"none 1>&6 - link_static_flag= -fi -LDFLAGS="$save_LDFLAGS" -$rm conftest* - -if test -z "$LN_S"; then - # Check to see if we can use ln -s, or we need hard links. - echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 - $rm conftest.dat - if ln -s X conftest.dat 2>/dev/null; then - $rm conftest.dat - LN_S="ln -s" - else - LN_S=ln - fi - if test "$LN_S" = "ln -s"; then - echo "$ac_t"yes 1>&6 - else - echo "$ac_t"no 1>&6 - fi -fi - -# Make sure LD is an absolute path. -if test -z "$LD"; then - ac_prog=ld - if test "$with_gcc" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 - echo "$progname:991: checking for ld used by GCC" >&5 - ac_prog=`($CC -print-prog-name=ld) 2>&5` - case "$ac_prog" in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we are not using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac - elif test "$with_gnu_ld" = yes; then - echo $ac_n "checking for GNU ld... $ac_c" 1>&6 - echo "$progname:1015: checking for GNU ld" >&5 - else - echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 - echo "$progname:1018: checking for non-GNU ld" >&5 - fi - - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" - fi - - if test -n "$LD"; then - echo "$ac_t$LD" 1>&6 - else - echo "$ac_t"no 1>&6 - fi - - if test -z "$LD"; then - echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 - exit 1 - fi -fi - -# Check to see if it really is or is not GNU ld. -echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 -# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - with_gnu_ld=yes -else - with_gnu_ld=no -fi -echo "$ac_t$with_gnu_ld" 1>&6 - -# See if the linker supports building shared libraries. -echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 - -allow_undefined_flag= -no_undefined_flag= -need_lib_prefix=unknown -need_version=unknown -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -archive_cmds= -archive_expsym_cmds= -old_archive_from_new_cmds= -export_dynamic_flag_spec= -whole_archive_flag_spec= -thread_safe_flag_spec= -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no -hardcode_shlibpath_var=unsupported -runpath_var= -always_export_symbols=no -export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' -# include_expsyms should be a list of space-separated symbols to be *always* -# included in the symbol list -include_expsyms= -# exclude_expsyms can be an egrep regular expression of symbols to exclude -# it will be wrapped by ` (' and `)$', so one must not match beginning or -# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', -# as well as any symbol that contains `d'. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" -# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out -# platforms (ab)use it in PIC code, but their linkers get confused if -# the symbol is explicitly referenced. Since portable code cannot -# rely on this symbol name, it's probably fine to never include it in -# preloaded symbol tables. - -case "$host_os" in -cygwin* | mingw*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$with_gcc" != yes; then - with_gnu_ld=no - fi - ;; - -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case "$host_os" in - aix3* | aix4*) - # On AIX, the GNU linker is very broken - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - ;; - - amigaos*) - archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=yes - - # Extract the symbol export list from an `--export-all' def file, - # then regenerate the def file from the symbol export list, so that - # the compiled dll only exports the symbol export list. - # Be careful not to strip the DATA tag left by newer dlltools. - export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ - test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ - $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ - sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $objdir/$soname-def > $export_symbols' - - # If DATA tags from a recent dlltool are present, honour them! - archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ - _lt_hint=1; - cat $export_symbols | while read symbol; do - set dummy \$symbol; - case \$# in - 2) echo " \$2 @ \$_lt_hint ; " >> $objdir/$soname-def;; - *) echo " \$2 @ \$_lt_hint \$3 ; " >> $objdir/$soname-def;; - esac; - _lt_hint=`expr 1 + \$_lt_hint`; - done~ - test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ - test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ - $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ - $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ - $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' - - old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' - # can we support soname and/or expsyms with a.out? -oliva - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - case $host_os in - cygwin* | mingw*) - # dlltool doesn't understand --whole-archive et. al. - whole_archive_flag_spec= - ;; - *) - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - ;; - esac - fi -else - # PORTME fill in a description of your system's linker (not GNU ld) - case "$host_os" in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$with_gcc" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4*) - hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' - hardcode_libdir_separator=':' - if test "$with_gcc" = yes; then - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - shared_flag='-shared' - else - shared_flag='${wl}-bM:SRE' - hardcode_direct=yes - fi - allow_undefined_flag=' ${wl}-berok' - archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' - archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' - case "$host_os" in aix4.[01]|aix4.[01].*) - # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on - always_export_symbols=yes ;; - esac - ;; - - amigaos*) - archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - cygwin* | mingw*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs' - fix_srcfile_path='`cygpath -w $srcfile`' - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9* | hpux10* | hpux11*) - case "$host_os" in - hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; - *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; - esac - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_minus_L=yes # Not in the search PATH, but as the default - # location of the library. - export_dynamic_flag_spec='${wl}-E' - ;; - - irix5* | irix6*) - if test "$with_gcc" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF - fi - hardcode_libdir_flag_spec='${wl}-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - openbsd*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' - ;; - - osf3*) - if test "$with_gcc" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # As osf3* with the addition of the -msym flag - if test "$with_gcc" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - rhapsody*) - archive_cmds='$CC -bundle -undefined suppress -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flags_spec='-L$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case "$host_os" in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $linkopts' - else - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - unixware7*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac -fi -echo "$ac_t$ld_shlibs" 1>&6 -test "$ld_shlibs" = no && can_build_shared=no - -if test -z "$NM"; then - echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 - case "$NM" in - [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - NM="$ac_dir/nm -B" - break - elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - NM="$ac_dir/nm -p" - break - else - NM=${NM="$ac_dir/nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - fi - fi - done - IFS="$ac_save_ifs" - test -z "$NM" && NM=nm - ;; - esac - echo "$ac_t$NM" 1>&6 -fi - -# Check for command to grab the raw symbol name followed by C symbol from nm. -echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" - -# Define system-specific variables. -case "$host_os" in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw*) - symcode='[ABCDGISTW]' - ;; -hpux*) # Its linker distinguishes data from code symbols - global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" - ;; -irix*) - symcode='[BCDEGRST]' - ;; -solaris*) - symcode='[BDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then - symcode='[ABCDGISTW]' -fi - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. - global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - $rm conftest* - cat > conftest.c <&5 - if { (eval echo $progname:1654: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then - # Now try to grab the symbols. - nlist=conftest.nm - if { echo "$progname:1657: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then - - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if egrep ' nm_test_var$' "$nlist" >/dev/null; then - if egrep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.c -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' - - cat <> conftest.c -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[] = -{ -EOF - sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c - cat <<\EOF >> conftest.c - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$objext conftstm.$objext - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="conftstm.$objext" - CFLAGS="$CFLAGS$no_builtin_flag" - if { (eval echo $progname:1709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - pipe_works=yes - else - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 - fi - LIBS="$save_LIBS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 - fi - $rm conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - global_symbol_pipe= - fi -done -if test "$pipe_works" = yes; then - echo "${ac_t}ok" 1>&6 -else - echo "${ac_t}failed" 1>&6 -fi - -if test -z "$global_symbol_pipe"; then - global_symbol_to_cdecl= -fi - -# Check hardcoding attributes. -echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var"; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$hardcode_shlibpath_var" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -echo "$ac_t$hardcode_action" 1>&6 - - -reload_flag= -reload_cmds='$LD$reload_flag -o $output$reload_objs' -echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 -# PORTME Some linkers may need a different reload flag. -reload_flag='-r' -echo "$ac_t$reload_flag" 1>&6 -test -n "$reload_flag" && reload_flag=" $reload_flag" - -# PORTME Fill in your ld.so characteristics -library_names_spec= -libname_spec='lib$name' -soname_spec= -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -file_magic_cmd= -file_magic_test_file= -deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [regex]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given egrep regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. -echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 -case "$host_os" in -aix3*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}.so$major' - ;; - -aix4*) - version_type=linux - # AIX has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - # We preserve .a as extension for shared libraries though AIX4.2 - # and later linker supports .so - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' - shlibpath_var=LIBPATH - deplibs_check_method=pass_all - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}.so' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - deplibs_check_method=pass_all - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - file_magic_cmd=/usr/bin/file - file_magic_test_file=/shlib/libc.so - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - export_dynamic_flag_spec=-rdynamic - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw*) - version_type=windows - need_version=no - need_lib_prefix=no - if test "$with_gcc" = yes; then - library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' - else - library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' - fi - dynamic_linker='Win32 ld.exe' - deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - file_magic_cmd='${OBJDUMP} -f' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case "$version_type" in - freebsd-elf*) - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /usr/lib/libc.so*` - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - deplibs_check_method=unknown - library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case "$host_os" in - freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - deplibs_check_method=pass_all - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - dynamic_linker="$host_os dld.sl" - version_type=sunos - need_lib_prefix=no - need_version=no - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' - soname_spec='${libname}${release}.sl$major' - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - case "$host_os" in - hpux10.20*) - # TODO: Does this work for hpux-11 too? - deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' - file_magic_cmd=/usr/bin/file - file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -irix5* | irix6*) - version_type=irix - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}.so.$major' - library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' - case "$host_os" in - irix5*) - libsuff= shlibsuff= - # this will be overridden with pass_all, but let us keep it just in case - deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" - ;; - *) - case "$LD" in # libtool.m4 will add one of these switches to LD - *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /lib${libsuff}/libc.so*` - deplibs_check_method='pass_all' - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux-gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - deplibs_check_method=pass_all - - if test -f /lib/ld.so.1; then - dynamic_linker='GNU ld.so' - else - # Only the GNU ld.so supports shared libraries on MkLinux. - case "$host_cpu" in - powerpc*) dynamic_linker=no ;; - *) dynamic_linker='Linux ld.so' ;; - esac - fi - ;; - -netbsd*) - version_type=sunos - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' - soname_spec='${libname}${release}.so$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - ;; - -openbsd*) - version_type=sunos - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - need_version=no - fi - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - ;; - -os2*) - libname_spec='$name' - need_lib_prefix=no - library_names_spec='$libname.dll $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_version=no - soname_spec='${libname}${release}.so' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - shlibpath_var=LD_LIBRARY_PATH - # this will be overridden with pass_all, but let us keep it just in case - deplibs_check_method='file_magic COFF format alpha shared library' - file_magic_cmd=/usr/bin/file - file_magic_test_file=/shlib/libc.so - deplibs_check_method='pass_all' - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rhapsody*) - version_type=sunos - library_names_spec='${libname}.so' - soname_spec='${libname}.so' - shlibpath_var=DYLD_LIBRARY_PATH - deplibs_check_method=pass_all - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" - file_magic_cmd=/usr/bin/file - file_magic_test_file=/lib/libc.so - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - case "$host_vendor" in - sequent) - file_magic_cmd='/bin/file' - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - ncr) - deplibs_check_method='pass_all' - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - esac - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' - soname_spec='$libname.so.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$ac_t$dynamic_linker" 1>&6 -test "$dynamic_linker" = no && can_build_shared=no - -# Report the final consequences. -echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 - -# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in -# configure.in, otherwise build static only libraries. -case "$host_os" in -cygwin* | mingw* | os2*) - if test x$can_build_shared = xyes; then - test x$enable_win32_dll = xno && can_build_shared=no - echo "checking if package supports dlls... $can_build_shared" 1>&6 - fi -;; -esac - -if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then - case "$deplibs_check_method" in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - egrep "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac -fi - -echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4*) - test "$enable_shared" = yes && enable_static=no - ;; -esac - -echo "$ac_t$enable_shared" 1>&6 - -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes - -echo "checking whether to build static libraries... $enable_static" 1>&6 - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -echo $ac_n "checking for objdir... $ac_c" 1>&6 -rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - objdir=_libs -fi -rmdir .libs 2>/dev/null -echo "$ac_t$objdir" 1>&6 - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else -if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then - lt_cv_dlopen=no lt_cv_dlopen_libs= -echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "$progname:2248: checking for dlopen in -ldl" >&5 -ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldl $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dlopen""... $ac_c" 1>&6 -echo "$progname:2288: checking for dlopen" >&5 -if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -dlopen(); -#endif - -; return 0; } -EOF -if { (eval echo $progname:2318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_dlopen=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_dlopen=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 -echo "$progname:2335: checking for dld_link in -ldld" >&5 -ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for shl_load""... $ac_c" 1>&6 -echo "$progname:2375: checking for shl_load" >&5 -if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -shl_load(); -#endif - -; return 0; } -EOF -if { (eval echo $progname:2405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_shl_load=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_shl_load=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="shl_load" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "$progname:2423: checking for shl_load in -ldld" >&5 -ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - echo "$ac_t""no" 1>&6 -fi - - -fi - - -fi - - -fi - - -fi - -fi - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - fi - - case "$lt_cv_dlopen" in - dlopen) -for ac_hdr in dlfcn.h; do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "$progname:2488: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -int fnord = 0; -EOF -ac_try="$ac_compile >/dev/null 2>conftest.out" -{ (eval echo $progname:2498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi -done - - if test "x$ac_cv_header_dlfcn_h" = xyes; then - CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - fi - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 -echo "$progname:2526: checking whether a program can dlopen itself" >&5 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - lt_cv_dlopen_self=cross - else - cat > conftest.c < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LTDL_GLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LTDL_GLOBAL DL_GLOBAL -# else -# define LTDL_GLOBAL 0 -# endif -#endif - -/* We may have to define LTDL_LAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LTDL_LAZY_OR_NOW -# ifdef RTLD_LAZY -# define LTDL_LAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LTDL_LAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LTDL_LAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LTDL_LAZY_OR_NOW DL_NOW -# else -# define LTDL_LAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -fnord() { int i=42;} -main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); - if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); - if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } - -EOF -if { (eval echo $progname:2580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - lt_cv_dlopen_self=yes -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - lt_cv_dlopen_self=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$lt_cv_dlopen_self" 1>&6 - - if test "$lt_cv_dlopen_self" = yes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 -echo "$progname:2599: checking whether a statically linked program can dlopen itself" >&5 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - lt_cv_dlopen_self_static=cross - else - cat > conftest.c < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LTDL_GLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LTDL_GLOBAL DL_GLOBAL -# else -# define LTDL_GLOBAL 0 -# endif -#endif - -/* We may have to define LTDL_LAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LTDL_LAZY_OR_NOW -# ifdef RTLD_LAZY -# define LTDL_LAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LTDL_LAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LTDL_LAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LTDL_LAZY_OR_NOW DL_NOW -# else -# define LTDL_LAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -fnord() { int i=42;} -main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); - if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); - if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } - -EOF -if { (eval echo $progname:2653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - lt_cv_dlopen_self_static=yes -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - lt_cv_dlopen_self_static=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 -fi - ;; - esac - - case "$lt_cv_dlopen_self" in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case "$lt_cv_dlopen_self_static" in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - -# Copy echo and quote the copy, instead of the original, because it is -# used later. -ltecho="$echo" -if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then - ltecho="$CONFIG_SHELL \$0 --fallback-echo" -fi -LTSHELL="$SHELL" - -LTCONFIG_VERSION="$VERSION" - -# Only quote variables if we're using ltmain.sh. -case "$ltmain" in -*.sh) - # Now quote all the things that may contain metacharacters. - for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ - old_LD old_LDFLAGS old_LIBS \ - old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ - AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ - reload_flag reload_cmds wl \ - pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ - thread_safe_flag_spec whole_archive_flag_spec libname_spec \ - library_names_spec soname_spec \ - RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ - old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ - file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ - finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ - hardcode_libdir_flag_spec hardcode_libdir_separator \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do - - case "$var" in - reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case "$ltecho" in - *'\$0 --fallback-echo"') - ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - - trap "$rm \"$ofile\"; exit 1" 1 2 15 - echo "creating $ofile" - $rm "$ofile" - cat < "$ofile" -#! $SHELL - -# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. -# -# Copyright (C) 1996-1999 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="sed -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -### BEGIN LIBTOOL CONFIG -EOF - cfgfile="$ofile" - ;; - -*) - # Double-quote the variables that need it (for aesthetics). - for var in old_CC old_CFLAGS old_CPPFLAGS \ - old_LD old_LDFLAGS old_LIBS \ - old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do - eval "$var=\\\"\$var\\\"" - done - - # Just create a config file. - cfgfile="$ofile.cfg" - trap "$rm \"$cfgfile\"; exit 1" 1 2 15 - echo "creating $cfgfile" - $rm "$cfgfile" - cat < "$cfgfile" -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -EOF - ;; -esac - -cat <> "$cfgfile" -# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# -# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ -# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ -# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ -# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ -# $0$ltconfig_args -# -# Compiler and other test output produced by $progname, useful for -# debugging $progname, is in ./config.log if it exists. - -# The version of $progname that generated this script. -LTCONFIG_VERSION=$LTCONFIG_VERSION - -# Shell to use when invoking shell scripts. -SHELL=$LTSHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$ltecho - -# The archiver. -AR=$AR - -# The default C compiler. -CC=$CC - -# The linker used to build libraries. -LD=$LD - -# Whether we need hard or soft links. -LN_S=$LN_S - -# A BSD-compatible nm program. -NM=$NM - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$reload_flag -reload_cmds=$reload_cmds - -# How to pass a linker flag through the compiler. -wl=$wl - -# Object file suffix (normally "o"). -objext="$objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$pic_flag - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$compiler_c_o - -# Can we write directly to a .lo ? -compiler_o_lo=$compiler_o_lo - -# Must we lock files when doing compilation ? -need_locks=$need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$link_static_flag - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$RANLIB -old_archive_cmds=$old_archive_cmds -old_postinstall_cmds=$old_postinstall_cmds -old_postuninstall_cmds=$old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$old_archive_from_new_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$archive_cmds -archive_expsym_cmds=$archive_expsym_cmds -postinstall_cmds=$postinstall_cmds -postuninstall_cmds=$postuninstall_cmds - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$global_symbol_to_cdecl - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$hardcode_libdir_separator - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$include_expsyms - -EOF - -case "$ltmain" in -*.sh) - echo '### END LIBTOOL CONFIG' >> "$ofile" - echo >> "$ofile" - case "$host_os" in - aix3*) - cat <<\EOF >> "$ofile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # Append the ltmain.sh script. - sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - - chmod +x "$ofile" - ;; - -*) - # Compile the libtool program. - echo "FIXME: would compile $ltmain" - ;; -esac - -test -n "$cache_file" || exit 0 - -# AC_CACHE_SAVE -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -exit 0 - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltmain.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltmain.sh deleted file mode 100644 index db4982d8a9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/ltmain.sh +++ /dev/null @@ -1,6538 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -basename="s,^.*/,,g" - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - -# The name of this program: -progname=`echo "$progpath" | $SED $basename` -modename="$progname" - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 - -PROGRAM=ltmain.sh -PACKAGE=libtool -VERSION="1.5.20 Debian 1.5.20-2" -TIMESTAMP=" (1.1220.2.287 2005/08/31 18:54:15)" - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes. -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$progpath" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -##################################### -# Shell function definitions: -# This seems to be the best place for them - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -func_win32_libid () -{ - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ - $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then - win32_nmres=`eval $NM -f posix -A $1 | \ - sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` - if test "X$win32_nmres" = "Ximport" ; then - win32_libid_type="x86 archive import" - else - win32_libid_type="x86 archive static" - fi - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $echo $win32_libid_type -} - - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case "$@ " in - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - $echo "$modename: unable to infer tagged configuration" - $echo "$modename: specify a tag with \`--tag'" 1>&2 - exit $EXIT_FAILURE -# else -# $echo "$modename: using $tagname tagged configuration" - fi - ;; - esac - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - - $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" - $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 - exit $EXIT_FAILURE - fi -} - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - my_status="" - - $show "${rm}r $my_gentop" - $run ${rm}r "$my_gentop" - $show "$mkdir $my_gentop" - $run $mkdir "$my_gentop" - my_status=$? - if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then - exit $my_status - fi - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` - my_xdir="$my_gentop/$my_xlib" - - $show "${rm}r $my_xdir" - $run ${rm}r "$my_xdir" - $show "$mkdir $my_xdir" - $run $mkdir "$my_xdir" - status=$? - if test "$status" -ne 0 && test ! -d "$my_xdir"; then - exit $status - fi - case $host in - *-darwin*) - $show "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - if test -z "$run"; then - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` - darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` - if test -n "$darwin_arches"; then - darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - $show "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we have a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` - lipo -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - ${rm}r unfat-$$ - cd "$darwin_orig_dir" - else - cd "$darwin_orig_dir" - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - fi # $run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - func_extract_archives_result="$my_oldobjs" -} -# End of Shell function definitions -##################################### - -# Darwin sucks -eval std_shrext=\"$shrext_cmds\" - -# Parse our command line options once, thoroughly. -while test "$#" -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - tag) - tagname="$arg" - preserve_args="${preserve_args}=$arg" - - # Check whether tagname contains only valid characters - case $tagname in - *[!-_A-Za-z0-9,/]*) - $echo "$progname: invalid tag name: $tagname" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $tagname in - CC) - # Don't test for the "default" C tag, as we know, it's there, but - # not specially marked. - ;; - *) - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then - taglist="$taglist $tagname" - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" - else - $echo "$progname: ignoring unknown tag $tagname" 1>&2 - fi - ;; - esac - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - $echo - $echo "Copyright (C) 2005 Free Software Foundation, Inc." - $echo "This is free software; see the source for copying conditions. There is NO" - $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - exit $? - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath - # Now print the configurations for the tags. - for tagname in $taglist; do - ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" - done - exit $? - ;; - - --debug) - $echo "$progname: enabling shell trace mode" - set -x - preserve_args="$preserve_args $arg" - ;; - - --dry-run | -n) - run=: - ;; - - --features) - $echo "host: $host" - if test "$build_libtool_libs" = yes; then - $echo "enable shared libraries" - else - $echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - $echo "enable static libraries" - else - $echo "disable static libraries" - fi - exit $? - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - preserve_args="$preserve_args $arg" - ;; - - --tag) prevopt="--tag" prev=tag ;; - --tag=*) - set tag "$optarg" ${1+"$@"} - shift - prev=tag - preserve_args="$preserve_args --tag" - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE -fi - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 - $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 - case $nonopt in - *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - if test -n "$libobj" ; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit $EXIT_FAILURE - fi - arg_mode=target - continue - ;; - - -static | -prefer-pic | -prefer-non-pic) - later="$later $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - base_compile="$base_compile $lastarg" - continue - ;; - - * ) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - case $lastarg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, and some SunOS ksh mistreat backslash-escaping - # in scan sets (worked around with variable expansion), - # and furthermore cannot handle '|' '&' '(' ')' in scan sets - # at all, so we specify them separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - base_compile="$base_compile $lastarg" - done # for arg - - case $arg_mode in - arg) - $echo "$modename: you must specify an argument for -Xcompile" - exit $EXIT_FAILURE - ;; - target) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit $EXIT_FAILURE - ;; - *) - # Get the name of the library object. - [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSifmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.ii) xform=ii ;; - *.class) xform=class ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - *.java) xform=java ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` - case $qlibobj in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qlibobj="\"$qlibobj\"" ;; - esac - test "X$libobj" != "X$qlibobj" \ - && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." - objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir= - else - xdir=$xdir/ - fi - lobj=${xdir}$objdir/$objname - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$progpath" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - $echo "$srcfile" > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` - case $qsrcfile in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qsrcfile="\"$qsrcfile\"" ;; - esac - - $run $rm "$libobj" "${libobj}T" - - # Create a libtool object file (analogous to a ".la" file), - # but don't create it if we're doing a dry run. - test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - $show "$mv $output_obj $lobj" - if $run $mv $output_obj $lobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the PIC object to the libtool object file. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the non-PIC object the libtool object file. - # Only append if the libtool object file exists. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit $EXIT_FAILURE - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat $save_arg` - do -# moreargs="$moreargs $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - done - else - $echo "$modename: link input file \`$save_arg' does not exist" - exit $EXIT_FAILURE - fi - arg=$save_arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - xcclinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - darwin_framework) - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - prev= - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit $EXIT_FAILURE - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework|-arch) - prev=darwin_framework - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit $EXIT_FAILURE - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - deplibs="$deplibs -framework System" - continue - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - -model) - compile_command="$compile_command $arg" - compiler_flags="$compiler_flags $arg" - finalize_command="$finalize_command $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # -64, -mips[0-9] enable 64-bit mode on the SGI compiler - # -r[0-9][0-9]* specifies the processor on the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler - # +DA*, +DD* enable 64-bit mode on the HP compiler - # -q* pass through compiler args for the IBM compiler - # -m* pass through architecture-specific compiler args for GCC - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*) - - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - if test "$with_gcc" = "yes" ; then - compiler_flags="$compiler_flags $arg" - fi - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.$objext) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d "$output_objdir"; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test "$status" -ne 0 && test ! -d "$output_objdir"; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - case $host in - *cygwin* | *mingw* | *pw32*) - # don't eliminate duplications in $postdeps and $predeps - duplicate_compiler_generated_deps=yes - ;; - *) - duplicate_compiler_generated_deps=$duplicate_deps - ;; - esac - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; - esac - pre_post_deps="$pre_post_deps $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) - libs="$deplibs %DEPLIBS%" - test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" - ;; - esac - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - compiler_flags="$compiler_flags $deplib" - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if (${SED} -e '2q' $lib | - grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - library_names= - old_library= - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - if eval $echo \"$deplib\" 2>/dev/null \ - | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - $echo - $echo "*** Warning: Trying to link with static lib archive $deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because the file extensions .$libext of this argument makes me believe" - $echo "*** that it is just a static archive that I should not used here." - else - $echo - $echo "*** Warning: Linking the shared library $output against the" - $echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit $EXIT_FAILURE - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - dlprefiles="$dlprefiles $lib $dependency_libs" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $absdir" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - # This is a shared library - - # Warn about portability, can't link against -module's on - # some systems (darwin) - if test "$shouldnotlink" = yes && test "$pass" = link ; then - $echo - if test "$linkmode" = prog; then - $echo "*** Warning: Linking the executable $output against the loadable module" - else - $echo "*** Warning: Linking the shared library $output against the loadable module" - fi - $echo "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`$echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$extract_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$old_archive_from_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5* ) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a module then we can not link against - # it, someone is ignoring the new warnings I added - if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then - $echo "** Warning, lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - $echo - $echo "** And there doesn't seem to be a static archive available" - $echo "** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit $EXIT_FAILURE - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - $echo - $echo "*** Warning: This system can not link to static lib archive $lib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - $echo "*** But as you try to build a module library, libtool will still create " - $echo "*** a static module, that should work as long as the dlopening application" - $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="$absdir" - fi - depdepl= - case $host in - *-*-darwin*) - # we do not want to link against static libs, - # but need to link against shared - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$path/$depdepl" ; then - depdepl="$path/$depdepl" - fi - # do not add paths which are already there - case " $newlib_search_path " in - *" $path "*) ;; - *) newlib_search_path="$newlib_search_path $path";; - esac - fi - path="" - ;; - *) - path="-L$path" - ;; - esac - ;; - -l*) - case $host in - *-*-darwin*) - # Again, we only want to link against shared libraries - eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` - for tmp in $newlib_search_path ; do - if test -f "$tmp/lib$tmp_libs.dylib" ; then - eval depdepl="$tmp/lib$tmp_libs.dylib" - break - fi - done - path="" - ;; - *) continue ;; - esac - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - case " $deplibs " in - *" $depdepl "*) ;; - *) deplibs="$depdepl $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - tmp_libs="$tmp_libs $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit $EXIT_FAILURE - else - $echo - $echo "*** Warning: Linking the shared library $output against the non-libtool" - $echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test "$#" -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$2" - number_minor="$3" - number_revision="$4" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows) - current=`expr $number_major + $number_minor` - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - current=`expr $number_major + $number_minor - 1` - age="$number_minor" - revision="$number_minor" - ;; - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE - ;; - esac - ;; - no) - current="$2" - revision="$3" - age="$4" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test "$age" -gt "$current"; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - major=`expr $current - $age + 1` - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$echo "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - removelist="$removelist $p" - ;; - *) ;; - esac - done - if test -n "$removelist"; then - $show "${rm}r $removelist" - $run ${rm}r $removelist - fi - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` - deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` - dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for file magic test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name=`expr $a_deplib : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval $echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` - done - fi - if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ - | grep . >/dev/null; then - $echo - if test "X$deplibs_check_method" = "Xnone"; then - $echo "*** Warning: inter-library dependencies are not supported in this platform." - else - $echo "*** Warning: inter-library dependencies are not known to be supported." - fi - $echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - $echo - $echo "*** Warning: libtool could not satisfy all declared inter-library" - $echo "*** dependencies of module $libname. Therefore, libtool will create" - $echo "*** a static module, that should work as long as the dlopening" - $echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - $echo "*** The inter-library dependencies that have been dropped here will be" - $echo "*** automatically added whenever a program is linked with this library" - $echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - $echo - $echo "*** Since this library must not contain undefined symbols," - $echo "*** because either the platform does not support them or" - $echo "*** it was explicitly requested with -no-undefined," - $echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - if len=`expr "X$cmd" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - $show "$cmd" - $run eval "$cmd" || exit $? - skipped_export=false - else - # The command line is too long to execute in one step. - $show "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - tmp_deplibs="$tmp_deplibs $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - libobjs="$libobjs $func_extract_archives_result" - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise. - $echo "creating reloadable object files..." - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - output_la=`$echo "X$output" | $Xsed -e "$basename"` - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - delfiles= - last_robj= - k=1 - output=$output_objdir/$output_la-${k}.$objext - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" - if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - k=`expr $k + 1` - output=$output_objdir/$output_la-${k}.$objext - objlist=$obj - len=1 - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" - - if ${skipped_export-false}; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - libobjs=$output - # Append the command to create the export file. - eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" - fi - - # Set up a command to remove the reloadable object files - # after they are used. - i=0 - while test "$i" -lt "$k" - do - i=`expr $i + 1` - delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" - done - - $echo "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - - # Append the command to remove the reloadable object files - # to the just-reset $cmds. - eval cmds=\"\$cmds~\$rm $delfiles\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit $EXIT_FAILURE - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $run eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - if test "$tagname" = CXX ; then - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - fi - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval '$echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - $echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -" - - case $host in - *cygwin* | *mingw* ) - $echo >> "$output_objdir/$dlsyms" "\ -/* DATA imports from DLLs on WIN32 can't be const, because - runtime relocations are performed -- see ld's documentation - on pseudo-relocs */ -struct { -" - ;; - * ) - $echo >> "$output_objdir/$dlsyms" "\ -const struct { -" - ;; - esac - - - $echo >> "$output_objdir/$dlsyms" "\ - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then - case $progpath in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; - *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - cwrappersource=`$echo ${objdir}/lt-${outputname}.c` - cwrapper=`$echo ${output}.exe` - $rm $cwrappersource $cwrapper - trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - cat > $cwrappersource <> $cwrappersource<<"EOF" -#include -#include -#include -#include -#include -#include - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -#define HAVE_DOS_BASED_FILE_SYSTEM -#ifndef DIR_SEPARATOR_2 -#define DIR_SEPARATOR_2 '\\' -#endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -const char *program_name = NULL; - -void * xmalloc (size_t num); -char * xstrdup (const char *string); -char * basename (const char *name); -char * fnqualify(const char *path); -char * strendzap(char *str, const char *pat); -void lt_fatal (const char *message, ...); - -int -main (int argc, char *argv[]) -{ - char **newargz; - int i; - - program_name = (char *) xstrdup ((char *) basename (argv[0])); - newargz = XMALLOC(char *, argc+2); -EOF - - cat >> $cwrappersource <> $cwrappersource <<"EOF" - newargz[1] = fnqualify(argv[0]); - /* we know the script has the same name, without the .exe */ - /* so make sure newargz[1] doesn't end in .exe */ - strendzap(newargz[1],".exe"); - for (i = 1; i < argc; i++) - newargz[i+1] = xstrdup(argv[i]); - newargz[argc+1] = NULL; -EOF - - cat >> $cwrappersource <> $cwrappersource <<"EOF" - return 127; -} - -void * -xmalloc (size_t num) -{ - void * p = (void *) malloc (num); - if (!p) - lt_fatal ("Memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL -; -} - -char * -basename (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha (name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return (char *) base; -} - -char * -fnqualify(const char *path) -{ - size_t size; - char *p; - char tmp[LT_PATHMAX + 1]; - - assert(path != NULL); - - /* Is it qualified already? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha (path[0]) && path[1] == ':') - return xstrdup (path); -#endif - if (IS_DIR_SEPARATOR (path[0])) - return xstrdup (path); - - /* prepend the current directory */ - /* doesn't handle '~' */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ - p = XMALLOC(char, size); - sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); - return p; -} - -char * -strendzap(char *str, const char *pat) -{ - size_t len, patlen; - - assert(str != NULL); - assert(pat != NULL); - - len = strlen(str); - patlen = strlen(pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp(str, pat) == 0) - *str = '\0'; - } - return str; -} - -static void -lt_error_core (int exit_status, const char * mode, - const char * message, va_list ap) -{ - fprintf (stderr, "%s: %s: ", program_name, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, "FATAL", message, ap); - va_end (ap); -} -EOF - # we should really use a build-platform specific compiler - # here, but OTOH, the wrappers (shell script and this C one) - # are only useful if you want to execute the "real" binary. - # Since the "real" binary is built for $host, then this - # wrapper might as well be built for $host, too. - $run $LTCC -s -o $cwrapper $cwrappersource - ;; - esac - $rm $output - trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='${SED} -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - $echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit $EXIT_FAILURE - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - $echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit $EXIT_FAILURE - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - $echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit $EXIT_FAILURE - fi -fi\ -" - chmod +x $output - fi - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $addlibs - oldobjs="$oldobjs $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - $echo "X$obj" | $Xsed -e 's%^.*/%%' - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "copying selected object files to avoid basename conflicts..." - - if test -z "$gentop"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - status=$? - if test "$status" -ne 0 && test ! -d "$gentop"; then - exit $status - fi - fi - - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - counter=`expr $counter + 1` - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - $run ln "$obj" "$gentop/$newobj" || - $run cp "$obj" "$gentop/$newobj" - oldobjs="$oldobjs $gentop/$newobj" - ;; - *) oldobjs="$oldobjs $obj" ;; - esac - done - fi - - eval cmds=\"$old_archive_cmds\" - - if len=`expr "X$cmds" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - $echo "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - for obj in $save_oldobjs - do - oldobjs="$objlist $obj" - objlist="$objlist $obj" - eval test_cmds=\"$old_archive_cmds\" - if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - eval cmd=\"$cmd\" - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlfiles="$newdlfiles $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlprefiles="$newdlprefiles $abs" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit $EXIT_SUCCESS - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - case " $install_prog " in - *[\\\ /]cp\ *) ;; - *) prev=$arg ;; - esac - ;; - -g | -m | -o) prev=$arg ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test "$#" -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - exit $EXIT_FAILURE - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - cmds=$postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - file=`$echo $file|${SED} 's,.exe$,,'` - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit $EXIT_FAILURE - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir="$tmpdir/libtool-$$" - save_umask=`umask` - umask 0077 - if $mkdir "$tmpdir"; then - umask $save_umask - else - umask $save_umask - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$old_striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - cmds=$old_postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - cmds=$finish_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = : && exit $EXIT_SUCCESS - - $echo "----------------------------------------------------------------------" - $echo "Libraries have been installed in:" - for libdir in $libdirs; do - $echo " $libdir" - done - $echo - $echo "If you ever happen to want to link against installed libraries" - $echo "in a given directory, LIBDIR, you must either use libtool, and" - $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - $echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - $echo " during execution" - fi - if test -n "$runpath_var"; then - $echo " - add LIBDIR to the \`$runpath_var' environment variable" - $echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - $echo - $echo "See any operating system documentation about shared libraries for" - $echo "more information, such as the ld(1) and ld.so(8) manual pages." - $echo "----------------------------------------------------------------------" - exit $EXIT_SUCCESS - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit $EXIT_FAILURE - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit $EXIT_FAILURE - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit $EXIT_SUCCESS - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - rmdirs= - - origobjdir="$objdir" - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$origobjdir" - else - objdir="$dir/$origobjdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test "$mode" = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test "$mode" = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - cmds=$postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - cmds=$old_postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - - # Read the .lo file - . $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" \ - && test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" \ - && test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$mode" = clean ; then - noexename=$name - case $file in - *.exe) - file=`$echo $file|${SED} 's,.exe$,,'` - noexename=`$echo $name|${SED} 's,.exe$,,'` - # $file with .exe has already been added to rmfiles, - # add $file without .exe - rmfiles="$rmfiles $file" - ;; - esac - # Do a test to see if this is a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$noexename - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - objdir="$origobjdir" - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit $EXIT_FAILURE -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE. - -Report bugs to ." - exit $EXIT_SUCCESS - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; -esac - -$echo -$echo "Try \`$modename --help' for more information about other modes." - -exit $? - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/missing b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/missing deleted file mode 100755 index 6a37006e8f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/missing +++ /dev/null @@ -1,336 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -case "$1" in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing 0.4 - GNU automake" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. - You can get \`$1Help2man' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then - # We have makeinfo, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - tar) - shift - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - fi - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case "$firstarg" in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case "$firstarg" in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/mkinstalldirs b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/mkinstalldirs deleted file mode 100755 index 4324e052bb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/scripts/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id: mkinstalldirs,v 1.1 1999/06/27 07:45:05 cvs Exp $ - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" 1>&2 - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/stamp-h.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/stamp-h.in deleted file mode 100644 index 9788f70238..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/stamp-h.in +++ /dev/null @@ -1 +0,0 @@ -timestamp diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.am deleted file mode 100644 index 5213164a76..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.am +++ /dev/null @@ -1,65 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: tests Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 21.5.1999 -# ************************************************************************* - -INCLUDES = -I.. - -noinst_PROGRAMS = testsms testsms2 testparser testgsmlib testpb testpb2 \ - testspb testssms testcb - -TESTS = runspb.sh runspb2.sh runssms.sh runsms.sh \ - runparser.sh runspbi.sh - -# test files used for file-based phonebook and SMS testing -EXTRA_DIST = spb.pb runspb.sh runspb2.sh runssms.sh runsms.sh \ - runparser.sh \ - spb.pb spb2.pb \ - testparser-output.txt testspb-output.txt \ - testssms-output.txt testsms-output.txt \ - testspb2-output.txt \ - runspbi.sh spbi2-orig.pb spbi1.pb testspbi-output.txt - -# build testsms from testsms.cc and libgsmme.la -testsms_SOURCES = testsms.cc -testsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testsms2 from testsms2.cc and libgsmme.la -testsms2_SOURCES = testsms2.cc -testsms2_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testparser from testparser.cc and libgsmme.la -testparser_SOURCES = testparser.cc -testparser_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testgsmlib from testgsmlib.cc and libgsmme.la -testgsmlib_SOURCES = testgsmlib.cc -testgsmlib_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testpb from testpb.cc and libgsmme.la -testpb_SOURCES = testpb.cc -testpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testpb2 from testpb2.cc and libgsmme.la -testpb2_SOURCES = testpb2.cc -testpb2_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testspb from testspb.cc and libgsmme.la -testspb_SOURCES = testspb.cc -testspb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testssms from testssms.cc and libgsmme.la -testssms_SOURCES = testssms.cc -testssms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testcb from testcb.cc and libgsmme.la -testcb_SOURCES = testcb.cc -testcb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.in deleted file mode 100644 index e949e268ff..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/Makefile.in +++ /dev/null @@ -1,544 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: tests Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 21.5.1999 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -INCLUDES = -I.. - -noinst_PROGRAMS = testsms testsms2 testparser testgsmlib testpb testpb2 \ - testspb testssms testcb - - -TESTS = runspb.sh runspb2.sh runssms.sh runsms.sh \ - runparser.sh runspbi.sh - - -# test files used for file-based phonebook and SMS testing -EXTRA_DIST = spb.pb runspb.sh runspb2.sh runssms.sh runsms.sh \ - runparser.sh \ - spb.pb spb2.pb \ - testparser-output.txt testspb-output.txt \ - testssms-output.txt testsms-output.txt \ - testspb2-output.txt \ - runspbi.sh spbi2-orig.pb spbi1.pb testspbi-output.txt - - -# build testsms from testsms.cc and libgsmme.la -testsms_SOURCES = testsms.cc -testsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testsms2 from testsms2.cc and libgsmme.la -testsms2_SOURCES = testsms2.cc -testsms2_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testparser from testparser.cc and libgsmme.la -testparser_SOURCES = testparser.cc -testparser_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testgsmlib from testgsmlib.cc and libgsmme.la -testgsmlib_SOURCES = testgsmlib.cc -testgsmlib_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testpb from testpb.cc and libgsmme.la -testpb_SOURCES = testpb.cc -testpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testpb2 from testpb2.cc and libgsmme.la -testpb2_SOURCES = testpb2.cc -testpb2_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testspb from testspb.cc and libgsmme.la -testspb_SOURCES = testspb.cc -testspb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testssms from testssms.cc and libgsmme.la -testssms_SOURCES = testssms.cc -testssms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) - -# build testcb from testcb.cc and libgsmme.la -testcb_SOURCES = testcb.cc -testcb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) -subdir = tests -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -noinst_PROGRAMS = testsms$(EXEEXT) testsms2$(EXEEXT) testparser$(EXEEXT) \ - testgsmlib$(EXEEXT) testpb$(EXEEXT) testpb2$(EXEEXT) \ - testspb$(EXEEXT) testssms$(EXEEXT) testcb$(EXEEXT) -PROGRAMS = $(noinst_PROGRAMS) - -am_testcb_OBJECTS = testcb.$(OBJEXT) -testcb_OBJECTS = $(am_testcb_OBJECTS) -testcb_DEPENDENCIES = ../gsmlib/libgsmme.la -testcb_LDFLAGS = -am_testgsmlib_OBJECTS = testgsmlib.$(OBJEXT) -testgsmlib_OBJECTS = $(am_testgsmlib_OBJECTS) -testgsmlib_DEPENDENCIES = ../gsmlib/libgsmme.la -testgsmlib_LDFLAGS = -am_testparser_OBJECTS = testparser.$(OBJEXT) -testparser_OBJECTS = $(am_testparser_OBJECTS) -testparser_DEPENDENCIES = ../gsmlib/libgsmme.la -testparser_LDFLAGS = -am_testpb_OBJECTS = testpb.$(OBJEXT) -testpb_OBJECTS = $(am_testpb_OBJECTS) -testpb_DEPENDENCIES = ../gsmlib/libgsmme.la -testpb_LDFLAGS = -am_testpb2_OBJECTS = testpb2.$(OBJEXT) -testpb2_OBJECTS = $(am_testpb2_OBJECTS) -testpb2_DEPENDENCIES = ../gsmlib/libgsmme.la -testpb2_LDFLAGS = -am_testsms_OBJECTS = testsms.$(OBJEXT) -testsms_OBJECTS = $(am_testsms_OBJECTS) -testsms_DEPENDENCIES = ../gsmlib/libgsmme.la -testsms_LDFLAGS = -am_testsms2_OBJECTS = testsms2.$(OBJEXT) -testsms2_OBJECTS = $(am_testsms2_OBJECTS) -testsms2_DEPENDENCIES = ../gsmlib/libgsmme.la -testsms2_LDFLAGS = -am_testspb_OBJECTS = testspb.$(OBJEXT) -testspb_OBJECTS = $(am_testspb_OBJECTS) -testspb_DEPENDENCIES = ../gsmlib/libgsmme.la -testspb_LDFLAGS = -am_testssms_OBJECTS = testssms.$(OBJEXT) -testssms_OBJECTS = $(am_testssms_OBJECTS) -testssms_DEPENDENCIES = ../gsmlib/libgsmme.la -testssms_LDFLAGS = - -DEFS = @DEFS@ -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp -am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/testcb.Po ./$(DEPDIR)/testgsmlib.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/testparser.Po ./$(DEPDIR)/testpb.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/testpb2.Po ./$(DEPDIR)/testsms.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/testsms2.Po ./$(DEPDIR)/testspb.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/testssms.Po -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CXXFLAGS = @CXXFLAGS@ -DIST_SOURCES = $(testcb_SOURCES) $(testgsmlib_SOURCES) \ - $(testparser_SOURCES) $(testpb_SOURCES) $(testpb2_SOURCES) \ - $(testsms_SOURCES) $(testsms2_SOURCES) $(testspb_SOURCES) \ - $(testssms_SOURCES) -DIST_COMMON = Makefile.am Makefile.in -SOURCES = $(testcb_SOURCES) $(testgsmlib_SOURCES) $(testparser_SOURCES) $(testpb_SOURCES) $(testpb2_SOURCES) $(testsms_SOURCES) $(testsms2_SOURCES) $(testspb_SOURCES) $(testssms_SOURCES) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .cc .lo .o .obj -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu tests/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -testcb$(EXEEXT): $(testcb_OBJECTS) $(testcb_DEPENDENCIES) - @rm -f testcb$(EXEEXT) - $(CXXLINK) $(testcb_LDFLAGS) $(testcb_OBJECTS) $(testcb_LDADD) $(LIBS) -testgsmlib$(EXEEXT): $(testgsmlib_OBJECTS) $(testgsmlib_DEPENDENCIES) - @rm -f testgsmlib$(EXEEXT) - $(CXXLINK) $(testgsmlib_LDFLAGS) $(testgsmlib_OBJECTS) $(testgsmlib_LDADD) $(LIBS) -testparser$(EXEEXT): $(testparser_OBJECTS) $(testparser_DEPENDENCIES) - @rm -f testparser$(EXEEXT) - $(CXXLINK) $(testparser_LDFLAGS) $(testparser_OBJECTS) $(testparser_LDADD) $(LIBS) -testpb$(EXEEXT): $(testpb_OBJECTS) $(testpb_DEPENDENCIES) - @rm -f testpb$(EXEEXT) - $(CXXLINK) $(testpb_LDFLAGS) $(testpb_OBJECTS) $(testpb_LDADD) $(LIBS) -testpb2$(EXEEXT): $(testpb2_OBJECTS) $(testpb2_DEPENDENCIES) - @rm -f testpb2$(EXEEXT) - $(CXXLINK) $(testpb2_LDFLAGS) $(testpb2_OBJECTS) $(testpb2_LDADD) $(LIBS) -testsms$(EXEEXT): $(testsms_OBJECTS) $(testsms_DEPENDENCIES) - @rm -f testsms$(EXEEXT) - $(CXXLINK) $(testsms_LDFLAGS) $(testsms_OBJECTS) $(testsms_LDADD) $(LIBS) -testsms2$(EXEEXT): $(testsms2_OBJECTS) $(testsms2_DEPENDENCIES) - @rm -f testsms2$(EXEEXT) - $(CXXLINK) $(testsms2_LDFLAGS) $(testsms2_OBJECTS) $(testsms2_LDADD) $(LIBS) -testspb$(EXEEXT): $(testspb_OBJECTS) $(testspb_DEPENDENCIES) - @rm -f testspb$(EXEEXT) - $(CXXLINK) $(testspb_LDFLAGS) $(testspb_OBJECTS) $(testspb_LDADD) $(LIBS) -testssms$(EXEEXT): $(testssms_OBJECTS) $(testssms_DEPENDENCIES) - @rm -f testssms$(EXEEXT) - $(CXXLINK) $(testssms_LDFLAGS) $(testssms_OBJECTS) $(testssms_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcb.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testgsmlib.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testparser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testpb.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testpb2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsms.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsms2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testspb.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testssms.Po@am__quote@ - -distclean-depend: - -rm -rf ./$(DEPDIR) - -.cc.o: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -.cc.obj: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CXXCOMPILE) -c -o $@ `cygpath -w $<` - -.cc.lo: -@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -CXXDEPMODE = @CXXDEPMODE@ - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ETAGS = etags -ETAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH - -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; \ - srcdir=$(srcdir); export srcdir; \ - list='$(TESTS)'; \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *" $$tst "*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - echo "XPASS: $$tst"; \ - ;; \ - *) \ - echo "PASS: $$tst"; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *" $$tst "*) \ - xfail=`expr $$xfail + 1`; \ - echo "XFAIL: $$tst"; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - echo "FAIL: $$tst"; \ - ;; \ - esac; \ - fi; \ - done; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="All $$all tests passed"; \ - else \ - banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all tests failed"; \ - else \ - banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ - fi; \ - fi; \ - dashes=`echo "$$banner" | sed s/./=/g`; \ - echo "$$dashes"; \ - echo "$$banner"; \ - echo "$$dashes"; \ - test "$$failed" -eq 0; \ - else :; fi -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(PROGRAMS) - -installdirs: - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ - mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-compile distclean-depend \ - distclean-generic distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -uninstall-am: uninstall-info-am - -.PHONY: GTAGS all all-am check check-TESTS check-am clean clean-generic \ - clean-libtool clean-noinstPROGRAMS distclean distclean-compile \ - distclean-depend distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am info info-am install \ - install-am install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - tags uninstall uninstall-am uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runparser.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runparser.sh deleted file mode 100755 index 9ee9d312f5..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runparser.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -errorexit() { - echo $1 - exit 1 -} - -# run the test -./testparser > testparser.log - -# check if output differs from what it should be -diff testparser.log testparser-output.txt diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runsms.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runsms.sh deleted file mode 100755 index f027544ee7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runsms.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -errorexit() { - echo $1 - exit 1 -} - -# prepare locales to make date format reproducible -LC_ALL=en_US -LANG=en -LINGUAS=en -export LC_ALL LANG LINGUAS - -# run the test -./testsms > testsms.log - -# check if output differs from what it should be -diff testsms.log testsms-output.txt diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb.sh deleted file mode 100755 index fb8c6200f8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -errorexit() { - echo $1 - exit 1 -} - -cp spb.pb spb-copy.pb || errorexit "could not copy spb.pb to spb-copy.pb" - -# run the test -./testspb > testspb.log - -# add new contents of phonebook file to the test log -cat spb-copy.pb >> testspb.log - -# check if output differs from what it should be -diff testspb.log testspb-output.txt diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb2.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb2.sh deleted file mode 100755 index df8f123cae..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspb2.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -errorexit() { - echo $1 - exit 1 -} - -cp spb2.pb spb-copy.pb || errorexit "could not copy spb2.pb to spb2-copy.pb" - -# run the test -./testspb > testspb2.log - -# add new contents of phonebook file to the test log -cat spb-copy.pb >> testspb2.log - -# check if output differs from what it should be -diff testspb2.log testspb2-output.txt diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspbi.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspbi.sh deleted file mode 100755 index 94b5b459a4..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runspbi.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -errorexit() { - echo $1 - exit 1 -} - -cp spbi2-orig.pb spbi2.pb || - errorexit "could not copy spbi2-orig.pb to spbi2.pb" - -# run the test -../apps/gsmpb -V -i -s spbi1.pb -d spbi2.pb > testspbi.log - -# add new contents of phonebook file to the test log -cat spbi2.pb >> testspbi.log - -# check if output differs from what it should be -diff testspbi.log testspbi-output.txt diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runssms.sh b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runssms.sh deleted file mode 100755 index 5b11442189..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/runssms.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -errorexit() { - echo $1 - exit 1 -} - -rm -f sms.sms || errorexit "could not delete sms.sms" -touch sms.sms || errorexit "could not create sms.sms" - -# prepare locales to make date format reproducible -LC_ALL=en_US -LANG=en -LINGUAS=en -export LC_ALL LANG LINGUAS - -# run the test -./testssms > testssms.log - -# check if output differs from what it should be -diff testssms.log testssms-output.txt diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb.pb b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb.pb deleted file mode 100644 index debd672369..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb.pb +++ /dev/null @@ -1,11 +0,0 @@ -|Dieter Meier|793045 -|Edgar Hofmann|42345 -|Goethe|847159 -|Hans Hofmann|12345 -|Hans-Dieter Schmidt|82345 -|Hans-Dieter Schmidt|13333345 -|Heiner Mller|7890 -|line with \||0815 -|line with\\|0815 -|One line\rback to start|0815 -|two\nline|0815 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb2.pb b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb2.pb deleted file mode 100644 index ed0c16cc73..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spb2.pb +++ /dev/null @@ -1,11 +0,0 @@ -|Dieter Meier|017793045 -|Edgar Hofmann|+4942345 -|Goethe|847159 -|Hans Hofmann|0171 -|Hans-Dieter Schmidt|82345 -|Hans-Dieter Schmidt|13333345 -|Heiner Mller|7890 -|line with \||0815 -|line with\\|0815 -|One line\rback to start|0815 -|two\nline|0815 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi1.pb b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi1.pb deleted file mode 100644 index 11b913f254..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi1.pb +++ /dev/null @@ -1,3 +0,0 @@ -1|Nummer 4|4444444 -3|Nummer 3|3333333 -5|same name|12345 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi2-orig.pb b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi2-orig.pb deleted file mode 100644 index 90f2337bbd..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/spbi2-orig.pb +++ /dev/null @@ -1,4 +0,0 @@ -2|Nummer 3|3333333 -4|Nummer 4|4444444 -5|same name|23456 - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testcb.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testcb.cc deleted file mode 100644 index 59617d864f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testcb.cc +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: testcb.cc -// * -// * Purpose: Test cell broadcast SMS -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 3.8.2001 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -int main(int argc, char *argv[]) -{ - try - { - CBMessageRef cbm = new CBMessage("001000320111C3343D0F82C51A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100"); - - cout << cbm->toString(); - - cbm = new CBMessage("001000320111C4EAB3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100"); - - cout << cbm->toString(); - } - catch (GsmException &ge) - { - cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; - } -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testgsmlib.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testgsmlib.cc deleted file mode 100755 index a40e74178d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testgsmlib.cc +++ /dev/null @@ -1,179 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: testgsmlib.cc -// * -// * Purpose: Test general gsm functions (without SMS/phonebook) -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 17.5.1999 -// ************************************************************************* -#ifdef HAVE_CONFIG_H -#include -#endif -#ifdef WIN32 -#include -#include -#else -#include -#endif -#include -#include - -using namespace std; -using namespace gsmlib; - -// some time-consuming tests can be switched off by commenting out the -// following macros -#define TEST_OPERATOR_INFO - -void printForwardReason(string s, ForwardInfo &info) -{ - cout << " " << s << ": " - << (info._active ? "active " : "inactive ") - << "number: " << info._number - << " subaddr: " << info._subAddr - << " time: " << info._time << endl; -} - -int main(int argc, char *argv[]) -{ - try - { - cout << (string)"Opening device " + argv[1] << endl; -#ifdef WIN32 - Ref port = new Win32SerialPort((string)argv[1], 38400); -#else - Ref port = new UnixSerialPort((string)argv[1], B38400); -#endif - - cout << "Creating MeTa object" << endl; - MeTa m(port); - - cout << "Getting ME info" << endl; - MEInfo mei = m.getMEInfo(); - - cout << " Manufacturer: " << mei._manufacturer << endl - << " Model: " << mei._model << endl - << " Revision: " << mei._revision << endl - << " Serial Number: " << mei._serialNumber << endl << endl; - -#ifdef TEST_OPERATOR_INFO - try - { - cout << "Getting operator info" << endl; - vector opis = m.getAvailableOPInfo(); - for (vector::iterator i = opis.begin(); i != opis.end(); ++i) - { - cout << " Status: "; - switch (i->_status) - { - case 0: cout << "unknown"; break; - case 1: cout << "current"; break; - case 2: cout << "available"; break; - case 3: cout << "forbidden"; break; - } - cout << endl - << " Long name: '" << i->_longName << "' " - << " Short name: '" << i->_shortName << "' " - << " Numeric name: " << i->_numericName << endl; - } - } - catch (GsmException &ge) - { - if (ge.getErrorCode() == 0) - cout << "phone failure ignored" << endl; - else - throw; - } - cout << endl; -#endif // TEST_OPERATOR_INFO - - cout << "Current operator info" << endl; - OPInfo opi = m.getCurrentOPInfo(); - cout << " Long name: '" << opi._longName << "' " - << " Short name: '" << opi._shortName << "' " - << " Numeric name: " << opi._numericName << endl - << " Mode: "; - switch (opi._mode) - { - case 0: cout << "automatic"; break; - case 1: cout << "manual"; break; - case 2: cout << "deregister"; break; - case 4: cout << "manual/automatic"; break; - } - cout << endl; - - cout << "Facility lock capabilities" << endl << " "; - vector fclc = m.getFacilityLockCapabilities(); - for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) - cout << *i << " "; - cout << endl << endl; - - cout << "Facility lock states" << endl; - for (vector::iterator k = fclc.begin(); k != fclc.end(); ++k) - if (*k != "AB" && *k != "AG" && *k != "AC") - { - cout << " " << *k; - if (m.getFacilityLockStatus(*k, VoiceFacility)) - cout << " Voice"; - if (m.getFacilityLockStatus(*k, DataFacility)) - cout << " Data"; - if (m.getFacilityLockStatus(*k, FaxFacility)) - cout << " Fax"; - } - cout << endl; - - cout << "Facilities with password" << endl; - vector pwi = m.getPasswords(); - for (vector::iterator j = pwi.begin(); j != pwi.end(); ++j) - cout << " " << j->_facility << " len " << j->_maxPasswdLen << endl; - cout << endl; - - cout << "Network caller line identification identification: " - << (m.getNetworkCLIP() ? "on" : "off") << endl << endl; - - cout << "Call forwarding information" << endl; - for (int r = 0; r < 4; ++r) - { - switch (r) - { - case 0: cout << "UnconditionalReason" << endl; break; - case 1: cout << "MobileBusyReason" << endl; break; - case 2: cout << "NoReplyReason" << endl; break; - case 3: cout << "NotReachableReason" << endl; break; - } - ForwardInfo voice, fax, data; - m.getCallForwardInfo((ForwardReason)r, voice, fax, data); - printForwardReason("Voice", voice); - printForwardReason("Data", data); - printForwardReason("Fax", fax); - } - cout << endl; - - cout << "Battery charge status" << endl; - int bcs = m.getBatteryChargeStatus(); - switch (bcs) - { - case 0: cout << "ME is powered by the battery" << endl; break; - case 1: cout << "ME has a battery connected, but is not powered by it" - << endl; break; - case 2: cout << "ME does not have a battery connected" << endl; break; - case 3: cout << "Recognized power fault, calls inhibited" << endl; break; - } - cout << endl; - - cout << "Battery charge: " << m.getBatteryCharge() << endl << endl; - - cout << "Signal strength: " << m.getSignalStrength() << endl << endl; - - cout << "Bit error rate: " << m.getBitErrorRate() << endl << endl; - } - catch (GsmException &ge) - { - cerr << "GsmException '" << ge.what() << "'" << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser-output.txt b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser-output.txt deleted file mode 100644 index a5b16e7fb3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser-output.txt +++ /dev/null @@ -1,22 +0,0 @@ -Test 1 -(),("ME","SM","Which of the three items does not belong here?") - -Test 2 -(1-5),425,"+abcd"efgh" - -Test 3 -(1,2,3,4,5,7,11,12,25),425,Thisisatest."+a"ef"andsoforth - -Test 4 -(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125),(20),16 - -Test 5 -SM,7 - -Test 6 -(2,"S TELIA MOBITEL","S TELIA",24001) - -Error 1: expected ')' (at position 4 of string '(4-5') - -Error 3: expected end of line (at position 5 of string '"bla"bla"') - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser.cc deleted file mode 100644 index 99b178d197..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testparser.cc +++ /dev/null @@ -1,200 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: testparser.cc -// * -// * Purpose: Test AT result code parser -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 17.5.1999 -// ************************************************************************* - -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -void printIntList(vector &vb) -{ - cout << "("; - int j = 0; - bool first = true; - for (vector::iterator i = vb.begin(); - i != vb.end(); ++i) - { - if (*i) - { - if (! first) cout << ","; - cout << j; - first = false; - } - ++j; - } - cout << ")"; -} - -void printIntRange(IntRange ir) -{ - cout << "(" << ir._low << "-" << ir._high << ")"; -} - -void printStringList(vector vs) -{ - bool first = true; - cout << "("; - for (vector::iterator i = vs.begin(); - i != vs.end(); ++i) - { - if (! first) cout << ","; - cout << "\"" << *i << "\""; - first = false; - } - cout << ")"; -} - -int main(int argc, char *argv[]) -{ - try - { - { - cout << "Test 1" << endl; - Parser p((string)",(\"ME\", \"SM\"," + - "\"Which of the three items does not belong here?\")"); - - vector vs1 = p.parseStringList(true); - p.parseComma(); - vector vs2 = p.parseStringList(); - bool comma = p.parseComma(true); - - printStringList(vs1); - cout << ","; - printStringList(vs2); - if (comma) cout << ","; - cout << endl << endl; - } - { - cout << "Test 2" << endl; - Parser p("(1-5),425,\"+abcd\"efgh\""); - - IntRange ir = p.parseRange(); - p.parseComma(); - int i = p.parseInt(); - p.parseComma(); - string s = p.parseString(false, true); - - printIntRange(ir); - cout << "," << i << ",\"" << s << "\"" << endl << endl; - } - { - cout << "Test 3" << endl; - Parser p("(7,1-5,12-11,25),425,This is a test.\"+a\"ef\" and so forth"); - - vector vb = p.parseIntList(); - p.parseComma(); - int i = p.parseInt(); - p.parseComma(); - string s = p.parseEol(); - - printIntList(vb); - cout << "," << i << "," << s << endl << endl; - } - { - cout << "Test 4" << endl; - Parser p("(1-125),20,16"); - - vector vb = p.parseIntList(); - p.parseComma(); - vector vb2 = p.parseIntList(); - p.parseComma(); - int j = p.parseInt(); - - printIntList(vb); - cout << ","; - printIntList(vb2); - cout << "," << j << endl << endl; - } - { - cout << "Test 5" << endl; - Parser p("SM,7"); - - string s = p.parseString(); - p.parseComma(); - int i = p.parseInt(); - - cout << s << "," << i << endl << endl; - } - { - cout << "Test 6" << endl; - Parser p("(2,\"S TELIA MOBITEL\",\"S TELIA\",\"24001\")"); - - p.parseChar('('); - int status = p.parseInt(); - p.parseComma(); - string longName = p.parseString(true); - p.parseComma(); - string shortName = p.parseString(true); - p.parseComma(); - int numericName; - try - { - numericName = p.parseInt(true); - } - catch (GsmException &e) - { - if (e.getErrorClass() == ParserError) - { - // the Ericsson GM12 GSM modem returns the numeric ID as string - string s = p.parseString(); - numericName = checkNumber(s); - } - else - throw e; - } - p.parseChar(')'); - - cout << "(" << status << ",\"" << longName << "\",\"" - << shortName << "\"," - << numericName << ")" << endl << endl; - } - } - catch (GsmException &p) - { - // these tests shouldn't throw exceptions - assert(0); - } - - // Now some tests that should provoke an error - try - { - Parser p("(4-5"); - p.parseRange(); - } - catch (GsmException &p) - { - cout << "Error 1: " << p.what() << endl << endl; - } - try - { - Parser p("(4-5,3-4-5)"); - p.parseIntList(); - } - catch (GsmException &p) - { - cout << "Error 2: " << p.what() << endl << endl; - } - try - { - Parser p("\"bla\"bla\""); - p.parseString(); - p.checkEol(); - } - catch (GsmException &p) - { - cout << "Error 3: " << p.what() << endl << endl; - } - -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb.cc deleted file mode 100644 index 6f161349ef..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb.cc +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -void printPb(PhonebookEntry &e) -{ - cout << "number: " << e.telephone() - << " text: " << e.text() << endl; -} - -int main(int argc, char *argv[]) -{ - try - { - cout << (string)"Opening device " + argv[1] << endl; - Ref port = new UnixSerialPort((string)argv[1], B38400); - - cout << "Creating MeTa object" << endl; - MeTa m(port); - - cout << "Getting phonebook entries" << endl; - vector pbs = m.getPhoneBookStrings(); - for (vector::iterator i = pbs.begin(); i != pbs.end(); ++i) - { - PhonebookRef pb = m.getPhonebook(*i); - - cout << "Phonebook \"" << *i << "\" " << endl - << " Max number length: " << pb->getMaxTelephoneLen() << endl - << " Max text length: " << pb->getMaxTextLen() << endl - << " Capacity: " << pb->capacity() << endl - << " Size: " << pb->size() << endl; - - for (Phonebook::iterator j = pb->begin(); j != pb->end(); ++j) - if (! j->empty()) - cout << " Entry #" << j - pb->begin() - << "Number: \"" << j->telephone() << "\"" - << "Text: \"" << j->text() << "\"" << endl; - } - } - catch (GsmException &ge) - { - cerr << "GsmException '" << ge.what() << "'" << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb2.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb2.cc deleted file mode 100644 index f9769f9bfc..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testpb2.cc +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -bool isbla(PhonebookEntry &e) -{ - // cerr << "****'" << e.text() << "'" << endl; - return e.text() == "blabla"; -} - -int main(int argc, char *argv[]) -{ - try - { - cout << (string)"Opening device " + argv[1] << endl; - Ref port = new UnixSerialPort((string)argv[1], B38400); - - cout << "Creating MeTa object" << endl; - MeTa m(port); - - cout << "Getting phonebook entries" << endl; - vector pbs = m.getPhoneBookStrings(); - if (pbs.begin() == pbs.end()) - { - cerr << "no phonebooks available" << endl; - exit(1); - } - - PhonebookRef pb = m.getPhonebook(*pbs.begin()); - - cout << "Phonebook \"" << pb->name() << "\" " << endl - << " Max number length: " << pb->getMaxTelephoneLen() << endl - << " Max text length: " << pb->getMaxTextLen() << endl - << " Capacity: " << pb->capacity() << endl; - - cout << "Inserting entry 'blabla'" << endl; - PhonebookEntry e("123456", "blabla"); - pb->insert(pb->end(), e); - - int j = -1; - for (int i = 50; i < 60; ++i) - if (pb()[i].empty()) - { - pb()[i].set("23456", "blabla"); - j = i; - break; - } - - pb->erase(pb->begin() + j); - - Phonebook::iterator k; - do - { - k = find_if(pb->begin(), pb->end(), isbla); - if (k != pb->end()) - { - cerr << "Erasing #" << k - pb->begin() << endl; - pb->erase(k, k + 1); - } - } - while (k != pb->end()); - } - catch (GsmException &ge) - { - cerr << "GsmException '" << ge.what() << "'" << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms-output.txt b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms-output.txt deleted file mode 100644 index bee3c53bac..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms-output.txt +++ /dev/null @@ -1,167 +0,0 @@ ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '171' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 04/16/1999 08:09:44 AM (+0200) -User data length: 160 -User data header: 0x -User data: 'T-D1 News bis 31.05.99 kostenlos testen! ber 90 Programme aus Politik, Wirtschaft, Brse, Sport direkt per SMS aufs Handy. Mehr darber unter der Kurzwahl 2323' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '01805000102' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 12/17/1998 02:10:55 PM (+0100) -User data length: 159 -User data header: 0x -User data: 'Nicht vergessen! Die XtraWeihnachtsverlosung luft noch bis zum 24.12. Nutzen Sie jetzt Ihre Gewinnchance und faxen Sie Ihren Teiln.-Gutschein an 0180/5000 056' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '41794991200' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: 'dialing.de ' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 04/21/2001 12:15:28 PM (+0000) -User data length: 0 -User data header: 0x -User data: '' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '41794991200' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: 'dialing.de ' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 04/21/2001 12:15:28 PM (+0000) -User data length: 0 -User data header: 0x -User data: '' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '' -More messages to send: 0 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -SC timestamp: 00/00/2000 12:00:00 AM (+0000) -User data length: 0 -User data header: 0x -User data: '' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '' -More messages to send: 0 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -SC timestamp: 00/00/2000 12:00:00 AM (+0000) -User data length: 0 -User data header: 0x -User data: '' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-DELIVER-REPORT -SC address: '' -Protocol identifier present: 0 -Data coding scheme present: 0 -User data length present: 0 ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-STATUS-REPORT -SC address: '' -More messages to send: 0 -Status report qualifier: 0 -Message reference: 0 -Recipient address: '' -SC timestamp: 00/00/2000 12:00:00 AM (+0000) -Discharge time: 00/00/2000 12:00:00 AM (+0000) -Status: 0x0 'Short message received by the SME' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-COMMAND -SC address: '' -Message reference: 0 -Status report request: 1 -Protocol identifier: 0x0 -Command type: 0x0 -Message number: 0 -Destination address: '' -Command data length: 0 -Command data: '' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-SUBMIT -SC address: '' -Reject duplicates: 1 -Validity period format: relative -Reply path: 0 -User data header indicator: 0 -Status report request: 0 -Message reference: 0 -Destination address: '' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -Validity period: 2 days -User data length: 35 -User data header: 0x -User data: 'This is a submit message, isn't it?' ---------------------------------------------------------------------------- - - ---------------------------------------------------------------------------- -Message type: SMS-SUBMIT-REPORT -SC address: '' -SC timestamp: 00/00/2000 12:00:00 AM (+0000) -Protocol identifier present: 0 -Data coding scheme present: 0 -User data length present: 0 ---------------------------------------------------------------------------- - - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms.cc deleted file mode 100644 index bf5423b057..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms.cc +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************* -// * GSM TA/ME library -// * -// * File: testsms.cc -// * -// * Purpose: Test coder and encoder for SMS TPDUs -// * -// * Author: Peter Hofmann (software@pxh.de) -// * -// * Created: 17.5.1999 -// ************************************************************************* - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include - -using namespace std; -using namespace gsmlib; - -int main(int argc, char *argv[]) -{ - string pdu; - SMSMessageRef sms; - // test two SMS message I have received - sms = SMSMessage::decode("079194710167120004038571F1390099406180904480A0D41631067296EF7390383D07CD622E58CD95CB81D6EF39BDEC66BFE7207A794E2FBB4320AFB82C07E56020A8FC7D9687DBED32285C9F83A06F769A9E5EB340D7B49C3E1FA3C3663A0B24E4CBE76516680A7FCBE920725A5E5ED341F0B21C346D4E41E1BA790E4286DDE4BC0BD42CA3E5207258EE1797E5A0BA9B5E9683C86539685997EBEF61341B249BC966"); - cout << sms->toString() << endl; - - sms = SMSMessage::decode("0791947101671200040B851008050001F23900892171410155409FCEF4184D07D9CBF273793E2FBB432062BA0CC2D2E5E16B398D7687C768FADC5E96B3DFF3BAFB0C62EFEB663AC8FD1EA341E2F41CA4AFB741329A2B2673819C75BABEEC064DD36590BA4CD7D34149B4BC0C3A96EF69B77B8C0EBBC76550DD4D0699C3F8B21B344D974149B4BCEC0651CB69B6DBD53AD6E9F331BA9C7683C26E102C8683BD6A30180C04ABD900"); - cout << sms->toString() << endl; - - // test SMS decoding and encoding for messages with alphanumeric - // destination address - sms = SMSMessage::decode("07911497941902F00414D0E474989D769F5DE4320839001040122151820000"); - cout << sms->toString() << endl; - pdu = sms->encode(); - sms = SMSMessage::decode(pdu); - cout << sms->toString() << endl; - - // test all message types - sms = new SMSDeliverMessage(); - cout << sms->toString() << endl; - pdu = sms->encode(); - sms = SMSMessage::decode(pdu); - cout << sms->toString() << endl; - - // test all message types - sms = new SMSDeliverReportMessage(); - pdu = sms->encode(); - sms = SMSMessage::decode(pdu, false); - cout << sms->toString() << endl; - - // test all message types - sms = new SMSStatusReportMessage(); - pdu = sms->encode(); - sms = SMSMessage::decode(pdu); - cout << sms->toString() << endl; - - // test all message types - sms = new SMSCommandMessage(); - pdu = sms->encode(); - sms = SMSMessage::decode(pdu, false); - cout << sms->toString() << endl; - - // test all message types - SMSSubmitMessage *subsms = new SMSSubmitMessage(); - subsms->setUserData("This is a submit message, isn't it?"); - sms = subsms; - pdu = sms->encode(); - sms = SMSMessage::decode(pdu, false); - cout << sms->toString() << endl; - - // test all message types - sms = new SMSSubmitReportMessage(); - pdu = sms->encode(); - sms = SMSMessage::decode(pdu); - cout << sms->toString() << endl; - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms2.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms2.cc deleted file mode 100644 index cb9b395a86..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testsms2.cc +++ /dev/null @@ -1,89 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif -#ifdef WIN32 -#include -#else -#include -#endif -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -int main(int argc, char *argv[]) -{ - try - { - cout << (string)"Opening device " + argv[1] << endl; -#ifdef WIN32 - Ref port = new Win32SerialPort((string)argv[1], 38400); -#else - Ref port = new UnixSerialPort((string)argv[1], B38400); -#endif - - cout << "Creating MeTa object" << endl; - MeTa m(port); - - cout << "Setting message service level to 1" << endl; - m.setMessageService(1); - - vector storeList = m.getSMSStoreNames(); - - for (vector::iterator stn = storeList.begin(); - stn != storeList.end(); ++stn) - { - cout << "Getting store \"" << *stn << "\"" << endl; - SMSStoreRef st = m.getSMSStore(*stn); - - SMSMessageRef sms; - cout << "Creating SMS Submit Message and putting it into store" << endl; - SMSSubmitMessage *subsms = new SMSSubmitMessage(); -// Address scAddr("+491710760000"); -// subsms->setServiceCentreAddress(scAddr); - Address destAddr("0177123456"); - subsms->setDestinationAddress(destAddr); - subsms->setUserData("This message was sent from the store."); - TimePeriod tp; - tp._format = TimePeriod::Relative; - tp._relativeTime = 100; - /*subsms->setValidityPeriod(tp); - subsms->setValidityPeriodFormat(tp._format); - subsms->setStatusReportRequest(true);*/ - sms = subsms; - SMSStore::iterator smsIter = st->insert(st->end(), SMSStoreEntry(sms)); - cout << "Message entered at index #" - << smsIter - st->begin() << endl; - - //m.sendSMS(sms); - SMSMessageRef ackPdu; - int messageRef = smsIter->send(ackPdu); - cout << "Message reference: " << messageRef << endl - << "ACK PDU:" << endl - << (ackPdu.isnull() ? "no ack pdu" : ackPdu->toString()) - << endl; - - /* cout << "Erasing all unsent messages" << endl; - for (SMSStore::iterator s = st->begin(); s != st->end(); ++s) - if (! s->empty() && s->status() == SMSStoreEntry::StoredUnsent) - st->erase(s);*/ - - cout << "Printing store \"" << *stn << "\"" << endl; - for (SMSStore::iterator s = st->begin(); s != st->end(); ++s) - if (! s->empty()) - cout << s->message()->toString(); - - break; // only do one store - } - } - catch (GsmException &ge) - { - cerr << "GsmException '" << ge.what() << "'" << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb-output.txt b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb-output.txt deleted file mode 100644 index 83a56fa9f9..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb-output.txt +++ /dev/null @@ -1,47 +0,0 @@ -Entries in pbs-copy.pb: - Text: Dieter Meier Telephone: 793045 - Text: Edgar Hofmann Telephone: 42345 - Text: Goethe Telephone: 847159 - Text: Hans Hofmann Telephone: 12345 - Text: Hans-Dieter Schmidt Telephone: 82345 - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Heiner Mller Telephone: 7890 - Text: line with | Telephone: 0815 - Text: line with\ Telephone: 0815 - Text: One line back to start Telephone: 0815 - Text: two -line Telephone: 0815 -Removing entries with telephone == 0815 -Entries in pbs-copy.pb<2>: - Text: Hans Hofmann Telephone: 12345 - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Edgar Hofmann Telephone: 42345 - Text: Heiner Mller Telephone: 7890 - Text: Dieter Meier Telephone: 793045 - Text: Hans-Dieter Schmidt Telephone: 82345 - Text: Goethe Telephone: 847159 -Inserting some entries -Entries in pbs-copy.pb<3>: - Text: Dieter Meier Telephone: 793045 - Text: Edgar Hofmann Telephone: 42345 - Text: Goethe Telephone: 847159 - Text: Hans Hofmann Telephone: 12345 - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Hans-Dieter Schmidt Telephone: 41598254 - Text: Hans-Dieter Schmidt Telephone: 82345 - Text: Hans-Dieter|Hofmann Telephone: 34058 - Text: Heiner Mller Telephone: 7890 - Text: new line with continued Telephone: 08152 -Erasing all Hans-Dieter Schmidt entries -About to erase: - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Hans-Dieter Schmidt Telephone: 41598254 - Text: Hans-Dieter Schmidt Telephone: 82345 -Writing back to file -|Dieter Meier|793045 -|Edgar Hofmann|42345 -|Goethe|847159 -|Hans Hofmann|12345 -|Hans-Dieter\|Hofmann|34058 -|Heiner Mller|7890 -|new line with \r continued|08152 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb.cc deleted file mode 100644 index 43b9f512db..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb.cc +++ /dev/null @@ -1,81 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -void printPb(PhonebookEntry &e) -{ - cout << "number: " << e.telephone() - << " text: " << e.text() << endl; -} - -int main(int argc, char *argv[]) -{ - try - { - // open phonebook file - SortedPhonebook pb((string)"spb-copy.pb", false); - - // print all entries - cout << "Entries in pbs-copy.pb:" << endl; - for (SortedPhonebook::iterator i = pb.begin(); i != pb.end(); ++i) - cout << " Text: " << i->text() - << " Telephone: " << i->telephone() << endl; - - // remove all entries with telephone == "0815" - cout << "Removing entries with telephone == 0815" << endl; - pb.setSortOrder(ByTelephone); - - string s = "0815"; - pb.erase(s); - - cout << "Entries in pbs-copy.pb<2>:" << endl; - for (SortedPhonebook::iterator i = pb.begin(); i != pb.end(); ++i) - cout << " Text: " << i->text() - << " Telephone: " << i->telephone() << endl; - - // insert some entries - cout << "Inserting some entries" << endl; - pb.insert(PhonebookEntryBase("08152", "new line with \r continued")); - pb.insert(PhonebookEntryBase("41598254", "Hans-Dieter Schmidt")); - pb.insert(PhonebookEntryBase("34058", "Hans-Dieter|Hofmann")); - - pb.setSortOrder(ByText); - cout << "Entries in pbs-copy.pb<3>:" << endl; - for (SortedPhonebook::iterator i = pb.begin(); i != pb.end(); ++i) - cout << " Text: " << i->text() - << " Telephone: " << i->telephone() << endl; - - // test erasing all "Hans-Dieter Schmidt" entries - cout << "Erasing all Hans-Dieter Schmidt entries" << endl; - s = "Hans-Dieter Schmidt"; - pair range = - pb.equal_range(s); - cout << "About to erase:" << endl; - for (SortedPhonebook::iterator i = range.first; i != range.second; ++i) - cout << " Text: " << i->text() - << " Telephone: " << i->telephone() << endl; - - pb.erase(range.first, range.second); - - // write back to file - cout << "Writing back to file" << endl; - pb.sync(); - - // tests the NoCopy class - //SortedPhonebook pb2("spb.pb"); - //pb2 = pb; - } - catch (GsmException &ge) - { - cerr << "GsmException '" << ge.what() << "'" << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb2-output.txt b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb2-output.txt deleted file mode 100644 index 60e54ba669..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspb2-output.txt +++ /dev/null @@ -1,47 +0,0 @@ -Entries in pbs-copy.pb: - Text: Dieter Meier Telephone: 017793045 - Text: Edgar Hofmann Telephone: +4942345 - Text: Goethe Telephone: 847159 - Text: Hans Hofmann Telephone: 0171 - Text: Hans-Dieter Schmidt Telephone: 82345 - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Heiner Mller Telephone: 7890 - Text: line with | Telephone: 0815 - Text: line with\ Telephone: 0815 - Text: One line back to start Telephone: 0815 - Text: two -line Telephone: 0815 -Removing entries with telephone == 0815 -Entries in pbs-copy.pb<2>: - Text: Edgar Hofmann Telephone: +4942345 - Text: Hans Hofmann Telephone: 0171 - Text: Dieter Meier Telephone: 017793045 - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Heiner Mller Telephone: 7890 - Text: Hans-Dieter Schmidt Telephone: 82345 - Text: Goethe Telephone: 847159 -Inserting some entries -Entries in pbs-copy.pb<3>: - Text: Dieter Meier Telephone: 017793045 - Text: Edgar Hofmann Telephone: +4942345 - Text: Goethe Telephone: 847159 - Text: Hans Hofmann Telephone: 0171 - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Hans-Dieter Schmidt Telephone: 41598254 - Text: Hans-Dieter Schmidt Telephone: 82345 - Text: Hans-Dieter|Hofmann Telephone: 34058 - Text: Heiner Mller Telephone: 7890 - Text: new line with continued Telephone: 08152 -Erasing all Hans-Dieter Schmidt entries -About to erase: - Text: Hans-Dieter Schmidt Telephone: 13333345 - Text: Hans-Dieter Schmidt Telephone: 41598254 - Text: Hans-Dieter Schmidt Telephone: 82345 -Writing back to file -|Dieter Meier|017793045 -|Edgar Hofmann|+4942345 -|Goethe|847159 -|Hans Hofmann|0171 -|Hans-Dieter\|Hofmann|34058 -|Heiner Mller|7890 -|new line with \r continued|08152 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspbi-output.txt b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspbi-output.txt deleted file mode 100644 index e4a33e2fa6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testspbi-output.txt +++ /dev/null @@ -1,8 +0,0 @@ -updating 'same name' tel# 23456 to new tel# 12345(index 5) -deleting 'Nummer 3' tel# 3333333 (index #2) -deleting 'Nummer 4' tel# 4444444 (index #4) -inserting 'Nummer 4' tel# 4444444 (index #1) -inserting 'Nummer 3' tel# 3333333 (index #3) -1|Nummer 4|4444444 -3|Nummer 3|3333333 -5|same name|12345 diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms-output.txt b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms-output.txt deleted file mode 100644 index a0e7905939..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms-output.txt +++ /dev/null @@ -1,157 +0,0 @@ -Entries in sms.sms<0>: -Inserting some entries -Entries in sms.sms<1>: -Entry#2: ---------------------------------------------------------------------------- -Message type: SMS-SUBMIT -SC address: '' -Reject duplicates: 1 -Validity period format: relative -Reply path: 0 -User data header indicator: 0 -Status report request: 0 -Message reference: 0 -Destination address: '0177123456' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -Validity period: 2 days -User data length: 9 -User data header: 0x -User data: 'submit me' ---------------------------------------------------------------------------- - - -Entry#3: ---------------------------------------------------------------------------- -Message type: SMS-SUBMIT -SC address: '' -Reject duplicates: 1 -Validity period format: relative -Reply path: 0 -User data header indicator: 0 -Status report request: 0 -Message reference: 0 -Destination address: '' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -Validity period: 2 days -User data length: 35 -User data header: 0x -User data: 'This is a submit message, isn't it?' ---------------------------------------------------------------------------- - - -Entry#1: ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '01805000102' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 12/17/1998 02:10:55 PM (+0100) -User data length: 159 -User data header: 0x -User data: 'Nicht vergessen! Die XtraWeihnachtsverlosung luft noch bis zum 24.12. Nutzen Sie jetzt Ihre Gewinnchance und faxen Sie Ihren Teiln.-Gutschein an 0180/5000 056' ---------------------------------------------------------------------------- - - -Entry#0: ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '171' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 04/16/1999 08:09:44 AM (+0200) -User data length: 160 -User data header: 0x -User data: 'T-D1 News bis 31.05.99 kostenlos testen! ber 90 Programme aus Politik, Wirtschaft, Brse, Sport direkt per SMS aufs Handy. Mehr darber unter der Kurzwahl 2323' ---------------------------------------------------------------------------- - - -Entries in sms.sms<2>: -Entry#3: ---------------------------------------------------------------------------- -Message type: SMS-SUBMIT -SC address: '' -Reject duplicates: 1 -Validity period format: relative -Reply path: 0 -User data header indicator: 0 -Status report request: 0 -Message reference: 0 -Destination address: '' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -Validity period: 2 days -User data length: 35 -User data header: 0x -User data: 'This is a submit message, isn't it?' ---------------------------------------------------------------------------- - - -Entry#2: ---------------------------------------------------------------------------- -Message type: SMS-SUBMIT -SC address: '' -Reject duplicates: 1 -Validity period format: relative -Reply path: 0 -User data header indicator: 0 -Status report request: 0 -Message reference: 0 -Destination address: '0177123456' -Protocol identifier: 0x0 -Data coding scheme: default alphabet -Validity period: 2 days -User data length: 9 -User data header: 0x -User data: 'submit me' ---------------------------------------------------------------------------- - - -Entry#1: ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '01805000102' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 12/17/1998 02:10:55 PM (+0100) -User data length: 159 -User data header: 0x -User data: 'Nicht vergessen! Die XtraWeihnachtsverlosung luft noch bis zum 24.12. Nutzen Sie jetzt Ihre Gewinnchance und faxen Sie Ihren Teiln.-Gutschein an 0180/5000 056' ---------------------------------------------------------------------------- - - -Entry#0: ---------------------------------------------------------------------------- -Message type: SMS-DELIVER -SC address: '491710762100' -More messages to send: 1 -Reply path: 0 -User data header indicator: 0 -Status report indication: 0 -Originating address: '171' -Protocol identifier: 0x39 -Data coding scheme: default alphabet -SC timestamp: 04/16/1999 08:09:44 AM (+0200) -User data length: 160 -User data header: 0x -User data: 'T-D1 News bis 31.05.99 kostenlos testen! ber 90 Programme aus Politik, Wirtschaft, Brse, Sport direkt per SMS aufs Handy. Mehr darber unter der Kurzwahl 2323' ---------------------------------------------------------------------------- - - -Writing back to file diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms.cc b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms.cc deleted file mode 100644 index 4c30bd544f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/tests/testssms.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace gsmlib; - -int main(int argc, char *argv[]) -{ - try - { - // open SMS store file - SortedSMSStore sms((string)"sms.sms"); - - // print all entries - cout << "Entries in sms.sms<0>:" << endl; - for (SortedSMSStore::iterator i = sms.begin(); i != sms.end(); ++i) - cout << "Entry#" << i->index() << ":" << endl - << i->message()->toString() << endl; - - // insert some entries - cout << "Inserting some entries" << endl; - SMSMessageRef smsMessage; - // test two SMS message I have received - smsMessage = SMSMessage::decode("079194710167120004038571F1390099406180904480A0D41631067296EF7390383D07CD622E58CD95CB81D6EF39BDEC66BFE7207A794E2FBB4320AFB82C07E56020A8FC7D9687DBED32285C9F83A06F769A9E5EB340D7B49C3E1FA3C3663A0B24E4CBE76516680A7FCBE920725A5E5ED341F0B21C346D4E41E1BA790E4286DDE4BC0BD42CA3E5207258EE1797E5A0BA9B5E9683C86539685997EBEF61341B249BC966"); - sms.insert(SMSStoreEntry(smsMessage)); - - smsMessage = SMSMessage::decode("0791947101671200040B851008050001F23900892171410155409FCEF4184D07D9CBF273793E2FBB432062BA0CC2D2E5E16B398D7687C768FADC5E96B3DFF3BAFB0C62EFEB663AC8FD1EA341E2F41CA4AFB741329A2B2673819C75BABEEC064DD36590BA4CD7D34149B4BC0C3A96EF69B77B8C0EBBC76550DD4D0699C3F8B21B344D974149B4BCEC0651CB69B6DBD53AD6E9F331BA9C7683C26E102C8683BD6A30180C04ABD900"); - sms.insert(SMSStoreEntry(smsMessage)); - - smsMessage = new SMSSubmitMessage("submit me", "0177123456"); - sms.insert(SMSStoreEntry(smsMessage)); - - SMSSubmitMessage *subsms = new SMSSubmitMessage(); - subsms->setUserData("This is a submit message, isn't it?"); - smsMessage = subsms; - sms.insert(SMSStoreEntry(smsMessage)); - - // print all entries - cout << "Entries in sms.sms<1>:" << endl; - for (SortedSMSStore::iterator i = sms.begin(); i != sms.end(); ++i) - cout << "Entry#" << i->index() << ":" << endl - << i->message()->toString() << endl; - - // sort by telephone number - sms.setSortOrder(ByAddress); - - // print all entries - cout << "Entries in sms.sms<2>:" << endl; - for (SortedSMSStore::iterator i = sms.begin(); i != sms.end(); ++i) - cout << "Entry#" << i->index() << ":" << endl - << i->message()->toString() << endl; - - // write back to file - cout << "Writing back to file" << endl; - sms.sync(); - - } - catch (GsmException &ge) - { - cerr << "GsmException '" << ge.what() << "'" << endl; - return 1; - } - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/COPYING b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/COPYING deleted file mode 100644 index 78e994dd75..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/COPYING +++ /dev/null @@ -1,5 +0,0 @@ -WARNING - - The files getopt.c and getopt.h in this subdirectory (win32) are - not covered by the GNU LIBRARY GENERAL PUBLIC LICENSE as - reproduced in ../COPYING. They carry their own license instead. diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.am b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.am deleted file mode 100644 index a666fabf31..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -## Process this file with automake to produce Makefile.in -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: win32 Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 19.1.2001 -# ************************************************************************* - -EXTRA_DIST = getopt.c gsmctl.dsp gsmpb.dsp testgsmlib.dsp \ - getopt.h gsmlib.dsp gsmsendsms.dsp testsms.dsp \ - README.win gsm_config.h gsmlib.dsw gsmsmsstore.dsp \ - gsmsmsd.dsp testsms2.dsp diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.in b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.in deleted file mode 100644 index 4117eea211..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/Makefile.in +++ /dev/null @@ -1,259 +0,0 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# ************************************************************************* -# * GSM TA/ME library -# * -# * File: Makefile.am -# * -# * Purpose: win32 Makefile -# * -# * Author: Peter Hofmann (software@pxh.de) -# * -# * Created: 19.1.2001 -# ************************************************************************* -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AS = @AS@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CPP = @CPP@ -CXX = @CXX@ -DATADIRNAME = @DATADIRNAME@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -GENCAT = @GENCAT@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GSM_VERSION = @GSM_VERSION@ -HAVE_LIB = @HAVE_LIB@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -LIB = @LIB@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIB = @LTLIB@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ - -EXTRA_DIST = getopt.c gsmctl.dsp gsmpb.dsp testgsmlib.dsp \ - getopt.h gsmlib.dsp gsmsendsms.dsp testsms.dsp \ - README.win gsm_config.h gsmlib.dsw gsmsmsstore.dsp \ - gsmsmsd.dsp testsms2.dsp - -subdir = win32 -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/gsm_config.h -CONFIG_CLEAN_FILES = -DIST_SOURCES = -DIST_COMMON = COPYING Makefile.am Makefile.in -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu win32/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -tags: TAGS -TAGS: - -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile - -installdirs: - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-generic distclean-libtool - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -uninstall-am: uninstall-info-am - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am info info-am install install-am install-data \ - install-data-am install-exec install-exec-am install-info \ - install-info-am install-man install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool uninstall uninstall-am uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/README.win b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/README.win deleted file mode 100644 index 17aa648dd1..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/README.win +++ /dev/null @@ -1,41 +0,0 @@ -INTRODUCTION - - This is a Win32 port of gsmlib contributed by Frediano Ziglio - (Frediano.Ziglio@omnitel.it) and adapted by me. You can use the - library for inclusion in your own programs or the command line tools - which have been ported (with the exception of gsmsmsd). - -COMPILATION - - You need Microsoft VC++ 6.0 to compile the library and command - line tools. Because I prefer to use the ending .cc for C++ files you - need to make some changes to your development environment. These are - documented by Microsoft under this URL (one line): - - http://support.microsoft.com/support/kb/articles/Q181/5/ - 06.ASP?LN=EN-US&SD=gn&FR=0&qry=.cc&rnk=1&src=DHCS_MSPSS_gn_SRCH&SPR=VCC - - The title of the document is "HOWTO: Make VC++ Recognize File - Extensions as C/C++ Files". - - Then open the workspace gsmlib.dsw with Developer - Studio. Compilation should be straightforward after that, just make a - batch build of everything. - - If you encounter problems you can use the debug versions and set - the environment variable GSMLIB_DEBUG to 1 or 2 to get debugging - output. - -HINTS - - Use COMx: (x is the number of the COM device) instead of the UNIX - device name. If this doesn't work use "\\.\COMx:". - - - The files under Release are without debugging code. If you see - errors please use the Debug versions and execute - - set GSMLIB_DEBUG=2 - - for executing the programs. Please send me the debugging - output: - - gsmsmsstore ..... 2> \temp\debug.log diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.c b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.c deleted file mode 100644 index 45fcedc063..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.c +++ /dev/null @@ -1,185 +0,0 @@ -/***************************************************************************** - * - * MODULE NAME : GETOPT.C - * - * COPYRIGHTS: - * This module contains code made available by IBM - * Corporation on an AS IS basis. Any one receiving the - * module is considered to be licensed under IBM copyrights - * to use the IBM-provided source code in any way he or she - * deems fit, including copying it, compiling it, modifying - * it, and redistributing it, with or without - * modifications. No license under any IBM patents or - * patent applications is to be implied from this copyright - * license. - * - * A user of the module should understand that IBM cannot - * provide technical support for the module and will not be - * responsible for any consequences of use of the program. - * - * Any notices, including this one, are not to be removed - * from the module without the prior written consent of - * IBM. - * - * AUTHOR: Original author: - * G. R. Blair (BOBBLAIR at AUSVM1) - * Internet: bobblair@bobblair.austin.ibm.com - * - * Extensively revised by: - * John Q. Walker II, Ph.D. (JOHHQ at RALVM6) - * Internet: johnq@ralvm6.vnet.ibm.com - * - *****************************************************************************/ - -/****************************************************************************** - * getopt() - * - * The getopt() function is a command line parser. It returns the next - * option character in argv that matches an option character in opstring. - * - * The argv argument points to an array of argc+1 elements containing argc - * pointers to character strings followed by a null pointer. - * - * The opstring argument points to a string of option characters; if an - * option character is followed by a colon, the option is expected to have - * an argument that may or may not be separated from it by white space. - * The external variable optarg is set to point to the start of the option - * argument on return from getopt(). - * - * The getopt() function places in optind the argv index of the next argument - * to be processed. The system initializes the external variable optind to - * 1 before the first call to getopt(). - * - * When all options have been processed (that is, up to the first nonoption - * argument), getopt() returns EOF. The special option "--" may be used to - * delimit the end of the options; EOF will be returned, and "--" will be - * skipped. - * - * The getopt() function returns a question mark (?) when it encounters an - * option character not included in opstring. This error message can be - * disabled by setting opterr to zero. Otherwise, it returns the option - * character that was detected. - * - * If the special option "--" is detected, or all options have been - * processed, EOF is returned. - * - * Options are marked by either a minus sign (-) or a slash (/). - * - * No errors are defined. - *****************************************************************************/ - -#include /* for EOF */ -#include /* for strchr() */ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* static (global) variables that are specified as exported by getopt() */ -char *optarg = NULL; /* pointer to the start of the option argument */ -int optind = 1; /* number of the next argv[] to be evaluated */ -int opterr = 1; /* non-zero if a question mark should be returned - when a non-valid option character is detected */ - -/* handle possible future character set concerns by putting this in a macro */ -#define _next_char(string) (char)(*(string+1)) - -int getopt(int argc, char *argv[], char *opstring) -{ - static char *pIndexPosition = NULL; /* place inside current argv string */ - char *pArgString = NULL; /* where to start from next */ - char *pOptString; /* the string in our program */ - - - if (pIndexPosition != NULL) { - /* we last left off inside an argv string */ - if (*(++pIndexPosition)) { - /* there is more to come in the most recent argv */ - pArgString = pIndexPosition; - } - } - - if (pArgString == NULL) { - /* we didn't leave off in the middle of an argv string */ - if (optind >= argc) { - /* more command-line arguments than the argument count */ - pIndexPosition = NULL; /* not in the middle of anything */ - return EOF; /* used up all command-line arguments */ - } - - /*--------------------------------------------------------------------- - * If the next argv[] is not an option, there can be no more options. - *-------------------------------------------------------------------*/ - pArgString = argv[optind++]; /* set this to the next argument ptr */ - - if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ - ('-' != *pArgString)) { - --optind; /* point to current arg once we're done */ - optarg = NULL; /* no argument follows the option */ - pIndexPosition = NULL; /* not in the middle of anything */ - return EOF; /* used up all the command-line flags */ - } - - /* check for special end-of-flags markers */ - if ((strcmp(pArgString, "-") == 0) || - (strcmp(pArgString, "--") == 0)) { - optarg = NULL; /* no argument follows the option */ - pIndexPosition = NULL; /* not in the middle of anything */ - return EOF; /* encountered the special flag */ - } - - pArgString++; /* look past the / or - */ - } - - if (':' == *pArgString) { /* is it a colon? */ - /*--------------------------------------------------------------------- - * Rare case: if opterr is non-zero, return a question mark; - * otherwise, just return the colon we're on. - *-------------------------------------------------------------------*/ - return (opterr ? (int)'?' : (int)':'); - } - else if ((pOptString = strchr(opstring, *pArgString)) == 0) { - /*--------------------------------------------------------------------- - * The letter on the command-line wasn't any good. - *-------------------------------------------------------------------*/ - optarg = NULL; /* no argument follows the option */ - pIndexPosition = NULL; /* not in the middle of anything */ - return (opterr ? (int)'?' : (int)*pArgString); - } - else { - /*--------------------------------------------------------------------- - * The letter on the command-line matches one we expect to see - *-------------------------------------------------------------------*/ - if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ - /* It is a colon. Look for an argument string. */ - if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ - optarg = &pArgString[1]; /* Yes, it is */ - } - else { - /*------------------------------------------------------------- - * The argument string must be in the next argv. - * But, what if there is none (bad input from the user)? - * In that case, return the letter, and optarg as NULL. - *-----------------------------------------------------------*/ - if (optind < argc) - optarg = argv[optind++]; - else { - optarg = NULL; - return (opterr ? (int)'?' : (int)*pArgString); - } - } - pIndexPosition = NULL; /* not in the middle of anything */ - } - else { - /* it's not a colon, so just return the letter */ - optarg = NULL; /* no argument follows the option */ - pIndexPosition = pArgString; /* point to the letter we're on */ - } - return (int)*pArgString; /* return the letter that matched */ - } -} - -#ifdef __cplusplus -} -#endif diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.h deleted file mode 100644 index f7446f1c50..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/getopt.h +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************** - * - * MODULE NAME : GETOPT.H - * - * COPYRIGHTS: - * This module contains code made available by IBM - * Corporation on an AS IS basis. Any one receiving the - * module is considered to be licensed under IBM copyrights - * to use the IBM-provided source code in any way he or she - * deems fit, including copying it, compiling it, modifying - * it, and redistributing it, with or without - * modifications. No license under any IBM patents or - * patent applications is to be implied from this copyright - * license. - * - * A user of the module should understand that IBM cannot - * provide technical support for the module and will not be - * responsible for any consequences of use of the program. - * - * Any notices, including this one, are not to be removed - * from the module without the prior written consent of - * IBM. - * - * AUTHOR: Original author: - * G. R. Blair (BOBBLAIR at AUSVM1) - * Internet: bobblair@bobblair.austin.ibm.com - * - * Extensively revised by: - * John Q. Walker II, Ph.D. (JOHHQ at RALVM6) - * Internet: johnq@ralvm6.vnet.ibm.com - * - *****************************************************************************/ -#ifndef WIN32_GETOPT_H -#define WIN32_GETOPT_H - -#ifdef __cplusplus -extern "C" { -#endif - -extern char * optarg; -extern int optind; - -int getopt ( int argc, char **argv, char *optstring); - -#ifdef __cplusplus -} -#endif - -#endif // WIN32_GETOPT_H diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsm_config.h b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsm_config.h deleted file mode 100755 index 258d4fed52..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsm_config.h +++ /dev/null @@ -1,171 +0,0 @@ -/* gsm_config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define if using alloca.c. */ -#undef C_ALLOCA - -/* Define to empty if the keyword does not work. */ -#undef const - -/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. - This function is required for alloca.c support on those systems. */ -#undef CRAY_STACKSEG_END - -/* Define if you have alloca, as a function or macro. */ -#define HAVE_ALLOCA 1 -#define alloca _alloca // Microsoft - -/* Define if you have and it should be used (not on Ultrix). */ -#undef HAVE_ALLOCA_H - -/* Define if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define as __inline if that's what the C compiler calls it. */ -#undef inline - -/* Define to `long' if doesn't define. */ -#undef off_t - -/* Define if you need to in order for stat and other things to work. */ -#undef _POSIX_SOURCE - -/* Define to `unsigned' if doesn't define. */ -#undef size_t - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown - */ -#undef STACK_DIRECTION - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* used by libtool*/ -#define PACKAGE 0 - -/* used by libtool*/ -#define VERSION 0 - -/* Define if getopt_long() available */ -#undef HAVE_GETOPT_LONG - -/* Define if alarm() available */ -#undef HAVE_ALARM - -/* Define for NLS */ -#undef ENABLE_NLS -#undef HAVE_CATGETS -#undef HAVE_GETTEXT -#undef HAVE_LC_MESSAGES -#undef HAVE_STPCPY - -/* Define LOCALEDIR */ -#define LOCALEDIR "/usr/share/locale" - -/* Define if vsnprintf() function available */ -#define HAVE_VSNPRINTF 1 -#ifndef WIN32 -#define vsnprintf _vsnprintf -#endif// WIN32 - -/* The number of bytes in a unsigned int. */ -#define SIZEOF_UNSIGNED_INT 4 - -/* The number of bytes in a unsigned long int. */ -#define SIZEOF_UNSIGNED_LONG_INT 4 - -/* The number of bytes in a unsigned short int. */ -#define SIZEOF_UNSIGNED_SHORT_INT 2 - -/* Define if you have the __argz_count function. */ -#undef HAVE___ARGZ_COUNT - -/* Define if you have the __argz_next function. */ -#undef HAVE___ARGZ_NEXT - -/* Define if you have the __argz_stringify function. */ -#undef HAVE___ARGZ_STRINGIFY - -/* Define if you have the dcgettext function. */ -#undef HAVE_DCGETTEXT - -/* Define if you have the getcwd function. */ -#undef HAVE_GETCWD - -/* Define if you have the getpagesize function. */ -#undef HAVE_GETPAGESIZE - -/* Define if you have the munmap function. */ -#undef HAVE_MUNMAP - -/* Define if you have the putenv function. */ -#undef HAVE_PUTENV - -/* Define if you have the setenv function. */ -#undef HAVE_SETENV - -/* Define if you have the setlocale function. */ -#define HAVE_SETLOCALE 1 - -/* Define if you have the stpcpy function. */ -#undef HAVE_STPCPY - -/* Define if you have the strcasecmp function. */ -#undef HAVE_STRCASECMP -#define strcasecmp _strcmpi - -/* Define if you have the strchr function. */ -#define HAVE_STRCHR 1 - -/* Define if you have the strdup function. */ -#define HAVE_STRDUP 1 - -/* Define if you have the header file. */ -#undef HAVE_ARGZ_H - -/* Define if you have the header file. */ -#undef HAVE_LIBINTL_H - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define if you have the header file. */ -#define HAVE_MALLOC_H 1 - -/* Define if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* Define if you have the header file. */ -#undef HAVE_NL_TYPES_H - -/* Define if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define if you have the i library (-li). */ -#undef HAVE_LIBI - -/* Define if you have the intl library (-lintl). */ -#undef HAVE_LIBINTL - -// WIN32 specific defines -#pragma warning( disable : 4786 ) // Disable warning messages - // 4786 (id too long) - -// Win32 strftime() does not return length of output when passing -// NULL pointer -#define BROKEN_STRFTIME -// Win32 STL erase() for maps makes iterators invalid -#define BUGGY_MAP_ERASE diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmctl.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmctl.dsp deleted file mode 100644 index b48a1c54db..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmctl.dsp +++ /dev/null @@ -1,118 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gsmctl" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=gsmctl - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "gsmctl.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "gsmctl.mak" CFG="gsmctl - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "gsmctl - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "gsmctl - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gsmctl - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "gsmctl - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "gsmctl - Win32 Release" -# Name "gsmctl - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\getopt.c - -!IF "$(CFG)" == "gsmctl - Win32 Release" - -!ELSEIF "$(CFG)" == "gsmctl - Win32 Debug" - -# ADD CPP /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\apps\gsmctl.cc -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\getopt.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.2017.vcxproj b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.2017.vcxproj deleted file mode 100644 index 83fa970270..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.2017.vcxproj +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - gsmlib - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - - - - StaticLibrary - false - MultiByte - $(DefaultPlatformToolset) - - - StaticLibrary - false - MultiByte - $(DefaultPlatformToolset) - - - StaticLibrary - false - MultiByte - $(DefaultPlatformToolset) - - - StaticLibrary - false - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - MaxSpeed - OnlyExplicitInline - ../vcproject;..;.;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - true - .\Release/gsmlib.pch - .\Release/ - .\Release/ - .\Release/ - true - Level3 - true - /wd4290 /wd4996 %(AdditionalOptions) - 4838;4267;4101;4244;4554;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - /ignore:4221 %(AdditionalOptions) - - - true - - - - - Disabled - ..;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - Level3 - true - ProgramDatabase - /wd4290 /wd4996 %(AdditionalOptions) - 4838;4267;4101;4244;4554;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - false - %(IgnoreSpecificDefaultLibraries) - /ignore:4221 %(AdditionalOptions) - - - true - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../vcproject;..;.;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - true - true - Level3 - true - /wd4290 /wd4996 %(AdditionalOptions) - 4838;4267;4101;4244;4554;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - true - - - - - X64 - - - Disabled - ..;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - Level3 - true - ProgramDatabase - /wd4290 /wd4996 %(AdditionalOptions) - 4838;4267;4101;4244;4554;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - false - %(IgnoreSpecificDefaultLibraries) - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsp deleted file mode 100644 index ace489a252..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsp +++ /dev/null @@ -1,232 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gsmlib" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=gsmlib - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "gsmlib.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "gsmlib.mak" CFG="gsmlib - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "gsmlib - Win32 Release" (basierend auf "Win32 (x86) Static Library") -!MESSAGE "gsmlib - Win32 Debug" (basierend auf "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gsmlib - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /W3 /GR /GX /O2 /I "../vcproject" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /FR /YX /FD /TP /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "gsmlib - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "gsmlib - Win32 Release" -# Name "gsmlib - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;cc;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\gsmlib\gsm_at.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_error.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_cb.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_event.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_me_ta.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_nls.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_parser.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_phonebook.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sms.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sms_codec.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sms_store.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sorted_phonebook.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sorted_phonebook_base.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sorted_sms_store.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_util.cc -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_win32_serial.cc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\gsmlib\gsm_at.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_cb.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_error.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_event.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_map_key.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_me_ta.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_nls.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_parser.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_phonebook.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_port.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sms.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sms_codec.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sms_store.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sorted_phonebook.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sorted_phonebook_base.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sorted_sms_store.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_sysdep.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_util.h -# End Source File -# Begin Source File - -SOURCE=..\gsmlib\gsm_win32_serial.h -# End Source File -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsw b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsw deleted file mode 100644 index 21ab8168ac..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.dsw +++ /dev/null @@ -1,149 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELSCHT WERDEN! - -############################################################################### - -Project: "gsmctl"=".\gsmctl.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "gsmlib"=".\gsmlib.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "gsmpb"=".\gsmpb.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "gsmsendsms"=".\gsmsendsms.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "gsmsmsd"=".\gsmsmsd.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "gsmsmsstore"=".\gsmsmsstore.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "testgsmlib"=".\testgsmlib.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "testsms"=".\testsms.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Project: "testsms2"=".\testsms2.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name gsmlib - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.sln b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.sln deleted file mode 100755 index 928215c23d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmlib.sln +++ /dev/null @@ -1,92 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmctl", "gsmctl.vcproj", "{A822BA57-6F96-4C69-9E28-C0FB2667B1B0}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmlib", "gsmlib.vcproj", "{26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmpb", "gsmpb.vcproj", "{311D5A85-4DC1-4714-9B61-AE3C57B67B5B}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmsendsms", "gsmsendsms.vcproj", "{CF99664C-05D1-41A3-9B12-B79D55718377}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmsmsd", "gsmsmsd.vcproj", "{3C5D7948-5E49-4C78-9AAB-3AC53A15BEF4}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmsmsstore", "gsmsmsstore.vcproj", "{5A834BCC-8B96-4D1C-9811-ADC816797E3A}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgsmlib", "testgsmlib.vcproj", "{248E3E22-2203-4352-964E-32946A1A0AEC}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsms", "testsms.vcproj", "{BEE3EFDE-4C00-4CE5-9DFC-61DF6F0E5481}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsms2", "testsms2.vcproj", "{3E08AF8F-6DD3-40EC-AA97-C8D4237CA127}" - ProjectSection(ProjectDependencies) = postProject - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A822BA57-6F96-4C69-9E28-C0FB2667B1B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {A822BA57-6F96-4C69-9E28-C0FB2667B1B0}.Debug|Win32.Build.0 = Debug|Win32 - {A822BA57-6F96-4C69-9E28-C0FB2667B1B0}.Release|Win32.ActiveCfg = Release|Win32 - {A822BA57-6F96-4C69-9E28-C0FB2667B1B0}.Release|Win32.Build.0 = Release|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Debug|Win32.ActiveCfg = Debug|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Debug|Win32.Build.0 = Debug|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Release|Win32.ActiveCfg = Release|Win32 - {26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}.Release|Win32.Build.0 = Release|Win32 - {311D5A85-4DC1-4714-9B61-AE3C57B67B5B}.Debug|Win32.ActiveCfg = Debug|Win32 - {311D5A85-4DC1-4714-9B61-AE3C57B67B5B}.Debug|Win32.Build.0 = Debug|Win32 - {311D5A85-4DC1-4714-9B61-AE3C57B67B5B}.Release|Win32.ActiveCfg = Release|Win32 - {311D5A85-4DC1-4714-9B61-AE3C57B67B5B}.Release|Win32.Build.0 = Release|Win32 - {CF99664C-05D1-41A3-9B12-B79D55718377}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF99664C-05D1-41A3-9B12-B79D55718377}.Debug|Win32.Build.0 = Debug|Win32 - {CF99664C-05D1-41A3-9B12-B79D55718377}.Release|Win32.ActiveCfg = Release|Win32 - {CF99664C-05D1-41A3-9B12-B79D55718377}.Release|Win32.Build.0 = Release|Win32 - {3C5D7948-5E49-4C78-9AAB-3AC53A15BEF4}.Debug|Win32.ActiveCfg = Debug|Win32 - {3C5D7948-5E49-4C78-9AAB-3AC53A15BEF4}.Debug|Win32.Build.0 = Debug|Win32 - {3C5D7948-5E49-4C78-9AAB-3AC53A15BEF4}.Release|Win32.ActiveCfg = Release|Win32 - {3C5D7948-5E49-4C78-9AAB-3AC53A15BEF4}.Release|Win32.Build.0 = Release|Win32 - {5A834BCC-8B96-4D1C-9811-ADC816797E3A}.Debug|Win32.ActiveCfg = Debug|Win32 - {5A834BCC-8B96-4D1C-9811-ADC816797E3A}.Debug|Win32.Build.0 = Debug|Win32 - {5A834BCC-8B96-4D1C-9811-ADC816797E3A}.Release|Win32.ActiveCfg = Release|Win32 - {5A834BCC-8B96-4D1C-9811-ADC816797E3A}.Release|Win32.Build.0 = Release|Win32 - {248E3E22-2203-4352-964E-32946A1A0AEC}.Debug|Win32.ActiveCfg = Debug|Win32 - {248E3E22-2203-4352-964E-32946A1A0AEC}.Debug|Win32.Build.0 = Debug|Win32 - {248E3E22-2203-4352-964E-32946A1A0AEC}.Release|Win32.ActiveCfg = Release|Win32 - {248E3E22-2203-4352-964E-32946A1A0AEC}.Release|Win32.Build.0 = Release|Win32 - {BEE3EFDE-4C00-4CE5-9DFC-61DF6F0E5481}.Debug|Win32.ActiveCfg = Debug|Win32 - {BEE3EFDE-4C00-4CE5-9DFC-61DF6F0E5481}.Debug|Win32.Build.0 = Debug|Win32 - {BEE3EFDE-4C00-4CE5-9DFC-61DF6F0E5481}.Release|Win32.ActiveCfg = Release|Win32 - {BEE3EFDE-4C00-4CE5-9DFC-61DF6F0E5481}.Release|Win32.Build.0 = Release|Win32 - {3E08AF8F-6DD3-40EC-AA97-C8D4237CA127}.Debug|Win32.ActiveCfg = Debug|Win32 - {3E08AF8F-6DD3-40EC-AA97-C8D4237CA127}.Debug|Win32.Build.0 = Debug|Win32 - {3E08AF8F-6DD3-40EC-AA97-C8D4237CA127}.Release|Win32.ActiveCfg = Release|Win32 - {3E08AF8F-6DD3-40EC-AA97-C8D4237CA127}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmpb.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmpb.dsp deleted file mode 100644 index befc0f6d51..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmpb.dsp +++ /dev/null @@ -1,118 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gsmpb" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=gsmpb - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "gsmpb.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "gsmpb.mak" CFG="gsmpb - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "gsmpb - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "gsmpb - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gsmpb - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "gsmpb - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "gsmpb - Win32 Release" -# Name "gsmpb - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\getopt.c - -!IF "$(CFG)" == "gsmpb - Win32 Release" - -!ELSEIF "$(CFG)" == "gsmpb - Win32 Debug" - -# ADD CPP /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\apps\gsmpb.cc -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\getopt.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsendsms.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsendsms.dsp deleted file mode 100644 index 7e660fbdbb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsendsms.dsp +++ /dev/null @@ -1,118 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gsmsendsms" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=gsmsendsms - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "gsmsendsms.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "gsmsendsms.mak" CFG="gsmsendsms - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "gsmsendsms - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "gsmsendsms - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gsmsendsms - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "gsmsendsms - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "gsmsendsms - Win32 Release" -# Name "gsmsendsms - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\getopt.c - -!IF "$(CFG)" == "gsmsendsms - Win32 Release" - -!ELSEIF "$(CFG)" == "gsmsendsms - Win32 Debug" - -# ADD CPP /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\apps\gsmsendsms.cc -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\getopt.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsd.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsd.dsp deleted file mode 100644 index 2facfaa47c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsd.dsp +++ /dev/null @@ -1,118 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gsmsmsd" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=gsmsmsd - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "gsmsmsd.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "gsmsmsd.mak" CFG="gsmsmsd - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "gsmsmsd - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "gsmsmsd - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gsmsmsd - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "gsmsmsd - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "gsmsmsd - Win32 Release" -# Name "gsmsmsd - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\getopt.c - -!IF "$(CFG)" == "gsmsmsd - Win32 Release" - -!ELSEIF "$(CFG)" == "gsmsmsd - Win32 Debug" - -# ADD CPP /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\apps\gsmsmsd.cc -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\getopt.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsstore.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsstore.dsp deleted file mode 100644 index 5e7a9c150a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/gsmsmsstore.dsp +++ /dev/null @@ -1,119 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gsmsmsstore" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=gsmsmsstore - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "gsmsmsstore.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "gsmsmsstore.mak" CFG="gsmsmsstore - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "gsmsmsstore - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "gsmsmsstore - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gsmsmsstore - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "gsmsmsstore - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "gsmsmsstore - Win32 Release" -# Name "gsmsmsstore - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\getopt.c - -!IF "$(CFG)" == "gsmsmsstore - Win32 Release" - -!ELSEIF "$(CFG)" == "gsmsmsstore - Win32 Debug" - -# ADD CPP /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\apps\gsmsmsstore.cc -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\getopt.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testgsmlib.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testgsmlib.dsp deleted file mode 100644 index 26de21002d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testgsmlib.dsp +++ /dev/null @@ -1,101 +0,0 @@ -# Microsoft Developer Studio Project File - Name="testgsmlib" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=testgsmlib - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "testgsmlib.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "testgsmlib.mak" CFG="testgsmlib - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "testgsmlib - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "testgsmlib - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "testgsmlib - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /TP /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "testgsmlib - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "testgsmlib - Win32 Release" -# Name "testgsmlib - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\tests\testgsmlib.cc -# ADD CPP /I "../gsmlib" /I ".." /I "." /D "HAVE_CONFIG_H" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms.dsp deleted file mode 100644 index 09bf409bd2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="testsms" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=testsms - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "testsms.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "testsms.mak" CFG="testsms - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "testsms - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "testsms - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "testsms - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "testsms - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "testsms - Win32 Release" -# Name "testsms - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\tests\testsms.cc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms2.dsp b/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms2.dsp deleted file mode 100644 index 0ab2880c41..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/win32/testsms2.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="testsms2" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=testsms2 - Win32 Debug -!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "testsms2.mak". -!MESSAGE -!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "testsms2.mak" CFG="testsms2 - Win32 Debug" -!MESSAGE -!MESSAGE Fr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "testsms2 - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "testsms2 - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "testsms2 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /TP /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "testsms2 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gsmlib" /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /TP /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "testsms2 - Win32 Release" -# Name "testsms2 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\tests\testsms2.cc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen.h b/src/mod/endpoints/mod_gsmopen/gsmopen.h deleted file mode 100644 index 75f62148e3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmopen.h +++ /dev/null @@ -1,584 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli - * - * Maintainer: Giovanni Maruzzelli - * - * mod_gsmopen.cpp -- GSM Modem compatible Endpoint Module - * - */ - - -#define __STDC_LIMIT_MACROS - -#ifdef WIN32 -#define HAVE_VSNPRINTF -#pragma warning(disable: 4290) -#endif //WIN32 - -#define MY_EVENT_INCOMING_SMS "gsmopen::incoming_sms" -#define MY_EVENT_DUMP "gsmopen::dump_event" -#define MY_EVENT_ALARM "gsmopen::alarm" - -#define ALARM_FAILED_INTERFACE 0 -#define ALARM_NO_NETWORK_REGISTRATION 1 -#define ALARM_ROAMING_NETWORK_REGISTRATION 2 -#define ALARM_NETWORK_NO_SERVICE 3 -#define ALARM_NETWORK_NO_SIGNAL 4 -#define ALARM_NETWORK_LOW_SIGNAL 5 - -#undef GIOVA48 - -#ifndef GIOVA48 -#define SAMPLES_PER_FRAME 160 -#else // GIOVA48 -#define SAMPLES_PER_FRAME 960 -#endif // GIOVA48 - -#ifndef GIOVA48 -#define GSMOPEN_FRAME_SIZE 160 -#else //GIOVA48 -#define GSMOPEN_FRAME_SIZE 960 -#endif //GIOVA48 -#define SAMPLERATE_GSMOPEN 8000 - -#include -#ifndef WIN32 -#include -#include -#include -#include -#endif //WIN32 - -#ifndef WIN32 -#include -#endif //WIN32 - -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -#include -#include - -#ifdef _MSC_VER -//Windows macro for FD_SET includes a warning C4127: conditional expression is constant -#pragma warning(push) -#pragma warning(disable:4127) -#endif - -#define PROTOCOL_ALSA_VOICEMODEM 4 -#define PROTOCOL_AT 2 -#define PROTOCOL_FBUS2 1 -#define PROTOCOL_NO_SERIAL 3 - -#define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */ -#define AT_BUFSIZ AT_MESG_MAX_LENGTH -#define AT_MESG_MAX_LINES 20 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */ - -#ifndef GSMOPEN_SVN_VERSION -#define GSMOPEN_SVN_VERSION switch_version_full() -#endif /* GSMOPEN_SVN_VERSION */ - -#include "ctb-0.16/ctb.h" - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_CODEC = (1 << 7), - TFLAG_BREAK = (1 << 8) -} TFLAGS; - -typedef enum { - GFLAG_MY_CODEC_PREFS = (1 << 0) -} GFLAGS; - -#define DEBUGA_GSMOPEN(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev %s [%p|%-7lx][DEBUG_GSMOPEN %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_CALL(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev %s [%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define DEBUGA_PBX(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev %s [%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define ERRORA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "rev %s [%p|%-7lx][ERRORA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define WARNINGA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "rev %s [%p|%-7lx][WARNINGA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); -#define NOTICA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "rev %s [%p|%-7lx][NOTICA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); - -#define GSMOPEN_P_LOG GSMOPEN_SVN_VERSION, (void *)NULL, (unsigned long)55, __LINE__, tech_pvt ? tech_pvt->name ? tech_pvt->name : "none" : "none", -1, tech_pvt ? tech_pvt->interface_state : -1, tech_pvt ? tech_pvt->phone_callflow : -1 - -/*********************************/ -#define GSMOPEN_CAUSE_NORMAL 1 -#define GSMOPEN_CAUSE_FAILURE 2 -#define GSMOPEN_CAUSE_NO_ANSWER 3 -/*********************************/ -#define GSMOPEN_FRAME_DTMF 1 -/*********************************/ -#define GSMOPEN_CONTROL_RINGING 1 -#define GSMOPEN_CONTROL_ANSWER 2 -#define GSMOPEN_CONTROL_HANGUP 3 -#define GSMOPEN_CONTROL_BUSY 4 - -/*********************************/ -#define GSMOPEN_STATE_IDLE 0 -#define GSMOPEN_STATE_DOWN 1 -#define GSMOPEN_STATE_RING 2 -#define GSMOPEN_STATE_DIALING 3 -#define GSMOPEN_STATE_BUSY 4 -#define GSMOPEN_STATE_UP 5 -#define GSMOPEN_STATE_RINGING 6 -#define GSMOPEN_STATE_PRERING 7 -#define GSMOPEN_STATE_ERROR_DOUBLE_CALL 8 -#define GSMOPEN_STATE_SELECTED 9 -#define GSMOPEN_STATE_HANGUP_REQUESTED 10 -#define GSMOPEN_STATE_PREANSWER 11 -/*********************************/ -/* call flow from the device */ -#define CALLFLOW_CALL_IDLE 0 -#define CALLFLOW_CALL_DOWN 1 -#define CALLFLOW_INCOMING_RING 2 -#define CALLFLOW_CALL_DIALING 3 -#define CALLFLOW_CALL_LINEBUSY 4 -#define CALLFLOW_CALL_ACTIVE 5 -#define CALLFLOW_INCOMING_HANGUP 6 -#define CALLFLOW_CALL_RELEASED 7 -#define CALLFLOW_CALL_NOCARRIER 8 -#define CALLFLOW_CALL_INFLUX 9 -#define CALLFLOW_CALL_INCOMING 10 -#define CALLFLOW_CALL_FAILED 11 -#define CALLFLOW_CALL_NOSERVICE 12 -#define CALLFLOW_CALL_OUTGOINGRESTRICTED 13 -#define CALLFLOW_CALL_SECURITYFAIL 14 -#define CALLFLOW_CALL_NOANSWER 15 -#define CALLFLOW_STATUS_FINISHED 16 -#define CALLFLOW_STATUS_CANCELLED 17 -#define CALLFLOW_STATUS_FAILED 18 -#define CALLFLOW_STATUS_REFUSED 19 -#define CALLFLOW_STATUS_RINGING 20 -#define CALLFLOW_STATUS_INPROGRESS 21 -#define CALLFLOW_STATUS_UNPLACED 22 -#define CALLFLOW_STATUS_ROUTING 23 -#define CALLFLOW_STATUS_EARLYMEDIA 24 -#define CALLFLOW_INCOMING_CALLID 25 -#define CALLFLOW_STATUS_REMOTEHOLD 26 -#define CALLFLOW_CALL_REMOTEANSWER 27 -#define CALLFLOW_CALL_HANGUP_REQUESTED 28 - -/*********************************/ - -#define AT_OK 0 -#define AT_ERROR 1 - -#define GSMOPEN_MAX_INTERFACES 64 - -#define USSD_ENCODING_AUTO 0 -#define USSD_ENCODING_PLAIN 1 -#define USSD_ENCODING_HEX_7BIT 2 -#define USSD_ENCODING_HEX_8BIT 3 -#define USSD_ENCODING_UCS2 4 - -#ifndef WIN32 -struct GSMopenHandles { - int currentuserhandle; - int api_connected; - int fdesc[2]; -}; -#else //WIN32 - -struct GSMopenHandles { - HWND win32_hInit_MainWindowHandle; - HWND win32_hGlobal_GSMAPIWindowHandle; - HINSTANCE win32_hInit_ProcessHandle; - char win32_acInit_WindowClassName[128]; - UINT win32_uiGlobal_MsgID_GSMControlAPIAttach; - UINT win32_uiGlobal_MsgID_GSMControlAPIDiscover; - int currentuserhandle; - int api_connected; - switch_file_t *fdesc[2]; -}; - -#endif //WIN32 - -/*! - * \brief structure for storing the results of AT commands, in an array of AT_MESG_MAX_LINES * AT_MESG_MAX_LENGTH chars - */ -struct s_result { - int elemcount; - char result[AT_MESG_MAX_LINES][AT_MESG_MAX_LENGTH]; -}; - -struct ciapa_struct { - int state; - int hangupcause; -}; -typedef struct ciapa_struct ciapa_t; - -struct private_object { - unsigned int flags; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_frame_t read_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - char session_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_caller_profile_t *caller_profile; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - - char id[80]; - char name[80]; - char dialplan[80]; - char context[80]; - char dial_regex[256]; - char fail_dial_regex[256]; - char hold_music[256]; - char type[256]; - char X11_display[256]; -#ifdef WIN32 - unsigned short tcp_cli_port; - unsigned short tcp_srv_port; -#else - int tcp_cli_port; - int tcp_srv_port; -#endif - struct GSMopenHandles GSMopenHandles; - - int interface_state; /*!< \brief 'state' of the interface (channel) */ - char language[80]; /*!< \brief default Asterisk dialplan language for this interface */ - char exten[80]; /*!< \brief default Asterisk dialplan extension for this interface */ - int gsmopen_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */ - char callid_name[50]; - char callid_number[50]; - double playback_boost; - double capture_boost; - int stripmsd; - char gsmopen_call_id[512]; - int gsmopen_call_ongoing; - char gsmopen_friends[4096]; - char gsmopen_fullname[512]; - char gsmopen_displayname[512]; - int phone_callflow; /*!< \brief 'callflow' of the gsmopen interface (as opposed to phone interface) */ - int gsmopen; /*!< \brief config flag, bool, GSM support on this interface (0 if false, -1 if true) */ - int control_to_send; -#ifdef WIN32 - switch_file_t *audiopipe[2]; - switch_file_t *audiogsmopenpipe[2]; - switch_file_t *gsmopen_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ -#else /* WIN32 */ - int audiopipe[2]; - int audiogsmopenpipe[2]; - int gsmopen_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ -#endif /* WIN32 */ - switch_thread_t *tcp_srv_thread; - switch_thread_t *tcp_cli_thread; - switch_thread_t *gsmopen_signaling_thread; - switch_thread_t *gsmopen_api_thread; - int gsmopen_dir_entry_extension_prefix; - char gsmopen_user[256]; - char gsmopen_password[256]; - char destination[256]; - struct timeval answer_time; - - struct timeval transfer_time; - char transfer_callid_number[50]; - char gsmopen_transfer_call_id[512]; - int running; - unsigned long ib_calls; - unsigned long ob_calls; - unsigned long ib_failed_calls; - unsigned long ob_failed_calls; - - char controldevice_name[512]; /*!< \brief name of the serial device controlling the interface, possibly none */ - int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */ - char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */ - int controldevfd; /*!< \brief serial controlling file descriptor for this interface */ -#ifdef WIN32 - int controldevice_speed; -#else - speed_t controldevice_speed; -#endif // WIN32 - int controldev_dead; - - char at_dial_pre_number[64]; - char at_dial_post_number[64]; - char at_dial_expect[64]; - unsigned int at_early_audio; - char at_hangup[64]; - char at_hangup_expect[64]; - char at_answer[64]; - char at_answer_expect[64]; - unsigned int at_initial_pause; - char at_preinit_1[64]; - char at_preinit_1_expect[64]; - char at_preinit_2[64]; - char at_preinit_2_expect[64]; - char at_preinit_3[64]; - char at_preinit_3_expect[64]; - char at_preinit_4[64]; - char at_preinit_4_expect[64]; - char at_preinit_5[64]; - char at_preinit_5_expect[64]; - unsigned int at_after_preinit_pause; - - char at_postinit_1[64]; - char at_postinit_1_expect[64]; - char at_postinit_2[64]; - char at_postinit_2_expect[64]; - char at_postinit_3[64]; - char at_postinit_3_expect[64]; - char at_postinit_4[64]; - char at_postinit_4_expect[64]; - char at_postinit_5[64]; - char at_postinit_5_expect[64]; - - char at_send_dtmf[64]; - - char at_query_battchg[64]; - char at_query_battchg_expect[64]; - char at_query_signal[64]; - char at_query_signal_expect[64]; - char at_call_idle[64]; - char at_call_incoming[64]; - char at_call_active[64]; - char at_call_failed[64]; - char at_call_calling[64]; - -#define CIEV_STRING_SIZE 64 - char at_indicator_noservice_string[64]; - char at_indicator_nosignal_string[64]; - char at_indicator_lowsignal_string[64]; - char at_indicator_lowbattchg_string[64]; - char at_indicator_nobattchg_string[64]; - char at_indicator_callactive_string[64]; - char at_indicator_nocallactive_string[64]; - char at_indicator_nocallsetup_string[64]; - char at_indicator_callsetupincoming_string[64]; - char at_indicator_callsetupoutgoing_string[64]; - char at_indicator_callsetupremoteringing_string[64]; - - int at_indicator_callp; - int at_indicator_callsetupp; - int at_indicator_roamp; - int at_indicator_battchgp; - int at_indicator_servicep; - int at_indicator_signalp; - - int at_has_clcc; - int at_has_ecam; - - char at_cmgw[16]; - int no_ucs2; - time_t gsmopen_serial_sync_period; - - time_t gsmopen_serial_synced_timestamp; - struct s_result line_array; - - int unread_sms_msg_id; - int reading_sms_msg; - char sms_message[4800]; - char sms_sender[256]; - char sms_date[256]; - char sms_userdataheader[256]; - char sms_body[4800]; - char sms_datacodingscheme[256]; - char sms_servicecentreaddress[256]; - int sms_messagetype; - int sms_cnmi_not_supported; - int sms_pdu_not_supported; - - int ussd_request_encoding; - int ussd_response_encoding; - int ussd_request_hex; - int ussd_received; - int ussd_status; - char ussd_message[1024]; - char ussd_dcs[256]; - - struct timeval call_incoming_time; - switch_mutex_t *controldev_lock; - - int phonebook_listing; - int phonebook_querying; - int phonebook_listing_received_calls; - - int phonebook_first_entry; - int phonebook_last_entry; - int phonebook_number_lenght; - int phonebook_text_lenght; - FILE *phonebook_writing_fp; - - struct timeval ringtime; - ciapa_t *owner; - - time_t audio_play_reset_timestamp; - int audio_play_reset_period; - - switch_timer_t timer_read; - switch_timer_t timer_write; - teletone_dtmf_detect_state_t dtmf_detect; - switch_time_t old_dtmf_timestamp; - - int no_sound; - - dtmf_rx_state_t dtmf_state; - int active; - int home_network_registered; - int roaming_registered; - int not_registered; - int got_signal; - int signal_strength; - char imei[128]; - int requesting_imei; - char imsi[128]; - int requesting_imsi; - char operator_name[128]; - int requesting_operator_name; - char subscriber_number[128]; - int requesting_subscriber_number; - char device_mfg[128]; - int requesting_device_mfg; - char device_model[128]; - int requesting_device_model; - char device_firmware[128]; - int requesting_device_firmware; - int network_creg_not_supported; - char creg[128]; - - char controldevice_audio_name[512]; - int controldev_audio_fd; - int controldevice_audio_speed; - int controldev_audio_dead; - switch_mutex_t *controldev_audio_lock; - ctb::SerialPort * serialPort_serial_audio; - - ctb::SerialPort * serialPort_serial_control; - - char buffer2[320]; - int buffer2_full; - int serialPort_serial_audio_opened; - -}; - -typedef struct private_object private_t; - -void *SWITCH_THREAD_FUNC gsmopen_api_thread_func(switch_thread_t *thread, void *obj); -int gsmopen_audio_read(private_t *tech_pvt); -int gsmopen_audio_init(private_t *tech_pvt); -int gsmopen_signaling_read(private_t *tech_pvt); - -int gsmopen_call(private_t *tech_pvt, char *idest, int timeout); -int gsmopen_senddigit(private_t *tech_pvt, char digit); - -void *gsmopen_do_tcp_srv_thread_func(void *obj); -void *SWITCH_THREAD_FUNC gsmopen_do_tcp_srv_thread(switch_thread_t *thread, void *obj); - -void *gsmopen_do_tcp_cli_thread_func(void *obj); -void *SWITCH_THREAD_FUNC gsmopen_do_tcp_cli_thread(switch_thread_t *thread, void *obj); - -void *gsmopen_do_gsmopenapi_thread_func(void *obj); -void *SWITCH_THREAD_FUNC gsmopen_do_gsmopenapi_thread(switch_thread_t *thread, void *obj); -int dtmf_received(private_t *tech_pvt, char *value); -int start_audio_threads(private_t *tech_pvt); -int new_inbound_channel(private_t *tech_pvt); -int outbound_channel_answered(private_t *tech_pvt); -#if defined(WIN32) && !defined(__CYGWIN__) -int gsmopen_pipe_read(switch_file_t *pipe, short *buf, int howmany); -int gsmopen_pipe_write(switch_file_t *pipe, short *buf, int howmany); -/* Visual C do not have strsep ? */ -char *strsep(char **stringp, const char *delim); -#else -int gsmopen_pipe_read(int pipe, short *buf, int howmany); -int gsmopen_pipe_write(int pipe, short *buf, int howmany); -#endif /* WIN32 */ -int gsmopen_close_socket(unsigned int fd); -private_t *find_available_gsmopen_interface_rr(private_t *tech_pvt_calling); -int remote_party_is_ringing(private_t *tech_pvt); -int remote_party_is_early_media(private_t *tech_pvt); -int gsmopen_socket_create_and_bind(private_t *tech_pvt, int *which_port); - -void *gsmopen_do_controldev_thread(void *data); -int gsmopen_serial_init(private_t *tech_pvt, int controldevice_speed); -int gsmopen_serial_monitor(private_t *tech_pvt); -int gsmopen_serial_sync(private_t *tech_pvt); -int gsmopen_serial_sync_AT(private_t *tech_pvt); -int gsmopen_serial_config(private_t *tech_pvt); -int gsmopen_serial_config_AT(private_t *tech_pvt); - -#define gsmopen_serial_write_AT_expect(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 1, 0) -#define gsmopen_serial_write_AT_expect_noexpcr(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 0, 0) -#define gsmopen_serial_write_AT_expect_noexpcr_tout(P, D, S, T) gsmopen_serial_write_AT_expect1(P, D, S, 0, T) -#define gsmopen_serial_write_AT_expect_longtime(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 1, 5) -#define gsmopen_serial_write_AT_expect_longtime_noexpcr(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 0, 5) -int gsmopen_serial_write_AT(private_t *tech_pvt, const char *data); -int gsmopen_serial_write_AT_nocr(private_t *tech_pvt, const char *data); -int gsmopen_serial_write_AT_ack(private_t *tech_pvt, const char *data); -int gsmopen_serial_write_AT_ack_nocr_longtime(private_t *tech_pvt, const char *data); -int gsmopen_serial_write_AT_noack(private_t *tech_pvt, const char *data); -int gsmopen_serial_write_AT_expect1(private_t *tech_pvt, const char *data, const char *expected_string, int expect_crlf, int seconds); -int gsmopen_serial_AT_expect(private_t *tech_pvt, const char *expected_string, int expect_crlf, int seconds); -int gsmopen_serial_read_AT(private_t *tech_pvt, int look_for_ack, int timeout_usec, int timeout_sec, const char *expected_string, int expect_crlf); -int gsmopen_serial_read(private_t *tech_pvt); -#define RESULT_FAILURE 0 -#define RESULT_SUCCESS 1 -int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *ucs2_out, size_t outbytesleft); -int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outbytesleft); -int utf8_to_iso_8859_1(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *iso_8859_1_out, size_t outbytesleft); -#define PUSHA_UNLOCKA(x) if(option_debug > 100) ERRORA("PUSHA_UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); -#define POPPA_UNLOCKA(x) if(option_debug > 100) ERRORA("POPPA_UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); -#define LOKKA(x) switch_mutex_lock(x); -#define UNLOCKA(x) switch_mutex_unlock(x); - -#define gsmopen_queue_control(x, y) ERRORA("gsmopen_queue_control: %p, %d\n", GSMOPEN_P_LOG, (void *)x, y); - -#define ast_setstate(x, y) ERRORA("ast_setstate: %p, %d\n", GSMOPEN_P_LOG, (void *)x, y); - -int gsmopen_serial_read(private_t *tech_pvt); -int gsmopen_answer(private_t *tech_pvt); -int gsmopen_serial_answer(private_t *tech_pvt); -int gsmopen_serial_answer_AT(private_t *tech_pvt); -int gsmopen_serial_hangup(private_t *tech_pvt); -int gsmopen_serial_hangup_AT(private_t *tech_pvt); -int gsmopen_hangup(private_t *tech_pvt); -int gsmopen_serial_call(private_t *tech_pvt, char *dstr); -int gsmopen_serial_call_AT(private_t *tech_pvt, char *dstr); -int gsmopen_sendsms(private_t *tech_pvt, char *dest, char *text); - -void gsmopen_store_boost(char *s, double *boost); -int gsmopen_sound_boost(void *data, int samples_num, double boost); -int sms_incoming(private_t *tech_pvt); -int gsmopen_ring(private_t *tech_pvt); - -int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, size_t outbytesleft); -int gsmopen_serial_getstatus_AT(private_t *tech_pvt); - -int dump_event(private_t *tech_pvt); -int alarm_event(private_t *tech_pvt, int alarm_code, const char *alarm_message); -int dump_event_full(private_t *tech_pvt, int is_alarm, int alarm_code, const char *alarm_message); - -int gsmopen_serial_init_audio_port(private_t *tech_pvt, int controldevice_audio_speed); -int serial_audio_init(private_t *tech_pvt); -int serial_audio_shutdown(private_t *tech_pvt); -#ifndef WIN32 -void find_ttyusb_devices(private_t *tech_pvt, const char *dirname); -#endif// WIN32 -int gsmopen_ussd(private_t *tech_pvt, char *ussd, int waittime); -int ussd_incoming(private_t *tech_pvt); diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp deleted file mode 100644 index bfd465501a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +++ /dev/null @@ -1,3306 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli - * - * Maintainer: Giovanni Maruzzelli - * - * gsmopen_protocol.cpp -- Low Level Interface for mod_gamopen - * - */ - - - - -#include "gsmopen.h" -#ifdef WIN32 -#include "win_iconv.c" -#endif // WIN32 -#define WANT_GSMLIB - -#ifdef WANT_GSMLIB -#include - - -using namespace std; -using namespace gsmlib; -#endif // WANT_GSMLIB - - -extern int running; //FIXME -int gsmopen_dir_entry_extension = 1; //FIXME -int option_debug = 100; //FIXME - -#define gsmopen_sleep switch_sleep -#define gsmopen_strncpy switch_copy_string -extern switch_memory_pool_t *gsmopen_module_pool; -extern switch_endpoint_interface_t *gsmopen_endpoint_interface; - -#ifdef WIN32 -/***************/ -// from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/ - -#include - -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else /* */ -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif /* */ -struct sk_timezone { - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; -int gettimeofday(struct timeval *tv, struct sk_timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - if (NULL != tv) { - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch */ - tmpres /= 10; /*convert into microseconds */ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long) (tmpres / 1000000UL); - tv->tv_usec = (long) (tmpres % 1000000UL); - } - if (NULL != tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - return 0; -} - -/***************/ -#endif /* WIN32 */ - -int gsmopen_serial_init(private_t *tech_pvt, int controldevice_speed) -{ - if (!tech_pvt) - return -1; - - tech_pvt->serialPort_serial_control = new ctb::SerialPort(); - - /* windows: com ports above com9 need a special trick, which also works for com ports below com10 ... */ - char devname[512] = ""; - strcpy(devname, tech_pvt->controldevice_name); -#ifdef WIN32 - strcpy(devname,"\\\\.\\"); - strcat(devname, tech_pvt->controldevice_name); -#endif - - if (tech_pvt->serialPort_serial_control->Open(devname, 115200, "8N1", ctb::SerialPort::NoFlowControl) >= 0) { - DEBUGA_GSMOPEN("port %s, SUCCESS open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - } else { -#ifdef WIN32 - LPVOID msg; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &msg, - 0, - NULL); - ERRORA("port open failed for %s - %s", GSMOPEN_P_LOG, devname, (LPCTSTR) msg); - LocalFree(msg); -#else - ERRORA("port %s, NOT open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); -#endif - return -1; - } - - return 0; -} - -int gsmopen_serial_read(private_t *tech_pvt) -{ - if (tech_pvt && tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_read_AT(tech_pvt, 0, 100000, 0, NULL, 1); // a 10th of a second timeout -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_read_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_read_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - return -1; -} - -int gsmopen_serial_sync(private_t *tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_sync_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_sync_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_sync_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - - return -1; -} - -int gsmopen_serial_config(private_t *tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_config_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_config_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_config_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - - return -1; -} - -int gsmopen_serial_config_AT(private_t *tech_pvt) -{ - int res; - char at_command[5]; - int i; - - if (!tech_pvt) - return 0; - -/* initial_pause? */ - if (tech_pvt->at_initial_pause) { - DEBUGA_GSMOPEN("sleeping for %u usec\n", GSMOPEN_P_LOG, tech_pvt->at_initial_pause); - gsmopen_sleep(tech_pvt->at_initial_pause); - } - -/* go until first empty preinit string, or last preinit string */ - while (1) { - - char trash[4096]; - res = tech_pvt->serialPort_serial_control->Read(trash, 4096); - if (res) { - DEBUGA_GSMOPEN("READ %d on serialport init\n", GSMOPEN_P_LOG, res); - } - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CFUN=1"); - if (res) { - DEBUGA_GSMOPEN("no response to AT+CFUN=1. Continuing\n", GSMOPEN_P_LOG); - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT^CURC=0"); - if (res) { - DEBUGA_GSMOPEN("no response to AT^CURC=0. Continuing\n", GSMOPEN_P_LOG); - } - - if (strlen(tech_pvt->at_preinit_1)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_1, tech_pvt->at_preinit_1_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_1, tech_pvt->at_preinit_1_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_2)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_2, tech_pvt->at_preinit_2_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_2, tech_pvt->at_preinit_2_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_3)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_3, tech_pvt->at_preinit_3_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_3, tech_pvt->at_preinit_3_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_4)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_4, tech_pvt->at_preinit_4_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_4, tech_pvt->at_preinit_4_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_preinit_5)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_5, tech_pvt->at_preinit_5_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_5, tech_pvt->at_preinit_5_expect); - } - } else { - break; - } - - break; - } - -/* after_preinit_pause? */ - if (tech_pvt->at_after_preinit_pause) { - DEBUGA_GSMOPEN("sleeping for %u usec\n", GSMOPEN_P_LOG, tech_pvt->at_after_preinit_pause); - gsmopen_sleep(tech_pvt->at_after_preinit_pause); - } - - /* phone, brother, art you alive? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT"); - if (res) { - ERRORA("no response to AT\n", GSMOPEN_P_LOG); - return -1; - } - - /* for motorola, bring it back to "normal" mode if it happens to be in another mode */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+mode=0"); - if (res) { - DEBUGA_GSMOPEN("AT+mode=0 didn't get OK from the phone. If it is NOT Motorola," " no problem.\n", GSMOPEN_P_LOG); - } - gsmopen_sleep(50000); - /* for motorola end */ - - /* reset AT configuration to phone default */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "ATZ"); - if (res) { - DEBUGA_GSMOPEN("ATZ failed\n", GSMOPEN_P_LOG); - } - - /* disable AT command echo */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "ATE0"); - if (res) { - DEBUGA_GSMOPEN("ATE0 failed\n", GSMOPEN_P_LOG); - } - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CFUN=1"); - if (res) { - DEBUGA_GSMOPEN("no response to AT+CFUN=1. Continuing\n", GSMOPEN_P_LOG); - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT^CURC=0"); - if (res) { - DEBUGA_GSMOPEN("no response to AT^CURC=0. Continuing\n", GSMOPEN_P_LOG); - } - - - /* disable extended error reporting */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMEE=0"); - if (res) { - DEBUGA_GSMOPEN("AT+CMEE failed\n", GSMOPEN_P_LOG); - } - - /* various phone manufacturer identifier */ - for (i = 0; i < 10; i++) { - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "ATI%d", i); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res) { - DEBUGA_GSMOPEN("ATI%d command failed, continue\n", GSMOPEN_P_LOG, i); - } - } - - /* phone manufacturer */ - tech_pvt->requesting_device_mfg = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMI"); - tech_pvt->requesting_device_mfg = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CGMI failed\n", GSMOPEN_P_LOG); - } - - /* phone model */ - tech_pvt->requesting_device_model = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMM"); - tech_pvt->requesting_device_model = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CGMM failed\n", GSMOPEN_P_LOG); - } - - /* phone firmware */ - tech_pvt->requesting_device_firmware = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMR"); - tech_pvt->requesting_device_firmware = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CGMR failed\n", GSMOPEN_P_LOG); - } - - /* signal network registration with a +CREG unsolicited msg */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG=1"); - if (res) { - DEBUGA_GSMOPEN("AT+CREG=1 failed\n", GSMOPEN_P_LOG); - tech_pvt->network_creg_not_supported = 1; - } - if (!tech_pvt->network_creg_not_supported) { - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG?"); - if (res) { - DEBUGA_GSMOPEN("AT+CREG? failed\n", GSMOPEN_P_LOG); - } - } - /* query signal strength */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSQ"); - if (res) { - DEBUGA_GSMOPEN("AT+CSQ failed\n", GSMOPEN_P_LOG); - } - - /* operator name */ - tech_pvt->requesting_operator_name = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+COPS?"); - tech_pvt->requesting_operator_name = 0; - if (res) { - DEBUGA_GSMOPEN("AT+COPS? failed\n", GSMOPEN_P_LOG); - } - - /* subscriber number */ - tech_pvt->requesting_subscriber_number = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNUM"); - tech_pvt->requesting_subscriber_number = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CNUM failed, continue\n", GSMOPEN_P_LOG); - } - - /* IMEI */ - tech_pvt->requesting_imei = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+GSN"); - tech_pvt->requesting_imei = 0; - if (res) { - DEBUGA_GSMOPEN("AT+GSN failed\n", GSMOPEN_P_LOG); - tech_pvt->requesting_imei = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGSN"); - tech_pvt->requesting_imei = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CGSN failed\n", GSMOPEN_P_LOG); - } - } - /* IMSI */ - tech_pvt->requesting_imsi = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CIMI"); - tech_pvt->requesting_imsi = 0; - if (res) { - DEBUGA_GSMOPEN("AT+CIMI failed\n", GSMOPEN_P_LOG); - } - - /* signal incoming SMS with a +CMTI unsolicited msg */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=2,1,0,0,0"); - if (res) { - DEBUGA_GSMOPEN("AT+CNMI=2,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->sms_cnmi_not_supported = 1; - tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPMS=\"ME\",\"ME\",\"ME\""); - if (res) { - DEBUGA_GSMOPEN("no response to AT+CPMS=\"ME\",\"ME\",\"ME\". Continuing\n", GSMOPEN_P_LOG); - } - /* signal incoming SMS with a +CMTI unsolicited msg */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=2,1,0,0,0"); - if (res) { - DEBUGA_GSMOPEN("AT+CNMI=2,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->sms_cnmi_not_supported = 1; - tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPMS=\"ME\",\"ME\",\"ME\""); - if (res) { - DEBUGA_GSMOPEN("no response to AT+CPMS=\"ME\",\"ME\",\"ME\". Continuing\n", GSMOPEN_P_LOG); - } - /* signal incoming SMS with a +CMTI unsolicited msg */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=2,1,0,0,0"); - if (res) { - DEBUGA_GSMOPEN("AT+CNMI=2,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->sms_cnmi_not_supported = 1; - tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config - } - - /* what is the Message Center address (number) to which the SMS has to be sent? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCA?"); - if (res) { - DEBUGA_GSMOPEN("AT+CSCA? failed, continue\n", GSMOPEN_P_LOG); - } - /* what is the Message Format of SMSs? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF?"); - if (res) { - DEBUGA_GSMOPEN("AT+CMGF? failed, continue\n", GSMOPEN_P_LOG); - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1"); - if (res) { - ERRORA("Error setting SMS sending mode to TEXT on the cellphone, let's hope is TEXT by default. Continuing\n", GSMOPEN_P_LOG); - } - tech_pvt->sms_pdu_not_supported = 1; - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,8"); //unicode, 16 bit message - if (res) { - WARNINGA("AT+CSMP didn't get OK from the phone, continuing\n", GSMOPEN_P_LOG); - } - - /* what is the Charset of SMSs? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS?"); - if (res) { - DEBUGA_GSMOPEN("AT+CSCS? failed, continue\n", GSMOPEN_P_LOG); - } - - tech_pvt->no_ucs2 = 0; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\""); - if (res) { - WARNINGA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) didn't get OK from the phone, let's try with 'GSM'\n", GSMOPEN_P_LOG); - tech_pvt->no_ucs2 = 1; - } - if (tech_pvt->no_ucs2) { - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"GSM\""); - if (res) { - WARNINGA("AT+CSCS=\"GSM\" (set TE messages to GSM) didn't get OK from the phone\n", GSMOPEN_P_LOG); - } - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,0"); //normal, 7 bit message - if (res) { - WARNINGA("AT+CSMP didn't get OK from the phone, continuing\n", GSMOPEN_P_LOG); - } - } - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0"); - if (res) { - ERRORA("Error setting SMS sending mode to TEXT on the cellphone, let's hope is TEXT by default. Continuing\n", GSMOPEN_P_LOG); - } - tech_pvt->sms_pdu_not_supported = 0; - tech_pvt->no_ucs2 = 1; - - /* is the unsolicited reporting of mobile equipment event supported? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMER=?"); - if (res) { - DEBUGA_GSMOPEN("AT+CMER=? failed, continue\n", GSMOPEN_P_LOG); - } - /* request unsolicited reporting of mobile equipment indicators' events, to be screened by categories reported by +CIND=? */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMER=3,0,0,1"); - if (res) { - DEBUGA_GSMOPEN("AT+CMER=? failed, continue\n", GSMOPEN_P_LOG); - } - - /* is the solicited reporting of mobile equipment indications supported? */ - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CIND=?"); - if (res) { - DEBUGA_GSMOPEN("AT+CIND=? failed, continue\n", GSMOPEN_P_LOG); - } - - /* is the unsolicited reporting of call monitoring supported? sony-ericsson specific */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT*ECAM=?"); - if (res) { - DEBUGA_GSMOPEN("AT*ECAM=? failed, continue\n", GSMOPEN_P_LOG); - } - /* enable the unsolicited reporting of call monitoring. sony-ericsson specific */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT*ECAM=1"); - if (res) { - DEBUGA_GSMOPEN("AT*ECAM=1 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->at_has_ecam = 0; - } else { - tech_pvt->at_has_ecam = 1; - } - - /* disable unsolicited signaling of call list */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CLCC=0"); - if (res) { - DEBUGA_GSMOPEN("AT+CLCC=0 failed, continue\n", GSMOPEN_P_LOG); - tech_pvt->at_has_clcc = 0; - } else { - tech_pvt->at_has_clcc = 1; - } - - /* give unsolicited caller id when incoming call */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CLIP=1"); - if (res) { - DEBUGA_GSMOPEN("AT+CLIP failed, continue\n", GSMOPEN_P_LOG); - } - /* for motorola */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+MCST=1"); /* motorola call control codes - (to know when call is disconnected (they - don't give you "no carrier") */ - if (res) { - DEBUGA_GSMOPEN("AT+MCST=1 didn't get OK from the phone. If it is NOT Motorola," " no problem.\n", GSMOPEN_P_LOG); - } - /* for motorola end */ - -/* go until first empty postinit string, or last postinit string */ - while (1) { - - if (strlen(tech_pvt->at_postinit_1)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_1, tech_pvt->at_postinit_1_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_1, tech_pvt->at_postinit_1_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_2)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_2, tech_pvt->at_postinit_2_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_2, tech_pvt->at_postinit_2_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_3)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_3, tech_pvt->at_postinit_3_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_3, tech_pvt->at_postinit_3_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_4)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_4, tech_pvt->at_postinit_4_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_4, tech_pvt->at_postinit_4_expect); - } - } else { - break; - } - - if (strlen(tech_pvt->at_postinit_5)) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_5, tech_pvt->at_postinit_5_expect); - if (res) { - DEBUGA_GSMOPEN("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_5, tech_pvt->at_postinit_5_expect); - } - } else { - break; - } - - break; - } - - return 0; -} - -int gsmopen_serial_sync_AT(private_t *tech_pvt) -{ - gsmopen_sleep(10000); /* 10msec */ - time(&tech_pvt->gsmopen_serial_synced_timestamp); - return 0; -} - -int gsmopen_serial_read_AT(private_t *tech_pvt, int look_for_ack, int timeout_usec, int timeout_sec, const char *expected_string, int expect_crlf) -{ - int select_err = 1; - struct timeval timeout; - char tmp_answer[AT_BUFSIZ]; - char tmp_answer2[AT_BUFSIZ]; - char tmp_answer3[AT_BUFSIZ]; - char *tmp_answer_ptr; - char *last_line_ptr; - int i = 0; - int read_count = 0; - int la_counter = 0; - int at_ack = -1; - int la_read = 0; - int timeout_in_msec; - int msecs_passed = 0; - - timeout_in_msec = (timeout_sec * 1000) + (timeout_usec ? (timeout_usec / 1000) : 0); - - if (timeout_in_msec != 100) - DEBUGA_GSMOPEN("TIMEOUT=%d\n", GSMOPEN_P_LOG, timeout_in_msec); - - if (!running || !tech_pvt || !tech_pvt->running) { - return -1; - } - - tmp_answer_ptr = tmp_answer; - memset(tmp_answer, 0, sizeof(char) * AT_BUFSIZ); - memset(tmp_answer2, 0, sizeof(char) * AT_BUFSIZ); - memset(tmp_answer3, 0, sizeof(char) * AT_BUFSIZ); - - timeout.tv_sec = timeout_sec; - timeout.tv_usec = timeout_usec; - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - - while ((!tech_pvt->controldev_dead) && msecs_passed <= timeout_in_msec) { - char *token_ptr; - timeout.tv_sec = timeout_sec; //reset the timeout, linux modify it - timeout.tv_usec = timeout_usec; //reset the timeout, linux modify it - - read: - switch_sleep(20000); - msecs_passed += 20; - - if (timeout_in_msec != 100) { - //ERRORA("TIMEOUT=%d, PASSED=%d\n", GSMOPEN_P_LOG, timeout_in_msec, msecs_passed); - } - read_count = tech_pvt->serialPort_serial_control->Read(tmp_answer_ptr, AT_BUFSIZ - (tmp_answer_ptr - tmp_answer)); - memset(tmp_answer3, 0, sizeof(char) * AT_BUFSIZ); - strcpy(tmp_answer3, tmp_answer_ptr); - - if (read_count == 0) { - if (msecs_passed <= timeout_in_msec) { - goto read; - } - } - if (read_count == -1) { - ERRORA - ("read -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - return -1; - } - - tmp_answer_ptr = tmp_answer_ptr + read_count; - - la_counter = 0; - memset(tmp_answer2, 0, sizeof(char) * AT_BUFSIZ); - strcpy(tmp_answer2, tmp_answer); - if ((token_ptr = strtok(tmp_answer2, "\n\r"))) { - last_line_ptr = token_ptr; - strncpy(tech_pvt->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH); - if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) { - WARNINGA - ("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n", - GSMOPEN_P_LOG, token_ptr, tech_pvt->line_array.result[la_counter]); - } - la_counter++; - - while ((token_ptr = strtok(NULL, "\n\r"))) { - last_line_ptr = token_ptr; - strncpy(tech_pvt->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH); - if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) { - WARNINGA - ("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n", - GSMOPEN_P_LOG, token_ptr, tech_pvt->line_array.result[la_counter]); - } - la_counter++; - - if (la_counter == AT_MESG_MAX_LINES) { - ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG, - AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg); - WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3); - at_ack = AT_ERROR; - break; - } - - } - } else { - last_line_ptr = tmp_answer; - } - - if (expected_string && !expect_crlf) { - DEBUGA_GSMOPEN - ("last_line_ptr=|%s|, expected_string=|%s|, expect_crlf=%d, memcmp(last_line_ptr, expected_string, strlen(expected_string)) = %d\n", - GSMOPEN_P_LOG, last_line_ptr, expected_string, expect_crlf, memcmp(last_line_ptr, expected_string, strlen(expected_string))); - } - - if (expected_string && !expect_crlf && !memcmp(last_line_ptr, expected_string, strlen(expected_string)) - ) { - strncpy(tech_pvt->line_array.result[la_counter], last_line_ptr, AT_MESG_MAX_LENGTH); - // match expected string -> accept it withtout CRLF - la_counter++; - if (la_counter == AT_MESG_MAX_LINES) { - ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG, - AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg); - WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3); - at_ack = AT_ERROR; - break; - } - } - /* if the last line read was not a complete line, we'll read the rest in the future */ - else if (tmp_answer[strlen(tmp_answer) - 1] != '\r' && tmp_answer[strlen(tmp_answer) - 1] != '\n') - la_counter--; - - /* let's list the complete lines read so far, without re-listing the lines that have already been listed */ - for (i = la_read; i < la_counter; i++) { - DEBUGA_GSMOPEN("Read line %d: |%s| la_counter=%d\n", GSMOPEN_P_LOG, i, tech_pvt->line_array.result[i], la_counter); - } - - if (la_counter == AT_MESG_MAX_LINES) { - ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG, - AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg); - WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3); - at_ack = AT_ERROR; - break; - } - - - /* let's interpret the complete lines read so far (WITHOUT looking for OK, ERROR, and EXPECTED_STRING), without re-interpreting the lines that has been yet interpreted, so we're sure we don't miss anything */ - for (i = la_read; i < la_counter; i++) { - - if ((strcmp(tech_pvt->line_array.result[i], "RING") == 0)) { - /* with first RING we wait for callid */ - gettimeofday(&(tech_pvt->ringtime), NULL); - /* give CALLID (+CLIP) a chance, wait for the next RING before answering */ - if (tech_pvt->phone_callflow == CALLFLOW_INCOMING_RING) { - /* we're at the second ring, set the interface state, will be answered by gsmopen_do_monitor */ - DEBUGA_GSMOPEN("|%s| got second RING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->interface_state = GSMOPEN_STATE_RING; - } else { - /* we're at the first ring, so there is no CALLID yet thus clean the previous one - just in case we don't receive the caller identification in this new call */ - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - /* only send AT+CLCC? if the device previously reported its support */ - if (tech_pvt->at_has_clcc != 0) { - /* we're at the first ring, try to get CALLID (with +CLCC) */ - DEBUGA_GSMOPEN("|%s| got first RING, sending AT+CLCC?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - int res = gsmopen_serial_write_AT_noack(tech_pvt, "AT+CLCC?"); - if (res) { - ERRORA("AT+CLCC? (call list) was not correctly sent to the phone\n", GSMOPEN_P_LOG); - } - } else { - DEBUGA_GSMOPEN("|%s| got first RING, but not sending AT+CLCC? as this device " - "seems not to support\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - } - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CLCC", 5) == 0)) { - int commacount = 0; - int a = 0; - int b = 0; - int c = 0; - /* with clcc we wait for clip */ - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - - for (a = 0; a < (int) strlen(tech_pvt->line_array.result[i]); a++) { - - if (tech_pvt->line_array.result[i][a] == ',') { - commacount++; - } - if (commacount == 5) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_number[b] = tech_pvt->line_array.result[i][a]; - b++; - } - } - if (commacount == 7) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_name[c] = tech_pvt->line_array.result[i][a]; - c++; - } - } - } - - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - DEBUGA_GSMOPEN("|%s| CLCC CALLID: name is %s, number is %s\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], - tech_pvt->callid_name[0] ? tech_pvt->callid_name : "not available", - tech_pvt->callid_number[0] ? tech_pvt->callid_number : "not available"); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CLIP", 5) == 0)) { - int commacount = 0; - int a = 0; - int b = 0; - int c = 0; - /* with CLIP, we want to answer right away */ - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - - for (a = 7; a < (int) strlen(tech_pvt->line_array.result[i]); a++) { - if (tech_pvt->line_array.result[i][a] == ',') { - commacount++; - } - if (commacount == 0) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_number[b] = tech_pvt->line_array.result[i][a]; - b++; - } - } - if (commacount == 4) { - if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') { - tech_pvt->callid_name[c] = tech_pvt->line_array.result[i][a]; - c++; - } - } - } - - if (tech_pvt->interface_state != GSMOPEN_STATE_RING) { - gettimeofday(&(tech_pvt->call_incoming_time), NULL); - DEBUGA_GSMOPEN("GSMOPEN_STATE_RING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec); - - } - - tech_pvt->interface_state = GSMOPEN_STATE_RING; - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - DEBUGA_GSMOPEN("|%s| CLIP INCOMING CALLID: name is %s, number is %s\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], - (strlen(tech_pvt->callid_name) && tech_pvt->callid_name[0] != 1) ? tech_pvt->callid_name : "not available", - strlen(tech_pvt->callid_number) ? tech_pvt->callid_number : "not available"); - - if (!strlen(tech_pvt->callid_number)) { - strcpy(tech_pvt->callid_number, "not available"); - } - - if (!strlen(tech_pvt->callid_name) && tech_pvt->callid_name[0] != 1) { - strncpy(tech_pvt->callid_name, tech_pvt->callid_number, sizeof(tech_pvt->callid_name)); - snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name), "GSMopen: %s", tech_pvt->callid_number); - } - - DEBUGA_GSMOPEN("|%s| CLIP INCOMING CALLID: NOW name is %s, number is %s\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], tech_pvt->callid_name, tech_pvt->callid_number); - } - - if ((strcmp(tech_pvt->line_array.result[i], "+CMS ERROR: 500") == 0)) { - ERRORA("Received: \"%s\", generic error, maybe this account ran OUT OF CREDIT?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMS ERROR:", 11) == 0)) { - ERRORA("Received: \"%s\", what was this error about?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - if ((strcmp(tech_pvt->line_array.result[i], "BUSY") == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_LINEBUSY; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_LINEBUSY\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->phone_callflow != CALLFLOW_CALL_DOWN) { - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - - } else { - ERRORA("Why BUSY now?\n", GSMOPEN_P_LOG); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "NO ANSWER") == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_NOANSWER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOANSWER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NO_ANSWER; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } else { - ERRORA("Why NO ANSWER now?\n", GSMOPEN_P_LOG); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "NO CARRIER") == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - } else { - ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CBC:", 5) == 0)) { - int power_supply, battery_strenght, err; - - power_supply = battery_strenght = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &power_supply, &battery_strenght); - if (err < 2) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+CBC: xx,yy| now trying |+CBC:xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][5], "%d,%d", &power_supply, &battery_strenght); - DEBUGA_GSMOPEN("|%s| +CBC: Powered by %s, battery strenght=%d\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], power_supply ? "power supply" : "battery", battery_strenght); - - } - - if (err < 2) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+CBC:xx,yy| giving up\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - else { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CBC: Powered by %s, battery strenght=%d\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i], power_supply ? "power supply" : "battery", battery_strenght); - if (!power_supply) { - if (battery_strenght < 10) { - ERRORA("|%s| BATTERY ALMOST EXHAUSTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if (battery_strenght < 20) { - WARNINGA("|%s| BATTERY LOW\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - } - - } - } - - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CSQ:", 5) == 0)) { - int signal_quality, ber, err; - - signal_quality = ber = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &signal_quality, &ber); - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CSQ: Signal Quality: %d, Error Rate=%d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], signal_quality, ber); - if (err < 2) { - ERRORA("|%s| is not formatted as: |+CSQ: xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - if (signal_quality < 9 || signal_quality == 99) { - ERRORA - ("|%s| CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or use additional antenna\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->got_signal = 0; - alarm_event(tech_pvt, ALARM_NETWORK_NO_SIGNAL, "CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or use additional antenna"); - } else if (signal_quality < 11) { - WARNINGA("|%s| CELLPHONE GETS SIGNAL LOW\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->got_signal = 1; - alarm_event(tech_pvt, ALARM_NETWORK_LOW_SIGNAL, "CELLPHONE GETS SIGNAL LOW"); - } else { - tech_pvt->got_signal = 2; - } - - if (signal_quality == 99) { - tech_pvt->signal_strength = 0; - } else { - tech_pvt->signal_strength = (signal_quality * 2) - 113; /* RSSI [dBm] = reported_value * 2 - 113dB */ - } - - } - - } - if ((strncmp(tech_pvt->line_array.result[i], "+CREG:", 6) == 0)) { - int n, stat, err; - - n = stat = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &n, &stat); - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CREG: Display: %d, Registration=%d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], n, stat); - if (err < 2) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+CREG: xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - if (stat == 0) { - ERRORA - ("|%s| CELLPHONE is not registered to network, consider to move it or use additional antenna\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->not_registered = 1; - tech_pvt->home_network_registered = 0; - tech_pvt->roaming_registered = 0; - alarm_event(tech_pvt, ALARM_NO_NETWORK_REGISTRATION, - "CELLPHONE is not registered to network, consider to move it or use additional antenna"); - } else if (stat == 1) { - DEBUGA_GSMOPEN("|%s| CELLPHONE is registered to the HOME network\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->not_registered = 0; - tech_pvt->home_network_registered = 1; - tech_pvt->roaming_registered = 0; - } else { - ERRORA("|%s| CELLPHONE is registered to a ROAMING network\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - tech_pvt->not_registered = 0; - tech_pvt->home_network_registered = 0; - tech_pvt->roaming_registered = 1; - alarm_event(tech_pvt, ALARM_ROAMING_NETWORK_REGISTRATION, "CELLPHONE is registered to a ROAMING network"); - } - } - - } - - if ((strncmp(tech_pvt->line_array.result[i], "+COPS:", 6) == 0)) { - int mode, format, rat, err; - char oper[128] = ""; - mode = format = rat = err = 0; - - err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d,%*[\"]%[^\"]%*[\"],%d", &mode, &format, &oper, &rat); - if (err < 3) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+COPS: xx,yy,ssss,nn|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if (option_debug > 1) { - DEBUGA_GSMOPEN("|%s| +COPS: : Mode %d, Format %d, Operator %s, Rat %d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], mode, format, oper, rat); - } - - /* if we are requesting the operator name, copy it over */ - if (tech_pvt->requesting_operator_name) - strncpy(tech_pvt->operator_name, oper, sizeof(tech_pvt->operator_name)); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CNUM:", 6) == 0) || (strncmp(tech_pvt->line_array.result[i], "ERROR+CNUM:", 11) == 0)) { - int skip_chars, err, type; - char number[128] = ""; - char *in_ptr, *out_ptr; - - skip_chars = err = type = 0; - in_ptr = out_ptr = number; - - /* +CNUM or ERROR+CNUM ? */ - if ((strncmp(tech_pvt->line_array.result[i], "+CNUM:", 6) == 0)) - skip_chars = 7; - else - skip_chars = 12; - - err = sscanf(&tech_pvt->line_array.result[i][skip_chars], "%*[^,],%[^,],%d", &number, &type); - - /* Remove any double quotes */ - while (*in_ptr) { - if (*in_ptr != '\"') *out_ptr++ = *in_ptr; - in_ptr++; - } - *out_ptr = '\0'; - - if (err < 2) { - DEBUGA_GSMOPEN("|%s| is not formatted as: |+CNUM: \"Name\", \"+39025458068\", 145|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if (option_debug) { - DEBUGA_GSMOPEN("|%s| +CNUM: Subscriber number = %s, Type = %d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], number, type); - } - - /* Copy only the first number listed if there are more then one */ - if (tech_pvt->requesting_subscriber_number && !strlen(tech_pvt->subscriber_number)) - strncpy(tech_pvt->subscriber_number, number, sizeof(tech_pvt->subscriber_number)); - - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CMGW:", 6) == 0)) { - int err; - - err = sscanf(&tech_pvt->line_array.result[i][7], "%s", tech_pvt->at_cmgw); - DEBUGA_GSMOPEN("|%s| +CMGW: %s\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], tech_pvt->at_cmgw); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+CMGW: xxxx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - } - - if ((strncmp(tech_pvt->line_array.result[i], "^CEND:1", 7) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - DEBUGA_GSMOPEN("just received a remote HANGUP\n", GSMOPEN_P_LOG); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - DEBUGA_GSMOPEN("just sent GSMOPEN_CONTROL_HANGUP\n", GSMOPEN_P_LOG); - } - } else { - ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG); - } - } - - /* at_call_* are unsolicited messages sent by the modem to signal us about call processing activity and events */ - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_idle) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - DEBUGA_GSMOPEN("just received a remote HANGUP\n", GSMOPEN_P_LOG); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - DEBUGA_GSMOPEN("just sent GSMOPEN_CONTROL_HANGUP\n", GSMOPEN_P_LOG); - } - - tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_rwunlock(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NONE); - } - } else { - ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG); - } - - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_incoming) == 0)) { - - - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_INCOMING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - if (tech_pvt->phone_callflow != CALLFLOW_CALL_INCOMING && tech_pvt->phone_callflow != CALLFLOW_INCOMING_RING) { - //mark the time of CALLFLOW_CALL_INCOMING - gettimeofday(&(tech_pvt->call_incoming_time), NULL); - tech_pvt->phone_callflow = CALLFLOW_CALL_INCOMING; - DEBUGA_GSMOPEN("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec); - - } - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_active) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_ACTIVE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - if (tech_pvt->interface_state == CALLFLOW_CALL_DIALING || tech_pvt->interface_state == CALLFLOW_STATUS_EARLYMEDIA) { - DEBUGA_PBX("just received a remote ANSWER\n", GSMOPEN_P_LOG); - if (tech_pvt->phone_callflow == GSMOPEN_STATE_UP) { - DEBUGA_PBX("just sent GSMOPEN_CONTROL_RINGING\n", GSMOPEN_P_LOG); - DEBUGA_PBX("going to send GSMOPEN_CONTROL_ANSWER\n", GSMOPEN_P_LOG); - tech_pvt->interface_state = CALLFLOW_CALL_REMOTEANSWER; - DEBUGA_PBX("just sent GSMOPEN_CONTROL_ANSWER\n", GSMOPEN_P_LOG); - } - } else { - tech_pvt->interface_state = GSMOPEN_STATE_UP; - DEBUGA_PBX("just interface_state UP\n", GSMOPEN_P_LOG); - } - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_calling) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_DIALING; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_DIALING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_failed) == 0)) { - tech_pvt->phone_callflow = CALLFLOW_CALL_FAILED; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_FAILED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CSCA:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CSCA: Message Center Address!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CMGF:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| +CMGF: Message Format!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CMTI:", 6) == 0)) { //TODO SMS FIXME in config! - int err; - int pos; - - //FIXME all the following commands in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMTI: Incoming SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][12], "%d", &pos); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+CMTI: \"MT\",xx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - DEBUGA_GSMOPEN("|%s| +CMTI: Incoming SMS in position: %d!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], pos); - tech_pvt->unread_sms_msg_id = pos; - gsmopen_sleep(1000); - - char at_command[256]; - - if (tech_pvt->no_ucs2 == 0) { - int res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\""); - if (res) { - ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) didn't get OK from the phone, continuing\n", GSMOPEN_P_LOG); - //memset(tech_pvt->sms_message, 0, sizeof(tech_pvt->sms_message)); - } - } - - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGR=%d", tech_pvt->unread_sms_msg_id); - memset(tech_pvt->sms_message, 0, sizeof(tech_pvt->sms_message)); - - tech_pvt->reading_sms_msg = 1; - int res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - tech_pvt->reading_sms_msg = 0; - if (res) { - ERRORA("AT+CMGR (read SMS) didn't get OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGD=%d", tech_pvt->unread_sms_msg_id); /* delete the message */ - tech_pvt->unread_sms_msg_id = 0; - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res) { - ERRORA("AT+CMGD (Delete SMS) didn't get OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - - res = sms_incoming(tech_pvt); - - if (tech_pvt->phone_callflow == CALLFLOW_CALL_IDLE && tech_pvt->interface_state == GSMOPEN_STATE_DOWN && tech_pvt->owner == NULL) { - /* we're not in a call, neither calling */ - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"EEE\""); - if (res) { - DEBUGA_GSMOPEN("AT+CKPD=\"EEE\" (cellphone screen back to user) didn't get OK from the phone\n", GSMOPEN_P_LOG); - } - } - - } //CMTI well formatted - - } //CMTI - - if ((strncmp(tech_pvt->line_array.result[i], "+MMGL:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config! - int err = 0; - - if (option_debug) - DEBUGA_GSMOPEN("|%s| +MMGL: Listing Motorola SMSs!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][7], "%d", &tech_pvt->unread_sms_msg_id); - if (err < 1) { - ERRORA("|%s| is not formatted as: |+MMGL: xx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - } - if ((strncmp(tech_pvt->line_array.result[i], "+CMGL:", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGL: Listing SMSs!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - if ((strncmp(tech_pvt->line_array.result[i], "+MMGR:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +MMGR: Reading Motorola SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->reading_sms_msg) - tech_pvt->reading_sms_msg++; - } - if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"STO U", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading stored UNSENT SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"STO S", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading stored SENT SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"REC R", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading received READ SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"REC U", 13) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading received UNREAD SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->reading_sms_msg) - tech_pvt->reading_sms_msg++; - } else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: ", 6) == 0)) { //TODO SMS FIXME in config! - if (option_debug) - DEBUGA_GSMOPEN("|%s| +CMGR: Reading SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->reading_sms_msg) - tech_pvt->reading_sms_msg++; - } - - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 17") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_INFLUX; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_INFLUX\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 68") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_NOSERVICE; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOSERVICE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 70") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_OUTGOINGRESTRICTED; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_OUTGOINGRESTRICTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 72") == 0)) { /* motorola call processing unsolicited messages */ - tech_pvt->phone_callflow = CALLFLOW_CALL_SECURITYFAIL; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_SECURITYFAIL\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "+CPBR", 5) == 0)) { /* phonebook stuff begins */ - - if (tech_pvt->phonebook_querying) { /* probably phonebook struct begins */ - int err, first_entry, last_entry, number_lenght, text_lenght; - - if (option_debug) - DEBUGA_GSMOPEN("phonebook struct: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = sscanf(&tech_pvt->line_array.result[i][8], "%d-%d),%d,%d", &first_entry, &last_entry, &number_lenght, &text_lenght); - if (err < 4) { - - err = sscanf(&tech_pvt->line_array.result[i][7], "%d-%d,%d,%d", &first_entry, &last_entry, &number_lenght, &text_lenght); - } - - if (err < 4) { - ERRORA - ("phonebook struct: |%s| is nor formatted as: |+CPBR: (1-750),40,14| neither as: |+CPBR: 1-750,40,14|\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } else { - - if (option_debug) - DEBUGA_GSMOPEN - ("First entry: %d, last entry: %d, phone number max lenght: %d, text max lenght: %d\n", - GSMOPEN_P_LOG, first_entry, last_entry, number_lenght, text_lenght); - tech_pvt->phonebook_first_entry = first_entry; - tech_pvt->phonebook_last_entry = last_entry; - tech_pvt->phonebook_number_lenght = number_lenght; - tech_pvt->phonebook_text_lenght = text_lenght; - } - - } else { /* probably phonebook entry begins */ - - if (tech_pvt->phonebook_listing) { - int err, entry_id, entry_type; - - char entry_number[256]; - char entry_text[256]; - - if (option_debug) - DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = - sscanf(&tech_pvt->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", &entry_id, entry_number, &entry_type, - entry_text); - if (err < 4) { - ERRORA - ("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n", - GSMOPEN_P_LOG, err, tech_pvt->line_array.result[i]); - } else { - //TODO: sanitize entry_text - if (option_debug) - DEBUGA_GSMOPEN("Number: %s, Text: %s, Type: %d\n", GSMOPEN_P_LOG, entry_number, entry_text, entry_type); - /* write entry in phonebook file */ - if (tech_pvt->phonebook_writing_fp) { - gsmopen_dir_entry_extension++; - - fprintf(tech_pvt->phonebook_writing_fp, - "%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n", - entry_number, entry_text, "no", - tech_pvt->gsmopen_dir_entry_extension_prefix, "2", gsmopen_dir_entry_extension, "yes", "not_specified"); - fprintf(tech_pvt->phonebook_writing_fp, - "%s => ,%sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n", - entry_number, entry_text, "no", - tech_pvt->gsmopen_dir_entry_extension_prefix, "3", gsmopen_dir_entry_extension, "yes", "not_specified"); - } - } - - } - - if (tech_pvt->phonebook_listing_received_calls) { - int err, entry_id, entry_type; - - char entry_number[256] = ""; - char entry_text[256] = ""; - - if (option_debug) - DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - err = - sscanf(&tech_pvt->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", &entry_id, entry_number, &entry_type, - entry_text); - if (err < 1) { //we match only on the progressive id, maybe the remote party has not sent its number, and/or there is no corresponding text entry in the phone directory - ERRORA - ("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n", - GSMOPEN_P_LOG, err, tech_pvt->line_array.result[i]); - } else { - //TODO: sanitize entry_text - - if (option_debug) - DEBUGA_GSMOPEN("Number: %s, Text: %s, Type: %d\n", GSMOPEN_P_LOG, entry_number, entry_text, entry_type); - memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name)); - memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number)); - strncpy(tech_pvt->callid_name, entry_text, sizeof(tech_pvt->callid_name)); - strncpy(tech_pvt->callid_number, entry_number, sizeof(tech_pvt->callid_number)); - if (option_debug) - DEBUGA_GSMOPEN("incoming callid: Text: %s, Number: %s\n", GSMOPEN_P_LOG, tech_pvt->callid_name, tech_pvt->callid_number); - - DEBUGA_GSMOPEN("|%s| CPBR INCOMING CALLID: name is %s, number is %s\n", - GSMOPEN_P_LOG, tech_pvt->line_array.result[i], - tech_pvt->callid_name[0] != 1 ? tech_pvt->callid_name : "not available", - tech_pvt->callid_number[0] ? tech_pvt->callid_number : "not available"); - - /* mark the time of RING */ - gettimeofday(&(tech_pvt->ringtime), NULL); - tech_pvt->interface_state = GSMOPEN_STATE_RING; - tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING; - - } - - } - - else { - DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - - } - } - - } - if ((strncmp(tech_pvt->line_array.result[i], "+CUSD:", 6) == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| USSD received\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - int res = 0, status = 0; - unsigned int dcs = 0; - char ussd_msg[1024]; - memset(tech_pvt->ussd_message, '\0', sizeof(tech_pvt->ussd_message)); - memset(tech_pvt->ussd_dcs, '\0', sizeof(tech_pvt->ussd_dcs)); - res = sscanf(&tech_pvt->line_array.result[i][6], "%d,\"%1023[0-9A-F]\",%d", &status, ussd_msg, &dcs); - if (res == 1) { - NOTICA("received +CUSD with status %d\n", GSMOPEN_P_LOG, status); - tech_pvt->ussd_received = 1; - tech_pvt->ussd_status = status; - } else if (res == 3) { - tech_pvt->ussd_received = 1; - tech_pvt->ussd_status = status; - - //identifying dcs alphabet according to GSM 03.38 Cell Broadcast Data Coding Scheme - //CBDataCodingScheme should be used here, but it appears to be buggy (ucs2 messages are not recognized) - int alphabet = DCS_RESERVED_ALPHABET; - if (dcs == 0x11) { - alphabet = DCS_SIXTEEN_BIT_ALPHABET; - } else if ((dcs & 0xF0) <= 0x30){ - alphabet = DCS_DEFAULT_ALPHABET; - } else if ((dcs & 0xC0) == 0x40 || (dcs & 0xF0) == 0x90) { - alphabet = dcs & (3 << 2); - }; - - if ( (tech_pvt->ussd_response_encoding == USSD_ENCODING_AUTO && alphabet == DCS_DEFAULT_ALPHABET) - || tech_pvt->ussd_response_encoding == USSD_ENCODING_HEX_7BIT ) { - SMSDecoder d(ussd_msg); - d.markSeptet(); - string ussd_dec = gsmToLatin1(d.getString(strlen(ussd_msg) / 2 * 8 / 7)); - iso_8859_1_to_utf8(tech_pvt, (char *) ussd_dec.c_str(), tech_pvt->ussd_message, sizeof(tech_pvt->ussd_message)); - strcpy(tech_pvt->ussd_dcs, "default alphabet"); - } else if ( (tech_pvt->ussd_response_encoding == USSD_ENCODING_AUTO && alphabet == DCS_SIXTEEN_BIT_ALPHABET) - || tech_pvt->ussd_response_encoding == USSD_ENCODING_UCS2 ) { - ucs2_to_utf8(tech_pvt, ussd_msg, tech_pvt->ussd_message, sizeof(tech_pvt->ussd_message)); - strcpy(tech_pvt->ussd_dcs, "16-bit alphabet"); - } else if ( (tech_pvt->ussd_response_encoding == USSD_ENCODING_AUTO && alphabet == DCS_EIGHT_BIT_ALPHABET) - || tech_pvt->ussd_response_encoding == USSD_ENCODING_HEX_8BIT ) { - char ussd_dec[1024]; - memset(ussd_dec, '\0', sizeof(ussd_dec)); - hexToBuf(ussd_msg, (unsigned char*)ussd_dec); - iso_8859_1_to_utf8(tech_pvt, (char *) ussd_dec, tech_pvt->ussd_message, sizeof(tech_pvt->ussd_message)); - strcpy(tech_pvt->ussd_dcs, "8-bit alphabet"); - } else if ( tech_pvt->ussd_response_encoding == USSD_ENCODING_PLAIN ) { - string ussd_dec = gsmToLatin1(ussd_msg); - iso_8859_1_to_utf8(tech_pvt, (char *) ussd_dec.c_str(), tech_pvt->ussd_message, sizeof(tech_pvt->ussd_message)); - strcpy(tech_pvt->ussd_dcs, "default alphabet"); - } else { - ERRORA("USSD data coding scheme not supported=%d\n", GSMOPEN_P_LOG, dcs); - } - - NOTICA("USSD received: status=%d, message='%s', dcs='%d'\n", - GSMOPEN_P_LOG, tech_pvt->ussd_status, tech_pvt->ussd_message, dcs); - - ussd_incoming(tech_pvt); - } else { - ERRORA ("res=%d, +CUSD command has wrong format: %s\n", - GSMOPEN_P_LOG, res, tech_pvt->line_array.result[i]); - } - } - - if ((strncmp(tech_pvt->line_array.result[i], "*ECAV", 5) == 0) || (strncmp(tech_pvt->line_array.result[i], "*ECAM", 5) == 0)) { /* sony-ericsson call processing unsolicited messages */ - int res, ccid, ccstatus, calltype, processid, exitcause, number, type; - res = ccid = ccstatus = calltype = processid = exitcause = number = type = 0; - res = - sscanf(&tech_pvt->line_array.result[i][6], "%d,%d,%d,%d,%d,%d,%d", &ccid, &ccstatus, &calltype, &processid, &exitcause, &number, - &type); - /* only changes the phone_callflow if enought parameters were parsed */ - if (res >= 3) { - switch (ccstatus) { - case 0: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_DOWN); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 1: - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: CALLING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 2: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_DIALING); - } - tech_pvt->interface_state = CALLFLOW_CALL_DIALING; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: CONNECTING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 3: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_UP); - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - tech_pvt->interface_state = GSMOPEN_STATE_UP; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: ACTIVE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 4: - if (option_debug > 1) - DEBUGA_GSMOPEN - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle HOLD event\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - case 5: - if (option_debug > 1) - DEBUGA_GSMOPEN - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle WAITING event\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i]); - break; - case 6: - if (option_debug > 1) - DEBUGA_GSMOPEN - ("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle ALERTING event\n", GSMOPEN_P_LOG, - tech_pvt->line_array.result[i]); - break; - case 7: - if (tech_pvt->owner) { - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_BUSY); - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_BUSY); - } - tech_pvt->phone_callflow = CALLFLOW_CALL_LINEBUSY; - tech_pvt->interface_state = GSMOPEN_STATE_BUSY; - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: BUSY\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - break; - } - } else { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: could not parse parameters\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - } - - /* at_indicator_* are unsolicited messages sent by the phone to signal us that some of its visual indicators on its screen has changed, based on CIND CMER ETSI docs */ - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_noservice_string) == 0)) { - ERRORA("|%s| at_indicator_noservice_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - alarm_event(tech_pvt, ALARM_NETWORK_NO_SERVICE, "at_indicator_noservice_string"); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nosignal_string) == 0)) { - ERRORA("|%s| at_indicator_nosignal_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - alarm_event(tech_pvt, ALARM_NETWORK_NO_SIGNAL, "at_indicator_nosignal_string"); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_lowsignal_string) == 0)) { - WARNINGA("|%s| at_indicator_lowsignal_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - alarm_event(tech_pvt, ALARM_NETWORK_LOW_SIGNAL, "at_indicator_lowsignal_string"); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_lowbattchg_string) == 0)) { - WARNINGA("|%s| at_indicator_lowbattchg_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nobattchg_string) == 0)) { - ERRORA("|%s| at_indicator_nobattchg_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callactive_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callactive_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nocallactive_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_nocallactive_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nocallsetup_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_nocallsetup_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupincoming_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callsetupincoming_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupoutgoing_string) == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callsetupoutgoing_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupremoteringing_string) - == 0)) { - DEBUGA_GSMOPEN("|%s| at_indicator_callsetupremoteringing_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - } - - } - - /* let's look for OK, ERROR and EXPECTED_STRING in the complete lines read so far, without re-looking at the lines that has been yet looked at */ - for (i = la_read; i < la_counter; i++) { - if (expected_string) { - if ((strncmp(tech_pvt->line_array.result[i], expected_string, strlen(expected_string)) - == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("|%s| got what EXPECTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - at_ack = AT_OK; - } - } else { - if ((strcmp(tech_pvt->line_array.result[i], "OK") == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("got OK\n", GSMOPEN_P_LOG); - at_ack = AT_OK; - } - } - if ((strcmp(tech_pvt->line_array.result[i], "ERROR") == 0)) { - if (option_debug > 1) - DEBUGA_GSMOPEN("got ERROR\n", GSMOPEN_P_LOG); - at_ack = AT_ERROR; - } - - /* if we are requesting IMEI, put the line into the imei buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->requesting_imei && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMEI */ - strncpy(tech_pvt->imei, tech_pvt->line_array.result[i], sizeof(tech_pvt->imei)); - } - } - - /* if we are requesting IMSI, put the line into the imsi buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->requesting_imsi && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMSI */ - strncpy(tech_pvt->imsi, tech_pvt->line_array.result[i], sizeof(tech_pvt->imsi)); - } - } - - /* if we are requesting device manufacturer, model or firmware version, - * put the line into the buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->requesting_device_mfg && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { - strncpy(tech_pvt->device_mfg, tech_pvt->line_array.result[i], sizeof(tech_pvt->device_mfg)); - } - } - - if (tech_pvt->requesting_device_model && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { - strncpy(tech_pvt->device_model, tech_pvt->line_array.result[i], sizeof(tech_pvt->device_model)); - } - } - - if (tech_pvt->requesting_device_firmware && at_ack == -1) { - if (strlen(tech_pvt->line_array.result[i])) { - strncpy(tech_pvt->device_firmware, tech_pvt->line_array.result[i], sizeof(tech_pvt->device_firmware)); - } - } - - - /* if we are reading an sms message from memory, put the line into the sms buffer if the line is not "OK" or "ERROR" */ - if (tech_pvt->reading_sms_msg > 1 && at_ack == -1) { - int c; - char sms_body[16000]; - int err = 0; - memset(sms_body, '\0', sizeof(sms_body)); - - if (strncmp(tech_pvt->line_array.result[i], "+CMGR", 5) == 0) { /* we are reading the "header" of an SMS */ - char content[512]; - char content2[512]; - int inside_comma = 0; - int inside_quote = 0; - int which_field = 0; - int d = 0; - - DEBUGA_GSMOPEN("HERE\n", GSMOPEN_P_LOG); - - memset(content, '\0', sizeof(content)); - - for (c = 0; c < (int) strlen(tech_pvt->line_array.result[i]); c++) { - if (tech_pvt->line_array.result[i][c] == ',' && tech_pvt->line_array.result[i][c - 1] != '\\' && inside_quote == 0) { - if (inside_comma) { - inside_comma = 0; - DEBUGA_GSMOPEN("inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - } else { - inside_comma = 1; - DEBUGA_GSMOPEN("inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - } - } - if (tech_pvt->line_array.result[i][c] == '"' && tech_pvt->line_array.result[i][c - 1] != '\\') { - if (inside_quote) { - inside_quote = 0; - DEBUGA_GSMOPEN("END_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content); - - memset(content2, '\0', sizeof(content2)); - if (which_field == 1) { - err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2)); - } else { - err = 0; - strncpy(content2, content, sizeof(content2)); - } - DEBUGA_GSMOPEN("%d content2=%s\n", GSMOPEN_P_LOG, which_field, content2); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2); - - memset(content, '\0', sizeof(content)); - d = 0; - if (which_field == 1) { - strncpy(tech_pvt->sms_sender, content2, sizeof(tech_pvt->sms_sender)); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2); - - } else if (which_field == 2) { - strncpy(tech_pvt->sms_date, content2, sizeof(tech_pvt->sms_date)); - DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2); - } else if (which_field > 2) { - WARNINGA("WHY which_field is > 2 ? (which_field is %d)\n", GSMOPEN_P_LOG, which_field); - } - which_field++; - } else { - inside_quote = 1; - DEBUGA_GSMOPEN("START_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote, - &tech_pvt->line_array.result[i][c]); - } - } - if (inside_quote && tech_pvt->line_array.result[i][c] != '"') { - - content[d] = tech_pvt->line_array.result[i][c]; - d++; - - } - - } - } //it was the +CMGR answer from the cellphone - else { - DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body); - DEBUGA_GSMOPEN("tech_pvt->line_array.result[i]=%s\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]); - if (tech_pvt->sms_pdu_not_supported) { - char content3[1000]; - strncpy(tech_pvt->sms_message, tech_pvt->line_array.result[i], sizeof(tech_pvt->sms_message)); - - - memset(content3, '\0', sizeof(content3)); - DEBUGA_GSMOPEN("sms_message=%s\n", GSMOPEN_P_LOG, tech_pvt->sms_message); - ucs2_to_utf8(tech_pvt, tech_pvt->sms_message, content3, sizeof(content3)); - DEBUGA_GSMOPEN("content3=%s\n", GSMOPEN_P_LOG, content3); - strncpy(tech_pvt->sms_body, content3, sizeof(tech_pvt->sms_body)); - if (tech_pvt->sms_cnmi_not_supported) { - sms_incoming(tech_pvt); - DEBUGA_GSMOPEN("2 content3=%s\n", GSMOPEN_P_LOG, content3); - } - } else { - - - try { - char content2[1000]; - SMSMessageRef sms; - - DEBUGA_GSMOPEN("about to decode\n", GSMOPEN_P_LOG); - try { - sms = SMSMessage::decode(tech_pvt->line_array.result[i]); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大 - } - catch(...) { - ERRORA("GsmException\n", GSMOPEN_P_LOG); - gsmopen_sleep(5000); - return -1; - } - - DEBUGA_GSMOPEN("after decode\n", GSMOPEN_P_LOG); - -#if 0 - char letsee[1024]; - memset(letsee, '\0', sizeof(letsee)); - - DEBUGA_GSMOPEN("about to letsee\n", GSMOPEN_P_LOG); - try { - sprintf(letsee, "|%s|\n", sms->toString().c_str()); - } - catch(...) { - ERRORA("GsmException\n", GSMOPEN_P_LOG); - sleep(5); - return -1; - } - DEBUGA_GSMOPEN("after letsee\n", GSMOPEN_P_LOG); - - DEBUGA_GSMOPEN("SMS=\n%s\n", GSMOPEN_P_LOG, letsee); -#endif //0 - memset(content2, '\0', sizeof(content2)); - if (sms->dataCodingScheme().getAlphabet() == DCS_DEFAULT_ALPHABET) { - iso_8859_1_to_utf8(tech_pvt, (char *) sms->userData().c_str(), content2, sizeof(content2)); - } else if (sms->dataCodingScheme().getAlphabet() == DCS_SIXTEEN_BIT_ALPHABET) { - ucs2_to_utf8(tech_pvt, (char *) bufToHex((unsigned char *) sms->userData().data(), sms->userData().length()).c_str(), - content2, sizeof(content2)); - } else { - ERRORA("dataCodingScheme not supported=%u\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - - } - DEBUGA_GSMOPEN("dataCodingScheme=%u\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet()); - DEBUGA_GSMOPEN("dataCodingScheme=%s\n", GSMOPEN_P_LOG, sms->dataCodingScheme().toString().c_str()); - DEBUGA_GSMOPEN("address=%s\n", GSMOPEN_P_LOG, sms->address().toString().c_str()); - DEBUGA_GSMOPEN("serviceCentreAddress=%s\n", GSMOPEN_P_LOG, sms->serviceCentreAddress().toString().c_str()); - DEBUGA_GSMOPEN("serviceCentreTimestamp=%s\n", GSMOPEN_P_LOG, sms->serviceCentreTimestamp().toString().c_str()); - DEBUGA_GSMOPEN("UserDataHeader=%s\n", GSMOPEN_P_LOG, (char *)bufToHex((unsigned char *) - ((string) sms->userDataHeader()).data(), sms->userDataHeader().length()).c_str()); - DEBUGA_GSMOPEN("messageType=%d\n", GSMOPEN_P_LOG, sms->messageType()); - DEBUGA_GSMOPEN("userData= |||%s|||\n", GSMOPEN_P_LOG, content2); - - - memset(sms_body, '\0', sizeof(sms_body)); - strncpy(sms_body, content2, sizeof(sms_body)); - DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body); - strncpy(tech_pvt->sms_body, sms_body, sizeof(tech_pvt->sms_body)); - strncpy(tech_pvt->sms_sender, sms->address().toString().c_str(), sizeof(tech_pvt->sms_sender)); - strncpy(tech_pvt->sms_date, sms->serviceCentreTimestamp().toString().c_str(), sizeof(tech_pvt->sms_date)); - strncpy(tech_pvt->sms_userdataheader, (char *) - bufToHex((unsigned char *)((string) sms->userDataHeader()).data(), sms->userDataHeader().length()).c_str(), - sizeof(tech_pvt->sms_userdataheader)); - strncpy(tech_pvt->sms_datacodingscheme, sms->dataCodingScheme().toString().c_str(), sizeof(tech_pvt->sms_datacodingscheme)); - strncpy(tech_pvt->sms_servicecentreaddress, sms->serviceCentreAddress().toString().c_str(), - sizeof(tech_pvt->sms_servicecentreaddress)); - tech_pvt->sms_messagetype = sms->messageType(); - - } - catch(...) { - ERRORA("GsmException\n", GSMOPEN_P_LOG); - gsmopen_sleep(5000); - return -1; - } - - - - - - } - - } //it was the UCS2 from cellphone - - } //we were reading the SMS - - } - - la_read = la_counter; - - if (look_for_ack && at_ack > -1) - break; - - if (la_counter == AT_MESG_MAX_LINES) { - ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG, - AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg); - WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3); - at_ack = AT_ERROR; - break; - } - - } - - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - if (select_err == -1) { - ERRORA("select returned -1 on %s, setting controldev_dead, error was: %s\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name, strerror(errno)); - tech_pvt->controldev_dead = 1; - - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "select returned -1 on interface, setting controldev_dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - if (tech_pvt->owner) - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - switch_sleep(1000000); - return -1; - } - - if (tech_pvt->phone_callflow == CALLFLOW_CALL_INCOMING && tech_pvt->call_incoming_time.tv_sec) { //after three sec of CALLFLOW_CALL_INCOMING, we assume the phone is incapable of notifying RING (eg: motorola c350), so we try to answer - char list_command[64]; - struct timeval call_incoming_timeout; - gettimeofday(&call_incoming_timeout, NULL); - call_incoming_timeout.tv_sec -= 3; - DEBUGA_GSMOPEN - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (call_incoming_timeout.tv_sec > tech_pvt->call_incoming_time.tv_sec) { - - tech_pvt->call_incoming_time.tv_sec = 0; - tech_pvt->call_incoming_time.tv_usec = 0; - DEBUGA_GSMOPEN - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - int res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBS=RC"); - if (res) { - ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG); - } - tech_pvt->phonebook_querying = 1; - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBR=?"); - if (res) { - ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG); - } - tech_pvt->phonebook_querying = 0; - sprintf(list_command, "AT+CPBR=%d,%d", tech_pvt->phonebook_first_entry, tech_pvt->phonebook_last_entry); - tech_pvt->phonebook_listing_received_calls = 1; - res = gsmopen_serial_write_AT_expect_longtime(tech_pvt, list_command, "OK"); - if (res) { - WARNINGA("AT+CPBR=%d,%d failed, continue\n", GSMOPEN_P_LOG, tech_pvt->phonebook_first_entry, tech_pvt->phonebook_last_entry); - } - tech_pvt->phonebook_listing_received_calls = 0; - } - } - - if (tech_pvt->phone_callflow == CALLFLOW_INCOMING_RING) { - struct timeval call_incoming_timeout; - gettimeofday(&call_incoming_timeout, NULL); - call_incoming_timeout.tv_sec -= 10; - // DEBUGA_GSMOPEN ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (call_incoming_timeout.tv_sec > tech_pvt->ringtime.tv_sec) { - ERRORA("Ringing stopped and I have not answered. Why?\n", GSMOPEN_P_LOG); - DEBUGA_GSMOPEN - ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", - GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); - if (tech_pvt->owner) { - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - } - } - } - tech_pvt->line_array.elemcount = la_counter; - //NOTICA (" OUTSIDE this gsmopen_serial_device %s \n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - if (look_for_ack) - return at_ack; - else - return 0; -} - -int gsmopen_serial_write_AT(private_t *tech_pvt, const char *data) -{ - int howmany; - int i; - int res; - int count; - char *Data = (char *) data; - - if (!tech_pvt) - return -1; - - howmany = strlen(Data); - - for (i = 0; i < howmany; i++) { - res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1); - - if (res != 1) { - DEBUGA_GSMOPEN("Error sending (%.1s): %d (%s)\n", GSMOPEN_P_LOG, &Data[i], res, strerror(errno)); - gsmopen_sleep(100000); - for (count = 0; count < 10; count++) { - res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1); - if (res == 1) { - DEBUGA_GSMOPEN("Successfully RE-sent (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno)); - break; - } else - DEBUGA_GSMOPEN("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno)); - gsmopen_sleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno)); - - - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - - - return -1; - } - } - if (option_debug > 1) - DEBUGA_GSMOPEN("sent data... (%.1s)\n", GSMOPEN_P_LOG, &Data[i]); - gsmopen_sleep(1000); /* release the cpu */ - } - - res = tech_pvt->serialPort_serial_control->Write((char *) "\r", 1); - - if (res != 1) { - DEBUGA_GSMOPEN("Error sending (carriage return): %d (%s)\n", GSMOPEN_P_LOG, res, strerror(errno)); - gsmopen_sleep(100000); - for (count = 0; count < 10; count++) { - res = tech_pvt->serialPort_serial_control->Write((char *) "\r", 1); - - if (res == 1) { - DEBUGA_GSMOPEN("Successfully RE-sent carriage return: %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno)); - break; - } else - DEBUGA_GSMOPEN("Error RE-sending (carriage return): %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno)); - gsmopen_sleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (carriage return): %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno)); - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - return -1; - } - } - if (option_debug > 1) - DEBUGA_GSMOPEN("sent (carriage return)\n", GSMOPEN_P_LOG); - gsmopen_sleep(1000); /* release the cpu */ - - return howmany; -} - -int gsmopen_serial_write_AT_nocr(private_t *tech_pvt, const char *data) -{ - int howmany; - int i; - int res; - int count; - char *Data = (char *) data; - - if (!tech_pvt) - return -1; - - howmany = strlen(Data); - - for (i = 0; i < howmany; i++) { - res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1); - - if (res != 1) { - DEBUGA_GSMOPEN("Error sending (%.1s): %d (%s)\n", GSMOPEN_P_LOG, &Data[i], res, strerror(errno)); - gsmopen_sleep(100000); - for (count = 0; count < 10; count++) { - res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1); - if (res == 1) - break; - else - DEBUGA_GSMOPEN("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno)); - gsmopen_sleep(100000); - - } - if (res != 1) { - ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno)); - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - return -1; - } - } - if (option_debug > 1) - DEBUGA_GSMOPEN("sent data... (%.1s)\n", GSMOPEN_P_LOG, &Data[i]); - gsmopen_sleep(1000); /* release the cpu */ - } - - gsmopen_sleep(1000); /* release the cpu */ - - return howmany; -} - -int gsmopen_serial_write_AT_noack(private_t *tech_pvt, const char *data) -{ - - if (option_debug > 1) - DEBUGA_GSMOPEN("gsmopen_serial_write_AT_noack: %s\n", GSMOPEN_P_LOG, data); - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (gsmopen_serial_write_AT(tech_pvt, data) != (int) strlen(data)) { - - ERRORA("Error sending data... (%s)\n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - return -1; - } - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return 0; -} - -int gsmopen_serial_write_AT_ack(private_t *tech_pvt, const char *data) -{ - int at_result = AT_ERROR; - - if (!tech_pvt) - return -1; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("sending: %s\n", GSMOPEN_P_LOG, data); - if (gsmopen_serial_write_AT(tech_pvt, data) != (int) strlen(data)) { - ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, and if it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, powered down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - return -1; - } - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, 0, NULL, 1); // 1/10th sec timeout - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_write_AT_ack_nocr_longtime(private_t *tech_pvt, const char *data) -{ - int at_result = AT_ERROR; - - if (!tech_pvt) - return -1; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("sending: %s\n", GSMOPEN_P_LOG, data); - if (gsmopen_serial_write_AT_nocr(tech_pvt, data) != (int) strlen(data)) { - ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, and if it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, powered down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - return -1; - } - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, 20, NULL, 1); // 20.5 sec timeout - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_write_AT_expect1(private_t *tech_pvt, const char *data, const char *expected_string, int expect_crlf, int seconds) -{ - int at_result = AT_ERROR; - - if (!tech_pvt) - return -1; - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("sending: %s, expecting: %s\n", GSMOPEN_P_LOG, data, expected_string); - if (gsmopen_serial_write_AT(tech_pvt, data) != (int) strlen(data)) { - ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno)); - UNLOCKA(tech_pvt->controldev_lock); - - ERRORA - ("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, and if it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, powered down or battery exhausted\n", - GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->controldev_dead = 1; - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - - UNLOCKA(tech_pvt->controldev_lock); - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; - gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); - } - switch_sleep(1000000); - - - return -1; - } - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, seconds, expected_string, expect_crlf); // minimum half a sec timeout - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_AT_expect(private_t *tech_pvt, const char *expected_string, int expect_crlf, int seconds) -{ - int at_result = AT_ERROR; - - if (!tech_pvt) - return -1; - - - PUSHA_UNLOCKA(tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - if (option_debug > 1) - DEBUGA_GSMOPEN("expecting: %s\n", GSMOPEN_P_LOG, expected_string); - - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, seconds, expected_string, expect_crlf); // minimum 1/10th sec timeout - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(tech_pvt->controldev_lock); - - return at_result; - -} - -int gsmopen_serial_answer(private_t *tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_answer_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_answer_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_answer_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - return -1; -} - -int gsmopen_serial_answer_AT(private_t *tech_pvt) -{ - int res; - - if (!tech_pvt) - return -1; - - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_answer, tech_pvt->at_answer_expect); - if (res) { - DEBUGA_GSMOPEN - ("at_answer command failed, command used: %s, expecting: %s, trying with AT+CKPD=\"S\"\n", - GSMOPEN_P_LOG, tech_pvt->at_answer, tech_pvt->at_answer_expect); - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"S\""); - if (res) { - ERRORA("at_answer command failed, command used: 'AT+CKPD=\"S\"', giving up\n", GSMOPEN_P_LOG); - return -1; - } - } - //res = gsmopen_serial_write_AT_expect(tech_pvt, "AT^DDSETEX=2", tech_pvt->at_dial_expect); - DEBUGA_GSMOPEN("AT: call answered\n", GSMOPEN_P_LOG); - return 0; -} - -int gsmopen_serial_hangup(private_t *tech_pvt) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_hangup_AT(tech_pvt); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_hangup_FBUS2(tech_pvt); -#endif /* GSMOPEN_FBUS2 */ -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_hangup_CVM_BUSMAIL(tech_pvt); -#endif /* GSMOPEN_CVM */ - return -1; -} - -int gsmopen_serial_hangup_AT(private_t *tech_pvt) -{ - int res; - - if (!tech_pvt) - return -1; - - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_hangup, tech_pvt->at_hangup_expect); - if (res) { - DEBUGA_GSMOPEN("at_hangup command failed, command used: %s, trying to use AT+CKPD=\"EEE\"\n", GSMOPEN_P_LOG, tech_pvt->at_hangup); - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"EEE\""); - if (res) { - ERRORA("at_hangup command failed, command used: 'AT+CKPD=\"EEE\"'\n", GSMOPEN_P_LOG); - return -1; - } - - } - - res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CHUP"); - if (res) { - DEBUGA_GSMOPEN("at_hangup command timeout, command used: 'AT+CHUP'\n", GSMOPEN_P_LOG); - } - - } - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - return 0; -} - -int gsmopen_serial_call(private_t *tech_pvt, char *dstr) -{ - if (tech_pvt->controldevprotocol == PROTOCOL_AT) - return gsmopen_serial_call_AT(tech_pvt, dstr); -#ifdef GSMOPEN_FBUS2 - if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2) - return gsmopen_serial_call_FBUS2(tech_pvt, dstr); -#endif /* GSMOPEN_FBUS2 */ - if (tech_pvt->controldevprotocol == PROTOCOL_NO_SERIAL) - return 0; -#ifdef GSMOPEN_CVM - if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL) - return gsmopen_serial_call_CVM_BUSMAIL(tech_pvt, dstr); -#endif /* GSMOPEN_CVM */ - return -1; -} - -int gsmopen_serial_call_AT(private_t *tech_pvt, char *dstr) -{ - int res; - char at_command[256]; - - if (option_debug) - DEBUGA_PBX("Dialing %s\n", GSMOPEN_P_LOG, dstr); - memset(at_command, 0, sizeof(at_command)); - tech_pvt->phone_callflow = CALLFLOW_CALL_DIALING; - tech_pvt->interface_state = GSMOPEN_STATE_DIALING; - sprintf(at_command, "%s%s%s", tech_pvt->at_dial_pre_number, dstr, tech_pvt->at_dial_post_number); - DEBUGA_PBX("Dialstring %s\n", GSMOPEN_P_LOG, at_command); - res = gsmopen_serial_write_AT_expect(tech_pvt, at_command, tech_pvt->at_dial_expect); - if (res) { - ERRORA("dial command failed, dial string was: %s\n", GSMOPEN_P_LOG, at_command); - return -1; - } - //res = gsmopen_serial_write_AT_expect(tech_pvt, "AT^DDSETEX=2", tech_pvt->at_dial_expect); - - return 0; -} - -int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outbytesleft) -{ - char converted[16000]; - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - size_t inbytesleft; - int c; - char stringa[5]; - double hexnum; - int i = 0; - - memset(converted, '\0', sizeof(converted)); - - DEBUGA_GSMOPEN("ucs2_in=|%s|, utf8_out=|%s|\n", GSMOPEN_P_LOG, ucs2_in, utf8_out); - for (c = 0; c < (int) strlen(ucs2_in); c++) { - sprintf(stringa, "0x%c%c", ucs2_in[c], ucs2_in[c + 1]); - c++; - hexnum = strtod(stringa, NULL); - converted[i] = (char) hexnum; - i++; - } - - outbuf = utf8_out; - inbuf = converted; - - iconv_format = iconv_open("UTF8", "UCS-2BE"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - - inbytesleft = i; - DEBUGA_GSMOPEN("1 ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out); - -#ifdef WIN32 - iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#else // WIN32 - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#endif // WIN32 - if (iconv_res == (size_t) -1) { - DEBUGA_GSMOPEN("2 ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out); - DEBUGA_GSMOPEN("3 error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno); - iconv_close(iconv_format); - return -1; - } - DEBUGA_GSMOPEN - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n", - GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out); - iconv_close(iconv_format); - - return 0; -} - -int utf8_to_iso_8859_1(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *iso_8859_1_out, size_t outbytesleft) -{ - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - - outbuf = iso_8859_1_out; - inbuf = utf8_in; - - iconv_format = iconv_open("ISO_8859-1", "UTF8"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - outbytesleft = strlen(utf8_in) * 2; - - DEBUGA_GSMOPEN("in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, iso_8859_1_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, iso_8859_1_out); -#ifdef WIN32 - iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#else // WIN32 - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#endif // WIN32 - if (iconv_res == (size_t) -1) { - DEBUGA_GSMOPEN("cannot translate in iso_8859_1 error: %s (errno: %d)\n", GSMOPEN_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_GSMOPEN - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, iso_8859_1_out=%s\n", - GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, iso_8859_1_out); - iconv_close(iconv_format); - return 0; -} - - -int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, size_t outbytesleft) -{ - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - size_t inbytesleft; - - DEBUGA_GSMOPEN("iso_8859_1_in=%s\n", GSMOPEN_P_LOG, iso_8859_1_in); - - outbuf = utf8_out; - inbuf = iso_8859_1_in; - - iconv_format = iconv_open("UTF8", "ISO_8859-1"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - - inbytesleft = strlen(iso_8859_1_in) * 2; -#ifdef WIN32 - iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#else // WIN32 - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#endif // WIN32 - if (iconv_res == (size_t) -1) { - DEBUGA_GSMOPEN("ciao in=%s, inleft=%d, out=%s, outleft=%d, utf8_out=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_out); - DEBUGA_GSMOPEN("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_GSMOPEN - (" strlen(iso_8859_1_in)=%d, iconv_res=%d, inbuf=%s, inleft=%d, out=%s, outleft=%d, utf8_out=%s\n", - GSMOPEN_P_LOG, (int) strlen(iso_8859_1_in), iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_out); - - iconv_close(iconv_format); - - return 0; -} - -int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *ucs2_out, size_t outbytesleft) -{ - iconv_t iconv_format; - int iconv_res; - char *outbuf; - char *inbuf; - char converted[16000]; - int i; - char stringa[16]; - char stringa2[16]; - - memset(converted, '\0', sizeof(converted)); - - outbuf = converted; - inbuf = utf8_in; - - iconv_format = iconv_open("UCS-2BE", "UTF8"); - if (iconv_format == (iconv_t) -1) { - ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); - return -1; - } - outbytesleft = 16000; - - DEBUGA_GSMOPEN("in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, converted=%s\n", - GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, converted); -#ifdef WIN32 - iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#else // WIN32 - iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#endif // WIN32 - if (iconv_res == (size_t) -1) { - ERRORA("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno); - return -1; - } - DEBUGA_GSMOPEN - ("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, converted=%s\n", - GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, converted); - iconv_close(iconv_format); - - for (i = 0; i < 16000 - (int) outbytesleft; i++) { - memset(stringa, '\0', sizeof(stringa)); - memset(stringa2, '\0', sizeof(stringa2)); - sprintf(stringa, "%02X", converted[i]); - DEBUGA_GSMOPEN("character is |%02X|\n", GSMOPEN_P_LOG, converted[i]); - stringa2[0] = stringa[strlen(stringa) - 2]; - stringa2[1] = stringa[strlen(stringa) - 1]; - strncat(ucs2_out, stringa2, ((outbytesleft - strlen(ucs2_out)) - 1)); //add the received line to the buffer - DEBUGA_GSMOPEN("stringa=%s, stringa2=%s, ucs2_out=%s\n", GSMOPEN_P_LOG, stringa, stringa2, ucs2_out); - } - return 0; -} - -/*! \brief Answer incoming call, - * Part of PBX interface */ -int gsmopen_answer(private_t *tech_pvt) -{ - int res; - - if (option_debug) { - DEBUGA_PBX("ENTERING FUNC\n", GSMOPEN_P_LOG); - } - /* do something to actually answer the call, if needed (eg. pick up the phone) */ - if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) { - if (gsmopen_serial_answer(tech_pvt)) { - ERRORA("gsmopen_answer FAILED\n", GSMOPEN_P_LOG); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return -1; - } - } - tech_pvt->interface_state = GSMOPEN_STATE_UP; - tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE; - - while (tech_pvt->interface_state == GSMOPEN_STATE_RING) { - gsmopen_sleep(10000); //10msec - } - if (tech_pvt->interface_state != GSMOPEN_STATE_UP) { - ERRORA("call answering failed\n", GSMOPEN_P_LOG); - res = -1; - } else { - if (option_debug) - DEBUGA_PBX("call answered\n", GSMOPEN_P_LOG); - res = 0; - - if (tech_pvt->owner) { - DEBUGA_PBX("going to send GSMOPEN_STATE_UP\n", GSMOPEN_P_LOG); - ast_setstate(tech_pvt->owner, GSMOPEN_STATE_UP); - DEBUGA_PBX("just sent GSMOPEN_STATE_UP\n", GSMOPEN_P_LOG); - } - } - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return res; -} - -int gsmopen_ring(private_t *tech_pvt) -{ - int res = 0; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - switch_core_session_rwunlock(session); - return 0; - } - - new_inbound_channel(tech_pvt); - - gsmopen_sleep(10000); - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - - switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING); - if (channel) { - switch_channel_mark_ring_ready(channel); - DEBUGA_GSMOPEN("switch_channel_mark_ring_ready(channel);\n", GSMOPEN_P_LOG); - } else { - ERRORA("no channel\n", GSMOPEN_P_LOG); - } - switch_core_session_rwunlock(session); - } else { - ERRORA("no session\n", GSMOPEN_P_LOG); - - } - - return res; -} - -/*! \brief Hangup gsmopen call - * Part of PBX interface, called from ast_hangup */ - -int gsmopen_hangup(private_t *tech_pvt) -{ - - /* if there is not gsmopen pvt why we are here ? */ - if (!tech_pvt) { - ERRORA("Asked to hangup channel not connected\n", GSMOPEN_P_LOG); - return 0; - } - - DEBUGA_GSMOPEN("ENTERING FUNC\n", GSMOPEN_P_LOG); - - if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) { - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - /* actually hangup through the serial port */ - if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) { - int res; - res = gsmopen_serial_hangup(tech_pvt); - if (res) { - ERRORA("gsmopen_serial_hangup error: %d\n", GSMOPEN_P_LOG, res); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return -1; - } - } - - while (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - gsmopen_sleep(10000); //10msec - } - if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) { - ERRORA("call hangup failed\n", GSMOPEN_P_LOG); - return -1; - } else { - DEBUGA_GSMOPEN("call hungup\n", GSMOPEN_P_LOG); - } - } - } else { - tech_pvt->interface_state = GSMOPEN_STATE_DOWN; - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - } - - switch_set_flag(tech_pvt, TFLAG_HANGUP); - if (option_debug) { - DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG); - } - return 0; -} - -int gsmopen_call(private_t *tech_pvt, char *rdest, int timeout) -{ - - int result; - - DEBUGA_GSMOPEN("Calling GSM, rdest is: %s\n", GSMOPEN_P_LOG, rdest); - - result=gsmopen_serial_call(tech_pvt, rdest); - return result; -} - -int gsmopen_senddigit(private_t *tech_pvt, char digit) -{ - - DEBUGA_GSMOPEN("DIGIT received: %c\n", GSMOPEN_P_LOG, digit); - if (tech_pvt->controldevprotocol == PROTOCOL_AT && tech_pvt->at_send_dtmf[0]) { - int res = 0; - char at_command[256]; - - memset(at_command, '\0', 256); - sprintf(at_command, "%s=1,%c", tech_pvt->at_send_dtmf, digit); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res) { - DEBUGA_GSMOPEN("XXX answer (OK) takes long to come, goes into timeout. command used: '%s=1,%c'\n", GSMOPEN_P_LOG, tech_pvt->at_send_dtmf, - digit); - } - } - - return 0; -} - -int gsmopen_sendsms(private_t *tech_pvt, char *dest, char *text) -{ - int failed = 0; - int err = 0; - char mesg_test[1024]; - - DEBUGA_GSMOPEN("GSMopenSendsms: dest=%s text=%s\n", GSMOPEN_P_LOG, dest, text); - DEBUGA_GSMOPEN("START\n", GSMOPEN_P_LOG); - /* we can use gsmopen_request to get the channel, but gsmopen_request would look for onowned channels, and probably we can send SMSs while a call is ongoing - * - */ - - if (tech_pvt->controldevprotocol != PROTOCOL_AT) { - ERRORA(", GSMOPEN_P_LOGGSMopenSendsms supports only AT command cellphones at the moment :-( !\n", GSMOPEN_P_LOG); - return RESULT_FAILURE; - } - - if (tech_pvt->controldevprotocol == PROTOCOL_AT) { - char smscommand[16000]; - memset(smscommand, '\0', sizeof(smscommand)); - char pdu2[16000]; - memset(pdu2, '\0', sizeof(pdu2)); - int pdulenght = 0; - string pdu; - - PUSHA_UNLOCKA(&tech_pvt->controldev_lock); - LOKKA(tech_pvt->controldev_lock); - - if (tech_pvt->no_ucs2 || tech_pvt->sms_pdu_not_supported == 0) { - try { - int bad_8859 = 0; - - memset(mesg_test, '\0', sizeof(mesg_test)); - sprintf(mesg_test, ":) ciao belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大aèéàòçù"); //let's test the beauty of utf8 - //sprintf(mesg_test,":) ciao belè èéàòìù"); - //text=mesg_test; - - bad_8859 = utf8_to_iso_8859_1(tech_pvt, text, strlen(text), smscommand, sizeof(smscommand)); - if (!bad_8859) { - err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0"); - if (err) { - ERRORA("AT+CMGF=0 (set message sending to PDU (as opposed to TEXT) didn't get OK from the phone\n", GSMOPEN_P_LOG); - } - SMSMessageRef smsMessage; - smsMessage = new SMSSubmitMessage(smscommand, dest); - pdu = smsMessage->encode(); - strncpy(pdu2, pdu.c_str(), sizeof(pdu2) - 1); - memset(smscommand, '\0', sizeof(smscommand)); - pdulenght = pdu.length() / 2 - 1; - sprintf(smscommand, "AT+CMGS=%d", pdulenght); - } else { - int ok; - - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(&tech_pvt->controldev_lock); - - tech_pvt->no_ucs2 = 0; - tech_pvt->sms_pdu_not_supported = 1; - - ok = gsmopen_sendsms(tech_pvt, dest, text); - - tech_pvt->no_ucs2 = 1; - tech_pvt->sms_pdu_not_supported = 0; - - err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0"); - if (err) { - ERRORA("AT+CMGF=0 (set message sending to PDU (as opposed to TEXT) didn't get OK from the phone\n", GSMOPEN_P_LOG); - } - return ok; - } - - } - catch(GsmException & ge) { - ERRORA("GsmException= |||%s|||\n", GSMOPEN_P_LOG, ge.what()); - } - - - - } else { - char dest2[1048]; - - err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1"); - if (err) { - ERRORA("AT+CMGF=1 (set message sending to TEXT (as opposed to PDU) didn't get OK from the phone\n", GSMOPEN_P_LOG); - } - - memset(dest2, '\0', sizeof(dest2)); - utf8_to_ucs2(tech_pvt, dest, strlen(dest), dest2, sizeof(dest2)); - sprintf(smscommand, "AT+CMGS=\"%s\"", dest2); - } - err = gsmopen_serial_write_AT_noack(tech_pvt, smscommand); - if (err) { - ERRORA("Error sending SMS\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - err = gsmopen_serial_AT_expect(tech_pvt, "> ", 0, 1); // wait 1.1s for the prompt, no crlf - if (err) { - DEBUGA_GSMOPEN - ("Error or timeout getting prompt '> ' for sending sms directly to the remote party. BTW, seems that we cannot do that with Motorola c350, so we'll write to cellphone memory, then send from memory\n", - GSMOPEN_P_LOG); - - err = gsmopen_serial_write_AT_ack(tech_pvt, "ATE1"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!! - if (err) { - ERRORA("Error activating echo from modem\n", GSMOPEN_P_LOG); - } - tech_pvt->at_cmgw[0] = '\0'; - sprintf(smscommand, "AT+CMGW=\"%s\"", dest); //TODO: support phones that only accept pdu mode - err = gsmopen_serial_write_AT_noack(tech_pvt, smscommand); - if (err) { - ERRORA("Error writing SMS destination to the cellphone memory\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - err = gsmopen_serial_AT_expect(tech_pvt, "> ", 0, 1); // wait 1.5s for the prompt, no crlf - if (err) { - ERRORA("Error or timeout getting prompt '> ' for writing sms text in cellphone memory\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - } - - if (tech_pvt->no_ucs2 || tech_pvt->sms_pdu_not_supported == 0) { - memset(smscommand, '\0', sizeof(smscommand)); - sprintf(smscommand, "%s", pdu2); - } else { - memset(mesg_test, '\0', sizeof(mesg_test)); - sprintf(mesg_test, ":) ciao belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大aèéàòçù"); //let's test the beauty of utf8 - //text=mesg_test; - - memset(smscommand, '\0', sizeof(smscommand)); - if (tech_pvt->no_ucs2) { - sprintf(smscommand, "%s", text); - } else { - utf8_to_ucs2(tech_pvt, text, strlen(text), smscommand, sizeof(smscommand)); - } - - } - smscommand[strlen(smscommand)] = 0x1A; - DEBUGA_GSMOPEN("smscommand len is: %d, text is:|||%s|||\n", GSMOPEN_P_LOG, (int) strlen(smscommand), smscommand); - - err = gsmopen_serial_write_AT_ack_nocr_longtime(tech_pvt, smscommand); - //TODO would be better to unlock controldev here - if (err) { - ERRORA("Error writing SMS text to the cellphone memory\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - if (tech_pvt->at_cmgw[0]) { - sprintf(smscommand, "AT+CMSS=%s", tech_pvt->at_cmgw); - err = gsmopen_serial_write_AT_expect_longtime(tech_pvt, smscommand, "OK"); - if (err) { - ERRORA("Error sending SMS from the cellphone memory\n", GSMOPEN_P_LOG); - failed = 1; - goto uscita; - } - - err = gsmopen_serial_write_AT_ack(tech_pvt, "ATE0"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!! - if (err) { - ERRORA("Error de-activating echo from modem\n", GSMOPEN_P_LOG); - } - } - uscita: - gsmopen_sleep(1000); - - if (tech_pvt->at_cmgw[0]) { - - /* let's see what we've sent, just for check TODO: Motorola isn't reliable! Motorola c350 tells that all was sent, but is not true! It just sends how much it fits into one SMS FIXME: need an algorithm to calculate how many ucs2 chars fits into an SMS. It make difference based, probably, on the GSM alphabet translation, or so */ - sprintf(smscommand, "AT+CMGR=%s", tech_pvt->at_cmgw); - err = gsmopen_serial_write_AT_ack(tech_pvt, smscommand); - if (err) { - ERRORA("Error reading SMS back from the cellphone memory\n", GSMOPEN_P_LOG); - } - - /* let's delete from cellphone memory what we've sent */ - sprintf(smscommand, "AT+CMGD=%s", tech_pvt->at_cmgw); - err = gsmopen_serial_write_AT_ack(tech_pvt, smscommand); - if (err) { - ERRORA("Error deleting SMS from the cellphone memory\n", GSMOPEN_P_LOG); - } - - tech_pvt->at_cmgw[0] = '\0'; - } - UNLOCKA(tech_pvt->controldev_lock); - POPPA_UNLOCKA(&tech_pvt->controldev_lock); - } - - DEBUGA_GSMOPEN("FINISH\n", GSMOPEN_P_LOG); - if (failed) - return -1; - else - return RESULT_SUCCESS; -} - -int gsmopen_ussd(private_t *tech_pvt, char *ussd, int waittime) -{ - int res = 0; - DEBUGA_GSMOPEN("gsmopen_ussd: %s\n", GSMOPEN_P_LOG, ussd); - if (tech_pvt->controldevprotocol == PROTOCOL_AT) { - char at_command[1024]; - - string ussd_enc = latin1ToGsm(ussd); - SMSEncoder e; - e.markSeptet(); - e.setString(ussd_enc); - string ussd_hex = e.getHexString(); - - memset(at_command, '\0', sizeof(at_command)); - tech_pvt->ussd_received = 0; - if (tech_pvt->ussd_request_encoding == USSD_ENCODING_PLAIN - ||tech_pvt->ussd_request_encoding == USSD_ENCODING_AUTO) { - snprintf(at_command, sizeof(at_command), "AT+CUSD=1,\"%s\",15", ussd_enc.c_str()); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res && tech_pvt->ussd_request_encoding == USSD_ENCODING_AUTO) { - DEBUGA_GSMOPEN("Plain request failed, trying HEX7 encoding...\n", GSMOPEN_P_LOG); - snprintf(at_command, sizeof(at_command), "AT+CUSD=1,\"%s\",15", ussd_hex.c_str()); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - if (res == 0) { - DEBUGA_GSMOPEN("HEX 7-bit request encoding will be used from now on\n", GSMOPEN_P_LOG); - tech_pvt->ussd_request_encoding = USSD_ENCODING_HEX_7BIT; - } - } - } else if (tech_pvt->ussd_request_encoding == USSD_ENCODING_HEX_7BIT) { - snprintf(at_command, sizeof(at_command), "AT+CUSD=1,\"%s\",15", ussd_hex.c_str()); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - } else if (tech_pvt->ussd_request_encoding == USSD_ENCODING_HEX_8BIT) { - string ussd_h8 = bufToHex((const unsigned char*)ussd_enc.c_str(), ussd_enc.length()); - snprintf(at_command, sizeof(at_command), "AT+CUSD=1,\"%s\",15", ussd_h8.c_str()); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - } else if (tech_pvt->ussd_request_encoding == USSD_ENCODING_UCS2) { - char ussd_ucs2[1000]; - memset(ussd_ucs2, '\0', sizeof(ussd_ucs2)); - utf8_to_ucs2(tech_pvt, ussd, strlen(ussd), ussd_ucs2, sizeof(ussd_ucs2)); - snprintf(at_command, sizeof(at_command), "AT+CUSD=1,\"%s\",15", ussd_ucs2); - res = gsmopen_serial_write_AT_ack(tech_pvt, at_command); - } - if (res) { - return res; - } - if (waittime > 0) - res = gsmopen_serial_read_AT(tech_pvt, 1, 0, waittime, "+CUSD", 1); - } - return res; -} - -/************************************************/ - -/* LUIGI RIZZO's magic */ -/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must - * be representable in 16 bits to avoid overflows. - */ -#define BOOST_SCALE (1<<9) -#define BOOST_MAX 40 /* slightly less than 7 bits */ - -/* - * store the boost factor - */ -void gsmopen_store_boost(char *s, double *boost) -{ - private_t *tech_pvt = NULL; - - if (sscanf(s, "%lf", boost) != 1) { - ERRORA("invalid boost <%s>\n", GSMOPEN_P_LOG, s); - return; - } - if (*boost < -BOOST_MAX) { - WARNINGA("boost %s too small, using %d\n", GSMOPEN_P_LOG, s, -BOOST_MAX); - *boost = -BOOST_MAX; - } else if (*boost > BOOST_MAX) { - WARNINGA("boost %s too large, using %d\n", GSMOPEN_P_LOG, s, BOOST_MAX); - *boost = BOOST_MAX; - } -#ifdef WIN32 - *boost = exp(log((double) 10) * *boost / 20) * BOOST_SCALE; -#else - *boost = exp(log(10) * *boost / 20) * BOOST_SCALE; -#endif //WIN32 - if (option_debug > 1) - DEBUGA_GSMOPEN("setting boost %s to %f\n", GSMOPEN_P_LOG, s, *boost); -} - -int gsmopen_sound_boost(void *data, int samples_num, double boost) -{ -/* LUIGI RIZZO's magic */ - if (boost != 0 && (boost < 511 || boost > 513)) { /* scale and clip values */ - int i, x; - - int16_t *ptr = (int16_t *) data; - - for (i = 0; i < samples_num; i++) { - x = (int) (ptr[i] * boost) / BOOST_SCALE; - if (x > 32767) { - x = 32767; - } else if (x < -32768) { - x = -32768; - } - ptr[i] = (int16_t) x; - } - } else { - //printf("BOOST=%f\n", boost); - } - - return 0; -} - -int gsmopen_serial_getstatus_AT(private_t *tech_pvt) -{ - int res; - private_t *p = tech_pvt; - - if (!p) - return -1; - - PUSHA_UNLOCKA(p->controldev_lock); - LOKKA(p->controldev_lock); - res = gsmopen_serial_write_AT_ack(p, "AT"); - if (res) { - ERRORA("AT was not acknowledged, continuing but maybe there is a problem\n", GSMOPEN_P_LOG); - } - gsmopen_sleep(1000); - - if (strlen(p->at_query_battchg)) { - res = gsmopen_serial_write_AT_expect(p, p->at_query_battchg, p->at_query_battchg_expect); - if (res) { - WARNINGA("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, p->at_query_battchg, p->at_query_battchg_expect); - } - gsmopen_sleep(1000); - } - - if (strlen(p->at_query_signal)) { - res = gsmopen_serial_write_AT_expect(p, p->at_query_signal, p->at_query_signal_expect); - if (res) { - WARNINGA("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, p->at_query_signal, p->at_query_signal_expect); - } - gsmopen_sleep(1000); - } - - if (!p->network_creg_not_supported) { - res = gsmopen_serial_write_AT_ack(p, "AT+CREG?"); - if (res) { - WARNINGA("%s didn't get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, "AT+CREG?", "OK"); - } - gsmopen_sleep(1000); - } - //FIXME all the following commands in config! - - if (p->sms_cnmi_not_supported) { - res = gsmopen_serial_write_AT_ack(p, "AT+MMGL=\"HEADER ONLY\""); - if (res) { - WARNINGA - ("%s didn't get %s from the phone. If your phone is not Motorola, please contact the gsmopen developers. Else, if your phone IS a Motorola, probably a long msg was incoming and ther first part was read and then deleted. The second part is now orphan. If you got this warning repeatedly, and you cannot correctly receive SMSs from this interface, please manually clean all messages (and the residual parts of them) from the cellphone/SIM. Continuing.\n", - GSMOPEN_P_LOG, "AT+MMGL=\"HEADER ONLY\"", "OK"); - } else { - gsmopen_sleep(1000); - if (p->unread_sms_msg_id) { - char at_command[256]; - - res = gsmopen_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\""); - if (res) { - ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) didn't get OK from the phone\n", GSMOPEN_P_LOG); - memset(p->sms_message, 0, sizeof(p->sms_message)); - } - - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGR=%d", p->unread_sms_msg_id); - memset(p->sms_message, 0, sizeof(p->sms_message)); - - p->reading_sms_msg = 1; - res = gsmopen_serial_write_AT_ack(p, at_command); - p->reading_sms_msg = 0; - if (res) { - ERRORA("AT+CMGR (read SMS) didn't get OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - res = gsmopen_serial_write_AT_ack(p, "AT+CSCS=\"GSM\""); - if (res) { - ERRORA("AT+CSCS=\"GSM\" (set TE messages to GSM) didn't get OK from the phone\n", GSMOPEN_P_LOG); - } - memset(at_command, 0, sizeof(at_command)); - sprintf(at_command, "AT+CMGD=%d", p->unread_sms_msg_id); /* delete the message */ - p->unread_sms_msg_id = 0; - res = gsmopen_serial_write_AT_ack(p, at_command); - if (res) { - ERRORA("AT+CMGD (Delete SMS) didn't get OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command); - } - - if (strlen(p->sms_message)) { - DEBUGA_GSMOPEN("got SMS incoming message. SMS received was:---%s---\n", GSMOPEN_P_LOG, p->sms_message); - } - } - } - } - - UNLOCKA(p->controldev_lock); - POPPA_UNLOCKA(p->controldev_lock); - return 0; -} - -int gsmopen_serial_init_audio_port(private_t *tech_pvt, int controldevice_audio_speed) -{ - /* - * TODO - * hmm, it doesn't look very different from gsmopen_serial_init_port, does it? - */ - - if (!tech_pvt) - return -1; - - tech_pvt->serialPort_serial_audio = new ctb::SerialPort(); - - /* windows: com ports above com9 need a special trick, which also works for com ports below com10 ... */ - char devname[512] = ""; - strcpy(devname, tech_pvt->controldevice_audio_name); -#ifdef WIN32 - strcpy(devname,"\\\\.\\"); - strcat(devname, tech_pvt->controldevice_audio_name); -#endif - - if (tech_pvt->serialPort_serial_audio->Open(devname, 115200, "8N1", ctb::SerialPort::NoFlowControl) >= 0) { - DEBUGA_GSMOPEN("port %s, SUCCESS open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_audio_name); - tech_pvt->serialPort_serial_audio_opened =1; - gsmopen_serial_write_AT_expect(tech_pvt, "AT^DDSETEX=2", tech_pvt->at_dial_expect); - } else { -#ifdef WIN32 - LPVOID msg; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &msg, - 0, - NULL); - ERRORA("port open failed for %s - %s", GSMOPEN_P_LOG, devname, (LPCTSTR) msg); - LocalFree(msg); -#else - ERRORA("port %s, NOT open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_audio_name); -#endif - return -1; - } - - return 0; -} - -int serial_audio_init(private_t *tech_pvt) -{ - int res; - int err; - - res = gsmopen_serial_init_audio_port(tech_pvt, tech_pvt->controldevice_audio_speed); - DEBUGA_GSMOPEN("serial_audio_init res=%d\n", GSMOPEN_P_LOG, res); - - if (res == 0) - err = 0; - else - err = 1; - - return err; -} - -int serial_audio_shutdown(private_t *tech_pvt) -{ - - int res; - - if (!tech_pvt || !tech_pvt->serialPort_serial_audio) - return -1; - - res = tech_pvt->serialPort_serial_audio->Close(); - DEBUGA_GSMOPEN("serial_audio_shutdown res=%d (controldev_audio_fd is %d)\n", GSMOPEN_P_LOG, res, tech_pvt->controldev_audio_fd); - tech_pvt->serialPort_serial_audio_opened =0; - - return res; -} diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/COPYRIGHT b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/COPYRIGHT deleted file mode 100644 index 9d0d9da185..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/COPYRIGHT +++ /dev/null @@ -1,18 +0,0 @@ -Copyright - -Copyright (C) 1999-2010 Joachim Buermann (jbuermann@iftools.com) - -ctb is free software; you can redistribute it and/or modify it under -the term of the GNU Library General Public Licence as published by the -Free Software Foundation. - -This library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public Licence for more details - - -EXCEPTION NOTICE -As a special exception, you may use, copy, link, modify and distribute -under the user's own terms, binary object code versions of works based -on the library. diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/GNUmakefile b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/GNUmakefile deleted file mode 100644 index e39a687d4c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/GNUmakefile +++ /dev/null @@ -1,293 +0,0 @@ -# ========================================================================= -# This makefile was generated by -# Bakefile 0.2.5 (http://www.bakefile.org) -# Do not modify, all changes will be overwritten! -# ========================================================================= - - - -# ------------------------------------------------------------------------- -# These are configurable options: -# ------------------------------------------------------------------------- - -# 'install' program location -INSTALL ?= install - -# Location where the package is installed by 'make install' -prefix ?= /usr/local - -# Destination root (/ is used if empty) -DESTDIR ?= - -# -AR ?= ar - -# -RANLIB ?= ranlib - -# Compiler flags to link shared library -LINK_DLL_FLAGS ?= -shared - -# C++ compiler -CXX = g++ - -# Standard flags for C++ -CXXFLAGS ?= - -# Standard preprocessor flags (common for CC and CXX) -CPPFLAGS ?= - -# Standard linker flags -LDFLAGS ?= - -# Set to 1 to build debug version [0,1] -DEBUG ?= 0 - -# -GPIB ?= 0 - - - -# ------------------------------------------------------------------------- -# Do not modify the rest of this file! -# ------------------------------------------------------------------------- - -### Variables: ### - -CPPDEPS = -MT$@ -MF`echo $@ | sed -e 's,\.o$$,.d,'` -MD -MP -CTB_LIB_CXXFLAGS = $(____DEBUG) $(____DEBUG_1) -D_THREAD_SAFE -pthread \ - $(__OPTIMIZE_FLAG) -I../include $(CPPFLAGS) $(CXXFLAGS) -CTB_LIB_OBJECTS = \ - $(OUTPUT)/ctb_lib_fifo.o \ - $(OUTPUT)/ctb_lib_getopt.o \ - $(OUTPUT)/ctb_lib_iobase.o \ - $(OUTPUT)/ctb_lib_portscan.o \ - $(OUTPUT)/ctb_lib_serportx.o \ - $(OUTPUT)/ctb_lib_serport.o \ - $(OUTPUT)/ctb_lib_timer.o \ - $(__GPIBSRC_OBJECTS) -CTB_DLL_CXXFLAGS = $(____DEBUG) $(____DEBUG_1) -D_THREAD_SAFE -pthread \ - $(__OPTIMIZE_FLAG) -I../include -fPIC -DPIC $(CPPFLAGS) $(CXXFLAGS) -CTB_DLL_OBJECTS = \ - $(OUTPUT)/ctb_dll_fifo.o \ - $(OUTPUT)/ctb_dll_getopt.o \ - $(OUTPUT)/ctb_dll_iobase.o \ - $(OUTPUT)/ctb_dll_portscan.o \ - $(OUTPUT)/ctb_dll_serportx.o \ - $(OUTPUT)/ctb_dll_serport.o \ - $(OUTPUT)/ctb_dll_timer.o \ - $(__GPIBSRC_OBJECTS_1) -CTBTEST_CXXFLAGS = $(____DEBUG) $(____DEBUG_1) -DGPIB=$(GPIB) -D_THREAD_SAFE \ - -pthread $(__OPTIMIZE_FLAG) -I../include $(CPPFLAGS) $(CXXFLAGS) -CTBTEST_OBJECTS = \ - $(OUTPUT)/ctbtest_ctbtest.o - -### Conditionally set variables: ### - -ifeq ($(DEBUG),0) -OUTPUT = release -endif -ifeq ($(DEBUG),1) -OUTPUT = debug -endif -ifeq ($(DEBUG),1) -LIBFLAG = d -endif -ifeq ($(GPIB),1) -GPIBFLAG = _gpib -endif -ifeq ($(GPIB),1) -GPIBINC = gpib.h -endif -ifeq ($(GPIB),1) -__GPIBSRC_OBJECTS = \ - $(OUTPUT)/ctb_lib_gpib.o -endif -ifeq ($(GPIB),1) -__GPIBSRC_OBJECTS_1 = \ - $(OUTPUT)/ctb_dll_gpib.o -endif -ifeq ($(DEBUG),0) -____DEBUG = -DNDEBUG -endif -ifeq ($(DEBUG),1) -____DEBUG = -endif -ifeq ($(DEBUG),0) -__OPTIMIZE_FLAG = -O0 -endif -ifeq ($(DEBUG),1) -__OPTIMIZE_FLAG = -O2 -endif -ifeq ($(GPIB),1) -__SYSLIB2_p = -lgpib -endif -ifeq ($(DEBUG),0) -____DEBUG_1 = -endif -ifeq ($(DEBUG),1) -____DEBUG_1 = -g -endif - - -all: $(OUTPUT) -$(OUTPUT): - @mkdir -p $(OUTPUT) - -### Targets: ### - -all: ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so $(OUTPUT)/ctbtest tip-linux - -install: install_ctb_lib install_ctb_dll - $(INSTALL) -d $(DESTDIR)$(prefix)/include/ctb-0.16 - for f in ctb.h fifo.h getopt.h $(GPIBINC) iobase.h linux/serport.h linux/timer.h portscan.h serport.h serportx.h timer.h; do \ - if test ! -d $(DESTDIR)$(prefix)/include/ctb-0.16/`dirname $$f` ; then \ - $(INSTALL) -d $(DESTDIR)$(prefix)/include/ctb-0.16/`dirname $$f`; \ - fi; \ - $(INSTALL) -m 644 ../include/ctb-0.16/$$f $(DESTDIR)$(prefix)/include/ctb-0.16/$$f; \ - done - -uninstall: uninstall_ctb_lib uninstall_ctb_dll - for f in ctb.h fifo.h getopt.h $(GPIBINC) iobase.h linux/serport.h linux/timer.h portscan.h serport.h serportx.h timer.h; do \ - rm -f $(DESTDIR)$(prefix)/include/ctb-0.16/$$f; \ - done - -clean: - rm -f $(OUTPUT)/*.o - rm -f $(OUTPUT)/*.d - rm -f ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - rm -f ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so - rm -f ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so - rm -f $(OUTPUT)/ctbtest - -htmldoc: - (cd ..; tar -cvzf manual/libctb-0.16-htmldoc.tar.gz docs/html/ ) - -tarball: - (cd ../..; tar -cvzf libctb-0.16.tar.gz \ - libctb-0.16/build/ \ - libctb-0.16/manual/refman.pdf \ - libctb-0.16/include \ - libctb-0.16/python \ - libctb-0.16/samples \ - libctb-0.16/src \ - libctb-0.16/lib/gpib32.lib \ - --exclude=release \ - --exclude=debug \ - --exclude=install \ - --exclude=output \ - --exclude=website \ - --exclude=*~ \ - --exclude=buildall.sh \ - --exclude=buildall.bat \ - --exclude=version-update.sh \ - --exclude=libctb-0.16.tar.gz \ - --exclude=*.ilk \ - --exclude=*.log \ - --exclude=*.o* \ - --exclude=*.pdb \ - --exclude=*.pyc \ - --exclude=.svn; mv libctb-0.16.tar.gz libctb-0.16/build ) - -../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a: $(CTB_LIB_OBJECTS) - rm -f $@ - $(AR) rcu $@ $(CTB_LIB_OBJECTS) - $(RANLIB) $@ - -install_ctb_lib: ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - $(INSTALL) -d $(DESTDIR)$(prefix)/lib - $(INSTALL) -m 644 ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a $(DESTDIR)$(prefix)/lib - -uninstall_ctb_lib: - rm -f $(DESTDIR)$(prefix)/lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - -../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so: $(CTB_DLL_OBJECTS) - $(CXX) $(LINK_DLL_FLAGS) -fPIC -o $@ $(CTB_DLL_OBJECTS) $(____DEBUG_1) -pthread -L../lib $(LDFLAGS) -lpthread $(__SYSLIB2_p) - -install_ctb_dll: ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so - $(INSTALL) -d $(DESTDIR)$(prefix)/lib - $(INSTALL) -m 644 ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so $(DESTDIR)$(prefix)/lib - install -c ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so $(DESTDIR)$(prefix)/lib - -uninstall_ctb_dll: - rm -f $(DESTDIR)$(prefix)/lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so - rm -f $(DESTDIR)$(prefix)/lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.so - -$(OUTPUT)/ctbtest: $(CTBTEST_OBJECTS) ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - $(CXX) -o $@ $(CTBTEST_OBJECTS) $(____DEBUG_1) -pthread -L../lib $(LDFLAGS) ../lib/libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a -lpthread $(__SYSLIB2_p) - -tip-linux: - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. On Linux you'll now" - @echo " have to run (as root):" - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) install" - @echo " " - @echo " to install the libraries in $(prefix)/lib" - @echo " and the header files in $(prefix)/include/ctb-0.16" - @echo " " - @echo " Don't forget to run ldconfig (also as root)" - @echo " " - @echo " ctb comes with no guarantees and doesn't claim" - @echo " to be suitable for any purpose." - @echo "================================================================" - @echo " " - -$(OUTPUT)/ctb_lib_fifo.o: ./../src/fifo.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_getopt.o: ./../src/getopt.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_iobase.o: ./../src/iobase.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_portscan.o: ./../src/portscan.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_serportx.o: ./../src/serportx.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_serport.o: ./../src/linux/serport.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_timer.o: ./../src/linux/timer.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_lib_gpib.o: ./../src/gpib.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_fifo.o: ./../src/fifo.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_getopt.o: ./../src/getopt.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_iobase.o: ./../src/iobase.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_portscan.o: ./../src/portscan.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_serportx.o: ./../src/serportx.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_serport.o: ./../src/linux/serport.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_timer.o: ./../src/linux/timer.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctb_dll_gpib.o: ./../src/gpib.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)/ctbtest_ctbtest.o: ./../samples/ctbtest.cpp - $(CXX) -c -o $@ $(CTBTEST_CXXFLAGS) $(CPPDEPS) $< - -.PHONY: all install uninstall clean install_ctb_lib uninstall_ctb_lib \ - install_ctb_dll uninstall_ctb_dll - - -# Dependencies tracking: --include $(OUTPUT)/*.d diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/README b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/README deleted file mode 100644 index fdcdb1d37b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/README +++ /dev/null @@ -1,169 +0,0 @@ - -CTB (Communication toolbox library) 08.02.2010 -====================================================================== - -Website: http://www.iftools.com/opensource/ctb.en.php -Version: 0.16 - - -Linux GCC compiliation ----------------------------------------------------------------- - -Type 'make DEBUG=x GPIB=x' or 'make -f GNUmakefile DEBUG=x GPIB=x' - -Type the same command with an additional install as root to copy the -headers and libs to there according system places -(i.e. /usr/local/include/ctb-0.16 and /usr/local/lib/libctb-0.16.a) -like: - -sudo make DEBUG=x GPIB=x install - - -Microsoft MingW32 compilation ----------------------------------------------------------------- - -Type mingw32-make -f makefile.gcc DEBUG=x GPIB=x - -Please note! Currently only a shared ctb library will be created. -You have to copy the ctb-VERSION.dll in the application path of -your application linked with ctb or in a global dll folder (but -not recommented!) - - -Microsoft Visual C++ compilation ----------------------------------------------------------------- - -Type 'nmake -f makefile.vc DEBUG=x GPIB=x' - -To create all libs (debug/release with and without gpib support) -just input: ./buildall.bat in the build folder. - - -Borland C++ 5.0/5.5 compilation ----------------------------------------------------------------- - -Type 'make -f makefile.bcc DEBUG=x GPIB=x' - - -Watcom C++ 10.6/11 and OpenWatcom compilation ----------------------------------------------------------------- - -Type 'wmake -f makefile.wat' - - -Python support --------------- - -Since version 0.9 ctb also includes a python module ctb.py. -To build the python module by yourself, your system has to satisfy -the following requirements: - -- the SWIG program, you get it at http://www.swig.org/ (for linux, - take a look in your favorite distribution package manager). - The current ctb module was build with SWIG version 1.3.29 (linux) - and version 1.3.40 (Windows) -- the develop files for python (means the header and the library - files). I tested it with Python 2.4. You will get it at: - http://www.python.org/ftp/python/2.4.4/python-2.4.4.msi -- if you want to communicate via GPIB, a GPIB installation (GPIB - controller and software, for instance a Nation Instruments or - Keithley card). On Linux the libgpib. - -Like the building of the wxctb C++ library, you also can choose -between GPIB and non GPIB (default) support. - -Compile the python module - -Linux -cd in the python/src/linux folder and type: -./makepy.sh USE_GPIB -or -./makepy.sh -if you don't need any GPIB support - -Windows -cd in the python/src/windows folder. Open the makepy.bat with your -favorite editor and set the commented enviroment variables. See the -makepy.bat file for more information, how you can do that. -After that, just type: - -./makepy.sh USE_GPIB -(for GPIB support) or -./makepy.sh -if you don't need any GPIB support - -At last set the python modul path to the ctb-0.15/python/module -path. -On linux: - -export PYTHONPATH=somepath/ctb-0.15/python/module/linux - -On Windows: - -set PYTHONPATH=drive:\somepath\ctb-0.15\python\module\win32 - - -ChangeLog ---------- - -0.16 - - added port scan function. - - bug fixes for MingW build. - -0.15 - - added ctb namespace and removed all wx prefix (also in the header - path). - - Linux: A serial port cannot opened twice or more any longer. - - 9 bit data transmission support using the parity bit as ninth bit. - - improved documentation - - Some more documentation - -0.14 - - Support for non-standard baudrates (depends on the used UART - or USB to RS232 converter. - -0.13 - - remove the expect and match mechanism. They didn't work very - well, and a future implementation should be done as a - independent library. If someone missed this functions, please - let me know. - -0.12 - - more documentation for doxygen - - replace the ugly GetSettingsAsString methods by a more intuitive - one. - - wxGPIB::Read now checks the MAV bit before reading. This resolves - some stderr stuff on linux. - -0.11 - - the gpib sources are no longer depending on the OS. They are - identical for linux and windows. - - add the current version to the ctb include path, so you can - handle a parallel installation of different versions. - For instance: The header path wx/ctb is replaced by wx/ctb-0.11 - -0.10 - - replace the former gpib async io access with the standard - NI-488 functions (ibrd,ibwrt). To avoid blocking, the internal - gpib timeout was set to the lowest value, whereas the wxIOBase - methods handles the timeout in a global and transparent manner. - - add a FindListener method in the wxGPIB class to look for all - connected gpib devices (listeners). - - The Read and Readv method of the python wxIOBase class returns - additional zero bytes, fixed. - -0.9 - - added python support for both, serial and gpib - -0.8 - - added bakefile support - -0.7 - - added GPIB (Nation Instruments GPIB cards) support - - -Authors' info -------------- - -Joachim Buermann jbuermann@iftools.com - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/libctb.bkl b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/libctb.bkl deleted file mode 100644 index eb5670bd4a..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/libctb.bkl +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - - - - - - - - - 0.16 - libctb - - - - % - - - - - - - - - - debug - release - - $(OUTPUT) - - - ..$(DIRSEP)lib - - - - - d - - - - pthread - winmm - - - - gpib - gpib32 - - - - linux - win32 - - - - _gpib - - - - - ../src/gpib.cpp - - - - - - gpib.h - - - - - off - speed - - - - ../src/fifo.cpp - ../src/getopt.cpp - ../src/iobase.cpp - ../src/portscan.cpp - ../src/serportx.cpp - ../src/$(OS)/serport.cpp - ../src/$(OS)/timer.cpp - - - - - (cd ..; tar -cvzf manual/$(value) docs/html/ ) - - - - - - $(NAME)-$(VERSION)-htmldoc.tar.gz - - - - - - (cd ../..; tar -cvzf $(value) \ - $(NAME)-$(VERSION)/build/ \ - $(NAME)-$(VERSION)/manual/refman.pdf \ - $(NAME)-$(VERSION)/include \ - $(NAME)-$(VERSION)/python \ - $(NAME)-$(VERSION)/samples \ - $(NAME)-$(VERSION)/src \ - $(NAME)-$(VERSION)/lib/gpib32.lib \ - --exclude=release \ - --exclude=debug \ - --exclude=install \ - --exclude=output \ - --exclude=website \ - --exclude=*~ \ - --exclude=buildall.sh \ - --exclude=buildall.bat \ - --exclude=g++.sh \ - --exclude=version-update.sh \ - --exclude=$(value) \ - --exclude=*.ilk \ - --exclude=*.log \ - --exclude=*.o* \ - --exclude=*.pdb \ - --exclude=*.pyc \ - --exclude=.svn; mv $(value) $(NAME)-$(VERSION)/build ) - - - - - - $(NAME)-$(VERSION).tar.gz - - - - - - ..$(DIRSEP)include$(DIRSEP)ctb-$(VERSION) - - ctb.h - fifo.h - getopt.h - $(GPIBINC) - iobase.h - linux/serport.h - linux/timer.h - portscan.h - serport.h - serportx.h - timer.h - - $(INCLUDEDIR)$(DIRSEP)ctb-$(VERSION) - - - - ../lib - ctb$(LIBFLAG)$(GPIBFLAG)-$(VERSION) - - multi - static - $(OPTIMIZE_FLAG) - - $(FILES) - $(GPIBSRC) - - ../lib - $(SYSLIB1) - $(SYSLIB2) - ../include - $(LIBDIR) - - - ../lib - multi - ctb$(LIBFLAG)$(GPIBFLAG)-$(VERSION) - static - $(OPTIMIZE_FLAG) - ctb$(LIBFLAG)$(GPIBFLAG)-$(VERSION) - - $(FILES) - $(GPIBSRC) - - ../lib - $(SYSLIB1) - $(SYSLIB2) - ../include - $(LIBDIR) - - - - - - GPIB=$(GPIB) - multi - static - $(OPTIMIZE_FLAG) - - ../samples/ctbtest.cpp - - ../include - ../lib - ctb_lib - $(SYSLIB1) - $(SYSLIB2) - - - - vc - $(FORMAT) - - - - - - @if not exist $(INSTALLDIR)\lib\$(LIBNAME)_lib mkdir $(INSTALLDIR)\lib\$(LIBNAME)_lib - - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-$(VERSION).lib $(INSTALLDIR)\lib\$(LIBNAME)_lib - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-$(VERSION).dll $(INSTALLDIR)\lib\$(LIBNAME)_lib - - @if not exist $(INSTALLDIR)\include\ctb-$(VERSION)\win32 mkdir $(INSTALLDIR)\include\ctb-$(VERSION)\win32 - @copy ..\include\ctb-$(VERSION)\*.h $(INSTALLDIR)\include\ctb-$(VERSION) - @copy ..\include\ctb-$(VERSION)\win32\*.h $(INSTALLDIR)\include\ctb-$(VERSION)\win32 - - - - - all - - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. On Linux you'll now" - @echo " have to run (as root):" - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) install" - @echo " " - @echo " to install the libraries in $(LIBDIR)" - @echo " and the header files in $(INCLUDEDIR)/ctb-$(VERSION)" - @echo " " - @echo " Don't forget to run ldconfig (also as root)" - @echo " " - @echo " ctb comes with no guarantees and doesn't claim" - @echo " to be suitable for any purpose." - @echo "================================================================" - @echo " " - - - - - all - - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. If you have an installed " - @echo " wxWidget package (WXWIN must be defined in the enviroment), " - @echo " you'll now have to run: " - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) wxinstall " - @echo " " - @echo " to install the libraries in: " - @echo " $(INSTALLDIR)$(DIRSEP)lib$(DIRSEP)$(LIBNAME)_lib " - @echo " and the header files in" - @echo " $(INSTALLDIR)$(DIRSEP)ctb-$(VERSION)" - @echo " " - @echo " If you are using another compiler (Borland, Watcom, mingw,...) " - @echo " take a look in the README in this directory! " - @echo " " - @echo " ctb comes with no guarantees and doesn't claim " - @echo " to be suitable for any purpose. " - @echo "================================================================" - @echo " " - - - - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.bcc b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.bcc deleted file mode 100644 index 6afadafb3f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.bcc +++ /dev/null @@ -1,269 +0,0 @@ -# ========================================================================= -# This makefile was generated by -# Bakefile 0.2.5 (http://www.bakefile.org) -# Do not modify, all changes will be overwritten! -# ========================================================================= - -.autodepend - -!ifndef BCCDIR -!ifndef MAKEDIR -!error Your Borland compiler does not define MAKEDIR. Please define the BCCDIR variable, e.g. BCCDIR=d:\bc4 -!endif -BCCDIR = $(MAKEDIR)\.. -!endif - - - -# ------------------------------------------------------------------------- -# These are configurable options: -# ------------------------------------------------------------------------- - -# C++ compiler -!ifndef CXX -CXX = bcc32 -!endif - -# Standard flags for C++ -!ifndef CXXFLAGS -CXXFLAGS = -!endif - -# Standard preprocessor flags (common for CC and CXX) -!ifndef CPPFLAGS -CPPFLAGS = -a8 -g0 -!endif - -# Standard linker flags -!ifndef LDFLAGS -LDFLAGS = -!endif - -# Set to 1 to build debug version [0,1] -!ifndef DEBUG -DEBUG = 0 -!endif - -# -!ifndef GPIB -GPIB = 0 -!endif - -# -!ifndef WXDIR -WXDIR = $(WXWIN) -!endif - -# -!ifndef INSTALLDIR -INSTALLDIR = $(WXWIN) -!endif - - - -# ------------------------------------------------------------------------- -# Do not modify the rest of this file! -# ------------------------------------------------------------------------- - -### Variables: ### - -CTB_LIB_CXXFLAGS = -I$(BCCDIR)\include $(____DEBUG) $(____DEBUG_2) -tWM \ - $(__OPTIMIZE_FLAG) -I..\include $(CPPFLAGS) $(CXXFLAGS) -CTB_LIB_OBJECTS = \ - $(OUTPUT)\ctb_lib_fifo.obj \ - $(OUTPUT)\ctb_lib_getopt.obj \ - $(OUTPUT)\ctb_lib_iobase.obj \ - $(OUTPUT)\ctb_lib_portscan.obj \ - $(OUTPUT)\ctb_lib_serportx.obj \ - $(OUTPUT)\ctb_lib_serport.obj \ - $(OUTPUT)\ctb_lib_timer.obj \ - $(____GPIBSRC_FILENAMES_OBJECTS) -CTB_DLL_CXXFLAGS = -I$(BCCDIR)\include $(____DEBUG) $(____DEBUG_2) -tWM \ - $(__OPTIMIZE_FLAG) -I..\include $(CPPFLAGS) $(CXXFLAGS) -CTB_DLL_OBJECTS = \ - $(OUTPUT)\ctb_dll_fifo.obj \ - $(OUTPUT)\ctb_dll_getopt.obj \ - $(OUTPUT)\ctb_dll_iobase.obj \ - $(OUTPUT)\ctb_dll_portscan.obj \ - $(OUTPUT)\ctb_dll_serportx.obj \ - $(OUTPUT)\ctb_dll_serport.obj \ - $(OUTPUT)\ctb_dll_timer.obj \ - $(____GPIBSRC_FILENAMES_1_OBJECTS) -CTBTEST_CXXFLAGS = -I$(BCCDIR)\include $(____DEBUG) $(____DEBUG_2) \ - -DGPIB=$(GPIB) -tWM $(__OPTIMIZE_FLAG) -I..\include $(CPPFLAGS) $(CXXFLAGS) -CTBTEST_OBJECTS = \ - $(OUTPUT)\ctbtest_ctbtest.obj - -### Conditionally set variables: ### - -!if "$(DEBUG)" == "0" -OUTPUT = release -!endif -!if "$(DEBUG)" == "1" -OUTPUT = debug -!endif -!if "$(WXDIR)" == "" -INSTALLDIR = ..\lib -!endif -!if "$(DEBUG)" == "1" -LIBFLAG = d -!endif -!if "$(GPIB)" == "1" -GPIBFLAG = _gpib -!endif -!if "$(GPIB)" == "1" -____GPIBSRC_FILENAMES_OBJECTS = \ - $(OUTPUT)\ctb_lib_gpib.obj -!endif -!if "$(GPIB)" == "1" -____GPIBSRC_FILENAMES_1_OBJECTS = \ - $(OUTPUT)\ctb_dll_gpib.obj -!endif -!if "$(DEBUG)" == "0" -____DEBUG = -DNDEBUG -!endif -!if "$(DEBUG)" == "1" -____DEBUG = -!endif -!if "$(DEBUG)" == "0" -__OPTIMIZE_FLAG = -Od -!endif -!if "$(DEBUG)" == "1" -__OPTIMIZE_FLAG = -O2 -!endif -!if "$(GPIB)" == "1" -__SYSLIB2_p = gpib32.lib -!endif -!if "$(DEBUG)" == "0" -____DEBUG_2 = -v- -!endif -!if "$(DEBUG)" == "1" -____DEBUG_2 = -v -!endif - - -all: $(OUTPUT) -$(OUTPUT): - -if not exist $(OUTPUT) mkdir $(OUTPUT) - -### Targets: ### - -all: ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(OUTPUT)\ctbtest.exe tip-win32 - -clean: - -if exist $(OUTPUT)\*.obj del $(OUTPUT)\*.obj - -if exist $(OUTPUT)\*.res del $(OUTPUT)\*.res - -if exist $(OUTPUT)\*.csm del $(OUTPUT)\*.csm - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.tds del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.tds - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ilc del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ilc - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ild del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ild - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ilf del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ilf - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ils del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ils - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - -if exist $(OUTPUT)\ctbtest.exe del $(OUTPUT)\ctbtest.exe - -if exist $(OUTPUT)\ctbtest.tds del $(OUTPUT)\ctbtest.tds - -if exist $(OUTPUT)\ctbtest.ilc del $(OUTPUT)\ctbtest.ilc - -if exist $(OUTPUT)\ctbtest.ild del $(OUTPUT)\ctbtest.ild - -if exist $(OUTPUT)\ctbtest.ilf del $(OUTPUT)\ctbtest.ilf - -if exist $(OUTPUT)\ctbtest.ils del $(OUTPUT)\ctbtest.ils - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib: $(CTB_LIB_OBJECTS) - if exist $@ del $@ - tlib /a /p4096 $@ @&&| - $(CTB_LIB_OBJECTS) -| - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll: $(CTB_DLL_OBJECTS) - ilink32 -Tpd -q -L$(BCCDIR)\lib -L$(BCCDIR)\lib\psdk $(____DEBUG_2) -L..\lib $(LDFLAGS) @&&| - c0d32.obj $(CTB_DLL_OBJECTS),$@,, winmm.lib $(__SYSLIB2_p) import32.lib cw32mt.lib,, -| - implib -f ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16 $@ - -$(OUTPUT)\ctbtest.exe: $(CTBTEST_OBJECTS) ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - ilink32 -Tpe -q -L$(BCCDIR)\lib -L$(BCCDIR)\lib\psdk $(____DEBUG_2) -L..\lib $(LDFLAGS) @&&| - c0x32.obj $(CTBTEST_OBJECTS),$@,, ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib winmm.lib $(__SYSLIB2_p) import32.lib cw32mt.lib,, -| - -wxinstall: - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib $(INSTALLDIR)\lib\borland_lib - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(INSTALLDIR)\lib\borland_lib - - @if not exist $(INSTALLDIR)\include\ctb-0.16\win32 mkdir $(INSTALLDIR)\include\ctb-0.16\win32 - @copy ..\include\ctb-0.16\*.h $(INSTALLDIR)\include\ctb-0.16 - @copy ..\include\ctb-0.16\win32\*.h $(INSTALLDIR)\include\ctb-0.16\win32 - -tip-win32: - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. If you have an installed " - @echo " wxWidget package (WXWIN must be defined in the enviroment), " - @echo " you'll now have to run: " - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) wxinstall " - @echo " " - @echo " to install the libraries in: " - @echo " $(INSTALLDIR)\lib\borland_lib " - @echo " and the header files in" - @echo " $(INSTALLDIR)\ctb-0.16" - @echo " " - @echo " If you are using another compiler (Borland, Watcom, mingw,...) " - @echo " take a look in the README in this directory! " - @echo " " - @echo " ctb comes with no guarantees and doesn't claim " - @echo " to be suitable for any purpose. " - @echo "================================================================" - @echo " " - -$(OUTPUT)\ctb_lib_fifo.obj: .\..\src\fifo.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\fifo.cpp - -$(OUTPUT)\ctb_lib_getopt.obj: .\..\src\getopt.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\getopt.cpp - -$(OUTPUT)\ctb_lib_iobase.obj: .\..\src\iobase.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\iobase.cpp - -$(OUTPUT)\ctb_lib_portscan.obj: .\..\src\portscan.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\portscan.cpp - -$(OUTPUT)\ctb_lib_serportx.obj: .\..\src\serportx.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\serportx.cpp - -$(OUTPUT)\ctb_lib_serport.obj: .\..\src\win32\serport.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\win32\serport.cpp - -$(OUTPUT)\ctb_lib_timer.obj: .\..\src\win32\timer.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\win32\timer.cpp - -$(OUTPUT)\ctb_lib_gpib.obj: .\..\src\gpib.cpp - $(CXX) -q -c -P -o$@ $(CTB_LIB_CXXFLAGS) .\..\src\gpib.cpp - -$(OUTPUT)\ctb_dll_fifo.obj: .\..\src\fifo.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\fifo.cpp - -$(OUTPUT)\ctb_dll_getopt.obj: .\..\src\getopt.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\getopt.cpp - -$(OUTPUT)\ctb_dll_iobase.obj: .\..\src\iobase.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\iobase.cpp - -$(OUTPUT)\ctb_dll_portscan.obj: .\..\src\portscan.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\portscan.cpp - -$(OUTPUT)\ctb_dll_serportx.obj: .\..\src\serportx.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\serportx.cpp - -$(OUTPUT)\ctb_dll_serport.obj: .\..\src\win32\serport.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\win32\serport.cpp - -$(OUTPUT)\ctb_dll_timer.obj: .\..\src\win32\timer.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\win32\timer.cpp - -$(OUTPUT)\ctb_dll_gpib.obj: .\..\src\gpib.cpp - $(CXX) -q -c -P -o$@ $(CTB_DLL_CXXFLAGS) .\..\src\gpib.cpp - -$(OUTPUT)\ctbtest_ctbtest.obj: .\..\samples\ctbtest.cpp - $(CXX) -q -c -P -o$@ $(CTBTEST_CXXFLAGS) .\..\samples\ctbtest.cpp - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.gcc b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.gcc deleted file mode 100644 index febca07dc8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.gcc +++ /dev/null @@ -1,238 +0,0 @@ -# ========================================================================= -# This makefile was generated by -# Bakefile 0.2.5 (http://www.bakefile.org) -# Do not modify, all changes will be overwritten! -# ========================================================================= - - - -# ------------------------------------------------------------------------- -# These are configurable options: -# ------------------------------------------------------------------------- - -# Compiler flags to link shared library -LINK_DLL_FLAGS ?= -shared - -# C++ compiler -CXX = g++ - -# Standard flags for C++ -CXXFLAGS ?= - -# Standard preprocessor flags (common for CC and CXX) -CPPFLAGS ?= - -# Standard linker flags -LDFLAGS ?= - -# Set to 1 to build debug version [0,1] -DEBUG ?= 0 - -# -GPIB ?= 0 - -# -WXDIR ?= $(WXWIN) - -# -INSTALLDIR ?= $(WXWIN) - - - -# ------------------------------------------------------------------------- -# Do not modify the rest of this file! -# ------------------------------------------------------------------------- - -### Variables: ### - -CPPDEPS = -MT$@ -MF$@.d -MD -MP -CTB_LIB_CXXFLAGS = $(____DEBUG) $(____DEBUG_1) -mthreads $(__OPTIMIZE_FLAG) \ - -I..\include $(CPPFLAGS) $(CXXFLAGS) -CTB_LIB_OBJECTS = \ - $(OUTPUT)\ctb_lib_fifo.o \ - $(OUTPUT)\ctb_lib_getopt.o \ - $(OUTPUT)\ctb_lib_iobase.o \ - $(OUTPUT)\ctb_lib_portscan.o \ - $(OUTPUT)\ctb_lib_serportx.o \ - $(OUTPUT)\ctb_lib_serport.o \ - $(OUTPUT)\ctb_lib_timer.o \ - $(____GPIBSRC_FILENAMES_OBJECTS) -CTB_DLL_CXXFLAGS = $(____DEBUG) $(____DEBUG_1) -mthreads $(__OPTIMIZE_FLAG) \ - -I..\include $(CPPFLAGS) $(CXXFLAGS) -CTB_DLL_OBJECTS = \ - $(OUTPUT)\ctb_dll_fifo.o \ - $(OUTPUT)\ctb_dll_getopt.o \ - $(OUTPUT)\ctb_dll_iobase.o \ - $(OUTPUT)\ctb_dll_portscan.o \ - $(OUTPUT)\ctb_dll_serportx.o \ - $(OUTPUT)\ctb_dll_serport.o \ - $(OUTPUT)\ctb_dll_timer.o \ - $(____GPIBSRC_FILENAMES_1_OBJECTS) -CTBTEST_CXXFLAGS = $(____DEBUG) $(____DEBUG_1) -DGPIB=$(GPIB) -mthreads \ - $(__OPTIMIZE_FLAG) -I..\include $(CPPFLAGS) $(CXXFLAGS) -CTBTEST_OBJECTS = \ - $(OUTPUT)\ctbtest_ctbtest.o - -### Conditionally set variables: ### - -ifeq ($(DEBUG),0) -OUTPUT = release -endif -ifeq ($(DEBUG),1) -OUTPUT = debug -endif -ifeq ($(WXDIR),) -INSTALLDIR = ..\lib -endif -ifeq ($(DEBUG),1) -LIBFLAG = d -endif -ifeq ($(GPIB),1) -GPIBFLAG = _gpib -endif -ifeq ($(GPIB),1) -____GPIBSRC_FILENAMES_OBJECTS = \ - $(OUTPUT)\ctb_lib_gpib.o -endif -ifeq ($(GPIB),1) -____GPIBSRC_FILENAMES_1_OBJECTS = \ - $(OUTPUT)\ctb_dll_gpib.o -endif -ifeq ($(DEBUG),0) -____DEBUG = -DNDEBUG -endif -ifeq ($(DEBUG),1) -____DEBUG = -endif -ifeq ($(DEBUG),0) -__OPTIMIZE_FLAG = -O0 -endif -ifeq ($(DEBUG),1) -__OPTIMIZE_FLAG = -O2 -endif -ifeq ($(GPIB),1) -__SYSLIB2_p = -lgpib32 -endif -ifeq ($(DEBUG),0) -____DEBUG_1 = -endif -ifeq ($(DEBUG),1) -____DEBUG_1 = -g -endif - - -all: $(OUTPUT) -$(OUTPUT): - -if not exist $(OUTPUT) mkdir $(OUTPUT) - -### Targets: ### - -all: ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(OUTPUT)\ctbtest.exe tip-win32 - -clean: - -if exist $(OUTPUT)\*.o del $(OUTPUT)\*.o - -if exist $(OUTPUT)\*.d del $(OUTPUT)\*.d - -if exist ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a del ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll - -if exist ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a del ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - -if exist $(OUTPUT)\ctbtest.exe del $(OUTPUT)\ctbtest.exe - -..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a: $(CTB_LIB_OBJECTS) - if exist $@ del $@ - ar rcu $@ $(CTB_LIB_OBJECTS) - ranlib $@ - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll: $(CTB_DLL_OBJECTS) - $(CXX) $(LINK_DLL_FLAGS) -fPIC -o $@ $(CTB_DLL_OBJECTS) $(____DEBUG_1) -mthreads -Wl,--out-implib=..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a -L..\lib $(LDFLAGS) -lwinmm $(__SYSLIB2_p) - -$(OUTPUT)\ctbtest.exe: $(CTBTEST_OBJECTS) ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a - $(CXX) -o $@ $(CTBTEST_OBJECTS) $(____DEBUG_1) -mthreads -L..\lib $(LDFLAGS) ..\lib\libctb$(LIBFLAG)$(GPIBFLAG)-0.16.a -lwinmm $(__SYSLIB2_p) - -wxinstall: - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib $(INSTALLDIR)\lib\mingw_lib - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(INSTALLDIR)\lib\mingw_lib - - @if not exist $(INSTALLDIR)\include\ctb-0.16\win32 mkdir $(INSTALLDIR)\include\ctb-0.16\win32 - @copy ..\include\ctb-0.16\*.h $(INSTALLDIR)\include\ctb-0.16 - @copy ..\include\ctb-0.16\win32\*.h $(INSTALLDIR)\include\ctb-0.16\win32 - -tip-win32: - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. If you have an installed " - @echo " wxWidget package (WXWIN must be defined in the enviroment), " - @echo " you'll now have to run: " - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) wxinstall " - @echo " " - @echo " to install the libraries in: " - @echo " $(INSTALLDIR)\lib\mingw_lib " - @echo " and the header files in" - @echo " $(INSTALLDIR)\ctb-0.16" - @echo " " - @echo " If you are using another compiler (Borland, Watcom, mingw,...) " - @echo " take a look in the README in this directory! " - @echo " " - @echo " ctb comes with no guarantees and doesn't claim " - @echo " to be suitable for any purpose. " - @echo "================================================================" - @echo " " - -$(OUTPUT)\ctb_lib_fifo.o: ./../src/fifo.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_getopt.o: ./../src/getopt.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_iobase.o: ./../src/iobase.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_portscan.o: ./../src/portscan.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_serportx.o: ./../src/serportx.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_serport.o: ./../src/win32/serport.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_timer.o: ./../src/win32/timer.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_lib_gpib.o: ./../src/gpib.cpp - $(CXX) -c -o $@ $(CTB_LIB_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_fifo.o: ./../src/fifo.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_getopt.o: ./../src/getopt.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_iobase.o: ./../src/iobase.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_portscan.o: ./../src/portscan.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_serportx.o: ./../src/serportx.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_serport.o: ./../src/win32/serport.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_timer.o: ./../src/win32/timer.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctb_dll_gpib.o: ./../src/gpib.cpp - $(CXX) -c -o $@ $(CTB_DLL_CXXFLAGS) $(CPPDEPS) $< - -$(OUTPUT)\ctbtest_ctbtest.o: ./../samples/ctbtest.cpp - $(CXX) -c -o $@ $(CTBTEST_CXXFLAGS) $(CPPDEPS) $< - -.PHONY: all clean - - -SHELL := $(COMSPEC) - -# Dependencies tracking: --include $(OUTPUT)/*.d diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.vc b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.vc deleted file mode 100644 index 6b773f429b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.vc +++ /dev/null @@ -1,260 +0,0 @@ -# ========================================================================= -# This makefile was generated by -# Bakefile 0.2.5 (http://www.bakefile.org) -# Do not modify, all changes will be overwritten! -# ========================================================================= - - - -# ------------------------------------------------------------------------- -# These are configurable options: -# ------------------------------------------------------------------------- - -# C++ compiler -CXX = cl - -# Standard flags for C++ -CXXFLAGS = - -# Standard preprocessor flags (common for CC and CXX) -CPPFLAGS = - -# Standard linker flags -LDFLAGS = - -# Set to 1 to build debug version [0,1] -# 0 - Release -# 1 - Debug -DEBUG = 0 - -# -GPIB = 0 - -# -WXDIR = $(WXWIN) - -# -INSTALLDIR = $(WXWIN) - - - -# ------------------------------------------------------------------------- -# Do not modify the rest of this file! -# ------------------------------------------------------------------------- - -### Variables: ### - -CTB_LIB_CXXFLAGS = /MD$(____DEBUG_4) /DWIN32 $(____DEBUG) $(____DEBUG_2) \ - $(______DEBUG) /Fd..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.pdb \ - $(__OPTIMIZE_FLAG) /I..\include /GR /EHsc $(CPPFLAGS) $(CXXFLAGS) -CTB_LIB_OBJECTS = \ - $(OUTPUT)\ctb_lib_fifo.obj \ - $(OUTPUT)\ctb_lib_getopt.obj \ - $(OUTPUT)\ctb_lib_iobase.obj \ - $(OUTPUT)\ctb_lib_portscan.obj \ - $(OUTPUT)\ctb_lib_serportx.obj \ - $(OUTPUT)\ctb_lib_serport.obj \ - $(OUTPUT)\ctb_lib_timer.obj \ - $(____GPIBSRC_FILENAMES_OBJECTS) -CTB_DLL_CXXFLAGS = /MD$(____DEBUG_4) /DWIN32 $(____DEBUG) $(____DEBUG_2) \ - $(______DEBUG) /Fd..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.pdb \ - $(__OPTIMIZE_FLAG) /I..\include /GR /EHsc $(CPPFLAGS) $(CXXFLAGS) -CTB_DLL_OBJECTS = \ - $(OUTPUT)\ctb_dll_fifo.obj \ - $(OUTPUT)\ctb_dll_getopt.obj \ - $(OUTPUT)\ctb_dll_iobase.obj \ - $(OUTPUT)\ctb_dll_portscan.obj \ - $(OUTPUT)\ctb_dll_serportx.obj \ - $(OUTPUT)\ctb_dll_serport.obj \ - $(OUTPUT)\ctb_dll_timer.obj \ - $(____GPIBSRC_FILENAMES_1_OBJECTS) -CTBTEST_CXXFLAGS = /MD$(____DEBUG_4) /DWIN32 $(____DEBUG) $(____DEBUG_2) \ - $(______DEBUG) /Fd$(OUTPUT)\ctbtest.pdb /DGPIB=$(GPIB) $(__OPTIMIZE_FLAG) \ - /I..\include /GR /EHsc $(CPPFLAGS) $(CXXFLAGS) -CTBTEST_OBJECTS = \ - $(OUTPUT)\ctbtest_ctbtest.obj - -### Conditionally set variables: ### - -!if "$(DEBUG)" == "0" -OUTPUT = release -!endif -!if "$(DEBUG)" == "1" -OUTPUT = debug -!endif -!if "$(WXDIR)" == "" -INSTALLDIR = ..\lib -!endif -!if "$(DEBUG)" == "1" -LIBFLAG = d -!endif -!if "$(GPIB)" == "1" -GPIBFLAG = _gpib -!endif -!if "$(GPIB)" == "1" -____GPIBSRC_FILENAMES_OBJECTS = \ - $(OUTPUT)\ctb_lib_gpib.obj -!endif -!if "$(GPIB)" == "1" -____GPIBSRC_FILENAMES_1_OBJECTS = \ - $(OUTPUT)\ctb_dll_gpib.obj -!endif -!if "$(DEBUG)" == "0" -____DEBUG = /DNDEBUG -!endif -!if "$(DEBUG)" == "1" -____DEBUG = -!endif -!if "$(DEBUG)" == "0" -____DEBUG_2 = -!endif -!if "$(DEBUG)" == "1" -____DEBUG_2 = /Zi -!endif -!if "$(DEBUG)" == "0" -____DEBUG_3 = -!endif -!if "$(DEBUG)" == "1" -____DEBUG_3 = /DEBUG -!endif -!if "$(DEBUG)" == "0" -______DEBUG = -!endif -!if "$(DEBUG)" == "1" -______DEBUG = /D_DEBUG -!endif -!if "$(DEBUG)" == "0" -____DEBUG_4 = -!endif -!if "$(DEBUG)" == "1" -____DEBUG_4 = d -!endif -!if "$(DEBUG)" == "0" -__OPTIMIZE_FLAG = /Od -!endif -!if "$(DEBUG)" == "1" -__OPTIMIZE_FLAG = /O2 -!endif -!if "$(GPIB)" == "1" -__SYSLIB2_p = gpib32.lib -!endif - - -all: $(OUTPUT) -$(OUTPUT): - -if not exist $(OUTPUT) mkdir $(OUTPUT) - -### Targets: ### - -all: ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(OUTPUT)\ctbtest.exe tip-win32 - -clean: - -if exist $(OUTPUT)\*.obj del $(OUTPUT)\*.obj - -if exist $(OUTPUT)\*.res del $(OUTPUT)\*.res - -if exist $(OUTPUT)\*.pch del $(OUTPUT)\*.pch - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ilk del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.ilk - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.pdb del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.pdb - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - -if exist $(OUTPUT)\ctbtest.exe del $(OUTPUT)\ctbtest.exe - -if exist $(OUTPUT)\ctbtest.ilk del $(OUTPUT)\ctbtest.ilk - -if exist $(OUTPUT)\ctbtest.pdb del $(OUTPUT)\ctbtest.pdb - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib: $(CTB_LIB_OBJECTS) - if exist $@ del $@ - link /LIB /NOLOGO /OUT:$@ @<< - $(CTB_LIB_OBJECTS) -<< - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll: $(CTB_DLL_OBJECTS) - link /DLL /NOLOGO /OUT:$@ $(____DEBUG_3) /pdb:"..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.pdb" /LIBPATH:..\lib $(LDFLAGS) @<< - $(CTB_DLL_OBJECTS) winmm.lib $(__SYSLIB2_p) /IMPLIB:..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib -<< - -$(OUTPUT)\ctbtest.exe: $(CTBTEST_OBJECTS) ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - link /NOLOGO /OUT:$@ $(____DEBUG_3) /pdb:"$(OUTPUT)\ctbtest.pdb" /LIBPATH:..\lib $(LDFLAGS) @<< - $(CTBTEST_OBJECTS) ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib winmm.lib $(__SYSLIB2_p) -<< - -wxinstall: - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib $(INSTALLDIR)\lib\vc_lib - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(INSTALLDIR)\lib\vc_lib - - @if not exist $(INSTALLDIR)\include\ctb-0.16\win32 mkdir $(INSTALLDIR)\include\ctb-0.16\win32 - @copy ..\include\ctb-0.16\*.h $(INSTALLDIR)\include\ctb-0.16 - @copy ..\include\ctb-0.16\win32\*.h $(INSTALLDIR)\include\ctb-0.16\win32 - -tip-win32: - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. If you have an installed " - @echo " wxWidget package (WXWIN must be defined in the enviroment), " - @echo " you'll now have to run: " - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) wxinstall " - @echo " " - @echo " to install the libraries in: " - @echo " $(INSTALLDIR)\lib\vc_lib " - @echo " and the header files in" - @echo " $(INSTALLDIR)\ctb-0.16" - @echo " " - @echo " If you are using another compiler (Borland, Watcom, mingw,...) " - @echo " take a look in the README in this directory! " - @echo " " - @echo " ctb comes with no guarantees and doesn't claim " - @echo " to be suitable for any purpose. " - @echo "================================================================" - @echo " " - -$(OUTPUT)\ctb_lib_fifo.obj: .\..\src\fifo.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\fifo.cpp - -$(OUTPUT)\ctb_lib_getopt.obj: .\..\src\getopt.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\getopt.cpp - -$(OUTPUT)\ctb_lib_iobase.obj: .\..\src\iobase.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\iobase.cpp - -$(OUTPUT)\ctb_lib_portscan.obj: .\..\src\portscan.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\portscan.cpp - -$(OUTPUT)\ctb_lib_serportx.obj: .\..\src\serportx.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\serportx.cpp - -$(OUTPUT)\ctb_lib_serport.obj: .\..\src\win32\serport.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\win32\serport.cpp - -$(OUTPUT)\ctb_lib_timer.obj: .\..\src\win32\timer.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\win32\timer.cpp - -$(OUTPUT)\ctb_lib_gpib.obj: .\..\src\gpib.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_LIB_CXXFLAGS) .\..\src\gpib.cpp - -$(OUTPUT)\ctb_dll_fifo.obj: .\..\src\fifo.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\fifo.cpp - -$(OUTPUT)\ctb_dll_getopt.obj: .\..\src\getopt.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\getopt.cpp - -$(OUTPUT)\ctb_dll_iobase.obj: .\..\src\iobase.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\iobase.cpp - -$(OUTPUT)\ctb_dll_portscan.obj: .\..\src\portscan.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\portscan.cpp - -$(OUTPUT)\ctb_dll_serportx.obj: .\..\src\serportx.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\serportx.cpp - -$(OUTPUT)\ctb_dll_serport.obj: .\..\src\win32\serport.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\win32\serport.cpp - -$(OUTPUT)\ctb_dll_timer.obj: .\..\src\win32\timer.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\win32\timer.cpp - -$(OUTPUT)\ctb_dll_gpib.obj: .\..\src\gpib.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTB_DLL_CXXFLAGS) .\..\src\gpib.cpp - -$(OUTPUT)\ctbtest_ctbtest.obj: .\..\samples\ctbtest.cpp - $(CXX) /c /nologo /TP /Fo$@ $(CTBTEST_CXXFLAGS) .\..\samples\ctbtest.cpp - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.wat b/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.wat deleted file mode 100644 index 5041ddac36..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/build/makefile.wat +++ /dev/null @@ -1,283 +0,0 @@ -# ========================================================================= -# This makefile was generated by -# Bakefile 0.2.5 (http://www.bakefile.org) -# Do not modify, all changes will be overwritten! -# ========================================================================= - - - -# ------------------------------------------------------------------------- -# These are configurable options: -# ------------------------------------------------------------------------- - -# C++ compiler -CXX = wpp386 - -# Standard flags for C++ -CXXFLAGS = - -# Standard preprocessor flags (common for CC and CXX) -CPPFLAGS = - -# Standard linker flags -LDFLAGS = - -# Set to 1 to build debug version [0,1] -# 0 - Release -# 1 - Debug -DEBUG = 0 - -# -GPIB = 0 - -# -WXDIR = $(%WXWIN) - -# -INSTALLDIR = $(%WXWIN) - - - -# ------------------------------------------------------------------------- -# Do not modify the rest of this file! -# ------------------------------------------------------------------------- - -# Speed up compilation a bit: -!ifdef __LOADDLL__ -! loaddll wcc wccd -! loaddll wccaxp wccdaxp -! loaddll wcc386 wccd386 -! loaddll wpp wppdi86 -! loaddll wppaxp wppdaxp -! loaddll wpp386 wppd386 -! loaddll wlink wlink -! loaddll wlib wlibd -!endif - -# We need these variables in some bakefile-made rules: -WATCOM_CWD = $+ $(%cdrive):$(%cwd) $- - -### Conditionally set variables: ### - -OUTPUT = -!ifeq DEBUG 0 -OUTPUT = release -!endif -!ifeq DEBUG 1 -OUTPUT = debug -!endif -INSTALLDIR = -!ifeq WXDIR -INSTALLDIR = ..\lib -!endif -LIBFLAG = -!ifeq DEBUG 1 -LIBFLAG = d -!endif -GPIBFLAG = -!ifeq GPIB 1 -GPIBFLAG = _gpib -!endif -____GPIBSRC_FILENAMES_OBJECTS = -!ifeq GPIB 1 -____GPIBSRC_FILENAMES_OBJECTS = & - $(OUTPUT)\ctb_lib_gpib.obj -!endif -____GPIBSRC_FILENAMES_1_OBJECTS = -!ifeq GPIB 1 -____GPIBSRC_FILENAMES_1_OBJECTS = & - $(OUTPUT)\ctb_dll_gpib.obj -!endif -____DEBUG = -!ifeq DEBUG 0 -____DEBUG = -dNDEBUG -!endif -!ifeq DEBUG 1 -____DEBUG = -!endif -____DEBUG_0 = -!ifeq DEBUG 0 -____DEBUG_0 = -d0 -!endif -!ifeq DEBUG 1 -____DEBUG_0 = -d2 -!endif -____DEBUG_2 = -!ifeq DEBUG 0 -____DEBUG_2 = -!endif -!ifeq DEBUG 1 -____DEBUG_2 = debug all -!endif -__OPTIMIZE_FLAG = -!ifeq DEBUG 0 -__OPTIMIZE_FLAG = -od -!endif -!ifeq DEBUG 1 -__OPTIMIZE_FLAG = -ot -ox -!endif -__SYSLIB2_p = -!ifeq GPIB 1 -__SYSLIB2_p = gpib32.lib -!endif - -### Variables: ### - -CTB_LIB_CXXFLAGS = $(____DEBUG) $(____DEBUG_0) -bm $(__OPTIMIZE_FLAG) & - -i=..\include $(CPPFLAGS) $(CXXFLAGS) -CTB_LIB_OBJECTS = & - $(OUTPUT)\ctb_lib_fifo.obj & - $(OUTPUT)\ctb_lib_getopt.obj & - $(OUTPUT)\ctb_lib_iobase.obj & - $(OUTPUT)\ctb_lib_portscan.obj & - $(OUTPUT)\ctb_lib_serportx.obj & - $(OUTPUT)\ctb_lib_serport.obj & - $(OUTPUT)\ctb_lib_timer.obj & - $(____GPIBSRC_FILENAMES_OBJECTS) -CTB_DLL_CXXFLAGS = -bd $(____DEBUG) $(____DEBUG_0) -bm $(__OPTIMIZE_FLAG) & - -i=..\include $(CPPFLAGS) $(CXXFLAGS) -CTB_DLL_OBJECTS = & - $(OUTPUT)\ctb_dll_fifo.obj & - $(OUTPUT)\ctb_dll_getopt.obj & - $(OUTPUT)\ctb_dll_iobase.obj & - $(OUTPUT)\ctb_dll_portscan.obj & - $(OUTPUT)\ctb_dll_serportx.obj & - $(OUTPUT)\ctb_dll_serport.obj & - $(OUTPUT)\ctb_dll_timer.obj & - $(____GPIBSRC_FILENAMES_1_OBJECTS) -CTBTEST_CXXFLAGS = $(____DEBUG) $(____DEBUG_0) -dGPIB=$(GPIB) -bm & - $(__OPTIMIZE_FLAG) -i=..\include $(CPPFLAGS) $(CXXFLAGS) -CTBTEST_OBJECTS = & - $(OUTPUT)\ctbtest_ctbtest.obj - - -all : $(OUTPUT) -$(OUTPUT) : - -if not exist $(OUTPUT) mkdir $(OUTPUT) - -### Targets: ### - -all : .SYMBOLIC ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(OUTPUT)\ctbtest.exe tip-win32 - -clean : .SYMBOLIC - -if exist $(OUTPUT)\*.obj del $(OUTPUT)\*.obj - -if exist $(OUTPUT)\*.res del $(OUTPUT)\*.res - -if exist $(OUTPUT)\*.lbc del $(OUTPUT)\*.lbc - -if exist $(OUTPUT)\*.ilk del $(OUTPUT)\*.ilk - -if exist $(OUTPUT)\*.pch del $(OUTPUT)\*.pch - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll - -if exist ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib del ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - -if exist $(OUTPUT)\ctbtest.exe del $(OUTPUT)\ctbtest.exe - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib : $(CTB_LIB_OBJECTS) - @%create $(OUTPUT)\ctb_lib.lbc - @for %i in ($(CTB_LIB_OBJECTS)) do @%append $(OUTPUT)\ctb_lib.lbc +%i - wlib -q -p4096 -n -b $^@ @$(OUTPUT)\ctb_lib.lbc - -..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll : $(CTB_DLL_OBJECTS) - @%create $(OUTPUT)\ctb_dll.lbc - @%append $(OUTPUT)\ctb_dll.lbc option quiet - @%append $(OUTPUT)\ctb_dll.lbc name $^@ - @%append $(OUTPUT)\ctb_dll.lbc option caseexact - @%append $(OUTPUT)\ctb_dll.lbc $(____DEBUG_2) libpath ..\lib $(LDFLAGS) - @for %i in ($(CTB_DLL_OBJECTS)) do @%append $(OUTPUT)\ctb_dll.lbc file %i - @for %i in ( winmm.lib $(__SYSLIB2_p)) do @%append $(OUTPUT)\ctb_dll.lbc library %i - @%append $(OUTPUT)\ctb_dll.lbc - @%append $(OUTPUT)\ctb_dll.lbc system nt_dll - wlink @$(OUTPUT)\ctb_dll.lbc - wlib -q -n -b ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib +$^@ - -$(OUTPUT)\ctbtest.exe : $(CTBTEST_OBJECTS) ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib - @%create $(OUTPUT)\ctbtest.lbc - @%append $(OUTPUT)\ctbtest.lbc option quiet - @%append $(OUTPUT)\ctbtest.lbc name $^@ - @%append $(OUTPUT)\ctbtest.lbc option caseexact - @%append $(OUTPUT)\ctbtest.lbc $(____DEBUG_2) libpath ..\lib $(LDFLAGS) - @for %i in ($(CTBTEST_OBJECTS)) do @%append $(OUTPUT)\ctbtest.lbc file %i - @for %i in ( ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib winmm.lib $(__SYSLIB2_p)) do @%append $(OUTPUT)\ctbtest.lbc library %i - @%append $(OUTPUT)\ctbtest.lbc - @for %i in () do @%append $(OUTPUT)\ctbtest.lbc option stack=%i - wlink @$(OUTPUT)\ctbtest.lbc - -wxinstall : - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.lib $(INSTALLDIR)\lib\watcom_lib - @copy ..\lib\ctb$(LIBFLAG)$(GPIBFLAG)-0.16.dll $(INSTALLDIR)\lib\watcom_lib - - @if not exist $(INSTALLDIR)\include\ctb-0.16\win32 mkdir $(INSTALLDIR)\include\ctb-0.16\win32 - @copy ..\include\ctb-0.16\*.h $(INSTALLDIR)\include\ctb-0.16 - @copy ..\include\ctb-0.16\win32\*.h $(INSTALLDIR)\include\ctb-0.16\win32 - -tip-win32 : - @echo " " - @echo "================================================================" - @echo " The building of ctb is finished. If you have an installed " - @echo " wxWidget package (WXWIN must be defined in the enviroment), " - @echo " you'll now have to run: " - @echo " " - @echo " make DEBUG=$(DEBUG) GPIB=$(GPIB) wxinstall " - @echo " " - @echo " to install the libraries in: " - @echo " $(INSTALLDIR)\lib\watcom_lib " - @echo " and the header files in" - @echo " $(INSTALLDIR)\ctb-0.16" - @echo " " - @echo " If you are using another compiler (Borland, Watcom, mingw,...) " - @echo " take a look in the README in this directory! " - @echo " " - @echo " ctb comes with no guarantees and doesn't claim " - @echo " to be suitable for any purpose. " - @echo "================================================================" - @echo " " - -$(OUTPUT)\ctb_lib_fifo.obj : .AUTODEPEND .\..\src\fifo.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_getopt.obj : .AUTODEPEND .\..\src\getopt.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_iobase.obj : .AUTODEPEND .\..\src\iobase.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_portscan.obj : .AUTODEPEND .\..\src\portscan.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_serportx.obj : .AUTODEPEND .\..\src\serportx.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_serport.obj : .AUTODEPEND .\..\src\win32\serport.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_timer.obj : .AUTODEPEND .\..\src\win32\timer.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_lib_gpib.obj : .AUTODEPEND .\..\src\gpib.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_LIB_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_fifo.obj : .AUTODEPEND .\..\src\fifo.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_getopt.obj : .AUTODEPEND .\..\src\getopt.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_iobase.obj : .AUTODEPEND .\..\src\iobase.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_portscan.obj : .AUTODEPEND .\..\src\portscan.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_serportx.obj : .AUTODEPEND .\..\src\serportx.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_serport.obj : .AUTODEPEND .\..\src\win32\serport.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_timer.obj : .AUTODEPEND .\..\src\win32\timer.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctb_dll_gpib.obj : .AUTODEPEND .\..\src\gpib.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTB_DLL_CXXFLAGS) $< - -$(OUTPUT)\ctbtest_ctbtest.obj : .AUTODEPEND .\..\samples\ctbtest.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(CTBTEST_CXXFLAGS) $< - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/ctb.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/ctb.h deleted file mode 100644 index c71929f2be..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/ctb.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef LIBCTB_CTB_H_INCLUDED_ -#define LIBCTB_CTB_H_INCLUDED_ - -#include "ctb-0.16/fifo.h" -#if ( GPIB ) -# include "ctb-0.16/gpib.h" -#endif -#include "ctb-0.16/getopt.h" -#include "ctb-0.16/iobase.h" -//#include "ctb-0.16/kbhit.h" -#include "ctb-0.16/portscan.h" -#include "ctb-0.16/serport.h" -#include "ctb-0.16/serportx.h" -#include "ctb-0.16/timer.h" - -/*! - \mainpage ctb overview - - The ctb (communication toolbox) library was realized, to simplify the - communication with other instruments throughout the serial com ports - (at first). To make my life easier, it should works with Linux and - all win32 plattforms (excepted windows 3.1, which is a only 16bit OS) - because I develope my applications for both plattforms).\n - Some times later GPIB support was added to make ctb an integrated part - for the extensive test and calibration system of a company I worked - these days.\n - The main goal of the library was a non-blocked communication to avoid - frozen GUIs waiting for data which in some conditions never arrives. - - On the base ctb defines an abstract class IOBase, which must be - derivate for several interfaces (at now this was done for the - RS232 comports and GPIB IEEE488 interface). - - This leads to another feature: Because all classes depends on one - super class, you have just open your wanted interface and don't - worry about it's special typ later. This is like the 'Virtual - Instrument' featured by Nation Instruments LabView. - - Last not least: ctb provides one written code for Linux and Windows - (compiles well with GNU G++ and VC++). Without any dependences (execept - for a standard C++ compilier) ctb runs also in small enviroments like - embedded systems and doesn't need any graphic stuff for use. - - ctb is composed of five parts: - - - ctb::IOBase class - - ctb::SerialPort class - - ctb::GpibDevice class - - ctb::Timer class - - ctb::Fifo class - - \section IOBase IOBase class - - An abstract class for different interfaces. The idea behind this: - Similar to the virtual file system this class defines a lot of - preset member functions, which the derivate classes must be - overload.\n - In the main thing these are: open a interface (such as RS232), - reading and writing non blocked through the interface and at - last, close it.\n - For special interface settings the method ioctl was defined. - (control interface). ioctl covers some interface dependent - settings like switch on/off the RS232 status lines and must also - be defined from each derivated class. - - - \section SerialPort SerialPort class - - The class for the serial ports is named as - ctb::SerialPort. SerialPort is a wrapper for non blocked reading and - writing. This is easy under linux, but with windows a lot more - tricky. SerialPort is as simple as possible. It doesn't create any - gui events or signals, so it works also standalone. It's also not a - device driver, means, you must call the read method, if you look for - receiving data. - - You can write any desired data with any length (length type is - size_t, I think, on win32 and linux this is a 32Bit integer) and - SerialPort returns the really writen data length, also you can read - a lot of data and SerialPort returns the really received data count. - - Both, read and write returns immediatelly. Using these, the program - never blocks. Also IOBase implements a blocked read and write. You can - use these functions, if you want a definitiv count of data and never - accept less than this. Because there is a difficulty, when the - communication is interrupted or death, both blocked functions get a - timeout flag to returns after a given time interval. The timeouts - will be handled with the second timer class. - - As an additional benefit ctb features also 9 Bit transmission (with - take advantage of the parity bit), non-standard baudrates (depending - on your hardware but not on ctb) and all parity eventualities - including static parity settings like Mark and Space. - - \section GpibDevice GpibDevice class - - Named as ctb::GpibDevice. In the philosophy of the SerialPort class - GpibDevice also supports non-blocking communication. You can instant - as many GpibDevice objects as you need for instance to communicate - with a lot of different bus participants in a typical GPIB enviroment. - GPIB support was tested with PCI cards and USB adapter from Nation - Instrument and Keithley. - - \section Timer Timer class - - The idea of the ctb::Timer class is to base on the Unix C alarm - function. You create a Timer with a given alarm time and a adress of - flag, which the timer must set after the time is over. - - Because the alarm function cannot used more than once in the same - process (under windows I don't know a similar function), every timer - instance will be a separate thread after starting it. So you can start - a timer and continue in your program, make a lot of things and test - the flag whenever you want this. (For example, you read/write a - given count of data). - - \note - I think, it's a better style, to request a given count of data in - 100ms (for example) and trap the situation, if there are not enough - data after this time. And not do this for every byte! - - \section Fifo Fifo cass - Provides a simple thread safe fifo to realize a fast and simple - communication pipe between two threads (and was used also as a put - back mechanism for the wxIOBase and it's derivated classes).\n - ctb::Fifo tackles the concurrently access from different threads with an - internal temporary pointer asignment which was atomic. From there no - mutex or semaphore is involved and lead to a fast access. - - Please note:\n - The thread safeness is limited to the put/get write/read methods but - which should be sufficent for a fifo. - - - \latexonly \newpage \endlatexonly - - */ - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/fifo.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/fifo.h deleted file mode 100644 index d17079d4a2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/fifo.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef __LIBCTB_FIFO_H_INCLUDED_ -#define __LIBCTB_FIFO_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: fifo.h -// Purpose: -// Author: Joachim Buermann, Michael Hungershausen -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include - -/** - \file fifo.h -*/ - -namespace ctb { - -/*! - \class Fifo - A simple thread safe fifo to realize a put back mechanism for the - wxIOBase and it's derivated classes. -*/ - class Fifo - { - protected: - /*! the size of the fifo */ - size_t m_size; - /*! the start of the internal fifo buffer */ - char* m_begin; - /*! - the end of the internal fifo buffer (m_end marks the first - invalid byte AFTER the internal buffer) - */ - char* m_end; - /*! the current read position */ - char* m_rdptr; - /*! the current write position */ - char* m_wrptr; - public: - /*! - \brief the constructor initialize a fifo with the given size. - \param size size of the fifo - */ - Fifo(size_t size); - /*! - \brief the destructor destroys all internal memory. - */ - virtual ~Fifo(); - /*! - \brief clear all internal memory and set the read and write - pointers to the start of the internal memory. - \Note This function is not thread safe! Don't use it, if another - thread takes access to the fifo instance. Use a looping get() or - read() call instead of this. - */ - virtual void clear(); - /*! - \brief fetch the next available byte from the fifo. - \param ch points to a charater to store the result - \return 1 if successful, 0 otherwise - */ - virtual int get(char* ch); - /*! - \brief query the fifo for it's available bytes. - \return count of readable bytes, storing in the fifo - */ - size_t items(); - /*! - \brief put a character into the fifo. - \param ch the character to put in - \return 1 if successful, 0 otherwise - */ - virtual int put(char ch); - /*! - \brief read a given count of bytes out of the fifo. - \param data memory to store the readed data - \param count number of bytes to read - \return On success, the number of bytes read are returned, - 0 otherwise - */ - virtual int read(char* data,int count); - /*! - \brief write a given count of bytes into the fifo. - \param data start of the data to write - \param count number of bytes to write - \return On success, the number of bytes written are returned, - 0 otherwise - */ - virtual int write(char* data,int count); - }; - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/getopt.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/getopt.h deleted file mode 100644 index 2efd341889..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/getopt.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIBCTB_GETOPT_H_INCLUDED_ -#define LIBCTB_GETOPT_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: getopt.h -// Purpose: Simple wrapper file -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#if defined (WIN32) -# include "win32/getopt.h" -#else -# include -#endif - -#endif -// __WX_GETOPT_H diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/gpib.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/gpib.h deleted file mode 100644 index 1d360a8c49..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/gpib.h +++ /dev/null @@ -1,378 +0,0 @@ -#ifndef LIBCTB_GPIB_H_INCLUDED_ -#define LIBCTB_GPIB_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: gpibx.h -// Purpose: base class for gpib devices -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "ctb-0.16/iobase.h" - -namespace ctb { - -/*! - \file gpib.h -*/ - - /*! defines the os specific name for the first gpib controller */ - extern const char* GPIB1; - - /*! defines the os specific name for the second gpib controller */ - extern const char* GPIB2; - - /*! - \enum GpibTimeout - NI488.2 API defines the following valid timeouts. - */ - enum GpibTimeout - { - /// no timeout (infinity) - GpibTimeoutNone = 0, - /// 10 micro seconds - GpibTimeout10us, - /// 30 micro seconds - GpibTimeout30us, - /// 100 micro seconds - GpibTimeout100us, - /// 300 micro seconds - GpibTimeout300us, - /// 1 milli second - GpibTimeout1ms, - /// 3 milli seconds - GpibTimeout3ms, - /// 10 milli seconds - GpibTimeout10ms, - /// 30 milli seconds - GpibTimeout30ms, - /// 0.1 seconds - GpibTimeout100ms, - /// 0.3 seconds - GpibTimeout300ms, - /// 1 second - GpibTimeout1s, - /// 3 seconds - GpibTimeout3s, - /// 10 seconds - GpibTimeout10s, - /// 30 seconds - GpibTimeout30s, - /// 100 seconds - GpibTimeout100s, - /// 300 seconds (5 minutes) - GpibTimeout300s, - /// 1000 seconds - GpibTimeout1000s - }; - - /*! - \struct Gpib_DCS - - The device control struct for the gpib communication class. - This struct should be used, if you refer advanced parameter. - */ - struct Gpib_DCS - { - /*! primary address of GPIB device */ - int m_address1; - /*! secondary address of GPIB device */ - int m_address2; - /*! I/O timeout */ - GpibTimeout m_timeout; - /*! EOT enable */ - bool m_eot; - /*! - Defines the EOS character. - Note! Defining an EOS byte does not cause the driver to - automatically send that byte at the end of write I/O - operations. The application is responsible for placing the - EOS byte at the end of the data strings that it defines. - (National Instruments NI-488.2M Function Reference Manual) - */ - unsigned char m_eosChar; - /*! - Set the EOS mode (handling).m_eosMode may be a combination - of bits ORed together. The following bits can be used: - 0x04: Terminate read when EOS is detected. - 0x08: Set EOI (End or identify line) with EOS on write function - 0x10: Compare all 8 bits of EOS byte rather than low 7 bits - (all read and write functions). - */ - unsigned char m_eosMode; - /*! buffer for internal use */ - char m_buf[32]; - /*! to avoid memory leak warnings generated by swig */ - ~Gpib_DCS() {}; - /*! - \brief the constructor initiate the device control struct with - the common useful values and set the internal timeout for the - GPIB controller to 1ms to avoid (or better reduce) blocking - */ - Gpib_DCS() { - /*! set default device address to 1 */ - m_address1 = 1; - m_address2 = 0; - /*! - set the timeout to a short value to avoid blocking - (default are 1msec) - */ - m_timeout = GpibTimeout1ms; - m_eot = true; - /*! EOS character, see above! */ - m_eosChar = 0;//'\n'; - /*! EOS mode, see above! */ - m_eosMode = 0; - }; - /*! - \brief returns the internal parameters in a more human readable - string format like 'Adr: (1,0) to:1ms'. - \return the settings as a null terminated string - */ - char* GetSettings(); - }; - -/*! - \enum GpibIoctls - - The following Ioctl calls are only valid for the GpibDevice class. -*/ - enum GpibIoctls { - /*! - Set the adress of the via gpib connected device. - */ - CTB_GPIB_SETADR = CTB_GPIB, - /*! - Get the serial poll byte - */ - CTB_GPIB_GETRSP, - /*! - Get the GPIB status - */ - CTB_GPIB_GETSTA, - /*! - Get the last GPIB error number - */ - CTB_GPIB_GETERR, - /*! - Get the GPIB line status (hardware control lines) as an - integer. The lowest 8 bits correspond to the current state - of the lines. - */ - CTB_GPIB_GETLINES, - /*! - Set the GPIB specific timeout - */ - CTB_GPIB_SETTIMEOUT, - /*! - Forces the specified device to go to local program mode - */ - CTB_GPIB_GTL, - /*! - This routine can only be used if the specified GPIB - Interface Board is the System Controller. - Remember that even though the REN line is asserted, - the device(s) will not be put into remote state until is - addressed to listen by the Active Controller - */ - CTB_GPIB_REN, - /*! - The command asserts the GPIB interface clear (IFC) line for - ast least 100us if the GPIB board is the system controller. - This initializes the GPIB and makes the interface CIC and - active controller with ATN asserted. - Note! The IFC signal resets only the GPIB interface functions - of the bus devices and not the internal device functions. - For a device reset you should use the CTB_RESET command above. - */ - CTB_GPIB_RESET_BUS, - /*! - Configure the end-of-string (EOS) termination character. - Note! Defining an EOS byte does not cause the driver to - automatically send that byte at the end of write I/O - operations. The application is responsible for placing the - EOS byte at the end of the data strings that it defines. - (National Instruments NI-488.2M Function Reference Manual) - */ - CTB_GPIB_SET_EOS_CHAR, - /*! - Get the internal EOS termination character (see above). - */ - CTB_GPIB_GET_EOS_CHAR, - /*! - Set the EOS mode (handling).m_eosMode may be a combination - of bits ORed together. The following bits can be used: - 0x04: Terminate read when EOS is detected. - 0x08: Set EOI (End or identify line) with EOS on write function - 0x10: Compare all 8 bits of EOS byte rather than low 7 bits - (all read and write functions). - */ - CTB_GPIB_SET_EOS_MODE, - /*! - Get the internal EOS mode (see above). - */ - CTB_GPIB_GET_EOS_MODE, - }; - -/*! - \class GpibDevice - GpibDevice is the basic class for communication via the GPIB bus. -*/ - class GpibDevice : public IOBase - { - protected: - /*! - \brief - the internal board identifier, 0 for the first gpib controller, - 1 for the second one - */ - int m_board; - /*! - \brief - the file descriptor of the connected gpib device - */ - int m_hd; - /*! - \brief - contains the internal conditions of the GPIB communication like - GPIB error, timeout and so on... - */ - int m_state; - /*! the internal GPIB error number */ - int m_error; - /*! the count of data read or written */ - int m_count; - /*! - \brief contains the internal settings of the GPIB connection like - address, timeout, end of string character and so one... - */ - Gpib_DCS m_dcs; - int CloseDevice(); - /*! - \brief returns a short notation or more detail description of - the given GPIB error number. - \param error the occured GPIB error - \param detailed true for a more detailed description, false - otherwise - \return a null terminated string with the short or detailed - error message. - */ - virtual const char* GetErrorString(int error,bool detailed); - /*! - Open the interface (internally to request a file descriptor for the - given interface). The second parameter is a undefined pointer of a - Gpib_DCS data struct. - \param devname the name of the GPIB device, GPIB1 means the first - GPIB controller, GPIB2 the second (if available). - \param dcs untyped pointer of advanced device parameters, - \sa struct Gpib_DCS (data struct for the gpib device) - \return zero on success, otherwise -1 - */ - int OpenDevice(const char* devname, void* dcs); - public: - GpibDevice() { - m_board = -1; - m_hd = -1; - m_state = m_count = m_error = 0; - }; - virtual ~GpibDevice() {Close();}; - /*! - \brief returns the name of the class instance. You find this useful, - if you handle different devices like a serial port or a gpib device - via a IOBase pointer. - \return name of the class. - */ - const char* ClassName() {return "ctb::GpibDevice";}; - /*! - \brief returns a more detail description of the given error - number. - \param error the occured error number - \return null terminated string with the error description - */ - virtual const char* GetErrorDescription(int error) { - return GetErrorString(error,true); - }; - /*! - \brief returns a short notation like 'EABO' of the given error - number. - \param error the occured error number - \return null terminated string with the short error notation - */ - virtual const char* GetErrorNotation(int error) { - return GetErrorString(error,false); - }; - /*! - \brief request the current settings of the connected gpib device - as a null terminated string. - \return the settings as a string like 'Adr: (1,0) to:1ms' - */ - virtual char* GetSettingsAsString() { - return m_dcs.GetSettings(); - }; - /// This is only for internal usage - int Ibrd(char* buf,size_t len); - /// This is only for internal usage - int Ibwrt(char* buf,size_t len); - /*! - \brief Many operating characteristics are only possible for - special devices. To avoid the need of a lot of different functions - and to give the user a uniform interface, all this special - operating instructions will covered by one Ioctl methode (like - the linux ioctl call). - The Ioctl command (cmd) has encoded in it whether the argument - is an in parameter or out parameter, and the size of the - argument args in bytes. Macros and defines used in specifying an - ioctl request are located in iobase.h and the header file for - the derivated device (for example in gpib.h). - \param cmd one of GpibIoctls specify the ioctl request. - \param args is a typeless pointer to a memory location, where - Ioctl reads the request arguments or write the results. - Please note, that an invalid memory location or size involving - a buffer overflow or segmention fault! - */ - virtual int Ioctl(int cmd,void* args); - /*! - Returns the current state of the device. - \return 1 if device is valid and open, otherwise 0 - */ - int IsOpen() { - return m_hd >= 0; - }; - - /*! - \brief Opens a GPIB device in a user likely way. Insteed of - using the Device Control Struct just input your parameter in a - more intuitive manner. - \param devname the name of the GPIB controler like GPIB1 or GPIB2 - \param address the address of the connected device (1...31) - \return the new file descriptor, or -1 if an error occurred - */ - int Open( const char* devname, int address ); - - // Open overrides and hides the IOBase::Open( const char* - // devname, void* dcs ) of the base class! So bring it into scope - // again! - using IOBase::Open; - - int Read(char* buf,size_t len); - - int Write(char* buf,size_t len); - - /*! - \brief FindListener returns all listening devices connected to - the GPIB bus of the given board. - This function is not member of the GPIB class, becauce it - should do it's job before you open any GPIB connection. - \param board the board nummber. Default is the first board (=0). - Valid board numbers are 0 and 1. - \return -1 if an error occurred, otherwise a setting bit for - each listener address. Bit0 is always 0 (address 0 isn't valid, - Bit1 means address 1, Bit2 address 2 and so on... - */ - static int FindListeners(int board = 0); - }; - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/iobase.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/iobase.h deleted file mode 100644 index eda03b314f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/iobase.h +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef LIBCTB_IOBASE_H_INCLUDED_ -#define LIBCTB_IOBASE_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: iobase.h -// Purpose: io basic class -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "ctb-0.16/fifo.h" -#include - -/** - \file iobase.h -*/ - -namespace ctb { - - enum { - - CTB_COMMON = 0x0000, - CTB_SERIAL = 0x0100, - CTB_GPIB = 0x0200, - CTB_TIMEOUT_INFINITY = 0xFFFFFFFF - }; - -// const unsigned int wxTIMEOUT_INFINITY = 0xFFFFFFFF; - -/*! - \enum IOBaseIoctls - - Defines the ioctl calls for derivated classes. The following Ioctl - calls are valid for all from wxIOBase derivated classes. -*/ - enum IOBaseIoctls { - /*! - Reset the connected device. For a serial (RS232) connection, - a break is send. For GPIB the IFC (Interface Clear) line is - set. - */ - CTB_RESET = CTB_COMMON - }; - -/*! - \class IOBase - An abstract class for different interfaces. The idea behind this: - Similar to the virtual file system this class defines a lot of - preset member functions, which the derivate classes must be - overload. - In the main thing these are: open a interface (such as RS232), - reading and writing non blocked through the interface and at - last, close it. - For special interface settings the method ioctl was defined. - (control interface). ioctl covers some interface dependent - settings like switch on/off the RS232 status lines and must also - be defined from each derivated class. -*/ - - class IOBase - { - protected: - /*! - \brief internal fifo (first in, first out queue) to put back - already readed bytes into the reading stream. After put back a single - byte or sequence of characters, you can read them again with the - next Read call. - */ - Fifo* m_fifo; - enum { - /// fifosize of the putback fifo - fifoSize = 256 - }; - /*! - Close the interface (internally the file descriptor, which was - connected with the interface). - \return zero on success, otherwise -1. - */ - virtual int CloseDevice() = 0; - /*! - Open the interface (internally to request a file descriptor for the - given interface). The second parameter is a undefined pointer of a - device dependent data struct. It must be undefined, because different - devices have different settings. A serial device like the com ports - points here to a data struct, includes information like baudrate, - parity, count of stopbits and wordlen and so on. Another devices - (for example a IEEE) needs a adress and EOS (end of string character) - and don't use baudrate or parity. - \param devname the name of the device, presents the given interface. - Under windows for example COM1, under Linux /dev/cua0. Use wxCOMn to - avoid plattform depended code (n is the serial port number, beginning - with 1). - \param dcs untyped pointer of advanced device parameters, - \sa struct dcs_devCUA (data struct for the serail com ports) - \return zero on success, otherwise -1 - */ - virtual int OpenDevice(const char* devname, void* dcs = 0L) = 0; - public: - /*! - Default constructor - */ - IOBase() { - m_fifo = new Fifo(fifoSize); - }; - - /*! - Default destructor - */ - virtual ~IOBase() { - delete m_fifo; - }; - /*! - \brief A little helper function to detect the class name - \return the name of the class - */ - virtual const char* ClassName() {return "ctb::IOBase";}; - /*! - Closed the interface. Internally it calls the CloseDevice() - method, which must be defined in the derivated class. - \return zero on success, or -1 if an error occurred. - */ - int Close() {return CloseDevice();}; - - /*! - In this method we can do all things, which are different - between the discrete interfaces. The method is similar to the - C ioctl function. We take a command number and a integer - pointer as command parameter. - An example for this is the reset of a connection between a PC - and one ore more other instruments. On serial (RS232) connections - mostly a break will be send, GPIB on the other hand defines a - special line on the GPIB bus, to reset all connected devices. - If you only want to reset your connection, you should use the - Ioctl methode for doing this, independent of the real type of - the connection. - \param cmd a command identifier, (under Posix such as TIOCMBIS - for RS232 interfaces), IOBaseIoctls - \param args typeless parameter pointer for the command above. - \return zero on success, or -1 if an error occurred. - */ - virtual int Ioctl(int cmd,void* args) {return -1;}; - - /*! - Returns the current state of the device. - \return 1 if device is valid and open, otherwise 0 - */ - virtual int IsOpen() = 0; - - /*! - \param devname name of the interface, we want to open - \param dcs a untyped pointer to a device control struct. If - he is NULL, the default device parameter will be used. - \return the new file descriptor, or -1 if an error occurred - - The pointer dcs will be used for special device dependent - settings. Because this is very specific, the struct or - destination of the pointer will be defined by every device - itself. (For example: a serial device class should refer - things like parity, word length and count of stop bits, - a IEEE class adress and EOS character). - */ - int Open(const char* devname,void* dcs=0L) { - return OpenDevice(devname,dcs); - }; - - /*! - \brief In some circumstances you want to put back a already - readed byte (for instance, you have overreaded it and like to - parse the recieving bytes again). - The internal fifo stores fifoSize characters until you - have to read again. - \param ch the character to put back in the input stream - \return 1, if successful, otherwise 0 - */ - int PutBack(char ch) { - return m_fifo->put(ch); - }; - - /*! - Read attempt to read len bytes from the interface into the buffer - starting with buf. Read never blocks. If there are no bytes for - reading, Read returns zero otherwise the count of bytes been readed. - \param buf starting adress of the buffer - \param len count of bytes, we want to read - \return -1 on fails, otherwise the count of readed bytes - */ - virtual int Read(char* buf,size_t len) = 0; - - /*! - \brief - ReadUntilEos read bytes from the interface until the EOS string - was received or a timeout occurs. - ReadUntilEos returns the count of bytes been readed. The received - bytes are stored on the heap point by the readbuf pointer and - must delete by the caller. - \param readbuf points to the start of the readed bytes. You must - delete them, also if you received no byte. - \param readedBytes A pointer to the variable that receives the number - of bytes read. - \param eosString is the null terminated end of string sequence. - Default is the linefeed character. - \param timeout_in_ms the function returns after this time, also - if no eos occured (default is 1s). - \param quota defines a character between those an EOS doesn't - terminate the string - \return 1 on sucess (the operation ends successfull without a timeout), - 0 if a timeout occurred and -1 otherwise - */ - virtual int ReadUntilEOS(char*& readbuf, - size_t* readedBytes, - char* eosString = "\n", - long timeout_in_ms = 1000L, - char quota = 0); - - /*! - \brief - readv() attempts to read up to len bytes from the interface - into the buffer starting at buf. - readv() is blocked till len bytes are readed or the given - timeout in milliseconds was reached. - \param buf starting address of the buffer - \param len count bytes, we want to read - \param timeout_in_ms in milliseconds. If you don't want any timeout, - you give the wxTIMEOUT_INFINITY here. - But think of it: In this case, this function never returns - if there a not enough bytes to read. - \return the number of data bytes successfully read - */ - int Readv(char* buf,size_t len,unsigned int timeout_in_ms); - - /*! - \brief - readv() attempts to read up to len bytes from the interface - into the buffer starting at buf. - readv() is blocked till len bytes are readed or the timeout_flag - points on a int greater then zero. - \param buf starting adress of the buffer - \param len count bytes, we want to read - \param timeout_flag a pointer to an integer. If you don't want - any timeout, you given a null pointer here. - But think of it: In this case, this function comes never - back, if there a not enough bytes to read. - \param nice if true go to sleep for one ms (reduce CPU last), - if there is no byte available (default is false) - */ - int Readv(char* buf,size_t len,int* timeout_flag,bool nice=false); - - /*! - Write writes up to len bytes from the buffer starting with buf - into the interface. - \param buf start adress of the buffer - \param len count of bytes, we want to write - \return on success, the number of bytes written are returned - (zero indicates nothing was written). On error, -1 is returned. - */ - virtual int Write(char* buf,size_t len) = 0; - - /*! - Writev() writes up to len bytes to the interface from the buffer, - starting at buf. - Also Writev() blocks till all bytes are written or the given - timeout in milliseconds was reached. - \param buf starting address of the buffer - \param len count bytes, we want to write - \param timeout_in_ms timeout in milliseconds. If you give - wxTIMEOUT_INFINITY here, the function blocks, till all data was - written. - \return the number of data bytes successfully written. - */ - int Writev(char* buf,size_t len,unsigned int timeout_in_ms); - - /*! - Writev() writes up to len bytes to the interface from the buffer, - starting at buf. - Also Writev() blocks till all bytes are written or the timeout_flag - points to an integer greater then zero. - \param buf starting adress of the buffer - \param len count bytes, we want to write - \param timeout_flag a pointer to an integer. You also can give a null - pointer here. This blocks, til all data is writen. - \param nice if true go to sleep for one ms (reduce CPU last), - if there is no byte available (default is false) - */ - int Writev(char* buf,size_t len,int* timeout_flag,bool nice = false); - - }; - -} // namespace ctb - -#endif - - - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/kbhit.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/kbhit.h deleted file mode 100644 index 2a0545439c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/kbhit.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LIBCTB_KBHIT_H_INCLUDED_ -#define LIBCTB_KBHIT_H_INCLUDED_ - -namespace ctb { - - char GetKey(); - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h deleted file mode 100644 index d88528bd25..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef LIBCTB_LINUX_SERPORT_H_INCLUDED_ -#define LIBCTB_LINUX_SERPORT_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: linux/serport.h -// Purpose: -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "ctb-0.16/serportx.h" -#include -#include - -namespace ctb { - -/*! - \class SerialPort - - \brief the linux version -*/ - class SerialPort : public SerialPort_x - { - protected: - /*! - \brief under Linux, the serial ports are normal file descriptor - */ - int fd; - /*! - \brief Linux defines this struct termios for controling asynchronous - communication. t covered the active settings, save_t the original - settings. - */ - struct termios t, save_t; - - /*! - \brief The Linux serial driver summing all breaks, framings, overruns - and parity errors for each port during system runtime. Because we only - need the errors during a active connection, we must save the actual - error numbers in this separate structurs. - */ - struct serial_icounter_struct save_info, last_info; - - /*! - \brief adaptor member function, to convert the plattform independent - type wxBaud into a linux conform value. - \param baud the baudrate as wxBaud type - \return speed_t linux specific data type, defined in termios.h - */ - speed_t AdaptBaudrate( int baud ); - - int CloseDevice(); - int OpenDevice(const char* devname, void* dcs); - - /*! - \brief internal member function to set an unusal (non-standard) - baudrate. Called by SetBaudrate. - */ - int SetBaudrateAny( int baudrate ); - - /*! - \brief internal member function to set a standard baudrate. - Called by SetBaudrate. - */ - int SetBaudrateStandard( int baudrate ); - - public: - SerialPort(); - - ~SerialPort(); - - int ChangeLineState( SerialLineState flags ); - - int ClrLineState( SerialLineState flags ); - - int GetLineState(); - int Ioctl(int cmd,void* args); - int IsOpen(); - int Read(char* buf,size_t len); - int SendBreak(int duration); - - int SetBaudrate( int baudrate ); - - int SetParityBit( bool parity ); - - int SetLineState( SerialLineState flags ); - - int Write(char* buf,size_t len); - }; - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/timer.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/timer.h deleted file mode 100644 index 7cc1a51e01..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/timer.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef LIBCTB_LINUX_TIMER_H_INCLUDED_ -#define LIBCTB_LINUX_TIMER_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: linux/timer.h -// Purpose: -// Author: Joachim Buermann -// Id: $Id: timer.h,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -/** - \file timer.h -*/ - -#include - -namespace ctb { - -/*! - \brief A data struct, using from class timer. -*/ - struct timer_control - { - /*! - under linux, we used usec internally - */ - unsigned int usecs; - /*! - covers the adress of the exitflag - */ - int *exitflag; - /*! - covers the adress of the exit function. NULL, if - there was no exit function. - */ - void* (*exitfnc)(void*); - }; - -/*! - \class Timer - \brief A thread based timer class for handling timeouts in - an easier way. - - On starting every timer instance will create it's own thread. - The thread makes simply nothing, until it's given time is over. - After that, he set a variable, refer by it's adress to one - and exit. - - There are a lot of situations, which the timer class must handle. - The timer instance leaves his valid range (for example, the - timer instance is local inside a function, and the function fished) - BEFORE the thread was ending. In this case, the destructor must - terminate the thread in a correct way. (This is very different - between the OS. threads are a system resource like file descriptors - and must be deallocated after using it). - - The thread should be asynchronously stopped. Means, under all - circumstance, it must be possible, to finish the timer and start - it again. - - Several timer instance can be used simultanously. -*/ - class Timer - { - protected: - /*! - control covers the time interval, the adress - of the exitflag, and if not null, a function, which will - be called on the end. - */ - timer_control control; - /*! - stopped will be set by calling the stop() method. - Internaly the timer thread steadily tests the state of - this variable. If stopped not zero, the thread will be - finished. - */ - int stopped; - /*! - under linux we use the pthread library. tid covers the - identifier for a separate threads. - */ - pthread_t tid; - /*! - here we store the time interval, whilst the timer run. - This is waste!!! - */ - unsigned int timer_secs; - - public: - /*! - The constructor creates an timer object with the given - properties. The timer at this moment is not started. This - will be done with the start() member function. - \param msec time interval after that the the variable - pointed by exitflag is setting to one. - \param exitflag the adress of an integer, which was set - to one after the given time interval. - \warning The integer variable shouldn't leave it's valid - range, before the timer was finished. So never take a - local variable. - \param exitfnc A function, which was called after msec. - If you don't want this, refer a NULL pointer. - */ - Timer(unsigned int msec,int* exitflag,void*(*exitfnc)(void*)); - /*! - the destructor. If his was called (for example by leaving the - valid range of the timer object), the timer thread automaticaly - will finished. The exitflag wouldn't be set, also the exitfnc - wouldn't be called. - */ - ~Timer(); - /*! - starts the timer. But now a thread will created and started. - After this, the timer thread will be running until he was stopped - by calling stop() or reached his given time interval. - */ - int start(); - /*! - stops the timer and canceled the timer thread. After timer::stop() a new - start() will started the timer from beginning. - */ - int stop(); - }; - -/*! - \brief sleepms - A plattform independent function, to go to sleep for the given - time interval. - \param ms time interval in milli seconds -*/ - void sleepms(unsigned int ms); - -} // namespace ctb - -#endif - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/portscan.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/portscan.h deleted file mode 100644 index 92c4ba11d6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/portscan.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LIBCTB_PORTSCAN_H_INCLUDED_ -#define LIBCTB_PORTSCAN_H_INCLUDED_ - -#include -#include - -/** - \file portscan.h -*/ - -namespace ctb { - - /*! - \brief returns all available COM ports as an array of strings. - \param result stores the available COM ports - \param checkInUse return only ports which are available AND - unused (default) - \return true if successful, false otherwise - */ - bool GetAvailablePorts( std::vector& result, - bool checkInUse = true ); - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serport.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serport.h deleted file mode 100644 index 9488753d4b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serport.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LIBCTB_SERPORT_H_INCLUDED_ -#define LIBCTB_SERPORT_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: serport.h -// Purpose: simple wrapper file -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#if defined (WIN32) -# include "ctb-0.16/win32/serport.h" -#else -# include "ctb-0.16/linux/serport.h" -#endif - -#endif -// __SERPORT_BASE_H - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h deleted file mode 100644 index 4d29bb4ccc..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h +++ /dev/null @@ -1,451 +0,0 @@ -#ifndef LIBCTB_SERPORTX_H_INCLUDED_ -#define LIBCTB_SERPORTX_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: serportx.h -// Purpose: -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include -#include -#include "ctb-0.16/iobase.h" - -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -/** - \file serportx.h -*/ - -/*! - \def SERIALPORT_NAME_LEN - defines the maximum length of the os depending serial port names -*/ -#define SERIALPORT_NAME_LEN 32 - -namespace ctb { - - /*! specifices the first serial port */ - extern const char* COM1; - /*! specifies the second serial port */ - extern const char* COM2; - /*! specifies the third serial port */ - extern const char* COM3; - /*! specifies the fourth serial port */ - extern const char* COM4; - /*! specifies the fifth serial port */ - extern const char* COM5; - /*! specifies the sixth serial port */ - extern const char* COM6; - /*! specifies the seventh serial port */ - extern const char* COM7; - /*! specifies the eighth serial port */ - extern const char* COM8; - /*! specifies the ninth serial port */ - extern const char* COM9; - /*! specifies the tenth serial port */ - extern const char* COM10; - /*! specifies the eleventh serial port */ - extern const char* COM11; - /*! specifies the twelfth serial port */ - extern const char* COM12; - /*! specifies the thriteenth serial port */ - extern const char* COM13; - /*! specifies the fourteenth serial port */ - extern const char* COM14; - /*! specifies the fiveteenth serial port */ - extern const char* COM15; - /*! specifies the sixteenth serial port */ - extern const char* COM16; - /*! specifies the seventeenth serial port */ - extern const char* COM17; - /*! specifies the eighteenth serial port */ - extern const char* COM18; - /*! specifies the nineteenth serial port */ - extern const char* COM19; - /*! specifies the twentieth serial port */ - extern const char* COM20; - - /*! - \enum Parity - - \brief Defines the different modes of parity checking. Under - Linux, the struct termios will be set to provide the wanted - behaviour. - */ - enum Parity - { - /*! no parity check */ - ParityNone, - /*! odd parity check */ - ParityOdd, - /*! even parity check */ - ParityEven, - /*! mark (not implemented yet) */ - ParityMark, - /*! space (not implemented yet) */ - ParitySpace - }; - - /*! - \enum SerialLineState - - Defines the different modem control lines. The value for - each item are defined in /usr/include/bits/ioctl-types.h. - This is the linux definition. The window version translate - each item in it's own value. - modem lines defined in ioctl-types.h - \code - #define TIOCM_LE 0x001 - #define TIOCM_DTR 0x002 - #define TIOCM_RTS 0x004 - #define TIOCM_ST 0x008 - #define TIOCM_SR 0x010 - #define TIOCM_CTS 0x020 - #define TIOCM_CAR 0x040 - #define TIOCM_RNG 0x080 - #define TIOCM_DSR 0x100 - #define TIOCM_CD TIOCM_CAR - #define TIOCM_RI TIOCM_RNG - \endcode - */ - enum SerialLineState - { - /*! Data Carrier Detect (read only) */ - LinestateDcd = 0x040, - /*! Clear To Send (read only) */ - LinestateCts = 0x020, - /*! Data Set Ready (read only) */ - LinestateDsr = 0x100, - /*! Data Terminal Ready (write only) */ - LinestateDtr = 0x002, - /*! Ring Detect (read only) */ - LinestateRing = 0x080, - /*! Request To Send (write only) */ - LinestateRts = 0x004, - /*! no active line state, use this for clear */ - LinestateNull = 0x000 - }; - - /*! - \struct SerialPort_DCS - - The device control struct for the serial communication class. - This struct should be used, if you refer advanced parameter. - */ - struct SerialPort_DCS - { - /*! the baudrate */ - int baud; - /*! the parity */ - Parity parity; - /*! the wordlen */ - unsigned char wordlen; - /*! count of stopbits */ - unsigned char stopbits; - /*! rtscts flow control */ - bool rtscts; - /*! XON/XOFF flow control */ - bool xonxoff; - /*! buffer for internal use */ - char buf[16]; - SerialPort_DCS() { - baud = 38400; - parity = ParityNone; - wordlen = 8; - stopbits = 1; - rtscts = false; - xonxoff = false; - }; - // to avoid memory leak warnings generated by swig - ~SerialPort_DCS() {}; - /*! - \brief returns the internal settings of the DCS as a human - readable string like '8N1 115200'. - \return the internal settings as null terminated string - */ - char* GetSettings() { - const char ac[5] = {'N','O','E','M','S'}; - memset(buf,0,sizeof(buf)); - snprintf(buf,sizeof(buf)-1,"%i%c%i %i", - wordlen, - ac[parity], - stopbits, - baud); - return buf; - }; - }; - -/*! - \struct SerialPort_EINFO - - The internal communication error struct. It contains the number - of each error (break, framing, overrun and parity) since opening - the serial port. Each error number will be cleared if the open - methode was called. -*/ - struct SerialPort_EINFO - { - /*! number of breaks */ - int brk; - /*! number of framing errors */ - int frame; - /*! number of overrun errors */ - int overrun; - /*! number of parity errors */ - int parity; - SerialPort_EINFO() { - brk = frame = overrun = parity = 0; - }; - ~SerialPort_EINFO() {}; - }; - - /*! - \enum SerialPortIoctls - - The following Ioctl calls are only valid for the SerialPort - class. - */ - enum SerialPortIoctls { - /*! - Get all numbers of occured communication errors (breaks - framing, overrun and parity), so the args parameter of - the Ioctl call must pointed to a SerialPort_EINFO - struct. - */ - CTB_SER_GETEINFO = CTB_SERIAL, - /*! - Get integer 1, if a break occured since the last call - so the args parameter of the Ioctl methode must pointed - to an integer value. If there was no break, the result - is integer 0. - */ - CTB_SER_GETBRK, - /*! - Get integer 1, if a framing occured since the last call - so the args parameter of the Ioctl methode must pointed - to an integer value. If there was no break, the result - is integer 0. - */ - CTB_SER_GETFRM, - /*! - Get integer 1, if a overrun occured since the last call - so the args parameter of the Ioctl methode must pointed - to an integer value. If there was no break, the result - is integer 0. - */ - CTB_SER_GETOVR, - /*! - Get integer 1, if a parity occured since the last call - so the args parameter of the Ioctl methode must pointed - to an integer value. If there was no break, the result - is integer 0. - */ - CTB_SER_GETPAR, - /*! - Get the number of bytes received by the serial port driver - but not yet read by a Read or Readv Operation. - */ - CTB_SER_GETINQUE, - /*! - Set the parity bit on or off to use it as a ninth bit. - */ - CTB_SER_SETPAR - }; - -/*! - \class SerialPort_x - SerialPort_x is the basic class for serial communication via - the serial comports. It is also an abstract class and defines - all necessary methods, which the derivated plattform depended - classes must be invoke. -*/ - class SerialPort_x : public IOBase - { - protected: - /*! - \brief contains the internal settings of the serial port like - baudrate, protocol, wordlen and so on. - */ - SerialPort_DCS m_dcs; - /*! - \brief contains the internal (os specific) name of the serial - device. - */ - char m_devname[SERIALPORT_NAME_LEN]; - public: - - /*! - \enum FlowControl - \brief Specifies the flow control. - - - */ - enum FlowControl - { - NoFlowControl, /*!< No flow control at all */ - - RtsCtsFlowControl, /*!< Enable RTS/CTS hardware flow control */ - - XonXoffFlowControl /*!< Enable XON/XOFF protocol */ - }; - - SerialPort_x() {m_devname[0] = '\0';}; - virtual ~SerialPort_x() {}; - /*! - \brief returns the name of the class instance. You find this useful, - if you handle different devices like a serial port or a gpib device - via a IOBase pointer. - \return name of the class. - */ - const char* ClassName() {return "ctb::SerialPort";}; - - /*! - \brief change the linestates according to which bits - are set/unset in flags. - \param flags valid line flags are SERIAL_LINESTATE_DSR and/or - SERIAL_LINESTATE_RTS - \return zero on success, -1 if an error occurs - */ - virtual int ChangeLineState( SerialLineState flags ) = 0; - - /*! - \brief turn off status lines depending upon which bits (DSR and/or RTS) - are set in flags. - \param flags valid line flags are SERIAL_LINESTATE_DSR and/or - SERIAL_LINESTATE_RTS - \return zero on success, -1 if an error occurs - */ - virtual int ClrLineState( SerialLineState flags ) = 0; - - /*! - \brief Read the line states of DCD, CTS, DSR and RING - \return returns the appropriate bits on sucess, otherwise -1 - */ - virtual int GetLineState() = 0; - - /*! - \brief request the current settings of the connected serial port - as a null terminated string. - \return the settings as a string like '8N1 115200' - */ - virtual char* GetSettingsAsString() { - return m_dcs.GetSettings(); - }; - - /*! - \brief Many operating characteristics are only possible for - special devices. To avoid the need of a lot of different functions - and to give the user a uniform interface, all this special - operating instructions will covered by one Ioctl methode (like - the linux ioctl call). - The Ioctl command (cmd) has encoded in it whether the argument - is an in parameter or out parameter, and the size of the - argument args in bytes. Macros and defines used in specifying an - ioctl request are located in iobase.h and the header file for - the derivated device (for example in serportx.h). - \param cmd one of SerialPortIoctls specify the ioctl request. - \param args is a typeless pointer to a memory location, where - Ioctl reads the request arguments or write the results. - Please note, that an invalid memory location or size involving - a buffer overflow or segmention fault! - */ - virtual int Ioctl(int cmd,void* args) {return -1;}; - - /*! - \brief Opens a serial port in a user likely way. Insteed of - using the Device Control Struct just input your parameter in a - more intuitive manner. - \param portname the name of the serial port - \param baudrate any baudrate, also an unusual one, if your - serial device support them - \param protocol a string with the number of databits (5...8), - the parity setting (N=None,O=Odd,E=Even,M=Mark,S=Space), also - in lower case, and the count of stopbits (1...2) - \param flowControl one of NoFlowControl, RtsCtsFlowControl or - XonXoffFlowControl. - \return the new file descriptor, or -1 if an error occurred - */ - int Open( const char* portname, int baudrate, - const char* protocol = "8N1", - FlowControl flowControl = NoFlowControl ); - - /*! - \brief Opens the serial port with the given number. - \note The port numbering starts with 1 (COM1 for windows and - /dev/ttyS0 for Linux. Please note, that USB to RS232 converter - in Linux are named as /dev/ttyUSBx and from there have to - opened with their device name! - \param number of the serial port count from 1 - \param baudrate any baudrate, also an unusual one, if your - serial device support them - \param protocol a string with the number of databits (5...8), - the parity setting (N=None,O=Odd,E=Even,M=Mark,S=Space), also - in lower case, and the count of stopbits (1...2) - \param flowControl one of NoFlowControl, RtsCtsFlowControl or - XonXoffFlowControl. - \return the new file descriptor, or -1 if an error occurred - */ - int Open( const int portnumber, int baudrate, - const char* protocol = "8N1", - FlowControl flowControl = NoFlowControl ); - - // Open overrides and hides the IOBase::Open( const char* - // devname, void* dcs ) of the base class! So bring it into scope - // again! - using IOBase::Open; - - /*! - \brief Sendbreak transmits a continuous stream of zero-valued - bits for a specific duration. - \param duration If duration is zero, it transmits - zero-valued bits for at least 0.25 seconds, and not more that - 0.5 seconds. If duration is not zero, it sends zero-valued bits - for duration*N seconds, where N is at least 0.25, and not more - than 0.5. - \return zero on success, -1 if an error occurs. - */ - virtual int SendBreak(int duration) = 0; - - /*! - \brief Set the baudrate (also non-standard) - Please note: Non-standard baudrates like 70000 are not supported - by each UART and depends on the RS232 chipset you apply. - \param baudrate the new baudrate - \return zero on success, -1 if an error occurs - */ - virtual int SetBaudrate( int baudrate ) = 0; - - /*! - \brief turn on status lines depending upon which bits (DSR and/or RTS) - are set in flags. - \param flags valid line flags are SERIAL_LINESTATE_DSR and/or - SERIAL_LINESTATE_RTS - \return zero on success, -1 if an error occurs - */ - virtual int SetLineState( SerialLineState flags ) = 0; - - /*! - \brief Set the parity bit to a firm state, for instance to use - the parity bit as the ninth bit in a 9 bit dataword - communication. - \return zero on succes, a negative value if an error occurs - */ - virtual int SetParityBit( bool parity ) = 0; - - /*! - \brief check the given baudrate against a list of standard rates. - \ return true, if the baudrate is a standard value, false - otherwise - */ - static bool IsStandardRate( int rate ); - - }; - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/timer.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/timer.h deleted file mode 100644 index b1313ebfef..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/timer.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIBCTB_TIMER_H_INCLUDED_ -#define LIBCTB_TIMER_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: timer.h -// Purpose: simple wrapper file -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#if defined (WIN32) -# include "win32/timer.h" -#else -# include "linux/timer.h" -#endif - -#endif - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/getopt.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/getopt.h deleted file mode 100644 index d2a909fd73..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/getopt.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef LIBCTB_WIN32_GETOPT_H_INCLUDED_ -#define LIBCTB_WIN32_GETOPT_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: win32/getopt.h -// Purpose: -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -extern char* optarg; -extern int optind; - -int getopt(int argc, char* argv[], char* optstring); - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/gpib-32.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/gpib-32.h deleted file mode 100644 index 307c6ce001..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/gpib-32.h +++ /dev/null @@ -1,414 +0,0 @@ -/* - * - * - * Win32 include file - * for accessing the 32-bit GPIB DLL (gpib-32.dll) - * - * - * Contains user variables (ibsta, iberr, ibcnt, ibcntl), - * function prototypes and useful defined constants for - * calling NI-488 and NI-488.2 routines from a Microsoft - * C/C++ Win32 application. - * - * - * Copyright 1998 National Instruments Corporation - * - */ - -#ifndef DECL_32_H // ensure we are only included once -#define DECL_32_H - -#include "windows.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/***************************************************************************/ -/* HANDY CONSTANTS FOR USE BY APPLICATION PROGRAMS ... */ -/***************************************************************************/ -#define UNL 0x3f /* GPIB unlisten command */ -#define UNT 0x5f /* GPIB untalk command */ -#define GTL 0x01 /* GPIB go to local */ -#define SDC 0x04 /* GPIB selected device clear */ -#define PPC 0x05 /* GPIB parallel poll configure */ -#define GET 0x08 /* GPIB group execute trigger */ -#define TCT 0x09 /* GPIB take control */ -#define LLO 0x11 /* GPIB local lock out */ -#define DCL 0x14 /* GPIB device clear */ -#define PPU 0.16 /* GPIB parallel poll unconfigure */ -#define SPE 0x18 /* GPIB serial poll enable */ -#define SPD 0x19 /* GPIB serial poll disable */ -#define PPE 0x60 /* GPIB parallel poll enable */ -#define PPD 0x70 /* GPIB parallel poll disable */ - -/* GPIB status bit vector : */ -/* global variable ibsta and wait mask */ - -#define ERR (1<<15) /* Error detected */ -#define TIMO (1<<14) /* Timeout */ -#define END (1<<13) /* EOI or EOS detected */ -#define SRQI (1<<12) /* SRQ detected by CIC */ -#define RQS (1<<11) /* Device needs service */ -#define CMPL (1<<8) /* I/O completed */ -#define LOK (1<<7) /* Local lockout state */ -#define REM (1<<6) /* Remote state */ -#define CIC (1<<5) /* Controller-in-Charge */ -#define ATN (1<<4) /* Attention asserted */ -#define TACS (1<<3) /* Talker active */ -#define LACS (1<<2) /* Listener active */ -#define DTAS (1<<1) /* Device trigger state */ -#define DCAS (1<<0) /* Device clear state */ - -/* Error messages returned in global variable iberr */ - -#define EDVR 0 /* System error */ -#define ECIC 1 /* Function requires GPIB board to be CIC */ -#define ENOL 2 /* Write function detected no Listeners */ -#define EADR 3 /* Interface board not addressed correctly*/ -#define EARG 4 /* Invalid argument to function call */ -#define ESAC 5 /* Function requires GPIB board to be SAC */ -#define EABO 6 /* I/O operation aborted */ -#define ENEB 7 /* Non-existent interface board */ -#define EDMA 8 /* Error performing DMA */ -#define EOIP 10 /* I/O operation started before previous */ - /* operation completed */ -#define ECAP 11 /* No capability for intended operation */ -#define EFSO 12 /* File system operation error */ -#define EBUS 14 /* Command error during device call */ -#define ESTB 15 /* Serial poll status byte lost */ -#define ESRQ 16 /* SRQ remains asserted */ -#define ETAB 20 /* The return buffer is full. */ -#define ELCK 21 /* Address or board is locked. */ - -/* EOS mode bits */ - -#define BIN (1<<12) /* Eight bit compare */ -#define XEOS (1<<11) /* Send END with EOS byte */ -#define REOS (1<<10) /* Terminate read on EOS */ - -/* Timeout values and meanings */ - -#define TNONE 0 /* Infinite timeout (disabled) */ -#define T10us 1 /* Timeout of 10 us (ideal) */ -#define T30us 2 /* Timeout of 30 us (ideal) */ -#define T100us 3 /* Timeout of 100 us (ideal) */ -#define T300us 4 /* Timeout of 300 us (ideal) */ -#define T1ms 5 /* Timeout of 1 ms (ideal) */ -#define T3ms 6 /* Timeout of 3 ms (ideal) */ -#define T10ms 7 /* Timeout of 10 ms (ideal) */ -#define T30ms 8 /* Timeout of 30 ms (ideal) */ -#define T100ms 9 /* Timeout of 100 ms (ideal) */ -#define T300ms 10 /* Timeout of 300 ms (ideal) */ -#define T1s 11 /* Timeout of 1 s (ideal) */ -#define T3s 12 /* Timeout of 3 s (ideal) */ -#define T10s 13 /* Timeout of 10 s (ideal) */ -#define T30s 14 /* Timeout of 30 s (ideal) */ -#define T100s 15 /* Timeout of 100 s (ideal) */ -#define T300s 16 /* Timeout of 300 s (ideal) */ -#define T1000s 17 /* Timeout of 1000 s (ideal) */ - - -/* IBLN Constants */ -#define NO_SAD 0 -#define ALL_SAD -1 - - -/* The following constants are used for the second parameter of the - * ibconfig function. They are the "option" selection codes. - */ -#define IbcPAD 0x0001 /* Primary Address */ -#define IbcSAD 0x0002 /* Secondary Address */ -#define IbcTMO 0x0003 /* Timeout Value */ -#define IbcEOT 0x0004 /* Send EOI with last data byte? */ -#define IbcPPC 0x0005 /* Parallel Poll Configure */ -#define IbcREADDR 0x0006 /* Repeat Addressing */ -#define IbcAUTOPOLL 0x0007 /* Disable Auto Serial Polling */ -#define IbcCICPROT 0x0008 /* Use the CIC Protocol? */ -#define IbcIRQ 0x0009 /* Use PIO for I/O */ -#define IbcSC 0x000A /* Board is System Controller? */ -#define IbcSRE 0x000B /* Assert SRE on device calls? */ -#define IbcEOSrd 0x000C /* Terminate reads on EOS */ -#define IbcEOSwrt 0x000D /* Send EOI with EOS character */ -#define IbcEOScmp 0x000E /* Use 7 or 8-bit EOS compare */ -#define IbcEOSchar 0x000F /* The EOS character. */ -#define IbcPP2 0x0010 /* Use Parallel Poll Mode 2. */ -#define IbcTIMING 0x0011 /* NORMAL, HIGH, or VERY_HIGH timing. */ -#define IbcDMA 0x0012 /* Use DMA for I/O */ -#define IbcReadAdjust 0x0013 /* Swap bytes during an ibrd. */ -#define IbcWriteAdjust 0x014 /* Swap bytes during an ibwrt. */ -#define IbcSendLLO 0x0017 /* Enable/disable the sending of LLO. */ -#define IbcSPollTime 0x0018 /* Set the timeout value for serial polls. */ -#define IbcPPollTime 0x0019 /* Set the parallel poll length period. */ -#define IbcEndBitIsNormal 0x001A /* Remove EOS from END bit of IBSTA. */ -#define IbcUnAddr 0x001B /* Enable/disable device unaddressing. */ -#define IbcSignalNumber 0x001C /* Set UNIX signal number - unsupported */ -#define IbcBlockIfLocked 0x001D /* Enable/disable blocking for locked boards/devices */ -#define IbcHSCableLength 0x001F /* Length of cable specified for high speed timing.*/ -#define IbcIst 0x0020 /* Set the IST bit. */ -#define IbcRsv 0x0021 /* Set the RSV byte. */ - -/* - * Constants that can be used (in addition to the ibconfig constants) - * when calling the ibask() function. - */ - -#define IbaPAD IbcPAD -#define IbaSAD IbcSAD -#define IbaTMO IbcTMO -#define IbaEOT IbcEOT -#define IbaPPC IbcPPC -#define IbaREADDR IbcREADDR -#define IbaAUTOPOLL IbcAUTOPOLL -#define IbaCICPROT IbcCICPROT -#define IbaIRQ IbcIRQ -#define IbaSC IbcSC -#define IbaSRE IbcSRE -#define IbaEOSrd IbcEOSrd -#define IbaEOSwrt IbcEOSwrt -#define IbaEOScmp IbcEOScmp -#define IbaEOSchar IbcEOSchar -#define IbaPP2 IbcPP2 -#define IbaTIMING IbcTIMING -#define IbaDMA IbcDMA -#define IbaReadAdjust IbcReadAdjust -#define IbaWriteAdjust IbcWriteAdjust -#define IbaSendLLO IbcSendLLO -#define IbaSPollTime IbcSPollTime -#define IbaPPollTime IbcPPollTime -#define IbaEndBitIsNormal IbcEndBitIsNormal -#define IbaUnAddr IbcUnAddr -#define IbaSignalNumber IbcSignalNumber -#define IbaBlockIfLocked IbcBlockIfLocked -#define IbaHSCableLength IbcHSCableLength -#define IbaIst IbcIst -#define IbaRsv IbcRsv - -#define IbaBNA 0x0200 /* A device's access board. */ - - -/* Values used by the Send 488.2 command. */ -#define NULLend 0x00 /* Do nothing at the end of a transfer.*/ -#define NLend 0x01 /* Send NL with EOI after a transfer. */ -#define DABend 0x02 /* Send EOI with the last DAB. */ - -/* Value used by the 488.2 Receive command. - */ -#define STOPend 0x0100 - - -/* Address type (for 488.2 calls) */ - -typedef short Addr4882_t; /* System dependent: must be 16 bits */ - -/* - * This macro can be used to easily create an entry in address list - * that is required by many of the 488.2 functions. The primary address goes in the - * lower 8-bits and the secondary address goes in the upper 8-bits. - */ -#define MakeAddr(pad, sad) ((Addr4882_t)(((pad)&0xFF) | ((sad)<<8))) - -/* - * This value is used to terminate an address list. It should be - * assigned to the last entry. - */ -#ifndef NOADDR -#define NOADDR (Addr4882_t)((unsigned short)0xFFFF) -#endif - -/* - * The following two macros are used to "break apart" an address list - * entry. They take an unsigned integer and return either the primary - * or secondary address stored in the integer. - */ -#define GetPAD(val) ((val) & 0xFF) -#define GetSAD(val) (((val) >> 8) & 0xFF) - -/* iblines constants */ - -#define ValidEOI (short)0x0080 -#define ValidATN (short)0x0040 -#define ValidSRQ (short)0x0020 -#define ValidREN (short)0x0010 -#define ValidIFC (short)0x0008 -#define ValidNRFD (short)0x0004 -#define ValidNDAC (short)0x0002 -#define ValidDAV (short)0x0001 -#define BusEOI (short)0x8000 -#define BusATN (short)0x4000 -#define BusSRQ (short)0x2000 -#define BusREN (short)0x1000 -#define BusIFC (short)0x0800 -#define BusNRFD (short)0x0400 -#define BusNDAC (short)0x0200 -#define BusDAV (short)0x0100 - -/**** - **** typedef for ibnotify callback **** - ****/ -typedef int (__stdcall * GpibNotifyCallback_t)(int, int, int, long, PVOID); - -#define IBNOTIFY_REARM_FAILED 0xE00A003F - - -/*************************************************************************/ -/* */ -/* iblockx and ibunlockx definitions --- for use with GPIB-ENET only !! */ -/* */ -/*************************************************************************/ -#define TIMMEDIATE -1 -#define TINFINITE -2 -#define MAX_LOCKSHARENAME_LENGTH 64 - -#if defined(UNICODE) - #define iblockx iblockxW -#else - #define iblockx iblockxA -#endif - -extern int __stdcall iblockxA (int ud, int LockWaitTime, PCHAR LockShareName); -extern int __stdcall iblockxW (int ud, int LockWaitTime, PWCHAR LockShareName); -extern int __stdcall ibunlockx (int ud); - - -/***************************************************************************/ -/* IBSTA, IBERR, IBCNT, IBCNTL and FUNCTION PROTOTYPES */ -/* ( only included if not accessing the 32-bit DLL directly ) */ -/***************************************************************************/ -#if !defined(GPIB_DIRECT_ACCESS) - -/* - * Set up access to the user variables (ibsta, iberr, ibcnt, ibcntl). - * These are declared and exported by the 32-bit DLL. Separate copies - * exist for each process that accesses the DLL. They are shared by - * multiple threads of a single process. - */ - -extern int ibsta; -extern int iberr; -extern int ibcnt; -extern long ibcntl; - - -#if defined(UNICODE) - #define ibbna ibbnaW - #define ibfind ibfindW - #define ibrdf ibrdfW - #define ibwrtf ibwrtfW -#else - #define ibbna ibbnaA - #define ibfind ibfindA - #define ibrdf ibrdfA - #define ibwrtf ibwrtfA -#endif - -/* - * Extern 32-bit GPIB DLL functions - */ - -/* NI-488 Function Prototypes */ -extern int __stdcall ibfindA (LPCSTR udname); -extern int __stdcall ibbnaA (int ud, LPCSTR udname); -extern int __stdcall ibrdfA (int ud, LPCSTR filename); -extern int __stdcall ibwrtfA (int ud, LPCSTR filename); - -extern int __stdcall ibfindW (LPCWSTR udname); -extern int __stdcall ibbnaW (int ud, LPCWSTR udname); -extern int __stdcall ibrdfW (int ud, LPCWSTR filename); -extern int __stdcall ibwrtfW (int ud, LPCWSTR filename); - -extern int __stdcall ibask (int ud, int option, PINT v); -extern int __stdcall ibcac (int ud, int v); -extern int __stdcall ibclr (int ud); -extern int __stdcall ibcmd (int ud, PVOID buf, long cnt); -extern int __stdcall ibcmda (int ud, PVOID buf, long cnt); -extern int __stdcall ibconfig (int ud, int option, int v); -extern int __stdcall ibdev (int boardID, int pad, int sad, int tmo, int eot, int eos); -extern int __stdcall ibdiag (int ud, PVOID buf, long cnt); -extern int __stdcall ibdma (int ud, int v); -extern int __stdcall ibeos (int ud, int v); -extern int __stdcall ibeot (int ud, int v); -extern int __stdcall ibgts (int ud, int v); -extern int __stdcall ibist (int ud, int v); -extern int __stdcall iblines (int ud, PSHORT result); -extern int __stdcall ibln (int ud, int pad, int sad, PSHORT listen); -extern int __stdcall ibloc (int ud); -extern int __stdcall ibnotify (int ud, int mask, GpibNotifyCallback_t Callback, PVOID RefData); -extern int __stdcall ibonl (int ud, int v); -extern int __stdcall ibpad (int ud, int v); -extern int __stdcall ibpct (int ud); -extern int __stdcall ibpoke (int ud, long option, long v); -extern int __stdcall ibppc (int ud, int v); -extern int __stdcall ibrd (int ud, PVOID buf, long cnt); -extern int __stdcall ibrda (int ud, PVOID buf, long cnt); -extern int __stdcall ibrpp (int ud, PCHAR ppr); -extern int __stdcall ibrsc (int ud, int v); -extern int __stdcall ibrsp (int ud, PCHAR spr); -extern int __stdcall ibrsv (int ud, int v); -extern int __stdcall ibsad (int ud, int v); -extern int __stdcall ibsic (int ud); -extern int __stdcall ibsre (int ud, int v); -extern int __stdcall ibstop (int ud); -extern int __stdcall ibtmo (int ud, int v); -extern int __stdcall ibtrg (int ud); -extern int __stdcall ibwait (int ud, int mask); -extern int __stdcall ibwrt (int ud, PVOID buf, long cnt); -extern int __stdcall ibwrta (int ud, PVOID buf, long cnt); - -// GPIB-ENET only functions to support locking across machines -extern int __stdcall iblock (int ud); -extern int __stdcall ibunlock (int ud); - -/**************************************************************************/ -/* Functions to access Thread-Specific copies of the GPIB global vars */ - -extern int __stdcall ThreadIbsta (void); -extern int __stdcall ThreadIberr (void); -extern int __stdcall ThreadIbcnt (void); -extern long __stdcall ThreadIbcntl (void); - - -/**************************************************************************/ -/* NI-488.2 Function Prototypes */ - -extern void __stdcall AllSpoll (int boardID, Addr4882_t * addrlist, PSHORT results); -extern void __stdcall DevClear (int boardID, Addr4882_t addr); -extern void __stdcall DevClearList (int boardID, Addr4882_t * addrlist); -extern void __stdcall EnableLocal (int boardID, Addr4882_t * addrlist); -extern void __stdcall EnableRemote (int boardID, Addr4882_t * addrlist); -extern void __stdcall FindLstn (int boardID, Addr4882_t * addrlist, Addr4882_t * results, int limit); -extern void __stdcall FindRQS (int boardID, Addr4882_t * addrlist, PSHORT dev_stat); -extern void __stdcall PPoll (int boardID, PSHORT result); -extern void __stdcall PPollConfig (int boardID, Addr4882_t addr, int dataLine, int lineSense); -extern void __stdcall PPollUnconfig (int boardID, Addr4882_t * addrlist); -extern void __stdcall PassControl (int boardID, Addr4882_t addr); -extern void __stdcall RcvRespMsg (int boardID, PVOID buffer, long cnt, int Termination); -extern void __stdcall ReadStatusByte(int boardID, Addr4882_t addr, PSHORT result); -extern void __stdcall Receive (int boardID, Addr4882_t addr, PVOID buffer, long cnt, int Termination); -extern void __stdcall ReceiveSetup (int boardID, Addr4882_t addr); -extern void __stdcall ResetSys (int boardID, Addr4882_t * addrlist); -extern void __stdcall Send (int boardID, Addr4882_t addr, PVOID databuf, long datacnt, int eotMode); -extern void __stdcall SendCmds (int boardID, PVOID buffer, long cnt); -extern void __stdcall SendDataBytes (int boardID, PVOID buffer, long cnt, int eot_mode); -extern void __stdcall SendIFC (int boardID); -extern void __stdcall SendLLO (int boardID); -extern void __stdcall SendList (int boardID, Addr4882_t * addrlist, PVOID databuf, long datacnt, int eotMode); -extern void __stdcall SendSetup (int boardID, Addr4882_t * addrlist); -extern void __stdcall SetRWLS (int boardID, Addr4882_t * addrlist); -extern void __stdcall TestSRQ (int boardID, PSHORT result); -extern void __stdcall TestSys (int boardID, Addr4882_t * addrlist, PSHORT results); -extern void __stdcall Trigger (int boardID, Addr4882_t addr); -extern void __stdcall TriggerList (int boardID, Addr4882_t * addrlist); -extern void __stdcall WaitSRQ (int boardID, PSHORT result); - -#endif - - -#ifdef __cplusplus -} -#endif - - -#endif // DECL_32_H - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/serport.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/serport.h deleted file mode 100644 index 503f25cffb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/serport.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef LIBCTB_WIN32_TIMER_H_INCLUDED_ -#define LIBCTB_WIN32_TIMER_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: win32/serport.h -// Purpose: -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "../serportx.h" -#include - -namespace ctb { - - /*! - \class SerialPort - - \brief the win32 version - */ - class SerialPort : public SerialPort_x - { - protected: - /*! - \brief the win32 api equivalent for the Linux - file descriptor - */ - HANDLE fd; - /*! - \brief a very special struct in the win32 api for controling - an asynchronous serial communication through the com ports. - */ - OVERLAPPED m_ov; - - /*! - \brief The win32 API only allows to test for an existing - break, framing, overrun or parity, not for the occured numbers. - So every error event decrement this internal error struct and - can request by an Ioctl call. - */ - SerialPort_EINFO einfo; - - /*! - \brief The win32 API doesn't have any function to detect the - current state of the output lines RST and DTR (if someone knows - some function, please contact me). - So we save the state always after changing one or both lines - (for example, on Open, SetLineState and ChangeLineState) - */ - int m_rtsdtr_state; - - int CloseDevice(); - int OpenDevice(const char* devname, void* dcs); - public: - SerialPort(); - ~SerialPort(); - - int ChangeLineState( SerialLineState flags ); - int ClrLineState( SerialLineState flags ); - int GetLineState(); - int Ioctl(int cmd,void* args); - int IsOpen(); - int Read(char* buf,size_t len); - int SendBreak(int duration); - int SetBaudrate( int baudrate ); - int SetLineState( SerialLineState flags ); - int SetParityBit( bool parity ); - int Write(char* buf,size_t len); - }; - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/timer.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/timer.h deleted file mode 100644 index e750baead3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/win32/timer.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef LIBCTB_WINDOWS_TIMER_H_INCLUDED_ -#define LIBCTB_WINDOWS_TIMER_H_INCLUDED_ - -///////////////////////////////////////////////////////////////////////////// -// Name: win32/timer.h -// Purpose: -// Author: Joachim Buermann -// Copyright: (c) 2010 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include - -namespace ctb { - -/*! - \brief A data struct, using from class timer. -*/ - struct timer_control - { - /*! - under win32, we used msec internally - */ - unsigned int msecs; - /*! - covers the adress of the exitflag - */ - int *exitflag; - /*! - the running thread steadily polls this variable (only under win32). - If it's not zero, the thread terminate. - */ - MMRESULT stop; - /*! - covers the adress of the exit function. NULL, if - there was no exit function. - */ - void* (*exitfnc)(void*); - }; - -/*! - \class Timer - \brief A thread based timer class for handling timeouts in - an easier way. - - On starting every timer instance will create it's own thread. - The thread makes simply nothing, until it's given time is over. - After that, he set a variable, refer by it's adress to one - and exit. - - There are a lot of situations, which the timer class must handle. - The timer instance leaves his valid range (for example, the - timer instance is local inside a function, and the function fished) - BEFORE the thread was ending. In this case, the destructor must - terminate the thread in a correct way. (This is very different - between the OS. threads are a system resource like file descriptors - and must be deallocated after using it). - - The thread should be asynchronously stopped. Means, under all - circumstance, it must be possible, to finish the timer and start - it again. - - Several timer instance can be used simultanously. -*/ - class Timer - { - protected: - /*! - \brief win32 needs this - */ - DWORD id; - /*! - \brief in win32 internal handle for the timer thread - */ - MMRESULT h; - /*! - control covers the time interval, the adress - of the exitflag, and if not null, a function, which will - be called on the end. - */ - timer_control control; - /*! - here we store the time interval, whilst the timer run. - This is waste!!! - */ - unsigned int timer_secs; - public: - /*! - The constructor creates an timer object with the given - properties. The timer at this moment is not started. This - will be done with the start() member function. - \param msec time interval after that the the variable - pointed by exitflag is setting to one. - \param exitflag the adress of an integer, which was set - to one after the given time interval. - \warning The integer variable shouldn't leave it's valid - range, before the timer was finished. So never take a - local variable. - \param exitfnc A function, which was called after msec. - If you don't want this, refer a NULL pointer. - */ - Timer(unsigned int msec,int* exitflag,void*(*exitfnc)(void*)); - /*! - the destructor. If his was called (for example by leaving the - valid range of the timer object), the timer thread automaticaly - will finished. The exitflag wouldn't be set, also the exitfnc - wouldn't be called. - */ - ~Timer(); - /*! - starts the timer. But now a thread will created and started. - After this, the timer thread will be running until he was stopped - by calling stop() or reached his given time interval. - */ - int start(); - /*! - stops the timer and canceled the timer thread. After timer::stop() a new - start() will started the timer from beginning. - */ - int stop(); - }; - -/*! - \fn kill_all_timer() - \warning This function don't works under win32 and will be removed next - time. So don't use that! -*/ - void kill_all_timer(); - -/*! - \fn - A plattform independent function, to go to sleep for the given - time interval. - \param ms time interval in milli seconds -*/ - void sleepms(unsigned int ms); - -} // namespace ctb - -#endif diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/lib/EMPTY b/src/mod/endpoints/mod_gsmopen/libctb-0.16/lib/EMPTY deleted file mode 100644 index 887ae9333d..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/lib/EMPTY +++ /dev/null @@ -1 +0,0 @@ -ciao diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/manual/refman.pdf b/src/mod/endpoints/mod_gsmopen/libctb-0.16/manual/refman.pdf deleted file mode 100644 index 285e523de38e3d61bf48df51eef0e6bcaf4e408e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 727923 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 tSJ8#Y2Ht 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

mp6|9a)V=yUwS2LW3JF|c6>T$EDzej%OIqeHw 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 diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/ctb.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/ctb.py deleted file mode 100644 index 6b541ffe39..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/ctb.py +++ /dev/null @@ -1,455 +0,0 @@ -import wxctb, sys, re - -DCD = wxctb.LinestateDcd -CTS = wxctb.LinestateCts -DSR = wxctb.LinestateDsr -DTR = wxctb.LinestateDtr -RING = wxctb.LinestateRing -RTS = wxctb.LinestateRts -NULL = wxctb.LinestateNull - -def abstract(): - import inspect - caller = inspect.getouterframes(inspect.currentframe())[1][3] - raise NotImplementedError(caller + ' must be implemented in subclass') - -class IOBase: - def __init__(self): - self.device = None - # set timeout to 1000ms (the default) - self.timeout = 1000 - - def __del__(self): - pass - - def Close(self): - if self.device: - self.device.Close() - - def GetTimeout(self): - """ - Returns the internal timeout value in milliseconds - """ - return self.timeout - - def Ioctl(self,cmd,arg): - if self.device: - self.device.Ioctl(cmd,arg) - - def Open(self): - abstract() - - def PutBack(self,char): - return self.device.PutBack(char) - - def Read(self,length): - """ - Try to read the given count of data (length) and returns the - successfully readed number of data. The function never blocks. - For example: - readed = dev.Read(100) - """ - buf = "\x00"*(length+1) - rd = self.device.Read(buf,length) - return buf[0:rd] - - def ReadBinary(self,eos="\n"): - """ - Special SCPI command. Read the next data coded as a SCPI - binary format. - A binary data transfer will be startet by '#'. The next byte - tells the count of bytes for the binary length header, - following by the length bytes. After these the data begins. - For example: - #500004xxxx - The header length covers 5 Byte, the length of the binary - data is 4 (x means the binary data bytes) - """ - try: - eoslen = len(eos) - b=self.Readv(2) - if len(b) == 2: - hl = int(b[1]) - b = self.Readv(hl) - if len(b) == hl: - dl = int(b) - # don't left over the eos string or character in the - # device input buffer - data = self.Readv(dl+eoslen) - # check, if the binary data block is complete - if data[dl] == '#': - # not complete, another block is following - for c in data[dl:dl+eoslen]: - self.PutBack(c) - - data = data[:dl] + self.ReadBinary() - return data - except: - pass - return '' - - def ReadUntilEOS(self,eos="\n",quota=0): - """ - ReadUntilEOS(eosString=\"\\n\",timeout=1000) - Reads data until the given eos string was received (default is - the linefeed character (0x0a) or the internal timeout - (default 1000ms) was reached. - ReadUntilEOS returns the result as the following tuple: - ['received string',state,readedBytes] - If a timeout occurred, state is 0, otherwise 1 - """ - return self.device.ReadUntilEOS("",0,eos,self.timeout,quota) - - def Readv(self,length): - """ - Try to read the given count of data. Readv blocks until all data - was readed successfully or the internal timeout, set with the - class member function SetTimeout(timeout), was reached. - Returns the readed data. - """ - buf = "\x00"*length - rd = self.device.Readv(buf,length,self.timeout) - return buf[0:rd] - - def ResetBus(self): - """ - If the underlaying interface needs some special reset operations - (for instance the GPIB distinguish between a normal device reset - and a special bus reset), you can put some code here) - """ - pass - - def SetTimeout(self,timeout): - """ - Set the internal timeout value in milliseconds for all blocked - operations like ReadUntilEOS, Readv and Writev. - """ - self.timeout = timeout - - def Write(self,string): - """ - Writes the given string to the device and returns immediately. - Write returns the number of data bytes successfully written or a - negativ number if an error occured. For some circumstances, not - the complete string was written. - So you have to verify the return value to check this out. - """ - return self.device.Write(string,len(string)) - - def Writev(self,string): - """ - Writes the given string to the device. The function blocks until - the complete string was written or the internal timeout, set with - SetTimeout(timeout), was reached. - Writev returns the number of data successfully written or a - negativ value, if an errors occurred. - """ - return self.device.Writev(string,len(string),self.timeout) - -class SerialPort(IOBase): - def __init__(self): - IOBase.__init__(self) - - def __del__(self): - self.Close() - - def ChangeLineState(self,lineState): - """ - Change (toggle) the state of each the lines given in the - linestate parameter. Possible values are DTR and/or RTS. - For example to toggle the RTS line only: - dev.ChangeLineState(RTS) - """ - self.device.ChangeLineState(lineState) - - def ClrLineState(self,lineState): - """ - Clear the lines given in the linestate parameter. Possible - values are DTR and/or RTS. For example to clear only - the RTS line: - dev.ClrLineState(RTS) - """ - self.device.ClrLineState(lineState) - - def GetAvailableBytes(self): - """ - Returns the available bytes in the input queue of the serial - driver. - """ - n = wxctb.new_intp() - wxctb.intp_assign(n, 0) - self.device.Ioctl(wxctb.CTB_SER_GETINQUE,n) - return wxctb.intp_value(n) - - def GetCommErrors(self): - """ - Get the internal communication errors like breaks, framing, - parity or overrun errors. - Returns the count of each error as a tuple like this: - (b,f,o,p) = dev.GetCommErrors() - b: breaks, f: framing errors, o: overruns, p: parity errors - """ - einfo = wxctb.SerialPort_EINFO() - self.device.Ioctl(wxctb.CTB_SER_GETEINFO,einfo) - return einfo.brk,einfo.frame,einfo.overrun,einfo.parity - - def GetLineState(self): - """ - Returns the current linestates of the CTS, DCD, DSR and RING - signal line as an integer value with the appropriate bits or - -1 on error. - For example: - lines = dev.GetLineState() - if lines & CTS: - print \"CTS is on\" - """ - return self.device.GetLineState() - - def Open(self,devname,baudrate,protocol='8N1',handshake='no_handshake'): - """ - Open the device devname with the given baudrate, the protocol - like '8N1' (default) and the use of the handshake [no_handshake - (default), rtscts or xonxoff] - For example: - At Linux: - dev = SerialPort() - dev.Open(\"/dev/ttyS0\",115200) - or with a datalen of 7 bits, even parity, 2 stopbits and rts/cts - handshake: - dev.Open(\"/dev/ttyS0\",115200,'7E2',True) - At Windows: - dev = SerialPort() - dev.Open(\"COM1\",115200) - dev.Open(\"COM1\",115200,'7E2',True) - Returns the handle on success or a negativ value on failure. - """ - # the following parity values are valid: - # N:None, O:Odd, E:Even, M:Mark, S:Space - parity = {'N':0,'O':1,'E':2,'M':3,'S':4} - # the regular expression ensures a valid value for the datalen - # (5...8 bit) and the count of stopbits (1,2) - reg=re.compile(r"(?P[8765])"r"(?P

[NOEMS])"r"(?P[12])") - self.device = wxctb.SerialPort() - dcs = wxctb.SerialPort_DCS() - dcs.baud = baudrate - res = reg.search(protocol) - # handle the given protocol - if res: - dcs.wordlen = int(res.group('w')) - dcs.stopbits = int(res.group('s')) - dcs.parity = parity[res.group('p')] - # valid handshake are no one, rts/cts or xon/xoff - if handshake == 'rtscts': - dcs.rtscts = True - elif handshake == 'xonxoff': - dcs.xonxoff = True - - return self.device.Open(devname,dcs) - - def Reset(self): - """ - Send a break for 0.25s. - """ - self.device.SendBreak(0) - - def SetBaudrate(self,baudrate): - """ - Set the baudrate for the device. - """ - self.device.SetBaudrate(baudrate) - - def SetLineState(self,lineState): - """ - Set the lines given in the linestate parameter. Possible - values are DTR and/or RTS. For example to set both: - dev.SetLineState( DTR | RTS) - """ - self.device.SetLineState(lineState) - - def SetParityBit(self,parity): - """ - Set the parity bit explicitly to 0 or 1. Use this function, if - you would like to simulate a 9 bit wordlen at what the ninth bit - was represented by the parity bit value. For example: - dev.SetParityBit( 0 ) - dev.Write('some data sent with parity 0') - dev.SetParityBit( 1 ) - dev.Write('another sequence with parity 1') - """ - return self.device.SetParityBit( parity ) - -class GpibDevice(IOBase): - """ - GPIB class - """ - def __init__(self): - IOBase.__init__(self) - - def __del__(self): - self.Close() - - def FindListeners(self,board = 0): - """ - Returns the address of the connected devices as a list. - If no device is listening, the list is empty. If an error - occurs an IOError exception raised. For example: - g = GPIB() - listeners = g.FindListeners() - """ - listeners = wxctb.GPIB_x_FindListeners(board) - if listeners < 0: - raise IOError("GPIB board error") - result = [] - for i in range(1,31): - if listeners & (1 << i): - result.append(i) - return result - - def GetEosChar(self): - """ - Get the internal EOS termination character (see SetEosChar). - For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosChar() - """ - eos = wxctb.new_intp() - wxctb.intp_assign(eos, 0) - self.device.Ioctl(wxctb.CTB_GPIB_GET_EOS_CHAR,eos) - return wxctb.intp_value(eos) - - def GetEosMode(self): - """ - Get the internal EOS mode (see SetEosMode). - For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosMode() - """ - mode = wxctb.new_intp() - wxctb.intp_assign(mode, 0) - self.device.Ioctl(wxctb.CTB_GPIB_GET_EOS_MODE,mode) - return wxctb.intp_value(mode) - - def GetError(self): - errorString = " "*256 - self.device.GetError(errorString,256) - return errorString - - def GetSTB(self): - """ - Returns the value of the internal GPIB status byte register. - """ - stb = wxctb.new_intp() - wxctb.intp_assign(stb, 0) - self.device.Ioctl(wxctb.CTB_GPIB_GETRSP,stb) - return wxctb.intp_value(stb) - - # This is only for internal usage!!! - def Ibrd(self,length): - buf = "\x00"*length - state = self.device.Ibrd(buf,length) - return state,buf - - # This is only for internal usage!!! - def Ibwrt(self,string): - return self.device.Ibwrt(string,len(string)) - - def Open(self,devname,adr,eosChar=10,eosMode=0x08|0x04): - """ - Open(gpibdevice,address,eosChar,eosMode) - Opens a connected device at the GPIB bus. gpibdevice means the - controller, (mostly \"gpib1\"), address the address of the desired - device in the range 1...31. The eosChar defines the EOS character - (default is linefeed), eosMode may be a combination of bits ORed - together. The following bits can be used: - 0x04: Terminate read when EOS is detected. - 0x08: Set EOI (End or identify line) with EOS on write function - 0x10: Compare all 8 bits of EOS byte rather than low 7 bits - (all read and write functions). Default is 0x12 - For example: - dev = GPIB() - dev.Open(\"gpib1\",17) - Opens the device with the address 17, linefeed as EOS (default) - and eos mode with 0x04 and 0x08. - Open returns >= 0 or a negativ value, if something going wrong. - """ - self.device = wxctb.GpibDevice() - dcs = wxctb.Gpib_DCS() - dcs.m_address1 = adr - dcs.m_eosChar = eosChar - dcs.m_eosMode = eosMode - result = self.device.Open(devname,dcs) - return result - - def Reset(self): - """ - Resets the connected device. In the GPIB definition, the device - should be reset to it's initial state, so you can restart a - formely lost communication. - """ - self.device.Ioctl(wxctb.CTB_RESET,None) - - def ResetBus(self): - """ - The command asserts the GPIB interface clear (IFC) line for - ast least 100us if the GPIB board is the system controller. - This initializes the GPIB and makes the interface CIC and - active controller with ATN asserted. - Note! The IFC signal resets only the GPIB interface functions - of the bus devices and not the internal device functions. - For a device reset you should use the Reset() command above. - """ - self.device.Ioctl(wxctb.CTB_GPIB_RESET_BUS,None) - - def SetEosChar(self,eos): - """ - Configure the end-of-string (EOS) termination character. - Note! Defining an EOS byte does not cause the driver to - automatically send that byte at the end of write I/O - operations. The application is responsible for placing the - EOS byte at the end of the data strings that it defines. - (National Instruments NI-488.2M Function Reference Manual) - For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosChar(0x10) - """ - intp = wxctb.new_intp() - wxctb.intp_assign(intp, eos) - return self.device.Ioctl(wxctb.CTB_GPIB_SET_EOS_CHAR,intp) - - def SetEosMode(self,mode): - """ - Set the EOS mode (handling).m_eosMode may be a combination - of bits ORed together. The following bits can be used: - 0x04: Terminate read when EOS is detected. - 0x08: Set EOI (End or identify line) with EOS on write function - 0x10: Compare all 8 bits of EOS byte rather than low 7 bits - (all read and write functions). For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosMode(0x04 | 0x08) - """ - intp = wxctb.new_intp() - wxctb.intp_assign(intp, mode) - return self.device.Ioctl(wxctb.CTB_GPIB_SET_EOS_MODE,intp) - -def GetKey(): - """ - Returns the current pressed key or '\0', if no key is pressed. - You can simply create a query loop with: - while GetKey() == '\0': - ... make some stuff ... - - """ - return wxctb.GetKey() - -def GetVersion(): - """ - Returns the version of the ctb python module. The numbering - has the following format: x.y.z - x.y means the version of the underlaying ctb lib, z the version - of the python port. - """ - return "0.16" diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/wxctb.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/wxctb.py deleted file mode 100644 index f9e0d2ee6e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/module/linux/wxctb.py +++ /dev/null @@ -1,264 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.40 -# -# Do not make changes to this file unless you know what you are doing--modify -# the SWIG interface file instead. - -from sys import version_info -if version_info >= (2,6,0): - def swig_import_helper(): - from os.path import dirname - import imp - fp = None - try: - fp, pathname, description = imp.find_module('_wxctb', [dirname(__file__)]) - except ImportError: - import _wxctb - return _wxctb - if fp is not None: - try: - _mod = imp.load_module('_wxctb', fp, pathname, description) - finally: - fp.close() - return _mod - _wxctb = swig_import_helper() - del swig_import_helper -else: - import _wxctb -del version_info -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. -def _swig_setattr_nondynamic(self,class_type,name,value,static=1): - if (name == "thisown"): return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'SwigPyObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - if (not static) or hasattr(self,name): - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - -def _swig_setattr(self,class_type,name,value): - return _swig_setattr_nondynamic(self,class_type,name,value,0) - -def _swig_getattr(self,class_type,name): - if (name == "thisown"): return self.this.own() - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError(name) - -def _swig_repr(self): - try: strthis = "proxy of " + self.this.__repr__() - except: strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -try: - _object = object - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 - - -def _swig_setattr_nondynamic_method(set): - def set_attr(self,name,value): - if (name == "thisown"): return self.this.own(value) - if hasattr(self,name) or (name == "this"): - set(self,name,value) - else: - raise AttributeError("You cannot add attributes to %s" % self) - return set_attr - - - -def new_intp(): - return _wxctb.new_intp() -new_intp = _wxctb.new_intp - -def copy_intp(*args, **kwargs): - return _wxctb.copy_intp(*args, **kwargs) -copy_intp = _wxctb.copy_intp - -def delete_intp(*args, **kwargs): - return _wxctb.delete_intp(*args, **kwargs) -delete_intp = _wxctb.delete_intp - -def intp_assign(*args, **kwargs): - return _wxctb.intp_assign(*args, **kwargs) -intp_assign = _wxctb.intp_assign - -def intp_value(*args, **kwargs): - return _wxctb.intp_value(*args, **kwargs) -intp_value = _wxctb.intp_value -class timer_control(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined") - __repr__ = _swig_repr - usecs = _swig_property(_wxctb.timer_control_usecs_get, _wxctb.timer_control_usecs_set) - exitflag = _swig_property(_wxctb.timer_control_exitflag_get, _wxctb.timer_control_exitflag_set) - exitfnc = _swig_property(_wxctb.timer_control_exitfnc_get, _wxctb.timer_control_exitfnc_set) -timer_control_swigregister = _wxctb.timer_control_swigregister -timer_control_swigregister(timer_control) - -class Timer(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self, *args, **kwargs): - this = _wxctb.new_Timer(*args, **kwargs) - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_Timer - __del__ = lambda self : None; - def start(self): return _wxctb.Timer_start(self) - def stop(self): return _wxctb.Timer_stop(self) -Timer_swigregister = _wxctb.Timer_swigregister -Timer_swigregister(Timer) - - -def sleepms(*args, **kwargs): - return _wxctb.sleepms(*args, **kwargs) -sleepms = _wxctb.sleepms -CTB_RESET = _wxctb.CTB_RESET -class IOBase(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _wxctb.delete_IOBase - __del__ = lambda self : None; - def ClassName(self): return _wxctb.IOBase_ClassName(self) - def Close(self): return _wxctb.IOBase_Close(self) - def Ioctl(self, *args, **kwargs): return _wxctb.IOBase_Ioctl(self, *args, **kwargs) - def IsOpen(self): return _wxctb.IOBase_IsOpen(self) - def Open(self, *args, **kwargs): return _wxctb.IOBase_Open(self, *args, **kwargs) - def PutBack(self, *args, **kwargs): return _wxctb.IOBase_PutBack(self, *args, **kwargs) - def Read(self, *args, **kwargs): return _wxctb.IOBase_Read(self, *args, **kwargs) - def ReadUntilEOS(self, *args, **kwargs): return _wxctb.IOBase_ReadUntilEOS(self, *args, **kwargs) - def Readv(self, *args, **kwargs): return _wxctb.IOBase_Readv(self, *args, **kwargs) - def Write(self, *args, **kwargs): return _wxctb.IOBase_Write(self, *args, **kwargs) - def Writev(self, *args, **kwargs): return _wxctb.IOBase_Writev(self, *args, **kwargs) -IOBase_swigregister = _wxctb.IOBase_swigregister -IOBase_swigregister(IOBase) - -ParityNone = _wxctb.ParityNone -ParityOdd = _wxctb.ParityOdd -ParityEven = _wxctb.ParityEven -ParityMark = _wxctb.ParityMark -ParitySpace = _wxctb.ParitySpace -LinestateDcd = _wxctb.LinestateDcd -LinestateCts = _wxctb.LinestateCts -LinestateDsr = _wxctb.LinestateDsr -LinestateDtr = _wxctb.LinestateDtr -LinestateRing = _wxctb.LinestateRing -LinestateRts = _wxctb.LinestateRts -LinestateNull = _wxctb.LinestateNull -class SerialPort_DCS(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - baud = _swig_property(_wxctb.SerialPort_DCS_baud_get, _wxctb.SerialPort_DCS_baud_set) - parity = _swig_property(_wxctb.SerialPort_DCS_parity_get, _wxctb.SerialPort_DCS_parity_set) - wordlen = _swig_property(_wxctb.SerialPort_DCS_wordlen_get, _wxctb.SerialPort_DCS_wordlen_set) - stopbits = _swig_property(_wxctb.SerialPort_DCS_stopbits_get, _wxctb.SerialPort_DCS_stopbits_set) - rtscts = _swig_property(_wxctb.SerialPort_DCS_rtscts_get, _wxctb.SerialPort_DCS_rtscts_set) - xonxoff = _swig_property(_wxctb.SerialPort_DCS_xonxoff_get, _wxctb.SerialPort_DCS_xonxoff_set) - buf = _swig_property(_wxctb.SerialPort_DCS_buf_get, _wxctb.SerialPort_DCS_buf_set) - def __init__(self): - this = _wxctb.new_SerialPort_DCS() - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_SerialPort_DCS - __del__ = lambda self : None; - def GetSettings(self): return _wxctb.SerialPort_DCS_GetSettings(self) -SerialPort_DCS_swigregister = _wxctb.SerialPort_DCS_swigregister -SerialPort_DCS_swigregister(SerialPort_DCS) - -class SerialPort_EINFO(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - brk = _swig_property(_wxctb.SerialPort_EINFO_brk_get, _wxctb.SerialPort_EINFO_brk_set) - frame = _swig_property(_wxctb.SerialPort_EINFO_frame_get, _wxctb.SerialPort_EINFO_frame_set) - overrun = _swig_property(_wxctb.SerialPort_EINFO_overrun_get, _wxctb.SerialPort_EINFO_overrun_set) - parity = _swig_property(_wxctb.SerialPort_EINFO_parity_get, _wxctb.SerialPort_EINFO_parity_set) - def __init__(self): - this = _wxctb.new_SerialPort_EINFO() - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_SerialPort_EINFO - __del__ = lambda self : None; -SerialPort_EINFO_swigregister = _wxctb.SerialPort_EINFO_swigregister -SerialPort_EINFO_swigregister(SerialPort_EINFO) - -CTB_SER_GETEINFO = _wxctb.CTB_SER_GETEINFO -CTB_SER_GETBRK = _wxctb.CTB_SER_GETBRK -CTB_SER_GETFRM = _wxctb.CTB_SER_GETFRM -CTB_SER_GETOVR = _wxctb.CTB_SER_GETOVR -CTB_SER_GETPAR = _wxctb.CTB_SER_GETPAR -CTB_SER_GETINQUE = _wxctb.CTB_SER_GETINQUE -CTB_SER_SETPAR = _wxctb.CTB_SER_SETPAR -class SerialPort_x(IOBase): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _wxctb.delete_SerialPort_x - __del__ = lambda self : None; - def ClassName(self): return _wxctb.SerialPort_x_ClassName(self) - def ChangeLineState(self, *args, **kwargs): return _wxctb.SerialPort_x_ChangeLineState(self, *args, **kwargs) - def ClrLineState(self, *args, **kwargs): return _wxctb.SerialPort_x_ClrLineState(self, *args, **kwargs) - def GetLineState(self): return _wxctb.SerialPort_x_GetLineState(self) - def GetSettingsAsString(self): return _wxctb.SerialPort_x_GetSettingsAsString(self) - def Ioctl(self, *args, **kwargs): return _wxctb.SerialPort_x_Ioctl(self, *args, **kwargs) - def SendBreak(self, *args, **kwargs): return _wxctb.SerialPort_x_SendBreak(self, *args, **kwargs) - def SetBaudrate(self, *args, **kwargs): return _wxctb.SerialPort_x_SetBaudrate(self, *args, **kwargs) - def SetLineState(self, *args, **kwargs): return _wxctb.SerialPort_x_SetLineState(self, *args, **kwargs) - def SetParityBit(self, *args, **kwargs): return _wxctb.SerialPort_x_SetParityBit(self, *args, **kwargs) - IsStandardRate = staticmethod(_wxctb.SerialPort_x_IsStandardRate) -SerialPort_x_swigregister = _wxctb.SerialPort_x_swigregister -SerialPort_x_swigregister(SerialPort_x) - -def SerialPort_x_IsStandardRate(*args, **kwargs): - return _wxctb.SerialPort_x_IsStandardRate(*args, **kwargs) -SerialPort_x_IsStandardRate = _wxctb.SerialPort_x_IsStandardRate - -COM1 = "/dev/ttyS0" -COM2 = "/dev/ttyS1" -COM3 = "/dev/ttyS2" -COM4 = "/dev/ttyS3" -COM5 = "/dev/ttyS4" -COM6 = "/dev/ttyS5" -COM7 = "/dev/ttyS6" -COM8 = "/dev/ttyS7" -COM9 = "/dev/ttyS8" - -class SerialPort(SerialPort_x): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self): - this = _wxctb.new_SerialPort() - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_SerialPort - __del__ = lambda self : None; - def ChangeLineState(self, *args, **kwargs): return _wxctb.SerialPort_ChangeLineState(self, *args, **kwargs) - def ClrLineState(self, *args, **kwargs): return _wxctb.SerialPort_ClrLineState(self, *args, **kwargs) - def GetLineState(self): return _wxctb.SerialPort_GetLineState(self) - def Ioctl(self, *args, **kwargs): return _wxctb.SerialPort_Ioctl(self, *args, **kwargs) - def IsOpen(self): return _wxctb.SerialPort_IsOpen(self) - def Read(self, *args, **kwargs): return _wxctb.SerialPort_Read(self, *args, **kwargs) - def SendBreak(self, *args, **kwargs): return _wxctb.SerialPort_SendBreak(self, *args, **kwargs) - def SetBaudrate(self, *args, **kwargs): return _wxctb.SerialPort_SetBaudrate(self, *args, **kwargs) - def SetLineState(self, *args, **kwargs): return _wxctb.SerialPort_SetLineState(self, *args, **kwargs) - def SetParityBit(self, *args, **kwargs): return _wxctb.SerialPort_SetParityBit(self, *args, **kwargs) - def Write(self, *args, **kwargs): return _wxctb.SerialPort_Write(self, *args, **kwargs) -SerialPort_swigregister = _wxctb.SerialPort_swigregister -SerialPort_swigregister(SerialPort) - - -def GetKey(): - return _wxctb.GetKey() -GetKey = _wxctb.GetKey - - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/parity.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/parity.py deleted file mode 100755 index 910361b8e0..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/parity.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python - -import getopt, time, sys - -sys.path.insert( 0, r'/home/jb/project/libctb-0.16/python/module/linux') - -import ctb - -def main(): - - baudrate = 19200 - - devname = "" - - protocol = '8N1' - - try: - opt,arg = getopt.getopt(sys.argv[1:], - 'b:d:p:', - ['baudrate=', - 'device=', - 'protocol=' - ]) - - except getopt.GetoptError: - print "usage: parity.py [options]\n"\ - "\t-b baudrate\n"\ - "\t--baudrate=baudrate"\ - "\t-d device\n"\ - "\t--device=serial device name like /dev/ttyS0 or COM1\n"\ - "\t-h\n"\ - "\t--help print this\n"\ - "\n" - sys.exit(0) - - for o,a in opt: - - if o in ("-b","--baudrate"): - - baudrate = int(a) - - if o in ("-d","--device"): - - devname = a - - if o in ("-p","--protocol"): - - protocol = a - - - print "Using ctb version " + ctb.GetVersion() - - dev = ctb.SerialPort() - - if dev.Open( devname, baudrate, protocol ) < 0: - - print "Cannot open " + devname + "\n" - - # send the following string with a always set parity bit - dev.SetParityBit( 1 ) - - dev.Writev( "Hello World" ) - - # send the following string with a always cleared parity bit - dev.SetParityBit( 0 ) - - dev.Writev( "Hello World" ) - -main() - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/protocol.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/protocol.py deleted file mode 100755 index ff1731b895..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/protocol.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/python - -import getopt, time, sys - -sys.path.insert( 0, r'/home/jb/project/libctb-0.16/python/module/linux') - -import ctb - -def DataBlock(): - data = '' - for c in range( 0, 256): - data += '%c' % c - - return data - -def main(): - - baudrate = 19200 - - devname = "" - - try: - opt,arg = getopt.getopt(sys.argv[1:], - 'b:d:', - ['baudrate=', - 'device=' - ]) - - except getopt.GetoptError: - print "usage: protocol.py [options]\n"\ - "\t-b baudrate\n"\ - "\t--baudrate=baudrate"\ - "\t-d device\n"\ - "\t--device=serial device name like /dev/ttyS0 or COM1\n"\ - "\t-h\n"\ - "\t--help print this\n"\ - "\n" - sys.exit(0) - - for o,a in opt: - - if o in ("-b","--baudrate"): - - baudrate = int(a) - - if o in ("-d","--device"): - - devname = a - - print "Using ctb version " + ctb.GetVersion() - - dev = ctb.SerialPort() - - protocols = [ - '8N1','8O1','8E1','8S1','8M1' - ] - - dev.SetTimeout( 1000 ) - - for protocol in protocols: - - if dev.Open( devname, baudrate, protocol ) < 0: - - print "Cannot open " + devname + "\n" - - sys.exit( 1 ) - - else: - - print( "%i %s" % ( baudrate, protocol ) ) - - for i in range(0, 4 ): - - dev.Writev( "\x33" ) - - time.sleep( 0.0006 ) - - dev.Writev( "\x31" ) - - time.sleep( 0.0006 ) - - time.sleep( 0.5 ) - - dev.Close() - - -main() - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/rtsdtr.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/rtsdtr.py deleted file mode 100755 index e67a9ffd3b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/samples/rtsdtr.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python - -import getopt, time, sys - -sys.path.insert( 0, r'/home/jb/project/libctb-0.16/python/module/linux') - -import ctb - -def main(): - - devname = "" - - try: - opt,arg = getopt.getopt(sys.argv[1:], - 'd:', - ['device=' - ]) - - except getopt.GetoptError: - print "usage: parity.py [options]\n"\ - "\t-d device\n"\ - "\t--device=serial device name like /dev/ttyS0 or COM1\n"\ - "\t-h\n"\ - "\t--help print this\n"\ - "\n" - sys.exit(0) - - for o,a in opt: - - if o in ("-d","--device"): - - devname = a - - print "Using ctb version " + ctb.GetVersion() - - dev = ctb.SerialPort() - - if dev.Open( devname, 38400 ) < 0: - - print "Cannot open " + devname + "\n" - - dev.SetLineState( ctb.DTR ) - - dev.ClrLineState( ctb.RTS ) - - for i in range( 0, 100 ) : - - time.sleep( 0.01 ) - - dev.ChangeLineState( ctb.DTR | ctb.RTS ) - -main() - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.html b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.html deleted file mode 100644 index 7a5732fa9b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.html +++ /dev/null @@ -1,353 +0,0 @@ - - -Python: module ctb - - - - -
 
- 
ctb
index
/mnt/s/wxaddons/wxctb-0.9/SWIG/ctb.py
-

-

- - - - - -
 
-Modules
       
re
-
sys
-
wxctb
-

- - - - - -
 
-Classes
       
-
wxIOBase -
-
-
wxGPIB -
wxSerialPort -
-
-
-

- - - - - - - -
 
-class wxGPIB(wxIOBase)
   wxGPIB class
 
 Methods defined here:
-
GetError(self)
- -
GetSTB(self)
Returns the value of the internal GPIB status byte register.
- -
Ibrd(self, length)
# This is only for internal usage!!!
- -
Ibwrt(self, string)
# This is only for internal usage!!!
- -
Open(self, devname, adr)
Open(gpibdevice,address)
-Opens a connected device at the GPIB bus. gpibdevice means the
-controller, (mostly "gpib1"), address the address of the desired
-device in the range 1...31. For example:
-dev = wxGPIB()
-dev.Open("gpib1",17)
-Opens the device with the address 17.
-Open returns >= 0 or a negativ value, if something going wrong.
- -
Reset(self)
Resets the connected device. In the GPIB definition, the device
-should be reset to it's initial state, so you can restart a
-formely lost communication.
- -
ResetBus(self)
The command asserts the GPIB interface clear (IFC) line for
-ast least 100us if the GPIB board is the system controller.
-This initializes the GPIB and makes the interface CIC and
-active controller with ATN asserted.
-Note! The IFC signal resets only the GPIB interface functions
-of the bus devices and not the internal device functions.
-For a device reset you should use the Reset() command above.
- -
__del__(self)
- -
__init__(self)
- -
-Methods inherited from wxIOBase:
-
Close(self)
- -
GetTimeout(self)
Returns the internal timeout value in milliseconds
- -
Ioctl(self, cmd, arg)
- -
PutBack(self, char)
- -
Read(self, length)
Try to read the given count of data (length) and returns the
-successfully readed number of data. The function never blocks.
-For example:
-readed = dev.Read(100)
- -
ReadBinary(self, eos='\n')
Special SCPI command. Read the next data coded as a SCPI
-binary format.
-A binary data transfer will be startet by '#'. The next byte
-tells the count of bytes for the binary length header,
-following by the length bytes. After these the data begins.
-For example:
-#500004xxxx
-The header length covers 5 Byte, the length of the binary
-data is 4 (x means the binary data bytes)
- -
ReadUntilEOS(self, eos='\n', quota=0)
ReadUntilEOS(eosString="\n",timeout=1000)
-Reads data until the given eos string was received (default is
-the linefeed character (0x0a) or the internal timeout
-(default 1000ms) was reached.
-ReadUntilEOS returns the result as the following tuple:
-['received string',state,readedBytes]
-If a timeout occurred, state is 0, otherwise 1
- -
Readv(self, length)
Try to read the given count of data. Readv blocks until all data
-was readed successfully or the internal timeout, set with the
-class member function SetTimeout(timeout), was reached.
-Returns the readed data.
- -
SetTimeout(self, timeout)
Set the internal timeout value in milliseconds for all blocked
-operations like ReadUntilEOS, Readv and Writev.
- -
Write(self, string)
Writes the given string to the device and returns immediately.
-Write returns the number of data bytes successfully written or a
-negativ number if an error occured. For some circumstances, not
-the complete string was written.
-So you have to verify the return value to check this out.
- -
Writev(self, string)
Writes the given string to the device. The function blocks until
-the complete string was written or the internal timeout, set with
-SetTimeout(timeout), was reached.
-Writev returns the number of data successfully written or a
-negativ value, if an errors occurred.
- -

- - - - - -
 
-class wxIOBase
    Methods defined here:
-
Close(self)
- -
GetTimeout(self)
Returns the internal timeout value in milliseconds
- -
Ioctl(self, cmd, arg)
- -
Open(self)
- -
PutBack(self, char)
- -
Read(self, length)
Try to read the given count of data (length) and returns the
-successfully readed number of data. The function never blocks.
-For example:
-readed = dev.Read(100)
- -
ReadBinary(self, eos='\n')
Special SCPI command. Read the next data coded as a SCPI
-binary format.
-A binary data transfer will be startet by '#'. The next byte
-tells the count of bytes for the binary length header,
-following by the length bytes. After these the data begins.
-For example:
-#500004xxxx
-The header length covers 5 Byte, the length of the binary
-data is 4 (x means the binary data bytes)
- -
ReadUntilEOS(self, eos='\n', quota=0)
ReadUntilEOS(eosString="\n",timeout=1000)
-Reads data until the given eos string was received (default is
-the linefeed character (0x0a) or the internal timeout
-(default 1000ms) was reached.
-ReadUntilEOS returns the result as the following tuple:
-['received string',state,readedBytes]
-If a timeout occurred, state is 0, otherwise 1
- -
Readv(self, length)
Try to read the given count of data. Readv blocks until all data
-was readed successfully or the internal timeout, set with the
-class member function SetTimeout(timeout), was reached.
-Returns the readed data.
- -
ResetBus(self)
If the underlaying interface needs some special reset operations
-(for instance the GPIB distinguish between a normal device reset
-and a special bus reset), you can put some code here)
- -
SetTimeout(self, timeout)
Set the internal timeout value in milliseconds for all blocked
-operations like ReadUntilEOS, Readv and Writev.
- -
Write(self, string)
Writes the given string to the device and returns immediately.
-Write returns the number of data bytes successfully written or a
-negativ number if an error occured. For some circumstances, not
-the complete string was written.
-So you have to verify the return value to check this out.
- -
Writev(self, string)
Writes the given string to the device. The function blocks until
-the complete string was written or the internal timeout, set with
-SetTimeout(timeout), was reached.
-Writev returns the number of data successfully written or a
-negativ value, if an errors occurred.
- -
__del__(self)
- -
__init__(self)
- -

- - - - - -
 
-class wxSerialPort(wxIOBase)
    Methods defined here:
-
ChangeLineState(self, lineState)
Change (toggle) the state of each the lines given in the
-linestate parameter. Possible values are wxSERIAL_LINESTATE_DTR
-(means the DTR signal) and/or wxSERIAL_LINESTATE_RTS (RTS signal).
-For example to toggle the RTS line only:
-dev.ChangeLineState(wxSERIAL_LINESTATE_RTS)
- -
ClrLineState(self, lineState)
Clear the lines given in the linestate parameter. Possible
-values are wxSERIAL_LINESTATE_DTR (means the DTR signal) and/or
-wxSERIAL_LINESTATE_RTS (RTS signal). For example to clear only
-the RTS line:
-dev.ClrLineState(wxSERIAL_LINESTATE_RTS)
- -
GetAvailableBytes(self)
Returns the available bytes in the input queue of the serial
-driver.
- -
GetCommErrors(self)
Get the internal communication errors like breaks, framing,
-parity or overrun errors.
-Returns the count of each error as a tuple like this:
-(b,f,o,p) = dev.GetCommErrors()
-b: breaks, f: framing errors,  o: overruns, p: parity errors
- -
GetLineState(self)
Returns the current linestates of the CTS, DCD, DSR and RING
-signal line as an integer value with the appropriate bits or
--1 on error.
-For example:
-lines = dev.GetLineState()
-if lines & wxSERIAL_LINESTATE_CTS:
-    print "CTS is on"
- -
Open(self, devname, baudrate, protocol='8N1', handshake='no_handshake')
Open the device devname with the given baudrate, the protocol
-like '8N1' (default) and the use of the handshake [no_handshake
-(default), rtscts or xonxoff]
-For example:
-At Linux:
-dev = wxSerialPort()
-dev.Open("/dev/ttyS0",115200)
-or with a datalen of 7 bits, even parity, 2 stopbits and rts/cts
-handshake:
-dev.Open("/dev/ttyS0",115200,'7E2',True)
-At Windows:
-dev = wxSerialPort()
-dev.Open("COM1",115200)
-dev.Open("COM1",115200,'7E2',True)
-Returns the handle on success or a negativ value on failure.
- -
Reset(self)
Send a break for 0.25s.
- -
SetBaudRate(self, baudrate)
Set the baudrate for the device.
- -
SetLineState(self, lineState)
Set the lines given in the linestate parameter. Possible
-values are wxSERIAL_LINESTATE_DTR (means the DTR signal) and/or
-wxSERIAL_LINESTATE_RTS (RTS signal). For example to set both:
-dev.SetLineState(wxSERIAL_LINESTATE_DTR | wxSERIAL_LINESTATE_RTS)
- -
__del__(self)
- -
__init__(self)
- -
-Methods inherited from wxIOBase:
-
Close(self)
- -
GetTimeout(self)
Returns the internal timeout value in milliseconds
- -
Ioctl(self, cmd, arg)
- -
PutBack(self, char)
- -
Read(self, length)
Try to read the given count of data (length) and returns the
-successfully readed number of data. The function never blocks.
-For example:
-readed = dev.Read(100)
- -
ReadBinary(self, eos='\n')
Special SCPI command. Read the next data coded as a SCPI
-binary format.
-A binary data transfer will be startet by '#'. The next byte
-tells the count of bytes for the binary length header,
-following by the length bytes. After these the data begins.
-For example:
-#500004xxxx
-The header length covers 5 Byte, the length of the binary
-data is 4 (x means the binary data bytes)
- -
ReadUntilEOS(self, eos='\n', quota=0)
ReadUntilEOS(eosString="\n",timeout=1000)
-Reads data until the given eos string was received (default is
-the linefeed character (0x0a) or the internal timeout
-(default 1000ms) was reached.
-ReadUntilEOS returns the result as the following tuple:
-['received string',state,readedBytes]
-If a timeout occurred, state is 0, otherwise 1
- -
Readv(self, length)
Try to read the given count of data. Readv blocks until all data
-was readed successfully or the internal timeout, set with the
-class member function SetTimeout(timeout), was reached.
-Returns the readed data.
- -
ResetBus(self)
If the underlaying interface needs some special reset operations
-(for instance the GPIB distinguish between a normal device reset
-and a special bus reset), you can put some code here)
- -
SetTimeout(self, timeout)
Set the internal timeout value in milliseconds for all blocked
-operations like ReadUntilEOS, Readv and Writev.
- -
Write(self, string)
Writes the given string to the device and returns immediately.
-Write returns the number of data bytes successfully written or a
-negativ number if an error occured. For some circumstances, not
-the complete string was written.
-So you have to verify the return value to check this out.
- -
Writev(self, string)
Writes the given string to the device. The function blocks until
-the complete string was written or the internal timeout, set with
-SetTimeout(timeout), was reached.
-Writev returns the number of data successfully written or a
-negativ value, if an errors occurred.
- -

- - - - - -
 
-Functions
       
GetKey()
Returns the current pressed key or '', if no key is pressed.
-You can simply create a query loop with:
-while GetKey() == '':
-    ... make some stuff ...
-
abstract()
-

- - - - - -
 
-Data
       wxSERIAL_LINESTATE_CTS = 32
-wxSERIAL_LINESTATE_DCD = 64
-wxSERIAL_LINESTATE_DSR = 256
-wxSERIAL_LINESTATE_DTR = 2
-wxSERIAL_LINESTATE_NULL = 0
-wxSERIAL_LINESTATE_RING = 128
-wxSERIAL_LINESTATE_RTS = 4
- \ No newline at end of file diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.py deleted file mode 100644 index 6b541ffe39..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/ctb.py +++ /dev/null @@ -1,455 +0,0 @@ -import wxctb, sys, re - -DCD = wxctb.LinestateDcd -CTS = wxctb.LinestateCts -DSR = wxctb.LinestateDsr -DTR = wxctb.LinestateDtr -RING = wxctb.LinestateRing -RTS = wxctb.LinestateRts -NULL = wxctb.LinestateNull - -def abstract(): - import inspect - caller = inspect.getouterframes(inspect.currentframe())[1][3] - raise NotImplementedError(caller + ' must be implemented in subclass') - -class IOBase: - def __init__(self): - self.device = None - # set timeout to 1000ms (the default) - self.timeout = 1000 - - def __del__(self): - pass - - def Close(self): - if self.device: - self.device.Close() - - def GetTimeout(self): - """ - Returns the internal timeout value in milliseconds - """ - return self.timeout - - def Ioctl(self,cmd,arg): - if self.device: - self.device.Ioctl(cmd,arg) - - def Open(self): - abstract() - - def PutBack(self,char): - return self.device.PutBack(char) - - def Read(self,length): - """ - Try to read the given count of data (length) and returns the - successfully readed number of data. The function never blocks. - For example: - readed = dev.Read(100) - """ - buf = "\x00"*(length+1) - rd = self.device.Read(buf,length) - return buf[0:rd] - - def ReadBinary(self,eos="\n"): - """ - Special SCPI command. Read the next data coded as a SCPI - binary format. - A binary data transfer will be startet by '#'. The next byte - tells the count of bytes for the binary length header, - following by the length bytes. After these the data begins. - For example: - #500004xxxx - The header length covers 5 Byte, the length of the binary - data is 4 (x means the binary data bytes) - """ - try: - eoslen = len(eos) - b=self.Readv(2) - if len(b) == 2: - hl = int(b[1]) - b = self.Readv(hl) - if len(b) == hl: - dl = int(b) - # don't left over the eos string or character in the - # device input buffer - data = self.Readv(dl+eoslen) - # check, if the binary data block is complete - if data[dl] == '#': - # not complete, another block is following - for c in data[dl:dl+eoslen]: - self.PutBack(c) - - data = data[:dl] + self.ReadBinary() - return data - except: - pass - return '' - - def ReadUntilEOS(self,eos="\n",quota=0): - """ - ReadUntilEOS(eosString=\"\\n\",timeout=1000) - Reads data until the given eos string was received (default is - the linefeed character (0x0a) or the internal timeout - (default 1000ms) was reached. - ReadUntilEOS returns the result as the following tuple: - ['received string',state,readedBytes] - If a timeout occurred, state is 0, otherwise 1 - """ - return self.device.ReadUntilEOS("",0,eos,self.timeout,quota) - - def Readv(self,length): - """ - Try to read the given count of data. Readv blocks until all data - was readed successfully or the internal timeout, set with the - class member function SetTimeout(timeout), was reached. - Returns the readed data. - """ - buf = "\x00"*length - rd = self.device.Readv(buf,length,self.timeout) - return buf[0:rd] - - def ResetBus(self): - """ - If the underlaying interface needs some special reset operations - (for instance the GPIB distinguish between a normal device reset - and a special bus reset), you can put some code here) - """ - pass - - def SetTimeout(self,timeout): - """ - Set the internal timeout value in milliseconds for all blocked - operations like ReadUntilEOS, Readv and Writev. - """ - self.timeout = timeout - - def Write(self,string): - """ - Writes the given string to the device and returns immediately. - Write returns the number of data bytes successfully written or a - negativ number if an error occured. For some circumstances, not - the complete string was written. - So you have to verify the return value to check this out. - """ - return self.device.Write(string,len(string)) - - def Writev(self,string): - """ - Writes the given string to the device. The function blocks until - the complete string was written or the internal timeout, set with - SetTimeout(timeout), was reached. - Writev returns the number of data successfully written or a - negativ value, if an errors occurred. - """ - return self.device.Writev(string,len(string),self.timeout) - -class SerialPort(IOBase): - def __init__(self): - IOBase.__init__(self) - - def __del__(self): - self.Close() - - def ChangeLineState(self,lineState): - """ - Change (toggle) the state of each the lines given in the - linestate parameter. Possible values are DTR and/or RTS. - For example to toggle the RTS line only: - dev.ChangeLineState(RTS) - """ - self.device.ChangeLineState(lineState) - - def ClrLineState(self,lineState): - """ - Clear the lines given in the linestate parameter. Possible - values are DTR and/or RTS. For example to clear only - the RTS line: - dev.ClrLineState(RTS) - """ - self.device.ClrLineState(lineState) - - def GetAvailableBytes(self): - """ - Returns the available bytes in the input queue of the serial - driver. - """ - n = wxctb.new_intp() - wxctb.intp_assign(n, 0) - self.device.Ioctl(wxctb.CTB_SER_GETINQUE,n) - return wxctb.intp_value(n) - - def GetCommErrors(self): - """ - Get the internal communication errors like breaks, framing, - parity or overrun errors. - Returns the count of each error as a tuple like this: - (b,f,o,p) = dev.GetCommErrors() - b: breaks, f: framing errors, o: overruns, p: parity errors - """ - einfo = wxctb.SerialPort_EINFO() - self.device.Ioctl(wxctb.CTB_SER_GETEINFO,einfo) - return einfo.brk,einfo.frame,einfo.overrun,einfo.parity - - def GetLineState(self): - """ - Returns the current linestates of the CTS, DCD, DSR and RING - signal line as an integer value with the appropriate bits or - -1 on error. - For example: - lines = dev.GetLineState() - if lines & CTS: - print \"CTS is on\" - """ - return self.device.GetLineState() - - def Open(self,devname,baudrate,protocol='8N1',handshake='no_handshake'): - """ - Open the device devname with the given baudrate, the protocol - like '8N1' (default) and the use of the handshake [no_handshake - (default), rtscts or xonxoff] - For example: - At Linux: - dev = SerialPort() - dev.Open(\"/dev/ttyS0\",115200) - or with a datalen of 7 bits, even parity, 2 stopbits and rts/cts - handshake: - dev.Open(\"/dev/ttyS0\",115200,'7E2',True) - At Windows: - dev = SerialPort() - dev.Open(\"COM1\",115200) - dev.Open(\"COM1\",115200,'7E2',True) - Returns the handle on success or a negativ value on failure. - """ - # the following parity values are valid: - # N:None, O:Odd, E:Even, M:Mark, S:Space - parity = {'N':0,'O':1,'E':2,'M':3,'S':4} - # the regular expression ensures a valid value for the datalen - # (5...8 bit) and the count of stopbits (1,2) - reg=re.compile(r"(?P[8765])"r"(?P

[NOEMS])"r"(?P[12])") - self.device = wxctb.SerialPort() - dcs = wxctb.SerialPort_DCS() - dcs.baud = baudrate - res = reg.search(protocol) - # handle the given protocol - if res: - dcs.wordlen = int(res.group('w')) - dcs.stopbits = int(res.group('s')) - dcs.parity = parity[res.group('p')] - # valid handshake are no one, rts/cts or xon/xoff - if handshake == 'rtscts': - dcs.rtscts = True - elif handshake == 'xonxoff': - dcs.xonxoff = True - - return self.device.Open(devname,dcs) - - def Reset(self): - """ - Send a break for 0.25s. - """ - self.device.SendBreak(0) - - def SetBaudrate(self,baudrate): - """ - Set the baudrate for the device. - """ - self.device.SetBaudrate(baudrate) - - def SetLineState(self,lineState): - """ - Set the lines given in the linestate parameter. Possible - values are DTR and/or RTS. For example to set both: - dev.SetLineState( DTR | RTS) - """ - self.device.SetLineState(lineState) - - def SetParityBit(self,parity): - """ - Set the parity bit explicitly to 0 or 1. Use this function, if - you would like to simulate a 9 bit wordlen at what the ninth bit - was represented by the parity bit value. For example: - dev.SetParityBit( 0 ) - dev.Write('some data sent with parity 0') - dev.SetParityBit( 1 ) - dev.Write('another sequence with parity 1') - """ - return self.device.SetParityBit( parity ) - -class GpibDevice(IOBase): - """ - GPIB class - """ - def __init__(self): - IOBase.__init__(self) - - def __del__(self): - self.Close() - - def FindListeners(self,board = 0): - """ - Returns the address of the connected devices as a list. - If no device is listening, the list is empty. If an error - occurs an IOError exception raised. For example: - g = GPIB() - listeners = g.FindListeners() - """ - listeners = wxctb.GPIB_x_FindListeners(board) - if listeners < 0: - raise IOError("GPIB board error") - result = [] - for i in range(1,31): - if listeners & (1 << i): - result.append(i) - return result - - def GetEosChar(self): - """ - Get the internal EOS termination character (see SetEosChar). - For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosChar() - """ - eos = wxctb.new_intp() - wxctb.intp_assign(eos, 0) - self.device.Ioctl(wxctb.CTB_GPIB_GET_EOS_CHAR,eos) - return wxctb.intp_value(eos) - - def GetEosMode(self): - """ - Get the internal EOS mode (see SetEosMode). - For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosMode() - """ - mode = wxctb.new_intp() - wxctb.intp_assign(mode, 0) - self.device.Ioctl(wxctb.CTB_GPIB_GET_EOS_MODE,mode) - return wxctb.intp_value(mode) - - def GetError(self): - errorString = " "*256 - self.device.GetError(errorString,256) - return errorString - - def GetSTB(self): - """ - Returns the value of the internal GPIB status byte register. - """ - stb = wxctb.new_intp() - wxctb.intp_assign(stb, 0) - self.device.Ioctl(wxctb.CTB_GPIB_GETRSP,stb) - return wxctb.intp_value(stb) - - # This is only for internal usage!!! - def Ibrd(self,length): - buf = "\x00"*length - state = self.device.Ibrd(buf,length) - return state,buf - - # This is only for internal usage!!! - def Ibwrt(self,string): - return self.device.Ibwrt(string,len(string)) - - def Open(self,devname,adr,eosChar=10,eosMode=0x08|0x04): - """ - Open(gpibdevice,address,eosChar,eosMode) - Opens a connected device at the GPIB bus. gpibdevice means the - controller, (mostly \"gpib1\"), address the address of the desired - device in the range 1...31. The eosChar defines the EOS character - (default is linefeed), eosMode may be a combination of bits ORed - together. The following bits can be used: - 0x04: Terminate read when EOS is detected. - 0x08: Set EOI (End or identify line) with EOS on write function - 0x10: Compare all 8 bits of EOS byte rather than low 7 bits - (all read and write functions). Default is 0x12 - For example: - dev = GPIB() - dev.Open(\"gpib1\",17) - Opens the device with the address 17, linefeed as EOS (default) - and eos mode with 0x04 and 0x08. - Open returns >= 0 or a negativ value, if something going wrong. - """ - self.device = wxctb.GpibDevice() - dcs = wxctb.Gpib_DCS() - dcs.m_address1 = adr - dcs.m_eosChar = eosChar - dcs.m_eosMode = eosMode - result = self.device.Open(devname,dcs) - return result - - def Reset(self): - """ - Resets the connected device. In the GPIB definition, the device - should be reset to it's initial state, so you can restart a - formely lost communication. - """ - self.device.Ioctl(wxctb.CTB_RESET,None) - - def ResetBus(self): - """ - The command asserts the GPIB interface clear (IFC) line for - ast least 100us if the GPIB board is the system controller. - This initializes the GPIB and makes the interface CIC and - active controller with ATN asserted. - Note! The IFC signal resets only the GPIB interface functions - of the bus devices and not the internal device functions. - For a device reset you should use the Reset() command above. - """ - self.device.Ioctl(wxctb.CTB_GPIB_RESET_BUS,None) - - def SetEosChar(self,eos): - """ - Configure the end-of-string (EOS) termination character. - Note! Defining an EOS byte does not cause the driver to - automatically send that byte at the end of write I/O - operations. The application is responsible for placing the - EOS byte at the end of the data strings that it defines. - (National Instruments NI-488.2M Function Reference Manual) - For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosChar(0x10) - """ - intp = wxctb.new_intp() - wxctb.intp_assign(intp, eos) - return self.device.Ioctl(wxctb.CTB_GPIB_SET_EOS_CHAR,intp) - - def SetEosMode(self,mode): - """ - Set the EOS mode (handling).m_eosMode may be a combination - of bits ORed together. The following bits can be used: - 0x04: Terminate read when EOS is detected. - 0x08: Set EOI (End or identify line) with EOS on write function - 0x10: Compare all 8 bits of EOS byte rather than low 7 bits - (all read and write functions). For example: - g = GPIB() - g.Open(\"gpib1\",1) - eos = g.GetEosMode(0x04 | 0x08) - """ - intp = wxctb.new_intp() - wxctb.intp_assign(intp, mode) - return self.device.Ioctl(wxctb.CTB_GPIB_SET_EOS_MODE,intp) - -def GetKey(): - """ - Returns the current pressed key or '\0', if no key is pressed. - You can simply create a query loop with: - while GetKey() == '\0': - ... make some stuff ... - - """ - return wxctb.GetKey() - -def GetVersion(): - """ - Returns the version of the ctb python module. The numbering - has the following format: x.y.z - x.y means the version of the underlaying ctb lib, z the version - of the python port. - """ - return "0.16" diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/gpib.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/gpib.i deleted file mode 100644 index 752ecd3a18..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/gpib.i +++ /dev/null @@ -1,96 +0,0 @@ -%{ -#include "ctb-0.16/gpib.h" -%} - -%include iobase.i - -namespace ctb { - -%typemap(in) void * dcs (Gpib_DCS tmp) { - /* dont check for list */ - $1 = &tmp; -} - -enum GpibTimeout -{ - GpibTimeoutNONE = 0, - GpibTimeout10us, - GpibTimeout30us, - GpibTimeout100us, - GpibTimeout300us, - GpibTimeout1ms, - GpibTimeout3ms, - GpibTimeout10ms, - GpibTimeout30ms, - GpibTimeout100ms, - GpibTimeout300ms, - GpibTimeout1s, - GpibTimeout3s, - GpibTimeout10s, - GpibTimeout30s, - GpibTimeout100s, - GpibTimeout300s, - GpibTimeout1000s -}; - -struct Gpib_DCS -{ - int m_address1; - int m_address2; - GpibTimeout m_timeout; - bool m_eot; - unsigned char m_eosChar; - unsigned char m_eosMode; - Gpib_DCS(); - ~Gpib_DCS(); - char* GetSettings(); -}; - -enum { - CTB_GPIB_SETADR = CTB_GPIB, - CTB_GPIB_GETRSP, - CTB_GPIB_GETSTA, - CTB_GPIB_GETERR, - CTB_GPIB_GETLINES, - CTB_GPIB_SETTIMEOUT, - CTB_GPIB_GTL, - CTB_GPIB_REN, - CTB_GPIB_RESET_BUS, - CTB_GPIB_SET_EOS_CHAR, - CTB_GPIB_GET_EOS_CHAR, - CTB_GPIB_SET_EOS_MODE, - CTB_GPIB_GET_EOS_MODE -}; - -class GpibDevice : public IOBase -{ -protected: - int m_board; - int m_hd; - int m_state; - int m_error; - int m_count; - int m_asyncio; - Gpib_DCS m_dcs; - int CloseDevice(); - int OpenDevice(const char* devname, void* dcs); - virtual const char* GetErrorString(int error,bool detailed); -public: - GpibDevice(); - virtual ~GpibDevice(); - const char* ClassName(); - virtual const char* GetErrorDescription(int error); - virtual const char* GetErrorNotation(int error); - virtual char* GetSettingsAsString(); - int Ibrd(char* buf,size_t len); - int Ibwrt(char* buf,size_t len); - virtual int Ioctl(int cmd,void* args); - int IsOpen(); - int Read(char* buf,size_t len); - int Write(char* buf,size_t len); - - static int FindListeners(int board = 0); - -}; - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/iobase.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/iobase.i deleted file mode 100644 index c6bc452adb..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/iobase.i +++ /dev/null @@ -1,59 +0,0 @@ -%{ -#include "ctb-0.16/iobase.h" -%} - -namespace ctb { - -enum { - CTB_RESET = CTB_COMMON -}; - -%typemap(in) char *& readbuf (char * tmp) { - /* dont check for list */ - $1 = &tmp; -} - -%typemap(argout) char *& readbuf { - PyObject * plist = PyList_New(2); - PyList_SetItem(plist, 0, PyString_FromString(*$1)); - PyList_SetItem(plist, 1, $result); - $result = plist; - delete *$1; -} - -%typemap(in) size_t * readedBytes (size_t tmp) { - /* dont check for list */ - $1 = &tmp; -} - -%typemap(argout) size_t * readedBytes { - PyList_Append($result, PyInt_FromLong(*$1)); -} - -class IOBase -{ -protected: - virtual int CloseDevice() = 0; - virtual int OpenDevice(const char* devname, void* dcs = 0L) = 0; -public: - IOBase(); - virtual ~IOBase(); - - virtual const char* ClassName(); - int Close(); - virtual int Ioctl(int cmd,void* args); - virtual int IsOpen() = 0; - int Open(const char* devname,void* dcs=0L); - int PutBack(char ch); - virtual int Read(char* buf,size_t len) = 0; - virtual int ReadUntilEOS(char*& readbuf, - size_t* readedBytes, - char* eosString = "\n", - long timeout_in_ms = 1000L, - char quota = 0); - int Readv(char* buf,size_t len,unsigned int timeout_in_ms); - virtual int Write(char* buf,size_t len) = 0; - int Writev(char* buf,size_t len,unsigned int timeout_in_ms); -}; - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/kbhit.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/kbhit.i deleted file mode 100644 index 7e5b6cddd3..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/kbhit.i +++ /dev/null @@ -1,9 +0,0 @@ -%{ -#include "ctb-0.16/kbhit.h" -%} - -namespace ctb { - -char GetKey(); - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/makepy.sh b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/makepy.sh deleted file mode 100755 index 40b49dfb2e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/makepy.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -CFLAG='' -GPIB_SOURCES='' -GPIB_LIB='' -GPIB_SUPPORT='' - -# the python develop version. Please check the right version of your -# python developent enviroment -PYTHON_VERSION='2.6' - -for arg in $*; do - if [ "$arg" = "USE_GPIB" ]; then - GPIB_SOURCES='../../../src/gpib.cpp' - GPIB_LIB='-lgpib' - GPIB_SUPPORT='Yes' - else - echo '============================================================' - echo 'You run makepy.sh without GPIB support.' - echo 'If you want to create the python wxctb library with' - echo 'GPIB support, rerun the command with:' - echo 'makepy.sh USE_GPIB=1' - echo '============================================================' - GPIB_SUPPORT='No' - fi - if [ "$arg" = "USE_DEBUG" ]; then - CFLAG='-g' - fi -done - -echo "// This file is created automatically, don't change it!" > wxctb.i -echo "%module wxctb" >> wxctb.i -echo "typedef int size_t;" >> wxctb.i -echo "%include timer.i" >> wxctb.i -echo "%include serport.i" >> wxctb.i -echo "%include ../kbhit.i" >> wxctb.i -if [ "$arg" = "USE_GPIB" ]; then - echo "%include ../gpib.i" >> wxctb.i -fi - -echo "swig generates python wrapper files..." -swig -c++ -Wall -nodefault -python -keyword -new_repr -modern wxctb.i - -echo "create shared library wxctb with GPIB=$GPIB_SUPPORT for python"\ - "$PYTHON_VERSION ..." -g++ -Wall $CFLAG -shared -I /usr/include/python$PYTHON_VERSION/ \ - -I ../../../include \ - wxctb_wrap.cxx \ - ../../../src/linux/timer.cpp \ - ../../../src/linux/serport.cpp \ - ../../../src/serportx.cpp \ - ../../../src/kbhit.cpp \ - ../../../src/iobase.cpp \ - ../../../src/fifo.cpp \ - $GPIB_SOURCES \ - $GPIB_LIB \ - -o _wxctb.so - -echo "copy ctb.py, wxctb.py and _wxctb.so to the module/linux folder..." -mkdir -p ../../module/linux -cp ../ctb.py ../../module/linux/ -cp wxctb.py ../../module/linux/ -cp _wxctb.so ../../module/linux/ diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/serport.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/serport.i deleted file mode 100644 index 3150fe9117..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/serport.i +++ /dev/null @@ -1,50 +0,0 @@ -%module serport - -%{ -#include "ctb-0.16/linux/serport.h" -%} - -%include ../serportx.i - -namespace ctb { - -%pythoncode { -COM1 = "/dev/ttyS0" -COM2 = "/dev/ttyS1" -COM3 = "/dev/ttyS2" -COM4 = "/dev/ttyS3" -COM5 = "/dev/ttyS4" -COM6 = "/dev/ttyS5" -COM7 = "/dev/ttyS6" -COM8 = "/dev/ttyS7" -COM9 = "/dev/ttyS8" -}; - -class SerialPort : public SerialPort_x -{ -protected: - int fd; - struct termios t, save_t; - struct serial_icounter_struct save_info, last_info; - speed_t AdaptBaudrate(int baud); - - int CloseDevice(); - int OpenDevice(const char* devname, void* dcs); -public: - SerialPort(); - ~SerialPort(); - - int ChangeLineState(SerialLineState flags); - int ClrLineState(SerialLineState flags); - int GetLineState(); - int Ioctl(int cmd,void* args); - int IsOpen(); - int Read(char* buf,size_t len); - int SendBreak(int duration); - int SetBaudrate(int baudrate); - int SetLineState(SerialLineState flags); - int SetParityBit( bool parity ); - int Write(char* buf,size_t len); -}; - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/timer.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/timer.i deleted file mode 100644 index 5709224113..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/timer.i +++ /dev/null @@ -1,37 +0,0 @@ -%{ -#include "ctb-0.16/linux/timer.h" -%} - -%include cpointer.i - -// lets create new fuctions for pointer handling in python (for int *exitflag) -%pointer_functions(int, intp); - -namespace ctb { - -// perhaps we doesn''t need timer_control to export -// but we need if we want to inherit from timer in python -struct timer_control -{ - unsigned int usecs; - int *exitflag; - void* (*exitfnc)(void*); -}; - -class Timer -{ -protected: - timer_control control; - int stopped; - pthread_t tid; - unsigned int timer_secs; -public: - Timer(unsigned int msec,int* exitflag,void*(*exitfnc)(void*)=NULL); - ~Timer(); - int start(); - int stop(); -}; - -void sleepms(unsigned int ms); - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.i deleted file mode 100644 index 7f84b5fb33..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.i +++ /dev/null @@ -1,6 +0,0 @@ -// This file is created automatically, don't change it! -%module wxctb -typedef int size_t; -%include timer.i -%include serport.i -%include ../kbhit.i diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.py b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.py deleted file mode 100644 index f9e0d2ee6e..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb.py +++ /dev/null @@ -1,264 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.40 -# -# Do not make changes to this file unless you know what you are doing--modify -# the SWIG interface file instead. - -from sys import version_info -if version_info >= (2,6,0): - def swig_import_helper(): - from os.path import dirname - import imp - fp = None - try: - fp, pathname, description = imp.find_module('_wxctb', [dirname(__file__)]) - except ImportError: - import _wxctb - return _wxctb - if fp is not None: - try: - _mod = imp.load_module('_wxctb', fp, pathname, description) - finally: - fp.close() - return _mod - _wxctb = swig_import_helper() - del swig_import_helper -else: - import _wxctb -del version_info -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. -def _swig_setattr_nondynamic(self,class_type,name,value,static=1): - if (name == "thisown"): return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'SwigPyObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - if (not static) or hasattr(self,name): - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - -def _swig_setattr(self,class_type,name,value): - return _swig_setattr_nondynamic(self,class_type,name,value,0) - -def _swig_getattr(self,class_type,name): - if (name == "thisown"): return self.this.own() - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError(name) - -def _swig_repr(self): - try: strthis = "proxy of " + self.this.__repr__() - except: strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -try: - _object = object - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 - - -def _swig_setattr_nondynamic_method(set): - def set_attr(self,name,value): - if (name == "thisown"): return self.this.own(value) - if hasattr(self,name) or (name == "this"): - set(self,name,value) - else: - raise AttributeError("You cannot add attributes to %s" % self) - return set_attr - - - -def new_intp(): - return _wxctb.new_intp() -new_intp = _wxctb.new_intp - -def copy_intp(*args, **kwargs): - return _wxctb.copy_intp(*args, **kwargs) -copy_intp = _wxctb.copy_intp - -def delete_intp(*args, **kwargs): - return _wxctb.delete_intp(*args, **kwargs) -delete_intp = _wxctb.delete_intp - -def intp_assign(*args, **kwargs): - return _wxctb.intp_assign(*args, **kwargs) -intp_assign = _wxctb.intp_assign - -def intp_value(*args, **kwargs): - return _wxctb.intp_value(*args, **kwargs) -intp_value = _wxctb.intp_value -class timer_control(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined") - __repr__ = _swig_repr - usecs = _swig_property(_wxctb.timer_control_usecs_get, _wxctb.timer_control_usecs_set) - exitflag = _swig_property(_wxctb.timer_control_exitflag_get, _wxctb.timer_control_exitflag_set) - exitfnc = _swig_property(_wxctb.timer_control_exitfnc_get, _wxctb.timer_control_exitfnc_set) -timer_control_swigregister = _wxctb.timer_control_swigregister -timer_control_swigregister(timer_control) - -class Timer(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self, *args, **kwargs): - this = _wxctb.new_Timer(*args, **kwargs) - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_Timer - __del__ = lambda self : None; - def start(self): return _wxctb.Timer_start(self) - def stop(self): return _wxctb.Timer_stop(self) -Timer_swigregister = _wxctb.Timer_swigregister -Timer_swigregister(Timer) - - -def sleepms(*args, **kwargs): - return _wxctb.sleepms(*args, **kwargs) -sleepms = _wxctb.sleepms -CTB_RESET = _wxctb.CTB_RESET -class IOBase(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _wxctb.delete_IOBase - __del__ = lambda self : None; - def ClassName(self): return _wxctb.IOBase_ClassName(self) - def Close(self): return _wxctb.IOBase_Close(self) - def Ioctl(self, *args, **kwargs): return _wxctb.IOBase_Ioctl(self, *args, **kwargs) - def IsOpen(self): return _wxctb.IOBase_IsOpen(self) - def Open(self, *args, **kwargs): return _wxctb.IOBase_Open(self, *args, **kwargs) - def PutBack(self, *args, **kwargs): return _wxctb.IOBase_PutBack(self, *args, **kwargs) - def Read(self, *args, **kwargs): return _wxctb.IOBase_Read(self, *args, **kwargs) - def ReadUntilEOS(self, *args, **kwargs): return _wxctb.IOBase_ReadUntilEOS(self, *args, **kwargs) - def Readv(self, *args, **kwargs): return _wxctb.IOBase_Readv(self, *args, **kwargs) - def Write(self, *args, **kwargs): return _wxctb.IOBase_Write(self, *args, **kwargs) - def Writev(self, *args, **kwargs): return _wxctb.IOBase_Writev(self, *args, **kwargs) -IOBase_swigregister = _wxctb.IOBase_swigregister -IOBase_swigregister(IOBase) - -ParityNone = _wxctb.ParityNone -ParityOdd = _wxctb.ParityOdd -ParityEven = _wxctb.ParityEven -ParityMark = _wxctb.ParityMark -ParitySpace = _wxctb.ParitySpace -LinestateDcd = _wxctb.LinestateDcd -LinestateCts = _wxctb.LinestateCts -LinestateDsr = _wxctb.LinestateDsr -LinestateDtr = _wxctb.LinestateDtr -LinestateRing = _wxctb.LinestateRing -LinestateRts = _wxctb.LinestateRts -LinestateNull = _wxctb.LinestateNull -class SerialPort_DCS(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - baud = _swig_property(_wxctb.SerialPort_DCS_baud_get, _wxctb.SerialPort_DCS_baud_set) - parity = _swig_property(_wxctb.SerialPort_DCS_parity_get, _wxctb.SerialPort_DCS_parity_set) - wordlen = _swig_property(_wxctb.SerialPort_DCS_wordlen_get, _wxctb.SerialPort_DCS_wordlen_set) - stopbits = _swig_property(_wxctb.SerialPort_DCS_stopbits_get, _wxctb.SerialPort_DCS_stopbits_set) - rtscts = _swig_property(_wxctb.SerialPort_DCS_rtscts_get, _wxctb.SerialPort_DCS_rtscts_set) - xonxoff = _swig_property(_wxctb.SerialPort_DCS_xonxoff_get, _wxctb.SerialPort_DCS_xonxoff_set) - buf = _swig_property(_wxctb.SerialPort_DCS_buf_get, _wxctb.SerialPort_DCS_buf_set) - def __init__(self): - this = _wxctb.new_SerialPort_DCS() - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_SerialPort_DCS - __del__ = lambda self : None; - def GetSettings(self): return _wxctb.SerialPort_DCS_GetSettings(self) -SerialPort_DCS_swigregister = _wxctb.SerialPort_DCS_swigregister -SerialPort_DCS_swigregister(SerialPort_DCS) - -class SerialPort_EINFO(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - brk = _swig_property(_wxctb.SerialPort_EINFO_brk_get, _wxctb.SerialPort_EINFO_brk_set) - frame = _swig_property(_wxctb.SerialPort_EINFO_frame_get, _wxctb.SerialPort_EINFO_frame_set) - overrun = _swig_property(_wxctb.SerialPort_EINFO_overrun_get, _wxctb.SerialPort_EINFO_overrun_set) - parity = _swig_property(_wxctb.SerialPort_EINFO_parity_get, _wxctb.SerialPort_EINFO_parity_set) - def __init__(self): - this = _wxctb.new_SerialPort_EINFO() - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_SerialPort_EINFO - __del__ = lambda self : None; -SerialPort_EINFO_swigregister = _wxctb.SerialPort_EINFO_swigregister -SerialPort_EINFO_swigregister(SerialPort_EINFO) - -CTB_SER_GETEINFO = _wxctb.CTB_SER_GETEINFO -CTB_SER_GETBRK = _wxctb.CTB_SER_GETBRK -CTB_SER_GETFRM = _wxctb.CTB_SER_GETFRM -CTB_SER_GETOVR = _wxctb.CTB_SER_GETOVR -CTB_SER_GETPAR = _wxctb.CTB_SER_GETPAR -CTB_SER_GETINQUE = _wxctb.CTB_SER_GETINQUE -CTB_SER_SETPAR = _wxctb.CTB_SER_SETPAR -class SerialPort_x(IOBase): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _wxctb.delete_SerialPort_x - __del__ = lambda self : None; - def ClassName(self): return _wxctb.SerialPort_x_ClassName(self) - def ChangeLineState(self, *args, **kwargs): return _wxctb.SerialPort_x_ChangeLineState(self, *args, **kwargs) - def ClrLineState(self, *args, **kwargs): return _wxctb.SerialPort_x_ClrLineState(self, *args, **kwargs) - def GetLineState(self): return _wxctb.SerialPort_x_GetLineState(self) - def GetSettingsAsString(self): return _wxctb.SerialPort_x_GetSettingsAsString(self) - def Ioctl(self, *args, **kwargs): return _wxctb.SerialPort_x_Ioctl(self, *args, **kwargs) - def SendBreak(self, *args, **kwargs): return _wxctb.SerialPort_x_SendBreak(self, *args, **kwargs) - def SetBaudrate(self, *args, **kwargs): return _wxctb.SerialPort_x_SetBaudrate(self, *args, **kwargs) - def SetLineState(self, *args, **kwargs): return _wxctb.SerialPort_x_SetLineState(self, *args, **kwargs) - def SetParityBit(self, *args, **kwargs): return _wxctb.SerialPort_x_SetParityBit(self, *args, **kwargs) - IsStandardRate = staticmethod(_wxctb.SerialPort_x_IsStandardRate) -SerialPort_x_swigregister = _wxctb.SerialPort_x_swigregister -SerialPort_x_swigregister(SerialPort_x) - -def SerialPort_x_IsStandardRate(*args, **kwargs): - return _wxctb.SerialPort_x_IsStandardRate(*args, **kwargs) -SerialPort_x_IsStandardRate = _wxctb.SerialPort_x_IsStandardRate - -COM1 = "/dev/ttyS0" -COM2 = "/dev/ttyS1" -COM3 = "/dev/ttyS2" -COM4 = "/dev/ttyS3" -COM5 = "/dev/ttyS4" -COM6 = "/dev/ttyS5" -COM7 = "/dev/ttyS6" -COM8 = "/dev/ttyS7" -COM9 = "/dev/ttyS8" - -class SerialPort(SerialPort_x): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self): - this = _wxctb.new_SerialPort() - try: self.this.append(this) - except: self.this = this - __swig_destroy__ = _wxctb.delete_SerialPort - __del__ = lambda self : None; - def ChangeLineState(self, *args, **kwargs): return _wxctb.SerialPort_ChangeLineState(self, *args, **kwargs) - def ClrLineState(self, *args, **kwargs): return _wxctb.SerialPort_ClrLineState(self, *args, **kwargs) - def GetLineState(self): return _wxctb.SerialPort_GetLineState(self) - def Ioctl(self, *args, **kwargs): return _wxctb.SerialPort_Ioctl(self, *args, **kwargs) - def IsOpen(self): return _wxctb.SerialPort_IsOpen(self) - def Read(self, *args, **kwargs): return _wxctb.SerialPort_Read(self, *args, **kwargs) - def SendBreak(self, *args, **kwargs): return _wxctb.SerialPort_SendBreak(self, *args, **kwargs) - def SetBaudrate(self, *args, **kwargs): return _wxctb.SerialPort_SetBaudrate(self, *args, **kwargs) - def SetLineState(self, *args, **kwargs): return _wxctb.SerialPort_SetLineState(self, *args, **kwargs) - def SetParityBit(self, *args, **kwargs): return _wxctb.SerialPort_SetParityBit(self, *args, **kwargs) - def Write(self, *args, **kwargs): return _wxctb.SerialPort_Write(self, *args, **kwargs) -SerialPort_swigregister = _wxctb.SerialPort_swigregister -SerialPort_swigregister(SerialPort) - - -def GetKey(): - return _wxctb.GetKey() -GetKey = _wxctb.GetKey - - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb_wrap.cxx b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb_wrap.cxx deleted file mode 100644 index c72f220ded..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/linux/wxctb_wrap.cxx +++ /dev/null @@ -1,6469 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.40 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -#define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE - - -#ifdef __cplusplus -/* SwigValueWrapper is described in swig.swg */ -template class SwigValueWrapper { - struct SwigMovePointer { - T *ptr; - SwigMovePointer(T *p) : ptr(p) { } - ~SwigMovePointer() { delete ptr; } - SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } - } pointer; - SwigValueWrapper& operator=(const SwigValueWrapper& rhs); - SwigValueWrapper(const SwigValueWrapper& rhs); -public: - SwigValueWrapper() : pointer(0) { } - SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } - operator T&() const { return *pointer.ptr; } - T *operator&() { return pointer.ptr; } -}; - -template T SwigValueInit() { - return T(); -} -#endif - -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - - - -/* Python.h has to appear first */ -#include - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic C API SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the SWIG runtime code. - In 99.9% of the cases, SWIG just needs to declare them as 'static'. - - But only do this if strictly necessary, ie, if you have problems - with your compiler or suchlike. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The SWIG conversion methods, as ConvertPtr, return and integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old versions of SWIG, code such as the following was usually written: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - which is the same really, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - also requires SWIG_ConvertPtr to return new result values, such as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - SWIG errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() -*/ - -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (strcmp(iter->type->name, c) == 0) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (iter->type == from) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - register size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - -/* Compatibility macros for Python 3 */ -#if PY_VERSION_HEX >= 0x03000000 - -#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) -#define PyInt_Check(x) PyLong_Check(x) -#define PyInt_AsLong(x) PyLong_AsLong(x) -#define PyInt_FromLong(x) PyLong_FromLong(x) -#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) - -#endif - -#ifndef Py_TYPE -# define Py_TYPE(op) ((op)->ob_type) -#endif - -/* SWIG APIs for compatibility of both Python 2 & 3 */ - -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_Python_str_FromFormat PyUnicode_FromFormat -#else -# define SWIG_Python_str_FromFormat PyString_FromFormat -#endif - - -/* Warning: This function will allocate a new string in Python 3, - * so please call SWIG_Python_str_DelForPy3(x) to free the space. - */ -SWIGINTERN char* -SWIG_Python_str_AsChar(PyObject *str) -{ -#if PY_VERSION_HEX >= 0x03000000 - char *cstr; - char *newstr; - Py_ssize_t len; - str = PyUnicode_AsUTF8String(str); - PyBytes_AsStringAndSize(str, &cstr, &len); - newstr = (char *) malloc(len+1); - memcpy(newstr, cstr, len+1); - Py_XDECREF(str); - return newstr; -#else - return PyString_AsString(str); -#endif -} - -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) ) -#else -# define SWIG_Python_str_DelForPy3(x) -#endif - - -SWIGINTERN PyObject* -SWIG_Python_str_FromChar(const char *c) -{ -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_FromString(c); -#else - return PyString_FromString(c); -#endif -} - -/* Add PyOS_snprintf for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# define PyOS_snprintf _snprintf -# else -# define PyOS_snprintf snprintf -# endif -#endif - -/* A crude PyString_FromFormat implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 - -#ifndef SWIG_PYBUFFER_SIZE -# define SWIG_PYBUFFER_SIZE 1024 -#endif - -static PyObject * -PyString_FromFormat(const char *fmt, ...) { - va_list ap; - char buf[SWIG_PYBUFFER_SIZE * 2]; - int res; - va_start(ap, fmt); - res = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); -} -#endif - -/* Add PyObject_Del for old Pythons */ -#if PY_VERSION_HEX < 0x01060000 -# define PyObject_Del(op) PyMem_DEL((op)) -#endif -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* A crude PyExc_StopIteration exception for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# ifndef PyExc_StopIteration -# define PyExc_StopIteration PyExc_RuntimeError -# endif -# ifndef PyObject_GenericGetAttr -# define PyObject_GenericGetAttr 0 -# endif -#endif - -/* Py_NotImplemented is defined in 2.1 and up. */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef Py_NotImplemented -# define Py_NotImplemented PyExc_RuntimeError -# endif -#endif - -/* A crude PyString_AsStringAndSize implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef PyString_AsStringAndSize -# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} -# endif -#endif - -/* PySequence_Size for old Pythons */ -#if PY_VERSION_HEX < 0x02000000 -# ifndef PySequence_Size -# define PySequence_Size PySequence_Length -# endif -#endif - -/* PyBool_FromLong for old Pythons */ -#if PY_VERSION_HEX < 0x02030000 -static -PyObject *PyBool_FromLong(long ok) -{ - PyObject *result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; -} -#endif - -/* Py_ssize_t for old Pythons */ -/* This code is as recommended by: */ -/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -# define PY_SSIZE_T_MIN INT_MIN -#endif - -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); - if (value) { - char *tmp; - PyObject *old_str = PyObject_Str(value); - PyErr_Clear(); - Py_XINCREF(type); - - PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg); - SWIG_Python_str_DelForPy3(tmp); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_SetString(PyExc_RuntimeError, mesg); - } -} - -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ -# define SWIG_PYTHON_USE_GIL -# endif -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# ifndef SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif - -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - - -/* ----------------------------------------------------------------------------- - * Wrapper of PyInstanceMethod_New() used in Python 3 - * It is exported to the generated module, used for -fastproxy - * ----------------------------------------------------------------------------- */ -SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *self, PyObject *func) -{ -#if PY_VERSION_HEX >= 0x03000000 - return PyInstanceMethod_New(func); -#else - return NULL; -#endif -} - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) SwigPyClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, (char *) msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { - PyDict_SetItemString(d, (char*) name, obj); - Py_DECREF(obj); -} - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { -#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -#else - PyObject* o2; - PyObject* o3; - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyTuple_Check(result)) { - o2 = result; - result = PyTuple_New(1); - PyTuple_SET_ITEM(result, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SET_ITEM(o3, 0, obj); - o2 = result; - result = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return result; -#endif -} - -/* Unpack the argument tuple */ - -SWIGINTERN int -SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), (int)min); - return 0; - } - } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - register Py_ssize_t l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), (int)min, (int)l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), (int)max, (int)l); - return 0; - } else { - register int i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* How to access Py_None */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_BUILD_NONE -# ifndef SWIG_PYTHON_BUILD_NONE -# define SWIG_PYTHON_BUILD_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_BUILD_NONE -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue((char*)""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* SwigPyClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; -} SwigPyClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME SwigPyClientData * -SwigPyClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; -#else - data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); -#endif - if (data->newraw) { - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - } else { - data->newargs = obj; - } - Py_INCREF(data->newargs); - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - int flags; - Py_INCREF(data->destroy); - flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - return data; - } -} - -SWIGRUNTIME void -SwigPyClientData_Del(SwigPyClientData* data) -{ - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); -} - -/* =============== SwigPyObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -} SwigPyObject; - -SWIGRUNTIME PyObject * -SwigPyObject_long(SwigPyObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -SwigPyObject_format(const char* fmt, SwigPyObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) { - PyObject *ofmt = SWIG_Python_str_FromChar(fmt); - if (ofmt) { -#if PY_VERSION_HEX >= 0x03000000 - res = PyUnicode_Format(ofmt,args); -#else - res = PyString_Format(ofmt,args); -#endif - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -SwigPyObject_oct(SwigPyObject *v) -{ - return SwigPyObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -SwigPyObject_hex(SwigPyObject *v) -{ - return SwigPyObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -#ifdef METH_NOARGS -SwigPyObject_repr(SwigPyObject *v) -#else -SwigPyObject_repr(SwigPyObject *v, PyObject *args) -#endif -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *repr = SWIG_Python_str_FromFormat("", name, v); - if (v->next) { -#ifdef METH_NOARGS - PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); -#else - PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args); -#endif -#if PY_VERSION_HEX >= 0x03000000 - PyObject *joined = PyUnicode_Concat(repr, nrep); - Py_DecRef(repr); - Py_DecRef(nrep); - repr = joined; -#else - PyString_ConcatAndDel(&repr,nrep); -#endif - } - return repr; -} - -SWIGRUNTIME int -SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char *str; -#ifdef METH_NOARGS - PyObject *repr = SwigPyObject_repr(v); -#else - PyObject *repr = SwigPyObject_repr(v, NULL); -#endif - if (repr) { - str = SWIG_Python_str_AsChar(repr); - fputs(str, fp); - SWIG_Python_str_DelForPy3(str); - Py_DECREF(repr); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -SwigPyObject_str(SwigPyObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? - SWIG_Python_str_FromChar(result) : 0; -} - -SWIGRUNTIME int -SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -/* Added for Python 3.x, would it also be useful for Python 2.x? */ -SWIGRUNTIME PyObject* -SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) -{ - PyObject* res; - if( op != Py_EQ && op != Py_NE ) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - if( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ) - res = Py_True; - else - res = Py_False; - Py_INCREF(res); - return res; -} - - -SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); - -SWIGRUNTIME PyTypeObject* -SwigPyObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); - return type; -} - -SWIGRUNTIMEINLINE int -SwigPyObject_Check(PyObject *op) { - return (Py_TYPE(op) == SwigPyObject_type()) - || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0); -} - -SWIGRUNTIME PyObject * -SwigPyObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -SwigPyObject_dealloc(PyObject *v) -{ - SwigPyObject *sobj = (SwigPyObject *) v; - PyObject *next = sobj->next; - if (sobj->own == SWIG_POINTER_OWN) { - swig_type_info *ty = sobj->ty; - SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - if (data->delargs) { - /* we need to create a temporary object to carry the destroy operation */ - PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - Py_XDECREF(res); - } -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - else { - const char *name = SWIG_TypePrettyName(ty); - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); - } -#endif - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -SwigPyObject_append(PyObject* v, PyObject* next) -{ - SwigPyObject *sobj = (SwigPyObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!SwigPyObject_Check(next)) { - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -SwigPyObject_next(PyObject* v) -#else -SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - SwigPyObject *sobj = (SwigPyObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -SwigPyObject_disown(PyObject *v) -#else -SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - SwigPyObject *sobj = (SwigPyObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -SwigPyObject_acquire(PyObject *v) -#else -SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - SwigPyObject *sobj = (SwigPyObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -SwigPyObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) -#else - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - SwigPyObject *sobj = (SwigPyObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - SwigPyObject_acquire(v); - } else { - SwigPyObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - SwigPyObject_acquire(v,args); - } else { - SwigPyObject_disown(v,args); - } -#endif - } - return obj; - } -} - -#ifdef METH_O -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)SwigPyObject_append, METH_O, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)SwigPyObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_NOARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#else -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)SwigPyObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)SwigPyObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_VARARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#endif - -#if PY_VERSION_HEX < 0x02020000 -SWIGINTERN PyObject * -SwigPyObject_getattr(SwigPyObject *sobj,char *name) -{ - return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); -} -#endif - -SWIGRUNTIME PyTypeObject* -_PySwigObject_type(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods SwigPyObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - /* nb_divide removed in Python 3 */ -#if PY_VERSION_HEX < 0x03000000 - (binaryfunc)0, /*nb_divide*/ -#endif - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ -#if PY_VERSION_HEX < 0x03000000 - 0, /*nb_coerce*/ -#endif - (unaryfunc)SwigPyObject_long, /*nb_int*/ -#if PY_VERSION_HEX < 0x03000000 - (unaryfunc)SwigPyObject_long, /*nb_long*/ -#else - 0, /*nb_reserved*/ -#endif - (unaryfunc)0, /*nb_float*/ -#if PY_VERSION_HEX < 0x03000000 - (unaryfunc)SwigPyObject_oct, /*nb_oct*/ - (unaryfunc)SwigPyObject_hex, /*nb_hex*/ -#endif -#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ -#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ -#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject swigpyobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - /* PyObject header changed in Python 3 */ -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(&PyType_Type, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - (char *)"SwigPyObject", /* tp_name */ - sizeof(SwigPyObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyObject_dealloc, /* tp_dealloc */ - (printfunc)SwigPyObject_print, /* tp_print */ -#if PY_VERSION_HEX < 0x02020000 - (getattrfunc)SwigPyObject_getattr, /* tp_getattr */ -#else - (getattrfunc)0, /* tp_getattr */ -#endif - (setattrfunc)0, /* tp_setattr */ -#if PY_VERSION_HEX >= 0x03000000 - 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ -#else - (cmpfunc)SwigPyObject_compare, /* tp_compare */ -#endif - (reprfunc)SwigPyObject_repr, /* tp_repr */ - &SwigPyObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)SwigPyObject_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)SwigPyObject_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - swigpyobject_type = tmp; - /* for Python 3 we already assigned ob_type in PyVarObject_HEAD_INIT() */ -#if PY_VERSION_HEX < 0x03000000 - swigpyobject_type.ob_type = &PyType_Type; -#endif - type_init = 1; - } - return &swigpyobject_type; -} - -SWIGRUNTIME PyObject * -SwigPyObject_New(void *ptr, swig_type_info *ty, int own) -{ - SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} SwigPyPacked; - -SWIGRUNTIME int -SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -SwigPyPacked_repr(SwigPyPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return SWIG_Python_str_FromFormat("", result, v->ty->name); - } else { - return SWIG_Python_str_FromFormat("", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -SwigPyPacked_str(SwigPyPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); - } else { - return SWIG_Python_str_FromChar(v->ty->name); - } -} - -SWIGRUNTIME int -SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); - -SWIGRUNTIME PyTypeObject* -SwigPyPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); - return type; -} - -SWIGRUNTIMEINLINE int -SwigPyPacked_Check(PyObject *op) { - return ((op)->ob_type == _PySwigPacked_type()) - || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0); -} - -SWIGRUNTIME void -SwigPyPacked_dealloc(PyObject *v) -{ - if (SwigPyPacked_Check(v)) { - SwigPyPacked *sobj = (SwigPyPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -_PySwigPacked_type(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject swigpypacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - /* PyObject header changed in Python 3 */ -#if PY_VERSION_HEX>=0x03000000 - PyVarObject_HEAD_INIT(&PyType_Type, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - (char *)"SwigPyPacked", /* tp_name */ - sizeof(SwigPyPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ - (printfunc)SwigPyPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ -#if PY_VERSION_HEX>=0x03000000 - 0, /* tp_reserved in 3.0.1 */ -#else - (cmpfunc)SwigPyPacked_compare, /* tp_compare */ -#endif - (reprfunc)SwigPyPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)SwigPyPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - swigpypacked_type = tmp; - /* for Python 3 the ob_type already assigned in PyVarObject_HEAD_INIT() */ -#if PY_VERSION_HEX < 0x03000000 - swigpypacked_type.ob_type = &PyType_Type; -#endif - type_init = 1; - } - return &swigpypacked_type; -} - -SWIGRUNTIME PyObject * -SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (SwigPyPacked_Check(obj)) { - SwigPyPacked *sobj = (SwigPyPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIMEINLINE PyObject * -_SWIG_This(void) -{ - return SWIG_Python_str_FromChar("this"); -} - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -/* TODO: I don't know how to implement the fast getset in Python 3 right now */ -#if PY_VERSION_HEX>=0x03000000 -#define SWIG_PYTHON_SLOW_GETSET_THIS -#endif - -SWIGRUNTIME SwigPyObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - if (SwigPyObject_Check(pyobj)) { - return (SwigPyObject *) pyobj; - } else { - PyObject *obj = 0; -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !SwigPyObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - SwigPyObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (SwigPyObject *)obj; - } -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own == SWIG_POINTER_OWN) { - SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - if (ptr) *ptr = 0; - return SWIG_OK; - } else { - SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); - if (own) - *own = 0; - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (SwigPyObject *)sobj->next; - } else { - if (ptr) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); - if (own) - *own = *own | SWIG_CAST_NEW_MEMORY; - } - } - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) - *own = *own | sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - return SWIG_OK; - } else { - int res = SWIG_ERROR; - if (flags & SWIG_POINTER_IMPLICIT_CONV) { - SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - return res; - } - } -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) - return SWIG_ERROR; - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, without calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { -#if PY_VERSION_HEX >= 0x03000000 - inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None); - PyObject_SetAttr(inst, SWIG_This(), swig_this); - Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; -#else - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); -#endif - } - return inst; -#else -#if (PY_VERSION_HEX >= 0x02010000) - PyObject *inst; - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - return (PyObject *) inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } -#ifdef Py_TPFLAGS_HAVE_WEAKREFS - inst->in_weakreflist = NULL; -#endif -#ifdef Py_TPFLAGS_GC - PyObject_GC_Init(inst); -#endif - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -#endif -} - -SWIGRUNTIME void -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ - PyObject *dict; -#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - PyDict_SetItem(dict, SWIG_This(), swig_this); - return; - } -#endif - dict = PyObject_GetAttrString(inst, (char*)"__dict__"); - PyDict_SetItem(dict, SWIG_This(), swig_this); - Py_DECREF(dict); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { - return NULL; - } else { - SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - SwigPyObject_append((PyObject*) sthis, obj[1]); - } else { - SWIG_Python_SetSwigThis(obj[0], obj[1]); - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - if (!ptr) { - return SWIG_Py_Void(); - } else { - int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - PyObject *robj = SwigPyObject_New(ptr, type, own); - SwigPyClientData *clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; - if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - if (inst) { - Py_DECREF(robj); - robj = inst; - } - } - return robj; - } -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -SWIG_Python_DestroyModule(void *vptr) -{ - swig_module_info *swig_module = (swig_module_info *) vptr; - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; - if (data) SwigPyClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ - -#if PY_VERSION_HEX >= 0x03000000 - /* Add a dummy module object into sys.modules */ - PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION); -#else - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - swig_empty_runtime_method_table); -#endif - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -} - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); - return cache; -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = SWIG_Python_str_FromChar(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { - descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); - } else { - swig_module_info *swig_module = SWIG_Python_GetModule(); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { - obj = PyCObject_FromVoidPtr(descriptor, NULL); - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - char *tmp; - PyObject *old_str = PyObject_Str(value); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str)); - } else { - PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg); - } - SWIG_Python_str_DelForPy3(tmp); - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -SwigPyObject_GetDesc(PyObject *self) -{ - SwigPyObject *v = (SwigPyObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : (char*)""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && SwigPyObject_Check(obj)) { - const char *otype = (const char *) SwigPyObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - SWIG_Python_str_DelForPy3(cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); -#if SWIG_POINTER_EXCEPTION - if (flags) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } -#endif - } - return result; -} - - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_char swig_types[0] -#define SWIGTYPE_p_ctb__IOBase swig_types[1] -#define SWIGTYPE_p_ctb__SerialPort swig_types[2] -#define SWIGTYPE_p_ctb__SerialPort_DCS swig_types[3] -#define SWIGTYPE_p_ctb__SerialPort_EINFO swig_types[4] -#define SWIGTYPE_p_ctb__SerialPort_x swig_types[5] -#define SWIGTYPE_p_ctb__Timer swig_types[6] -#define SWIGTYPE_p_ctb__timer_control swig_types[7] -#define SWIGTYPE_p_f_p_void__p_void swig_types[8] -#define SWIGTYPE_p_int swig_types[9] -#define SWIGTYPE_p_p_char swig_types[10] -static swig_type_info *swig_types[12]; -static swig_module_info swig_module = {swig_types, 11, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - -#if (PY_VERSION_HEX <= 0x02000000) -# if !defined(SWIG_PYTHON_CLASSIC) -# error "This python version requires swig to be run with the '-classic' option" -# endif -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodern' option" -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodernargs' option" -#endif - -/*----------------------------------------------- - @(target):= _wxctb.so - ------------------------------------------------*/ -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_init PyInit__wxctb - -#else -# define SWIG_init init_wxctb - -#endif -#define SWIG_name "_wxctb" - -#define SWIGVERSION 0x010340 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) - - -#include - - -namespace swig { - class SwigPtr_PyObject { - protected: - PyObject *_obj; - - public: - SwigPtr_PyObject() :_obj(0) - { - } - - SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj) - { - Py_XINCREF(_obj); - } - - SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj) - { - if (initial_ref) { - Py_XINCREF(_obj); - } - } - - SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) - { - Py_XINCREF(item._obj); - Py_XDECREF(_obj); - _obj = item._obj; - return *this; - } - - ~SwigPtr_PyObject() - { - Py_XDECREF(_obj); - } - - operator PyObject *() const - { - return _obj; - } - - PyObject *operator->() const - { - return _obj; - } - }; -} - - -namespace swig { - struct SwigVar_PyObject : SwigPtr_PyObject { - SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { } - - SwigVar_PyObject & operator = (PyObject* obj) - { - Py_XDECREF(_obj); - _obj = obj; - return *this; - } - }; -} - - -#include "ctb-0.16/linux/timer.h" - - - static int *new_intp() { - return (new int); - } - - static int *copy_intp(int value) { - return (new int(static_cast< const int& >(value))); - } - - static void delete_intp(int *self) { - if (self) delete self; - } - - static void intp_assign(int *self, int value) { - *self = value; - } - - static int intp_value(int *self) { - return *self; - } - - -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; - } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = static_cast< int >(v); - } - } - return res; -} - - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject * -SWIG_From_int (int value) -{ - return SWIG_From_long (value); -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) -{ - if (PyInt_Check(obj)) { - long v = PyInt_AsLong(obj); - if (v >= 0) { - if (val) *val = v; - return SWIG_OK; - } else { - return SWIG_OverflowError; - } - } else if (PyLong_Check(obj)) { - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { - if (val) *val = (unsigned long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v > UINT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = static_cast< unsigned int >(v); - } - } - return res; -} - - -SWIGINTERNINLINE PyObject* -SWIG_From_unsigned_SS_long (unsigned long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value)); -} - - -SWIGINTERNINLINE PyObject * -SWIG_From_unsigned_SS_int (unsigned int value) -{ - return SWIG_From_unsigned_SS_long (value); -} - - -#include "ctb-0.16/linux/serport.h" - - -#include "ctb-0.16/serportx.h" - - -#include "ctb-0.16/iobase.h" - - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - if (carray) { - if (size > INT_MAX) { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - return pchar_descriptor ? - SWIG_NewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void(); - } else { -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_FromStringAndSize(carray, static_cast< int >(size)); -#else - return PyString_FromStringAndSize(carray, static_cast< int >(size)); -#endif - } - } else { - return SWIG_Py_Void(); - } -} - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtr(const char *cptr) -{ - return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); -} - - -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ -#if PY_VERSION_HEX>=0x03000000 - if (PyUnicode_Check(obj)) -#else - if (PyString_Check(obj)) -#endif - { - char *cstr; Py_ssize_t len; -#if PY_VERSION_HEX>=0x03000000 - if (!alloc && cptr) { - /* We can't allow converting without allocation, since the internal - representation of string in Python 3 is UCS-2/UCS-4 but we require - a UTF-8 representation. - TODO(bhy) More detailed explanation */ - return SWIG_RuntimeError; - } - obj = PyUnicode_AsUTF8String(obj); - PyBytes_AsStringAndSize(obj, &cstr, &len); - if(alloc) *alloc = SWIG_NEWOBJ; -#else - PyString_AsStringAndSize(obj, &cstr, &len); -#endif - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation. To warranty that, if you define - SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string - buffer is always returned. - - The default behavior is just to return the pointer value, - so, be careful. - */ -#if defined(SWIG_PYTHON_SAFE_CSTRINGS) - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1))); - *alloc = SWIG_NEWOBJ; - } - else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { - #if PY_VERSION_HEX>=0x03000000 - assert(0); /* Should never reach here in Python 3 */ - #endif - *cptr = SWIG_Python_str_AsChar(obj); - } - } - if (psize) *psize = len + 1; -#if PY_VERSION_HEX>=0x03000000 - Py_XDECREF(obj); -#endif - return SWIG_OK; - } else { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} - - - - - -SWIGINTERN int -SWIG_AsCharArray(PyObject * obj, char *val, size_t size) -{ - char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ; - int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize, &alloc); - if (SWIG_IsOK(res)) { - if ((csize == size + 1) && cptr && !(cptr[csize-1])) --csize; - if (csize <= size) { - if (val) { - if (csize) memcpy(val, cptr, csize*sizeof(char)); - if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(char)); - } - if (alloc == SWIG_NEWOBJ) { - delete[] cptr; - res = SWIG_DelNewMask(res); - } - return res; - } - if (alloc == SWIG_NEWOBJ) delete[] cptr; - } - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_char (PyObject * obj, char *val) -{ - int res = SWIG_AsCharArray(obj, val, 1); - if (!SWIG_IsOK(res)) { - long v; - res = SWIG_AddCast(SWIG_AsVal_long (obj, &v)); - if (SWIG_IsOK(res)) { - if ((CHAR_MIN <= v) && (v <= CHAR_MAX)) { - if (val) *val = static_cast< char >(v); - } else { - res = SWIG_OverflowError; - } - } - } - return res; -} - - -SWIGINTERNINLINE int -SWIG_AsVal_size_t (PyObject * obj, size_t *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v); - return res; -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_char (PyObject * obj, unsigned char *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v > UCHAR_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = static_cast< unsigned char >(v); - } - } - return res; -} - - -SWIGINTERNINLINE PyObject * -SWIG_From_unsigned_SS_char (unsigned char value) -{ - return SWIG_From_unsigned_SS_long (value); -} - - -SWIGINTERN int -SWIG_AsVal_bool (PyObject *obj, bool *val) -{ - int r = PyObject_IsTrue(obj); - if (r == -1) - return SWIG_ERROR; - if (val) *val = r ? true : false; - return SWIG_OK; -} - - -SWIGINTERNINLINE PyObject* - SWIG_From_bool (bool value) -{ - return PyBool_FromLong(value ? 1 : 0); -} - - -#include "ctb-0.16/kbhit.h" - - -SWIGINTERNINLINE PyObject * -SWIG_From_char (char c) -{ - return SWIG_FromCharPtrAndSize(&c,1); -} - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_new_intp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"new_intp",0,0)) SWIG_fail; - result = (int *)new_intp(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_copy_intp(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - int arg1 ; - int val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "value", NULL - }; - int *result = 0 ; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:copy_intp",kwnames,&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "copy_intp" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - result = (int *)copy_intp(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_intp(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - int *arg1 = (int *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "self", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:delete_intp",kwnames,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_int, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_intp" "', argument " "1"" of type '" "int *""'"); - } - arg1 = reinterpret_cast< int * >(argp1); - delete_intp(arg1); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_intp_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - int *arg1 = (int *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "value", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:intp_assign",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_int, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "intp_assign" "', argument " "1"" of type '" "int *""'"); - } - arg1 = reinterpret_cast< int * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "intp_assign" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - intp_assign(arg1,arg2); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_intp_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - int *arg1 = (int *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "self", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:intp_value",kwnames,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_int, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "intp_value" "', argument " "1"" of type '" "int *""'"); - } - arg1 = reinterpret_cast< int * >(argp1); - result = (int)intp_value(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_timer_control_usecs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::timer_control *arg1 = (ctb::timer_control *) 0 ; - unsigned int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - unsigned int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"timer_control_usecs_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__timer_control, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "timer_control_usecs_set" "', argument " "1"" of type '" "ctb::timer_control *""'"); - } - arg1 = reinterpret_cast< ctb::timer_control * >(argp1); - ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "timer_control_usecs_set" "', argument " "2"" of type '" "unsigned int""'"); - } - arg2 = static_cast< unsigned int >(val2); - if (arg1) (arg1)->usecs = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_timer_control_usecs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::timer_control *arg1 = (ctb::timer_control *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - unsigned int result; - - if(!PyArg_UnpackTuple(args,(char *)"timer_control_usecs_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__timer_control, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "timer_control_usecs_get" "', argument " "1"" of type '" "ctb::timer_control *""'"); - } - arg1 = reinterpret_cast< ctb::timer_control * >(argp1); - result = (unsigned int) ((arg1)->usecs); - resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_timer_control_exitflag_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::timer_control *arg1 = (ctb::timer_control *) 0 ; - int *arg2 = (int *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"timer_control_exitflag_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__timer_control, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "timer_control_exitflag_set" "', argument " "1"" of type '" "ctb::timer_control *""'"); - } - arg1 = reinterpret_cast< ctb::timer_control * >(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_int, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "timer_control_exitflag_set" "', argument " "2"" of type '" "int *""'"); - } - arg2 = reinterpret_cast< int * >(argp2); - if (arg1) (arg1)->exitflag = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_timer_control_exitflag_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::timer_control *arg1 = (ctb::timer_control *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"timer_control_exitflag_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__timer_control, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "timer_control_exitflag_get" "', argument " "1"" of type '" "ctb::timer_control *""'"); - } - arg1 = reinterpret_cast< ctb::timer_control * >(argp1); - result = (int *) ((arg1)->exitflag); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_timer_control_exitfnc_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::timer_control *arg1 = (ctb::timer_control *) 0 ; - void *(*arg2)(void *) = (void *(*)(void *)) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"timer_control_exitfnc_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__timer_control, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "timer_control_exitfnc_set" "', argument " "1"" of type '" "ctb::timer_control *""'"); - } - arg1 = reinterpret_cast< ctb::timer_control * >(argp1); - { - int res = SWIG_ConvertFunctionPtr(obj1, (void**)(&arg2), SWIGTYPE_p_f_p_void__p_void); - if (!SWIG_IsOK(res)) { - SWIG_exception_fail(SWIG_ArgError(res), "in method '" "timer_control_exitfnc_set" "', argument " "2"" of type '" "void *(*)(void *)""'"); - } - } - if (arg1) (arg1)->exitfnc = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_timer_control_exitfnc_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::timer_control *arg1 = (ctb::timer_control *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - void *(*result)(void *) = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"timer_control_exitfnc_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__timer_control, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "timer_control_exitfnc_get" "', argument " "1"" of type '" "ctb::timer_control *""'"); - } - arg1 = reinterpret_cast< ctb::timer_control * >(argp1); - result = (void *(*)(void *)) ((arg1)->exitfnc); - resultobj = SWIG_NewFunctionPtrObj((void *)(result), SWIGTYPE_p_f_p_void__p_void); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *timer_control_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__timer_control, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_new_Timer(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - unsigned int arg1 ; - int *arg2 = (int *) 0 ; - void *(*arg3)(void *) = (void *(*)(void *)) NULL ; - unsigned int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "msec",(char *) "exitflag",(char *) "exitfnc", NULL - }; - ctb::Timer *result = 0 ; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO|O:new_Timer",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_Timer" "', argument " "1"" of type '" "unsigned int""'"); - } - arg1 = static_cast< unsigned int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_int, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_Timer" "', argument " "2"" of type '" "int *""'"); - } - arg2 = reinterpret_cast< int * >(argp2); - if (obj2) { - { - int res = SWIG_ConvertFunctionPtr(obj2, (void**)(&arg3), SWIGTYPE_p_f_p_void__p_void); - if (!SWIG_IsOK(res)) { - SWIG_exception_fail(SWIG_ArgError(res), "in method '" "new_Timer" "', argument " "3"" of type '" "void *(*)(void *)""'"); - } - } - } - result = (ctb::Timer *)new ctb::Timer(arg1,arg2,arg3); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ctb__Timer, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_Timer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::Timer *arg1 = (ctb::Timer *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"delete_Timer",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__Timer, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Timer" "', argument " "1"" of type '" "ctb::Timer *""'"); - } - arg1 = reinterpret_cast< ctb::Timer * >(argp1); - delete arg1; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Timer_start(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::Timer *arg1 = (ctb::Timer *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"Timer_start",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__Timer, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Timer_start" "', argument " "1"" of type '" "ctb::Timer *""'"); - } - arg1 = reinterpret_cast< ctb::Timer * >(argp1); - result = (int)(arg1)->start(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Timer_stop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::Timer *arg1 = (ctb::Timer *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"Timer_stop",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__Timer, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Timer_stop" "', argument " "1"" of type '" "ctb::Timer *""'"); - } - arg1 = reinterpret_cast< ctb::Timer * >(argp1); - result = (int)(arg1)->stop(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *Timer_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__Timer, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_sleepms(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - unsigned int arg1 ; - unsigned int val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "ms", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:sleepms",kwnames,&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "sleepms" "', argument " "1"" of type '" "unsigned int""'"); - } - arg1 = static_cast< unsigned int >(val1); - ctb::sleepms(arg1); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_IOBase(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"delete_IOBase",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IOBase" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - delete arg1; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_ClassName(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"IOBase_ClassName",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_ClassName" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - result = (char *)(arg1)->ClassName(); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Close(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"IOBase_Close",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Close" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - result = (int)(arg1)->Close(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Ioctl(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - int arg2 ; - void *arg3 = (void *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int res3 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "cmd",(char *) "args", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:IOBase_Ioctl",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Ioctl" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IOBase_Ioctl" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IOBase_Ioctl" "', argument " "3"" of type '" "void *""'"); - } - result = (int)(arg1)->Ioctl(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_IsOpen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"IOBase_IsOpen",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_IsOpen" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - result = (int)(arg1)->IsOpen(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Open(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char *arg2 = (char *) 0 ; - void *arg3 = (void *) 0L ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - int res3 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "devname",(char *) "dcs", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO|O:IOBase_Open",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Open" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IOBase_Open" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - if (obj2) { - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IOBase_Open" "', argument " "3"" of type '" "void *""'"); - } - } - result = (int)(arg1)->Open((char const *)arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_PutBack(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - char val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "ch", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:IOBase_PutBack",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_PutBack" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - ecode2 = SWIG_AsVal_char(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IOBase_PutBack" "', argument " "2"" of type '" "char""'"); - } - arg2 = static_cast< char >(val2); - result = (int)(arg1)->PutBack(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Read(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char *arg2 = (char *) 0 ; - size_t arg3 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - size_t val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "buf",(char *) "len", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:IOBase_Read",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Read" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IOBase_Read" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IOBase_Read" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - result = (int)(arg1)->Read(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_ReadUntilEOS(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char **arg2 = 0 ; - size_t *arg3 = (size_t *) 0 ; - char *arg4 = (char *) "\n" ; - long arg5 = (long) 1000L ; - char arg6 = (char) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - char *tmp2 ; - size_t tmp3 ; - int res4 ; - char *buf4 = 0 ; - int alloc4 = 0 ; - long val5 ; - int ecode5 = 0 ; - char val6 ; - int ecode6 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - PyObject * obj5 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "readbuf",(char *) "readedBytes",(char *) "eosString",(char *) "timeout_in_ms",(char *) "quota", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|OOO:IOBase_ReadUntilEOS",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_ReadUntilEOS" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - { - /* dont check for list */ - arg2 = &tmp2; - } - { - /* dont check for list */ - arg3 = &tmp3; - } - if (obj3) { - res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "IOBase_ReadUntilEOS" "', argument " "4"" of type '" "char *""'"); - } - arg4 = reinterpret_cast< char * >(buf4); - } - if (obj4) { - ecode5 = SWIG_AsVal_long(obj4, &val5); - if (!SWIG_IsOK(ecode5)) { - SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "IOBase_ReadUntilEOS" "', argument " "5"" of type '" "long""'"); - } - arg5 = static_cast< long >(val5); - } - if (obj5) { - ecode6 = SWIG_AsVal_char(obj5, &val6); - if (!SWIG_IsOK(ecode6)) { - SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "IOBase_ReadUntilEOS" "', argument " "6"" of type '" "char""'"); - } - arg6 = static_cast< char >(val6); - } - result = (int)(arg1)->ReadUntilEOS(*arg2,arg3,arg4,arg5,arg6); - resultobj = SWIG_From_int(static_cast< int >(result)); - { - PyObject * plist = PyList_New(2); - PyList_SetItem(plist, 0, PyString_FromString(*arg2)); - PyList_SetItem(plist, 1, resultobj); - resultobj = plist; - delete *arg2; - } - { - PyList_Append(resultobj, PyInt_FromLong(*arg3)); - } - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; - return resultobj; -fail: - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Readv(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char *arg2 = (char *) 0 ; - size_t arg3 ; - unsigned int arg4 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - size_t val3 ; - int ecode3 = 0 ; - unsigned int val4 ; - int ecode4 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "buf",(char *) "len",(char *) "timeout_in_ms", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:IOBase_Readv",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Readv" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IOBase_Readv" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IOBase_Readv" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IOBase_Readv" "', argument " "4"" of type '" "unsigned int""'"); - } - arg4 = static_cast< unsigned int >(val4); - result = (int)(arg1)->Readv(arg2,arg3,arg4); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Write(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char *arg2 = (char *) 0 ; - size_t arg3 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - size_t val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "buf",(char *) "len", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:IOBase_Write",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Write" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IOBase_Write" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IOBase_Write" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - result = (int)(arg1)->Write(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_IOBase_Writev(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::IOBase *arg1 = (ctb::IOBase *) 0 ; - char *arg2 = (char *) 0 ; - size_t arg3 ; - unsigned int arg4 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - size_t val3 ; - int ecode3 = 0 ; - unsigned int val4 ; - int ecode4 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "buf",(char *) "len",(char *) "timeout_in_ms", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:IOBase_Writev",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__IOBase, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IOBase_Writev" "', argument " "1"" of type '" "ctb::IOBase *""'"); - } - arg1 = reinterpret_cast< ctb::IOBase * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IOBase_Writev" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IOBase_Writev" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IOBase_Writev" "', argument " "4"" of type '" "unsigned int""'"); - } - arg4 = static_cast< unsigned int >(val4); - result = (int)(arg1)->Writev(arg2,arg3,arg4); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *IOBase_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__IOBase, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_baud_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_baud_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_baud_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_DCS_baud_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - if (arg1) (arg1)->baud = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_baud_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_baud_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_baud_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (int) ((arg1)->baud); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_parity_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - ctb::Parity arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_parity_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_parity_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_DCS_parity_set" "', argument " "2"" of type '" "ctb::Parity""'"); - } - arg2 = static_cast< ctb::Parity >(val2); - if (arg1) (arg1)->parity = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_parity_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - ctb::Parity result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_parity_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_parity_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (ctb::Parity) ((arg1)->parity); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_wordlen_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - unsigned char arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - unsigned char val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_wordlen_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_wordlen_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - ecode2 = SWIG_AsVal_unsigned_SS_char(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_DCS_wordlen_set" "', argument " "2"" of type '" "unsigned char""'"); - } - arg2 = static_cast< unsigned char >(val2); - if (arg1) (arg1)->wordlen = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_wordlen_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - unsigned char result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_wordlen_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_wordlen_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (unsigned char) ((arg1)->wordlen); - resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_stopbits_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - unsigned char arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - unsigned char val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_stopbits_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_stopbits_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - ecode2 = SWIG_AsVal_unsigned_SS_char(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_DCS_stopbits_set" "', argument " "2"" of type '" "unsigned char""'"); - } - arg2 = static_cast< unsigned char >(val2); - if (arg1) (arg1)->stopbits = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_stopbits_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - unsigned char result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_stopbits_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_stopbits_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (unsigned char) ((arg1)->stopbits); - resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_rtscts_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - bool arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_rtscts_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_rtscts_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_DCS_rtscts_set" "', argument " "2"" of type '" "bool""'"); - } - arg2 = static_cast< bool >(val2); - if (arg1) (arg1)->rtscts = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_rtscts_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - bool result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_rtscts_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_rtscts_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (bool) ((arg1)->rtscts); - resultobj = SWIG_From_bool(static_cast< bool >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_xonxoff_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - bool arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_xonxoff_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_xonxoff_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_DCS_xonxoff_set" "', argument " "2"" of type '" "bool""'"); - } - arg2 = static_cast< bool >(val2); - if (arg1) (arg1)->xonxoff = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_xonxoff_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - bool result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_xonxoff_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_xonxoff_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (bool) ((arg1)->xonxoff); - resultobj = SWIG_From_bool(static_cast< bool >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_buf_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - char *arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - char temp2[16] ; - int res2 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_buf_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_buf_set" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - res2 = SWIG_AsCharArray(obj1, temp2, 16); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SerialPort_DCS_buf_set" "', argument " "2"" of type '" "char [16]""'"); - } - arg2 = reinterpret_cast< char * >(temp2); - if (arg2) memcpy(arg1->buf,arg2,16*sizeof(char)); - else memset(arg1->buf,0,16*sizeof(char)); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_buf_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_buf_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_buf_get" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (char *)(char *) ((arg1)->buf); - { - size_t size = 16; - - while (size && (result[size - 1] == '\0')) --size; - - resultobj = SWIG_FromCharPtrAndSize(result, size); - } - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_SerialPort_DCS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"new_SerialPort_DCS",0,0)) SWIG_fail; - result = (ctb::SerialPort_DCS *)new ctb::SerialPort_DCS(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ctb__SerialPort_DCS, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_SerialPort_DCS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"delete_SerialPort_DCS",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SerialPort_DCS" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - delete arg1; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_DCS_GetSettings(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_DCS *arg1 = (ctb::SerialPort_DCS *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_DCS_GetSettings",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_DCS, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_DCS_GetSettings" "', argument " "1"" of type '" "ctb::SerialPort_DCS *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_DCS * >(argp1); - result = (char *)(arg1)->GetSettings(); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *SerialPort_DCS_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__SerialPort_DCS, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_brk_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_brk_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_brk_set" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_EINFO_brk_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - if (arg1) (arg1)->brk = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_brk_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_brk_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_brk_get" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - result = (int) ((arg1)->brk); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_frame_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_frame_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_frame_set" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_EINFO_frame_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - if (arg1) (arg1)->frame = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_frame_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_frame_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_frame_get" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - result = (int) ((arg1)->frame); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_overrun_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_overrun_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_overrun_set" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_EINFO_overrun_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - if (arg1) (arg1)->overrun = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_overrun_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_overrun_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_overrun_get" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - result = (int) ((arg1)->overrun); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_parity_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_parity_set",2,2,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_parity_set" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_EINFO_parity_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - if (arg1) (arg1)->parity = arg2; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_EINFO_parity_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_EINFO_parity_get",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_EINFO_parity_get" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - result = (int) ((arg1)->parity); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_SerialPort_EINFO(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"new_SerialPort_EINFO",0,0)) SWIG_fail; - result = (ctb::SerialPort_EINFO *)new ctb::SerialPort_EINFO(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ctb__SerialPort_EINFO, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_SerialPort_EINFO(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_EINFO *arg1 = (ctb::SerialPort_EINFO *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"delete_SerialPort_EINFO",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_EINFO, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SerialPort_EINFO" "', argument " "1"" of type '" "ctb::SerialPort_EINFO *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_EINFO * >(argp1); - delete arg1; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *SerialPort_EINFO_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__SerialPort_EINFO, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_delete_SerialPort_x(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"delete_SerialPort_x",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SerialPort_x" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - delete arg1; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_ClassName(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_x_ClassName",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_ClassName" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - result = (char *)(arg1)->ClassName(); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_ChangeLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - ctb::SerialLineState arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "flags", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_x_ChangeLineState",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_ChangeLineState" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_ChangeLineState" "', argument " "2"" of type '" "ctb::SerialLineState""'"); - } - arg2 = static_cast< ctb::SerialLineState >(val2); - result = (int)(arg1)->ChangeLineState(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_ClrLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - ctb::SerialLineState arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "flags", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_x_ClrLineState",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_ClrLineState" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_ClrLineState" "', argument " "2"" of type '" "ctb::SerialLineState""'"); - } - arg2 = static_cast< ctb::SerialLineState >(val2); - result = (int)(arg1)->ClrLineState(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_GetLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_x_GetLineState",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_GetLineState" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - result = (int)(arg1)->GetLineState(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_GetSettingsAsString(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_x_GetSettingsAsString",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_GetSettingsAsString" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - result = (char *)(arg1)->GetSettingsAsString(); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_Ioctl(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - int arg2 ; - void *arg3 = (void *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int res3 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "cmd",(char *) "args", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:SerialPort_x_Ioctl",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_Ioctl" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_Ioctl" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SerialPort_x_Ioctl" "', argument " "3"" of type '" "void *""'"); - } - result = (int)(arg1)->Ioctl(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_SendBreak(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "duration", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_x_SendBreak",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_SendBreak" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_SendBreak" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - result = (int)(arg1)->SendBreak(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_SetBaudrate(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "baudrate", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_x_SetBaudrate",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_SetBaudrate" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_SetBaudrate" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - result = (int)(arg1)->SetBaudrate(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_SetLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - ctb::SerialLineState arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "flags", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_x_SetLineState",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_SetLineState" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_SetLineState" "', argument " "2"" of type '" "ctb::SerialLineState""'"); - } - arg2 = static_cast< ctb::SerialLineState >(val2); - result = (int)(arg1)->SetLineState(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_SetParityBit(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort_x *arg1 = (ctb::SerialPort_x *) 0 ; - bool arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "parity", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_x_SetParityBit",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort_x, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_x_SetParityBit" "', argument " "1"" of type '" "ctb::SerialPort_x *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort_x * >(argp1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_x_SetParityBit" "', argument " "2"" of type '" "bool""'"); - } - arg2 = static_cast< bool >(val2); - result = (int)(arg1)->SetParityBit(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_x_IsStandardRate(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - long arg1 ; - long val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "rate", NULL - }; - bool result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:SerialPort_x_IsStandardRate",kwnames,&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "SerialPort_x_IsStandardRate" "', argument " "1"" of type '" "long""'"); - } - arg1 = static_cast< long >(val1); - result = (bool)ctb::SerialPort_x::IsStandardRate(arg1); - resultobj = SWIG_From_bool(static_cast< bool >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *SerialPort_x_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__SerialPort_x, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_new_SerialPort(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort *result = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"new_SerialPort",0,0)) SWIG_fail; - result = (ctb::SerialPort *)new ctb::SerialPort(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ctb__SerialPort, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_SerialPort(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if(!PyArg_UnpackTuple(args,(char *)"delete_SerialPort",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SerialPort" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - delete arg1; - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_ChangeLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - ctb::SerialLineState arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "flags", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_ChangeLineState",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_ChangeLineState" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_ChangeLineState" "', argument " "2"" of type '" "ctb::SerialLineState""'"); - } - arg2 = static_cast< ctb::SerialLineState >(val2); - result = (int)(arg1)->ChangeLineState(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_ClrLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - ctb::SerialLineState arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "flags", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_ClrLineState",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_ClrLineState" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_ClrLineState" "', argument " "2"" of type '" "ctb::SerialLineState""'"); - } - arg2 = static_cast< ctb::SerialLineState >(val2); - result = (int)(arg1)->ClrLineState(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_GetLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_GetLineState",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_GetLineState" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - result = (int)(arg1)->GetLineState(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_Ioctl(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - int arg2 ; - void *arg3 = (void *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int res3 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "cmd",(char *) "args", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:SerialPort_Ioctl",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_Ioctl" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_Ioctl" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SerialPort_Ioctl" "', argument " "3"" of type '" "void *""'"); - } - result = (int)(arg1)->Ioctl(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_IsOpen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if(!PyArg_UnpackTuple(args,(char *)"SerialPort_IsOpen",1,1,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_IsOpen" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - result = (int)(arg1)->IsOpen(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_Read(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - char *arg2 = (char *) 0 ; - size_t arg3 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - size_t val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "buf",(char *) "len", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:SerialPort_Read",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_Read" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SerialPort_Read" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SerialPort_Read" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - result = (int)(arg1)->Read(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_SendBreak(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "duration", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_SendBreak",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_SendBreak" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_SendBreak" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - result = (int)(arg1)->SendBreak(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_SetBaudrate(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "baudrate", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_SetBaudrate",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_SetBaudrate" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_SetBaudrate" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - result = (int)(arg1)->SetBaudrate(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_SetLineState(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - ctb::SerialLineState arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "flags", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_SetLineState",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_SetLineState" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_SetLineState" "', argument " "2"" of type '" "ctb::SerialLineState""'"); - } - arg2 = static_cast< ctb::SerialLineState >(val2); - result = (int)(arg1)->SetLineState(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_SetParityBit(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - bool arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "parity", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SerialPort_SetParityBit",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_SetParityBit" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SerialPort_SetParityBit" "', argument " "2"" of type '" "bool""'"); - } - arg2 = static_cast< bool >(val2); - result = (int)(arg1)->SetParityBit(arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_SerialPort_Write(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - ctb::SerialPort *arg1 = (ctb::SerialPort *) 0 ; - char *arg2 = (char *) 0 ; - size_t arg3 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - size_t val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "buf",(char *) "len", NULL - }; - int result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:SerialPort_Write",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ctb__SerialPort, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SerialPort_Write" "', argument " "1"" of type '" "ctb::SerialPort *""'"); - } - arg1 = reinterpret_cast< ctb::SerialPort * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SerialPort_Write" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SerialPort_Write" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - result = (int)(arg1)->Write(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *SerialPort_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_ctb__SerialPort, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *_wrap_GetKey(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char result; - - if(!PyArg_UnpackTuple(args,(char *)"GetKey",0,0)) SWIG_fail; - result = (char)ctb::GetKey(); - resultobj = SWIG_From_char(static_cast< char >(result)); - return resultobj; -fail: - return NULL; -} - - -static PyMethodDef SwigMethods[] = { - { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL}, - { (char *)"new_intp", _wrap_new_intp, METH_VARARGS, NULL}, - { (char *)"copy_intp", (PyCFunction) _wrap_copy_intp, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_intp", (PyCFunction) _wrap_delete_intp, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"intp_assign", (PyCFunction) _wrap_intp_assign, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"intp_value", (PyCFunction) _wrap_intp_value, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"timer_control_usecs_set", _wrap_timer_control_usecs_set, METH_VARARGS, NULL}, - { (char *)"timer_control_usecs_get", _wrap_timer_control_usecs_get, METH_VARARGS, NULL}, - { (char *)"timer_control_exitflag_set", _wrap_timer_control_exitflag_set, METH_VARARGS, NULL}, - { (char *)"timer_control_exitflag_get", _wrap_timer_control_exitflag_get, METH_VARARGS, NULL}, - { (char *)"timer_control_exitfnc_set", _wrap_timer_control_exitfnc_set, METH_VARARGS, NULL}, - { (char *)"timer_control_exitfnc_get", _wrap_timer_control_exitfnc_get, METH_VARARGS, NULL}, - { (char *)"timer_control_swigregister", timer_control_swigregister, METH_VARARGS, NULL}, - { (char *)"new_Timer", (PyCFunction) _wrap_new_Timer, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_Timer", _wrap_delete_Timer, METH_VARARGS, NULL}, - { (char *)"Timer_start", _wrap_Timer_start, METH_VARARGS, NULL}, - { (char *)"Timer_stop", _wrap_Timer_stop, METH_VARARGS, NULL}, - { (char *)"Timer_swigregister", Timer_swigregister, METH_VARARGS, NULL}, - { (char *)"sleepms", (PyCFunction) _wrap_sleepms, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_IOBase", _wrap_delete_IOBase, METH_VARARGS, NULL}, - { (char *)"IOBase_ClassName", _wrap_IOBase_ClassName, METH_VARARGS, NULL}, - { (char *)"IOBase_Close", _wrap_IOBase_Close, METH_VARARGS, NULL}, - { (char *)"IOBase_Ioctl", (PyCFunction) _wrap_IOBase_Ioctl, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_IsOpen", _wrap_IOBase_IsOpen, METH_VARARGS, NULL}, - { (char *)"IOBase_Open", (PyCFunction) _wrap_IOBase_Open, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_PutBack", (PyCFunction) _wrap_IOBase_PutBack, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_Read", (PyCFunction) _wrap_IOBase_Read, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_ReadUntilEOS", (PyCFunction) _wrap_IOBase_ReadUntilEOS, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_Readv", (PyCFunction) _wrap_IOBase_Readv, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_Write", (PyCFunction) _wrap_IOBase_Write, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_Writev", (PyCFunction) _wrap_IOBase_Writev, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"IOBase_swigregister", IOBase_swigregister, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_baud_set", _wrap_SerialPort_DCS_baud_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_baud_get", _wrap_SerialPort_DCS_baud_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_parity_set", _wrap_SerialPort_DCS_parity_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_parity_get", _wrap_SerialPort_DCS_parity_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_wordlen_set", _wrap_SerialPort_DCS_wordlen_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_wordlen_get", _wrap_SerialPort_DCS_wordlen_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_stopbits_set", _wrap_SerialPort_DCS_stopbits_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_stopbits_get", _wrap_SerialPort_DCS_stopbits_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_rtscts_set", _wrap_SerialPort_DCS_rtscts_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_rtscts_get", _wrap_SerialPort_DCS_rtscts_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_xonxoff_set", _wrap_SerialPort_DCS_xonxoff_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_xonxoff_get", _wrap_SerialPort_DCS_xonxoff_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_buf_set", _wrap_SerialPort_DCS_buf_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_buf_get", _wrap_SerialPort_DCS_buf_get, METH_VARARGS, NULL}, - { (char *)"new_SerialPort_DCS", _wrap_new_SerialPort_DCS, METH_VARARGS, NULL}, - { (char *)"delete_SerialPort_DCS", _wrap_delete_SerialPort_DCS, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_GetSettings", _wrap_SerialPort_DCS_GetSettings, METH_VARARGS, NULL}, - { (char *)"SerialPort_DCS_swigregister", SerialPort_DCS_swigregister, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_brk_set", _wrap_SerialPort_EINFO_brk_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_brk_get", _wrap_SerialPort_EINFO_brk_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_frame_set", _wrap_SerialPort_EINFO_frame_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_frame_get", _wrap_SerialPort_EINFO_frame_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_overrun_set", _wrap_SerialPort_EINFO_overrun_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_overrun_get", _wrap_SerialPort_EINFO_overrun_get, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_parity_set", _wrap_SerialPort_EINFO_parity_set, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_parity_get", _wrap_SerialPort_EINFO_parity_get, METH_VARARGS, NULL}, - { (char *)"new_SerialPort_EINFO", _wrap_new_SerialPort_EINFO, METH_VARARGS, NULL}, - { (char *)"delete_SerialPort_EINFO", _wrap_delete_SerialPort_EINFO, METH_VARARGS, NULL}, - { (char *)"SerialPort_EINFO_swigregister", SerialPort_EINFO_swigregister, METH_VARARGS, NULL}, - { (char *)"delete_SerialPort_x", _wrap_delete_SerialPort_x, METH_VARARGS, NULL}, - { (char *)"SerialPort_x_ClassName", _wrap_SerialPort_x_ClassName, METH_VARARGS, NULL}, - { (char *)"SerialPort_x_ChangeLineState", (PyCFunction) _wrap_SerialPort_x_ChangeLineState, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_ClrLineState", (PyCFunction) _wrap_SerialPort_x_ClrLineState, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_GetLineState", _wrap_SerialPort_x_GetLineState, METH_VARARGS, NULL}, - { (char *)"SerialPort_x_GetSettingsAsString", _wrap_SerialPort_x_GetSettingsAsString, METH_VARARGS, NULL}, - { (char *)"SerialPort_x_Ioctl", (PyCFunction) _wrap_SerialPort_x_Ioctl, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_SendBreak", (PyCFunction) _wrap_SerialPort_x_SendBreak, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_SetBaudrate", (PyCFunction) _wrap_SerialPort_x_SetBaudrate, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_SetLineState", (PyCFunction) _wrap_SerialPort_x_SetLineState, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_SetParityBit", (PyCFunction) _wrap_SerialPort_x_SetParityBit, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_IsStandardRate", (PyCFunction) _wrap_SerialPort_x_IsStandardRate, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_x_swigregister", SerialPort_x_swigregister, METH_VARARGS, NULL}, - { (char *)"new_SerialPort", _wrap_new_SerialPort, METH_VARARGS, NULL}, - { (char *)"delete_SerialPort", _wrap_delete_SerialPort, METH_VARARGS, NULL}, - { (char *)"SerialPort_ChangeLineState", (PyCFunction) _wrap_SerialPort_ChangeLineState, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_ClrLineState", (PyCFunction) _wrap_SerialPort_ClrLineState, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_GetLineState", _wrap_SerialPort_GetLineState, METH_VARARGS, NULL}, - { (char *)"SerialPort_Ioctl", (PyCFunction) _wrap_SerialPort_Ioctl, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_IsOpen", _wrap_SerialPort_IsOpen, METH_VARARGS, NULL}, - { (char *)"SerialPort_Read", (PyCFunction) _wrap_SerialPort_Read, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_SendBreak", (PyCFunction) _wrap_SerialPort_SendBreak, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_SetBaudrate", (PyCFunction) _wrap_SerialPort_SetBaudrate, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_SetLineState", (PyCFunction) _wrap_SerialPort_SetLineState, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_SetParityBit", (PyCFunction) _wrap_SerialPort_SetParityBit, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_Write", (PyCFunction) _wrap_SerialPort_Write, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SerialPort_swigregister", SerialPort_swigregister, METH_VARARGS, NULL}, - { (char *)"GetKey", _wrap_GetKey, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static void *_p_ctb__SerialPort_xTo_p_ctb__IOBase(void *x, int *SWIGUNUSEDPARM(newmemory)) { - return (void *)((ctb::IOBase *) ((ctb::SerialPort_x *) x)); -} -static void *_p_ctb__SerialPortTo_p_ctb__IOBase(void *x, int *SWIGUNUSEDPARM(newmemory)) { - return (void *)((ctb::IOBase *) (ctb::SerialPort_x *) ((ctb::SerialPort *) x)); -} -static void *_p_ctb__SerialPortTo_p_ctb__SerialPort_x(void *x, int *SWIGUNUSEDPARM(newmemory)) { - return (void *)((ctb::SerialPort_x *) ((ctb::SerialPort *) x)); -} -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__IOBase = {"_p_ctb__IOBase", "ctb::IOBase *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__SerialPort = {"_p_ctb__SerialPort", "ctb::SerialPort *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__SerialPort_DCS = {"_p_ctb__SerialPort_DCS", "ctb::SerialPort_DCS *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__SerialPort_EINFO = {"_p_ctb__SerialPort_EINFO", "ctb::SerialPort_EINFO *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__SerialPort_x = {"_p_ctb__SerialPort_x", "ctb::SerialPort_x *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__Timer = {"_p_ctb__Timer", "ctb::Timer *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ctb__timer_control = {"_p_ctb__timer_control", "ctb::timer_control *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_f_p_void__p_void = {"_p_f_p_void__p_void", "void *(*)(void *)", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_int = {"_p_int", "int *|size_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_char, - &_swigt__p_ctb__IOBase, - &_swigt__p_ctb__SerialPort, - &_swigt__p_ctb__SerialPort_DCS, - &_swigt__p_ctb__SerialPort_EINFO, - &_swigt__p_ctb__SerialPort_x, - &_swigt__p_ctb__Timer, - &_swigt__p_ctb__timer_control, - &_swigt__p_f_p_void__p_void, - &_swigt__p_int, - &_swigt__p_p_char, -}; - -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__IOBase[] = { {&_swigt__p_ctb__IOBase, 0, 0, 0}, {&_swigt__p_ctb__SerialPort_x, _p_ctb__SerialPort_xTo_p_ctb__IOBase, 0, 0}, {&_swigt__p_ctb__SerialPort, _p_ctb__SerialPortTo_p_ctb__IOBase, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__SerialPort[] = { {&_swigt__p_ctb__SerialPort, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__SerialPort_DCS[] = { {&_swigt__p_ctb__SerialPort_DCS, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__SerialPort_EINFO[] = { {&_swigt__p_ctb__SerialPort_EINFO, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__SerialPort_x[] = { {&_swigt__p_ctb__SerialPort_x, 0, 0, 0}, {&_swigt__p_ctb__SerialPort, _p_ctb__SerialPortTo_p_ctb__SerialPort_x, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__Timer[] = { {&_swigt__p_ctb__Timer, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ctb__timer_control[] = { {&_swigt__p_ctb__timer_control, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_f_p_void__p_void[] = { {&_swigt__p_f_p_void__p_void, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_char, - _swigc__p_ctb__IOBase, - _swigc__p_ctb__SerialPort, - _swigc__p_ctb__SerialPort_DCS, - _swigc__p_ctb__SerialPort_EINFO, - _swigc__p_ctb__SerialPort_x, - _swigc__p_ctb__Timer, - _swigc__p_ctb__timer_control, - _swigc__p_f_p_void__p_void, - _swigc__p_int, - _swigc__p_p_char, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { -{0, 0, 0, 0.0, 0, 0}}; - -#ifdef __cplusplus -} -#endif -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned staticly to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int found, init; - - clientdata = clientdata; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - module_head = &swig_module; - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - found=0; - iter=module_head; - do { - if (iter==&swig_module) { - found=1; - break; - } - iter=iter->next; - } while (iter!= module_head); - - /* if the is found in the list, then all is done and we may leave */ - if (found) return; - /* otherwise we must add out module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpeters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ - /* c-mode */ -#endif -} -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - /* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - - /* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - - typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; - } swig_globalvar; - - typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; - } swig_varlinkobject; - - SWIGINTERN PyObject * - swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_InternFromString(""); -#else - return PyString_FromString(""); -#endif - } - - SWIGINTERN PyObject * - swig_varlink_str(swig_varlinkobject *v) { -#if PY_VERSION_HEX >= 0x03000000 - PyObject *str = PyUnicode_InternFromString("("); - PyObject *tail; - PyObject *joined; - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - tail = PyUnicode_FromString(var->name); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; - if (var->next) { - tail = PyUnicode_InternFromString(", "); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; - } - } - tail = PyUnicode_InternFromString(")"); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; -#else - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); -#endif - return str; - } - - SWIGINTERN int - swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { - char *tmp; - PyObject *str = swig_varlink_str(v); - fprintf(fp,"Swig global variables "); - fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str)); - SWIG_Python_str_DelForPy3(tmp); - Py_DECREF(str); - return 0; - } - - SWIGINTERN void - swig_varlink_dealloc(swig_varlinkobject *v) { - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } - } - - SWIGINTERN PyObject * - swig_varlink_getattr(swig_varlinkobject *v, char *n) { - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN int - swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN PyTypeObject* - swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - /* PyObject header changed in Python 3 */ -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(&PyType_Type, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* Number of items in variable part (ob_size) */ -#endif - (char *)"swigvarlink", /* Type name (tp_name) */ - sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ - 0, /* Itemsize (tp_itemsize) */ - (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ - (printfunc) swig_varlink_print, /* Print (tp_print) */ - (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ - (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc) swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - varlink_type = tmp; - /* for Python 3 we already assigned ob_type in PyVarObject_HEAD_INIT() */ -#if PY_VERSION_HEX < 0x03000000 - varlink_type.ob_type = &PyType_Type; -#endif - type_init = 1; - } - return &varlink_type; - } - - /* Create a variable linking object for use later */ - SWIGINTERN PyObject * - SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); - } - - SWIGINTERN void - SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - strncpy(gv->name,name,size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; - } - - SWIGINTERN PyObject * - SWIG_globals(void) { - static PyObject *_SWIG_globals = 0; - if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); - return _SWIG_globals; - } - - /* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - - /* Install Constants */ - SWIGINTERN void - SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } - } - - /* -----------------------------------------------------------------------------*/ - /* Fix SwigMethods to carry the callback ptrs when needed */ - /* -----------------------------------------------------------------------------*/ - - SWIGINTERN void - SWIG_Python_FixMethods(PyMethodDef *methods, - swig_const_info *const_table, - swig_type_info **types, - swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (c && (c = strstr(c, "swig_ptr: "))) { - int j; - swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - strncpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } - } - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif - -SWIGEXPORT -#if PY_VERSION_HEX >= 0x03000000 -PyObject* -#else -void -#endif -SWIG_init(void) { - PyObject *m, *d; -#if PY_VERSION_HEX >= 0x03000000 - static struct PyModuleDef SWIG_module = { - PyModuleDef_HEAD_INIT, - (char *) SWIG_name, - NULL, - -1, - SwigMethods, - NULL, - NULL, - NULL, - NULL - }; -#endif - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - -#if PY_VERSION_HEX >= 0x03000000 - m = PyModule_Create(&SWIG_module); -#else - m = Py_InitModule((char *) SWIG_name, SwigMethods); -#endif - d = PyModule_GetDict(m); - - SWIG_InitializeModule(0); - SWIG_InstallConstants(d,swig_const_table); - - - SWIG_Python_SetConstant(d, "CTB_RESET",SWIG_From_int(static_cast< int >(ctb::CTB_RESET))); - SWIG_Python_SetConstant(d, "ParityNone",SWIG_From_int(static_cast< int >(ctb::ParityNone))); - SWIG_Python_SetConstant(d, "ParityOdd",SWIG_From_int(static_cast< int >(ctb::ParityOdd))); - SWIG_Python_SetConstant(d, "ParityEven",SWIG_From_int(static_cast< int >(ctb::ParityEven))); - SWIG_Python_SetConstant(d, "ParityMark",SWIG_From_int(static_cast< int >(ctb::ParityMark))); - SWIG_Python_SetConstant(d, "ParitySpace",SWIG_From_int(static_cast< int >(ctb::ParitySpace))); - SWIG_Python_SetConstant(d, "LinestateDcd",SWIG_From_int(static_cast< int >(ctb::LinestateDcd))); - SWIG_Python_SetConstant(d, "LinestateCts",SWIG_From_int(static_cast< int >(ctb::LinestateCts))); - SWIG_Python_SetConstant(d, "LinestateDsr",SWIG_From_int(static_cast< int >(ctb::LinestateDsr))); - SWIG_Python_SetConstant(d, "LinestateDtr",SWIG_From_int(static_cast< int >(ctb::LinestateDtr))); - SWIG_Python_SetConstant(d, "LinestateRing",SWIG_From_int(static_cast< int >(ctb::LinestateRing))); - SWIG_Python_SetConstant(d, "LinestateRts",SWIG_From_int(static_cast< int >(ctb::LinestateRts))); - SWIG_Python_SetConstant(d, "LinestateNull",SWIG_From_int(static_cast< int >(ctb::LinestateNull))); - SWIG_Python_SetConstant(d, "CTB_SER_GETEINFO",SWIG_From_int(static_cast< int >(ctb::CTB_SER_GETEINFO))); - SWIG_Python_SetConstant(d, "CTB_SER_GETBRK",SWIG_From_int(static_cast< int >(ctb::CTB_SER_GETBRK))); - SWIG_Python_SetConstant(d, "CTB_SER_GETFRM",SWIG_From_int(static_cast< int >(ctb::CTB_SER_GETFRM))); - SWIG_Python_SetConstant(d, "CTB_SER_GETOVR",SWIG_From_int(static_cast< int >(ctb::CTB_SER_GETOVR))); - SWIG_Python_SetConstant(d, "CTB_SER_GETPAR",SWIG_From_int(static_cast< int >(ctb::CTB_SER_GETPAR))); - SWIG_Python_SetConstant(d, "CTB_SER_GETINQUE",SWIG_From_int(static_cast< int >(ctb::CTB_SER_GETINQUE))); - SWIG_Python_SetConstant(d, "CTB_SER_SETPAR",SWIG_From_int(static_cast< int >(ctb::CTB_SER_SETPAR))); -#if PY_VERSION_HEX >= 0x03000000 - return m; -#else - return; -#endif -} - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/serportx.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/serportx.i deleted file mode 100644 index 083daddab4..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/serportx.i +++ /dev/null @@ -1,84 +0,0 @@ -%{ -#include "ctb-0.16/serportx.h" -%} - -%include iobase.i - -namespace ctb { - -enum Parity -{ - ParityNone, - ParityOdd, - ParityEven, - ParityMark, - ParitySpace -}; - -enum SerialLineState -{ - LinestateDcd = 0x040, - LinestateCts = 0x020, - LinestateDsr = 0x100, - LinestateDtr = 0x002, - LinestateRing = 0x080, - LinestateRts = 0x004, - LinestateNull = 0x000 -}; - -struct SerialPort_DCS -{ - int baud; - Parity parity; - unsigned char wordlen; - unsigned char stopbits; - bool rtscts; - bool xonxoff; - char buf[16]; - SerialPort_DCS(); - ~SerialPort_DCS(); - char* GetSettings(); -}; - -struct SerialPort_EINFO -{ - int brk; - int frame; - int overrun; - int parity; - SerialPort_EINFO(); - ~SerialPort_EINFO(); -}; - -enum { - CTB_SER_GETEINFO = CTB_SERIAL, - CTB_SER_GETBRK, - CTB_SER_GETFRM, - CTB_SER_GETOVR, - CTB_SER_GETPAR, - CTB_SER_GETINQUE, - CTB_SER_SETPAR, -}; - -class SerialPort_x : public IOBase -{ -protected: - SerialPort_DCS m_dcs; - char m_devname[SERIALPORT_NAME_LEN]; -public: - SerialPort_x(); - virtual ~SerialPort_x(); - const char* ClassName(); - virtual int ChangeLineState(SerialLineState flags) = 0; - virtual int ClrLineState(SerialLineState flags) = 0; - virtual int GetLineState() = 0; - virtual char* GetSettingsAsString(); - virtual int Ioctl(int cmd,void* args); - virtual int SendBreak(int duration) = 0; - virtual int SetBaudrate(int baudrate) = 0; - virtual int SetLineState(SerialLineState flags) = 0; - virtual int SetParityBit( bool parity ) = 0; - static bool IsStandardRate( long rate ); -}; - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/makepy.bat b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/makepy.bat deleted file mode 100644 index 8320cb9e57..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/makepy.bat +++ /dev/null @@ -1,65 +0,0 @@ -@ECHO OFF - -REM ################################################################## -REM # set the path/settings of your compiler enviroment and remove the -REM # comment command (REM) -REM # (you don't need this, if you set it always in your system -REM # enviroment) -REM ################################################################## -REM CALL "c:\Programme\Microsoft Visual C++ Toolkit 2003\vcvars32.bat" - -REM ################################################################## -REM # set the path to your python24 (or python23) library, for example -REM # works for me with C:\Program Files\Python2.4\libs\python24.lib -REM ################################################################## -SET PYTHON_LIB="C:\Program Files\Python2.4\libs\python24.lib" - -REM ################################################################## -REM # set the include path of your python24 (python23) deleveloper -REM # header files. For me, it's on C:\Program Files -REM ################################################################## -SET PYTHON_INCLUDE="C:\Program Files\Python2.4\include" - -REM ################################################################## -REM # after installing swig, set the path, so the script can find it -REM ################################################################## -SET SWIG="C:\Program Files\swigwin-1.3.40\swig" - -REM ################################################################## -REM # DON'T CHANGE ANYMORE AT THE FOLLOWING LINES!!! -REM ################################################################## - -SET GPIB_LIB= -SET GPIB_SRC= - -ECHO // This file is created automatically, don't change it! > wxctb.i -ECHO %%module wxctb >> wxctb.i -ECHO typedef int size_t; >> wxctb.i -ECHO %%include timer.i >> wxctb.i -ECHO %%include serport.i >> wxctb.i -ECHO %%include ../kbhit.i >> wxctb.i - -IF NOT [%1]==[USE_GPIB] GOTO nogpib -SET GPIB_LIB=../../../lib/gpib32.lib -SET GPIB_SRC=../../../src/gpib.cpp -ECHO %%include ../gpib.i >> wxctb.i - -:nogpib - - -DEL *.obj wxctb_wrap.cxx *.lib *.dll *.exp - -ECHO "swig generates python wrapper files..." -%SWIG% -c++ -Wall -nodefault -python -keyword -new_repr -modern wxctb.i - -ECHO "create shared library wxctb for python 2.4..." -cl /LD /D WIN32 /I %PYTHON_INCLUDE% /I ../../../include wxctb_wrap.cxx ../../../src/win32/serport.cpp ../../../src/serportx.cpp ../../../src/win32/timer.cpp ../../../src/kbhit.cpp ../../../src/iobase.cpp %GPIB_SRC% ../../../src/fifo.cpp /link %PYTHON_LIB% winmm.lib %GPIB_LIB% - -MOVE wxctb_wrap.dll _wxctb.dll - -ECHO "copy ctb.py, wxctb.py and _wxctb.so to the module/win32 folder..." -MKDIR ..\..\module\win32 -COPY ..\ctb.py ..\..\module\win32 -COPY wxctb.py ..\..\module\win32 -COPY _wxctb.dll ..\..\module\win32 - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/serport.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/serport.i deleted file mode 100644 index 84cb69887c..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/serport.i +++ /dev/null @@ -1,57 +0,0 @@ -%{ -#include "ctb-0.16/win32/serport.h" -%} - -%include ../serportx.i - -namespace ctb { - -%pythoncode { -COM1 = "com1" -COM2 = "com2" -COM3 = "com3" -COM4 = "com4" -COM5 = "com5" -COM6 = "com6" -COM7 = "com7" -COM8 = "com8" -COM9 = "com9" -COM10 = "\\\\.\\com10" -COM11 = "\\\\.\\com11" -COM12 = "\\\\.\\com12" -COM13 = "\\\\.\\com13" -COM14 = "\\\\.\\com14" -COM15 = "\\\\.\\com15" -COM16 = "\\\\.\\com16" -COM17 = "\\\\.\\com17" -COM18 = "\\\\.\\com18" -COM19 = "\\\\.\\com19" -}; - -class SerialPort : public SerialPort_x -{ -protected: - HANDLE fd; - OVERLAPPED ov; - SerialPort_EINFO einfo; - - int CloseDevice(); - int OpenDevice(const char* devname, void* dcs); -public: - SerialPort(); - ~SerialPort(); - - int ChangeLineState(SerialLineState flags); - int ClrLineState(SerialLineState flags); - int GetLineState(); - int Ioctl(int cmd,void* args); - int IsOpen(); - int Read(char* buf,size_t len); - int SendBreak(int duration); - int SetBaudrate(int baudrate); - int SetLineState(SerialLineState flags); - int SetParityBit( bool parity ); - int Write(char* buf,size_t len); -}; - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/timer.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/timer.i deleted file mode 100644 index b95f26a0d4..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/timer.i +++ /dev/null @@ -1,39 +0,0 @@ -%{ -#include "ctb-0.16/win32/timer.h" -%} - -%include cpointer.i - -// lets create new fuctions for pointer handling in python (for int *exitflag) -%pointer_functions(int, intp); - -namespace ctb { - -// perhaps we doesn''t need timer_control to export -// but we need if we want to inherit from timer in python -struct timer_control -{ - unsigned int msecs; - int *exitflag; - MMRESULT stop; - void* (*exitfnc)(void*); -}; - -class Timer -{ -protected: - - DWORD id; - MMRESULT h; - timer_control control; - unsigned int timer_secs; -public: - Timer(unsigned int msec,int* exitflag,void*(*exitfnc)(void*)=NULL); - ~Timer(); - int start(); - int stop(); -}; - -void sleepms(unsigned int ms); - -}; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/wxctb.i b/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/wxctb.i deleted file mode 100644 index d00350fb03..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/python/src/win32/wxctb.i +++ /dev/null @@ -1,6 +0,0 @@ -// This file is created automatically, don't change it! -%module wxctb -typedef int size_t; -%include timer.i -%include serport.i -%include ../kbhit.i diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/samples/ctbtest.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/samples/ctbtest.cpp deleted file mode 100644 index bf84e20ed7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/samples/ctbtest.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "ctb-0.16/ctb.h" - -#include -#include -#include - -#include -#include - -using namespace std; - -// ----------------- options ------------------------------- -const char* options="a:b:d:e:hlp:t:"; - -const char* helpMessage = -{ - "A simple serial port class test\n" - "ctbtest [options]\n" - "available options are:\n" - "-a : address (only GPIB)\n" - "-b : baudrate [any value], default is 38400\n" - "-d : connected device, default is COM1\n" - "-e : eos\n" - "-h : print this\n" - "-l : list all available serial ports\n" - "-p : protocol like 8N1\n" - "-t : communication timeout in ms (default is 100ms)\n" -}; - -int main(int argc,char* argv[]) -{ - int address = 15; - - int baudrate = 19200; - - string devname = ctb::COM1; - - string eos = "\r\n"; - - string protocol = "8N1"; - - int timeout = 100; - - bool showAvailablePorts = false; - - int quit = 0; - - int val; - - while ( ( val=getopt( argc, argv, (char*)options ) ) != EOF ) { - switch ( val ) { - case 'a' : address = strtol( optarg, NULL, 10 ); break; - case 'b' : baudrate = strtol( optarg, NULL, 10 ); break; - case 'd' : devname = optarg; break; - case 'h' : cerr << helpMessage << endl; exit( 0 ); - case 'l' : showAvailablePorts = true; break; - case 'p' : protocol = optarg; break; - case 't' : timeout = strtol( optarg, NULL, 10 ); break; - } - } - - ctb::IOBase* device = NULL; - - std::vector ports; - - if( ctb::GetAvailablePorts( ports ) && showAvailablePorts ) { - - for( int i = 0; i < ports.size(); - std::cout << ports[ i++ ] << endl ) {}; - - return 0; - - } - - -#if ( GPIB ) - if( ( devname == ctb::GPIB1 ) || ( devname == ctb::GPIB2 ) ) { - - ctb::GpibDevice* gpibDevice = new ctb::GpibDevice(); - - if( gpibDevice->Open( devname.c_str(), address ) >= 0 ) { - - device = gpibDevice; - - } - - } - else { -#endif - - ctb::SerialPort* serialPort = new ctb::SerialPort(); - - if( serialPort->Open( devname.c_str(), baudrate, - protocol.c_str(), - ctb::SerialPort::NoFlowControl ) >= 0 ) { - - device = serialPort; - - } - -#if ( GPIB ) - } -#endif - - if( ! device ) { - - cout << "Cannot open " << devname.c_str() << endl; - - return -1; - - } - - // up to know you don't have to worry any longer about the kind of - // the connected device. As long as you do nothing something device - // specific (like toggle some modem control lines), the access is - // the same for each device. - - string line; - - char receiveBuf[ 128 ]; - - cout << "Enter your command or just press Enter without any\n" - "input for exit!"; - - while( true ) { - - cout << endl << "Your input >"; - - // read the string to send - getline( cin, line ); - - // add some defined EOS (end of string sequence or character) - if( line.empty() ) { - - break; - - } - - line += eos; - - // send data throughout the connected device independent of the typ - if( device->Writev( (char*)line.c_str(), - line.size(), - timeout ) != line.size() ) { - - cerr << "Incomplete data transmission" << endl; - - } - - int readed = 0; - - do { - - // in case of an event driven GUI you better use a non blocking - // Read(...) in your idle function. Here we have to wait for the - // response before we send another user command... - readed = device->Readv( receiveBuf, - sizeof( receiveBuf ) - 1, - timeout); - - // something received? - if( readed > 0 ) { - - receiveBuf[ readed ] = 0; - - cout << receiveBuf; - - } - - } while( readed > 0 ); - - cout << endl; - - } // while( true ) - - device->Close(); - - delete device; - - return 0; -} diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/fifo.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/fifo.cpp deleted file mode 100644 index c03e320846..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/fifo.cpp +++ /dev/null @@ -1,130 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: fifo.cpp -// Purpose: -// Author: Joachim Buermann, Michael Hungershausen -// Id: $Id$ -// Copyright: (c) 2006,2007 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "ctb-0.16/fifo.h" - -namespace ctb { - - Fifo::Fifo(size_t size) : - m_size(size) - { - m_begin = new char[size]; - m_end = m_begin + m_size; - m_rdptr = m_wrptr = m_begin; - }; - - Fifo::~Fifo() - { - delete m_begin; - }; - - void Fifo::clear() - { - m_rdptr = m_wrptr = m_begin; - }; - - int Fifo::get(char* ch) - { - if(m_rdptr != m_wrptr) { - *ch = *m_rdptr++; - if(m_rdptr >= m_end) { - m_rdptr = m_begin; - } - return 1; - } - return 0; - }; - - size_t Fifo::items() - { - char* tmp_wrptr = m_wrptr; - // the rdptr will only changed by the reader. If we suppose, that - // the caller of the items() method is identical with the reader, - // this should be thread save. - char* tmp_rdptr = m_rdptr; - - // if the write pointer is identical with the read, there are no - // more data in the Fifo - if(tmp_wrptr == tmp_rdptr) { - return 0; - } - // the write pointer is greater as the read pointer, so we just - // can calculate the difference for the remaining data - if(tmp_wrptr > tmp_rdptr) { - return (tmp_wrptr - tmp_rdptr); - } - // the write pointer has circulate and stands against the read - // pointer - else { - return (m_size - (tmp_rdptr - tmp_wrptr)); - } - }; - - int Fifo::put(char ch) - { - // for a thread safe operation, the write of a data byte must be - // atomic. So we first assign the current position of the write - // pointer to a temporary pointer. - // Increment it for the comparison with the end of the internal - // buffer and the read pointer - char* tmp_wrptr = m_wrptr + 1; - if(tmp_wrptr >= m_end) { - tmp_wrptr = m_begin; - } - if(tmp_wrptr == m_rdptr) { - return 0; - } - // this don't changes the write pointer! - *m_wrptr = ch; - // that's the trick! The following assignment is atomic and cannot - // interrupted within a read access by the read thread - m_wrptr = tmp_wrptr; - return 1; - }; - - int Fifo::read(char* data,int n) - { - int nresult = 0; - while(n--) { - // the same as get() - if(m_rdptr != m_wrptr) { - *data = *m_rdptr++; - if(m_rdptr >= m_end) { - m_rdptr = m_begin; - } - } - else { - break; - } - nresult++; - data++; - } - return nresult; - }; - - int Fifo::write(char* data,int n) - { - int nresult = 0; - while(n--) { - // the same as put() - char* tmp_wrptr = m_wrptr + 1; - if(tmp_wrptr >= m_end) { - tmp_wrptr = m_begin; - } - if(tmp_wrptr == m_rdptr) { - break; - } - *m_wrptr = *data++; - m_wrptr = tmp_wrptr; - nresult++; - } - return nresult; - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/getopt.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/getopt.cpp deleted file mode 100644 index 69afb2e7b7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/getopt.cpp +++ /dev/null @@ -1,14 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: getopt.cpp -// Purpose: simple wrapper file -// Author: Joachim Buermann -// Id: $Id: timer.h,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#if defined (WIN32) -# include "win32/getopt.cpp" -#endif - - diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/gpib.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/gpib.cpp deleted file mode 100644 index e2f577de64..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/gpib.cpp +++ /dev/null @@ -1,340 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: gpibx.cpp -// Purpose: -// Author: Joachim Buermann -// Id: $Id: gpibx.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001,2004 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "ctb-0.16/gpib.h" -#include "ctb-0.16/timer.h" -#include -#include -#ifdef WIN32 -# include "ctb-0.16/win32/gpib-32.h" -#if _MSC_VER < 1900 -# define snprintf _snprintf -#endif -#elif __GNUG__ -# include -#endif - -namespace ctb { - - const char* GPIB1 = "gpib1"; - const char* GPIB2 = "gpib2"; - - struct gpibErr_t { - int m_errno; - const char* m_notation; - const char* m_description; - }; - - static gpibErr_t gpibErrors[] = { - {0,"EDVR","DOS Error"}, - {1,"ECIC","Specified GPIB Interface Board is Not Active Controller"}, - {2,"ENOL","No present listing device"}, - {3,"EADR","GPIB Board has not been addressed properly"}, - {4,"EARG","Invalid argument"}, - {5,"ESAC","Specified GPIB Interface Board is not System Controller"}, - {6,"EABO","I/O operation aborted (time-out)"}, - {7,"ENEB","Non-existent GPIB board"}, - {10,"EOIP","Routine not allowed during asynchronous I/O operation"}, - {11,"ECAP","No capability for operation"}, - {12,"EFSO","File System Error"}, - {14,"EBUS","Command byte transfer error"}, - {15,"ESTB","Serial poll status byte lost"}, - {16,"ESQR","SRQ stuck in ON position"}, - {20,"ETAB","Table problem"}, - {247,"EINT","No interrupt configured on board"}, - {248,"EWMD","Windows is not in Enhanced mode"}, - {249,"EVDD","GPIB driver is not installed"}, - {250,"EOVR","Buffer Overflow"}, - {251,"ESML","Two library calls running simultaneously"}, - {252,"ECFG","Board type does not match GPIB.CFG"}, - {253,"ETMR","No Windows timers available"}, - {254,"ESLC","No Windows selectors available"}, - {255,"EBRK","Control-Break pressed"} - }; - - char* Gpib_DCS::GetSettings() - { - const char* to[] = { - "None","10us","30us","100us","300us","1ms","3ms","10ms","30ms", - "100ms","300ms","1s","3s","10s","30s","100s","300s","1000s" - }; - memset(m_buf,0,sizeof(m_buf)); - snprintf(m_buf,sizeof(m_buf)-1,"Adr: (%i,%i) to:%s", - m_address1, - m_address2, - to[m_timeout]); - return m_buf; - }; - - int GpibDevice::CloseDevice() - { - if(m_hd != -1) { - // goto local... - ibloc(m_hd); - // ...and switch device offline - ibonl(m_hd,0); - m_hd = -1; - m_board = -1; - } - return 0; - }; - - const char* GpibDevice::GetErrorString(int error,bool detailed) - { - for(size_t i=0;i<(sizeof(gpibErrors)/sizeof(gpibErr_t));i++) { - if(gpibErrors[i].m_errno == error) { - if(detailed) { - return gpibErrors[i].m_description; - } - else { - return gpibErrors[i].m_notation; - } - } - } - return 0; - }; - -// This is only for internal usage - int GpibDevice::Ibrd(char* buf,size_t len) - { - return ibrd(m_hd,buf,len); - }; - -// This is only for internal usage - int GpibDevice::Ibwrt(char* buf,size_t len) - { - return ibwrt(m_hd,buf,len); - }; - - int GpibDevice::Ioctl(int cmd,void* args) - { - switch(cmd) { - case CTB_RESET: - if(m_hd >= 0) { - ibclr(m_hd); - return 0; - } - return -1; - case CTB_GPIB_GETRSP: { - char spr = 0; - if(m_hd >= 0) { - ibrsp(m_hd,&spr); - *(int*)args = (int)spr; - return 0; - } - return 1; } - case CTB_GPIB_GETSTA: - *(int*)args = m_state; - return 0; - case CTB_GPIB_GETERR: - *(int*)args = m_error; - return 0; - case CTB_GPIB_GETLINES: { - short state = 0; - if(m_hd >= 0) { - iblines(m_board,&state); - *(int*)args = (int)state; - return 0; - } - return -1; } - case CTB_GPIB_SETTIMEOUT: { - if(m_hd >= 0) { - GpibTimeout timeout; - unsigned long to = *(unsigned long*)args; - // convert the timeout in ms (given by args) into the - // traditional NI-488.2 timeout period - if(to > 1000000) timeout = GpibTimeout1000s; - else if(to >= 300000) timeout = GpibTimeout300s; - else if(to >= 100000) timeout = GpibTimeout100s; - else if(to >= 30000) timeout = GpibTimeout30s; - else if(to >= 10000) timeout = GpibTimeout10s; - else if(to >= 3000) timeout = GpibTimeout3s; - else if(to >= 1000) timeout = GpibTimeout1s; - else if(to >= 300) timeout = GpibTimeout300ms; - else if(to >= 100) timeout = GpibTimeout100ms; - else if(to >= 30) timeout = GpibTimeout30ms; - else if(to >= 10) timeout = GpibTimeout10ms; - else if(to >= 3) timeout = GpibTimeout3ms; - else if(to >= 1) timeout = GpibTimeout1ms; - else timeout = GpibTimeoutNone; - ibtmo(m_hd,timeout); - return 0; - } - return -1; } - case CTB_GPIB_GTL: - // Forces the specified device to go to local program mode - if(m_hd >= 0) { - ibloc(m_hd); - return 0; - } - return -1; - case CTB_GPIB_REN: - // This routine can only be used if the specified GPIB - // Interface Board is the System Controller. - // Remember that even though the REN line is asserted, - // the device(s) will not be put into remote state until is - // addressed to listen by the Active Controller - if(m_hd) { - char adr = (char)m_dcs.m_address1; - ibsre(m_board,1); - ibcmd(m_board,&adr,1); - return 0; - } - return -1; - case CTB_GPIB_RESET_BUS: - ibsic(m_board); - return 0; - case CTB_GPIB_GET_EOS_CHAR: - if( m_hd ) { - *(int*)args = (int)m_dcs.m_eosChar; - return 0; - } - return -1; - case CTB_GPIB_SET_EOS_CHAR: -#ifdef __GNUG__ - // FIXME! - // Doesn't work with linux-gpib-3.2.08. All EOS beside 0x00 - // are blocking during sending data to the device. (Look at - // function my_ibwrt in linux-gpib-3.2.08/lib/ibWrt.c - if( m_hd ) { - m_dcs.m_eosChar = (char)*(int*)args; - ibeos(m_hd,(m_dcs.m_eosMode << 8) | m_dcs.m_eosChar); - return 0; - } -#endif - return -1; - case CTB_GPIB_GET_EOS_MODE: - if( m_hd ) { - *(int*)args = (int)m_dcs.m_eosMode; - return 0; - } - return -1; - case CTB_GPIB_SET_EOS_MODE: - if( m_hd ) { - m_dcs.m_eosMode = (char)*(int*)args; - ibeos(m_hd,(m_dcs.m_eosMode << 8) | m_dcs.m_eosChar); - return 0; - } - return -1; - } - // error or unknown command - return -1; - }; - - int GpibDevice::FindListeners(int board) - { - int listeners = 0; - if((unsigned int)board > 1) { - return -1; - } - // reset the GPIB, otherwise no connected device is found (linux) - SendIFC(board); - // list of primary addresses to searching for. Must be terminated - // with NOADDR. - Addr4882_t addrlist[31]; - // The range of valid addresses is 1...30, 0 is reservated by the - // controller, 31 is not valid - for(int i = 0;i < 30; i++) addrlist[i] = (Addr4882_t) i + 1; - addrlist[30] = NOADDR; - // place to store the results - Addr4882_t results[31]; - memset(results,0,sizeof(results)); - FindLstn(board, addrlist, results, 31); - if(ibsta & ERR) { - return -1; - } - for(int i=0;i<=30;i++) { - if(results[i]) { - listeners |= 1 << results[i]; - } - } - return listeners; - }; - - int GpibDevice::Open( const char* devname, int address ) - { - m_dcs.m_address1 = address; - - return OpenDevice( devname, &m_dcs ); - } - - - int GpibDevice::OpenDevice(const char* devname, void* dcs) - { - // if dcs isn't NULL, type cast - if(dcs) m_dcs = *(Gpib_DCS*)dcs; - - if(strncmp(devname,"gpib1",5) == 0) m_board = 0; - else if(strncmp(devname,"gpib2",5) == 0) m_board = 1; - if(m_board < 0) { - return -1; - } - // check for a valid timeout - if((unsigned int)m_dcs.m_timeout > GpibTimeout1000s) { - m_dcs.m_timeout = GpibTimeout10us; - } - - m_hd = ibdev(m_board, - m_dcs.m_address1, - m_dcs.m_address2, - m_dcs.m_timeout, - m_dcs.m_eot, -#ifdef __GNUG__ - // FIXME! - // linux-gpib-3.2.08 doesn't work with any EOS (blocks). - // Because we always has to add an EOS on the message - // (independent of the m_eosChar setting), we can ignore it! - 0 -#else - (m_dcs.m_eosMode << 8) | m_dcs.m_eosChar -#endif - ); - if(m_hd < 0) { - // no gpib controller installed (not found) - return -2; - } - // test for a connected listener (device with given address) - short int listen = 0; - ibln(m_board,m_dcs.m_address1,NO_SAD,&listen); - if(!listen) { - // no listener at the given address - CloseDevice(); - return -3; - } - // reset device - ibclr(m_hd); - // save state, error and count - m_state = ThreadIbsta(); - m_count = ThreadIbcnt(); - m_error = ThreadIberr(); - // no error - return 0; - }; - - int GpibDevice::Read(char* buf,size_t len) - { - // if something is in the fifo, first read that - if(m_fifo->items() > 0) { - return m_fifo->read(buf,len); - } - m_state = ibrd(m_hd,buf,len); - m_error = ThreadIberr(); - m_count = ThreadIbcnt(); - return m_count; - }; - - int GpibDevice::Write(char* buf,size_t len) - { - m_state = ibwrt(m_hd,buf,len); - m_error = ThreadIberr(); - m_count = ThreadIbcnt(); - return m_count; - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/iobase.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/iobase.cpp deleted file mode 100644 index b92ba4f2d6..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/iobase.cpp +++ /dev/null @@ -1,211 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: iobase.cpp -// Purpose: -// Author: Joachim Buermann -// Id: $Id: iobase.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include -#include -#include "ctb-0.16/iobase.h" -#include "ctb-0.16/timer.h" - -namespace ctb { - -#define DELTA_BUFSIZE 512 - - int IOBase::Readv(char* buf,size_t len,unsigned int timeout_in_ms) - { - char *cp = buf; - int n = 0; - int timeout = 0; - size_t toread = len; - - Timer t(timeout_in_ms,&timeout,NULL); - if(timeout_in_ms != 0xFFFFFFFF) { - t.start(); - } - - while(!timeout && (toread > 0)) { - if((n = Read(cp,toread)) < 0) { - break; - } - if(!n) { - sleepms(1); - } - toread -= n; - cp += n; - } - // ok, all bytes received - return(len - toread); - }; - -/* - Readv() calls the member function Read() repeatedly, til all - demand bytes were received. To avoid an endless loop, you - can refer an integer, which was set unequal zero after a - specific time. (See the timer class) -*/ - int IOBase::Readv(char* buf,size_t len,int* timeout_flag,bool nice) - { - size_t toread = len; - int n = 0; - char *cp = buf; - - while(toread > 0) { - if(timeout_flag && (*timeout_flag > 0)) { - return (len - toread); - } - if((n = Read(cp,toread)) < 0) { - return (len - toread); - } - if(!n && nice) { - sleepms(1); - } - if (n > 0) - { - toread -= n; - cp += n; - } - } - // ok, all bytes received - return(len - toread); - }; - - int IOBase::ReadUntilEOS(char*& readbuf, - size_t* readedBytes, - char* eosString, - long timeout_in_ms, - char quota) - { - int n = 0; - int timeout = 0; - int bufsize = DELTA_BUFSIZE; - int result = 0; - int quoted = 0; - char* buf = new char[bufsize]; - char* des = buf; - char* eos = eosString; - char ch; - - Timer t(timeout_in_ms,&timeout,NULL); - t.start(); - - while(!timeout) { - if(des >= &buf[bufsize]) { - // buffer full, realloc more memory - char* tmp = new char[bufsize + DELTA_BUFSIZE + 1]; - memcpy(tmp,buf,bufsize); - delete[] buf; - buf = tmp; - des = &buf[bufsize]; - bufsize += DELTA_BUFSIZE; - } - // read next byte - n = Read(&ch,1); - if(n < 0) { - // an error occured - result = -1; - break; - } - else if(n == 0) { - // no data available, give up the processor for some time - // to reduce the cpu last - sleepms(10); - continue; - } - // if eos is composed of more than one char, and the current - // byte doesn't match the next eos character, we handle the - // readed byte as a normal char (and not an eos) - if((eos != eosString) && (ch != *eos)) { - // FIXME! - // write all characters, which was matched the eos string - // until now (with the first wrong character all received - // eos characters are invalid and must handled as normal - // characters). - - // This doesn't work right and is only a little workaround - // because the received eos chars are lost - PutBack(ch); - // because we doesn't match the eos string, we must 'reset' - // the eos match - eos = eosString; - continue; - } - else { - if((ch == *eos) && !quoted) { - if(*++eos == 0) { - // the eos string is complete - result = 1; - break; - } - continue; - } - } - if(ch == quota) { - quoted ^= 1; - } - *des++ = ch; - } - *des = 0; - readbuf = buf; - *readedBytes = des - buf; - return result; - }; - - int IOBase::Writev(char* buf,size_t len,unsigned int timeout_in_ms) - { - char *cp = buf; - int n = 0; - int timeout = 0; - size_t towrite = len; - - Timer t(timeout_in_ms,&timeout,NULL); - if(timeout_in_ms != 0xFFFFFFFF) { - t.start(); - } - - while(!timeout && (towrite > 0)) { - if((n = Write(cp,towrite)) < 0) { - // an error occurs - break; - } - if(!n) { - sleepms(1); - } - towrite -= n; - cp += n; - } - return (len - towrite); - }; - -/* - Similar to Readv(). Writev() calls Write() repeatedly till - all bytes are written. -*/ - int IOBase::Writev(char* buf,size_t len,int* timeout_flag,bool nice) - { - size_t towrite = len; - int n = 0; - char *cp = buf; - - while(towrite > 0) { - if(timeout_flag && (*timeout_flag > 0)) { - return (len - towrite); - } - if((n = Write(cp,towrite)) < 0) { - // an error occurs - return (len - towrite); - } - if(!n && nice) { - sleepms(1); - } - towrite -= n; - cp += n; - } - return(len); - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/kbhit.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/kbhit.cpp deleted file mode 100644 index 4a244ea251..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/kbhit.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#if defined ( WIN32 ) -# include -#else -# include -# include -#endif - -namespace ctb { - - char GetKey() - { -#if defined ( WIN32 ) - if(_kbhit()) { - return _getch(); - } - return '\0'; -#else - int ch; - static struct termios t, save_t; - tcgetattr(0,&t); - save_t = t; - t.c_lflag &= ~(ICANON); - t.c_cc[VMIN] = 0; - t.c_cc[VTIME] = 0; - tcsetattr(0,TCSANOW,&t); - - ch = fgetc(stdin); - - tcsetattr(0,TCSANOW,&save_t); - if(ch != EOF) { - return ch; - } - return '\0'; -#endif - } - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp deleted file mode 100644 index a369abc5e7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp +++ /dev/null @@ -1,443 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: linux/serport.cpp -// Purpose: -// Author: Joachim Buermann -// Id: $Id: serport.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "ctb-0.16/linux/serport.h" - -#include -#include -#include -#include -#include -#include -#include - -#define CMSPAR 010000000000 /* mark or space (stick) parity */ - -namespace ctb { - - const char* COM1 = "/dev/ttyS0"; - const char* COM2 = "/dev/ttyS1"; - const char* COM3 = "/dev/ttyS2"; - const char* COM4 = "/dev/ttyS3"; - const char* COM5 = "/dev/ttyS4"; - const char* COM6 = "/dev/ttyS5"; - const char* COM7 = "/dev/ttyS6"; - const char* COM8 = "/dev/ttyS7"; - const char* COM9 = "/dev/ttyS8"; - const char* COM10 = "/dev/ttyS9"; - const char* COM11= "/dev/ttyS10"; - const char* COM12= "/dev/ttyS11"; - const char* COM13 = "/dev/ttyS12"; - const char* COM14 = "/dev/ttyS13"; - const char* COM15 = "/dev/ttyS14"; - const char* COM16 = "/dev/ttyS15"; - const char* COM17 = "/dev/ttyS16"; - const char* COM18 = "/dev/ttyS17"; - const char* COM19 = "/dev/ttyS18"; - const char* COM20 = "/dev/ttyS19"; - - SerialPort::SerialPort() : - SerialPort_x() - { - fd = -1; - }; - - SerialPort::~SerialPort() - { - Close(); - }; - - speed_t SerialPort::AdaptBaudrate( int baud ) - { - switch(baud) { - case 150: return B150; - case 300: return B300; - case 600: return B600; - case 1200: return B1200; - case 2400: return B2400; - case 4800: return B4800; - case 9600: return B9600; - case 19200: return B19200; - case 57600: return B57600; - case 115200: return B115200; - case 230400: return B230400; - case 460800: return B460800; - case 921600: return B921600; - - // NOTE! The speed of 38400 is required, if you want to set - // an non-standard baudrate. See below! - default: return B38400; - } - }; - - int SerialPort::CloseDevice() - { - int err = 0; - // only close an open file handle - if(fd < 0) return EBADF; - // With some systems, it is recommended to flush the serial port's - // Output before closing it, in order to avoid a possible hang of - // the process... - // Thanks to Germain (I couldn't answer you, because your email - // address was invalid) - tcflush(fd, TCOFLUSH); - - // Don't recover the orgin settings while the device is open. This - // implicate a mismatched data output! - // Just close device - err = close( fd ); - - fd = -1; - - return err; - }; - - int SerialPort::ChangeLineState( SerialLineState flags ) - { - int state; - ioctl(fd,TIOCMGET,&state); - state ^= flags; - return ioctl(fd,TIOCMSET,&state); - }; - - int SerialPort::ClrLineState( SerialLineState flags ) - { - return ioctl(fd,TIOCMBIC,&flags); - }; - - int SerialPort::GetLineState() - { - SerialLineState flags = LinestateNull; - - if( ioctl( fd, TIOCMGET, &flags ) < 0 ) { - - return -1; - - } - return (int)( flags & 0x1FF ); - }; - -// -// included from /usr/include/linux/serial.h -// -// struct serial_icounter_struct { -// int cts, dsr, rng, dcd; -// int rx, tx; -// int frame, overrun, parity, brk; -// int buf_overrun; -// int reserved[9]; -// }; -// - int SerialPort::Ioctl(int cmd, void* args) - { - int count = 0; - int err = 0; - struct serial_icounter_struct info; - SerialPort_EINFO einfo; - - switch(cmd) { - case CTB_RESET: - return SendBreak(0); - case CTB_SER_GETEINFO: - err = ioctl(fd,TIOCGICOUNT,&info); - if(err) return err; - einfo.brk = info.brk - save_info.brk; - einfo.frame = info.frame - save_info.frame; - einfo.overrun = info.overrun - save_info.overrun; - einfo.parity = info.parity - save_info.parity; - *(SerialPort_EINFO*)args = einfo; - break; - case CTB_SER_GETBRK: - err = ioctl(fd,TIOCGICOUNT,&info); - if(err) return err; - if(last_info.brk != info.brk) count = 1; - break; - case CTB_SER_GETFRM: - err = ioctl(fd,TIOCGICOUNT,&info); - if(err) return err; - if(last_info.frame != info.frame) count = 1; - break; - case CTB_SER_GETOVR: - err = ioctl(fd,TIOCGICOUNT,&info); - if(err) return err; - if(last_info.overrun != info.overrun) count = 1; - break; - case CTB_SER_GETPAR: - err = ioctl(fd,TIOCGICOUNT,&info); - if(err) return err; - if(last_info.parity != info.parity) count = 1; - break; - case CTB_SER_GETINQUE: - err = ioctl(fd,TIOCINQ,&count); - if(err) return err; - *(int*)args = count; - return 0; - case CTB_SER_SETPAR: - return SetParityBit( *(int*)args == 1 ); - default: - return -1; - } - last_info = info; - return 0; - }; - - int SerialPort::IsOpen() - { - return (fd != -1); - }; - - int SerialPort::OpenDevice(const char* devname, void* dcs) - { - // if dcs isn't NULL, type cast - if(dcs) m_dcs = *(SerialPort_DCS*)dcs; - // open serial comport device for reading and writing, - // don't wait (O_NONBLOCK) - fd = open(devname, O_RDWR | O_NOCTTY | O_NONBLOCK); - if(fd >= 0) { - - // exclusive use - int dummy; - - ioctl( fd, TIOCEXCL, &dummy ); - - tcgetattr(fd,&t); - save_t = t; - - // save the device name - strncpy(m_devname,(char*)devname,sizeof(m_devname)); - // we write an eos to avoid a buffer overflow - m_devname[sizeof(m_devname)-1] = '\0'; - - // Fill the internal terios struct. - // If the given baudrate is an non-standard one, the AdaptBaudrate - // call returns the linux specific value B38400 which is a - // condition for the later switch to an unusual baudrate! - cfsetspeed(&t, AdaptBaudrate( m_dcs.baud ) ); - - //cfsetospeed(&t, AdaptBaudrate( m_dcs.baud ) ); - - // parity settings - switch( m_dcs.parity ) { - - case ParityNone: - t.c_cflag &= ~PARENB; break; - - case ParityOdd: - t.c_cflag |= PARENB; - t.c_cflag |= PARODD; - break; - - case ParityEven: - t.c_cflag |= PARENB; - t.c_cflag &= ~PARODD; - break; - - case ParityMark: - t.c_cflag |= PARENB | CMSPAR | PARODD; - break; - - case ParitySpace: - t.c_cflag |= PARENB | CMSPAR; - t.c_cflag &= ~PARODD; - break; - } - - // stopbits - if(m_dcs.stopbits == 2) - t.c_cflag |= CSTOPB; - else - t.c_cflag &= ~CSTOPB; - // wordlen - t.c_cflag &= ~CSIZE; - if(m_dcs.wordlen == 7) t.c_cflag |= CS7; - else if(m_dcs.wordlen == 6) t.c_cflag |= CS6; - else if(m_dcs.wordlen == 5) t.c_cflag |= CS5; - // this is the default - else t.c_cflag |= CS8; - // rts/cts - if(m_dcs.rtscts == false) - t.c_cflag &= ~CRTSCTS; - else - t.c_cflag |= CRTSCTS; - - t.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN); - t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY); - t.c_iflag |= IGNPAR; - t.c_oflag &= ~OPOST; - - if(m_dcs.xonxoff == true) { - t.c_iflag |= (IXON | IXOFF); - } - - // look out! - // MIN = 1 means, in TIME (1/10 secs) defined timeout - // will be started AFTER receiving the first byte - // so we must set MIN = 0. (timeout starts immediately, abort - // also without readed byte) - t.c_cc[VMIN] = 0; - // timeout in 1/10 secs - // no timeout for non blocked transfer - t.c_cc[VTIME] = 0; - // write the settings - tcsetattr(fd,TCSANOW,&t); - // it's careless, but in the moment we don't test - // the return of tcsetattr (normally there is no error) - - // request the actual numbers of breaks, framing, overrun - // and parity errors (because Linux summing all of them during - // system lifetime, not only while serial port is open. - ioctl(fd,TIOCGICOUNT,&save_info); - // it's also careless, but we assume, that there was no error - last_info = save_info; - - // in case of a non-standard rate, the termios struct have to set - // with the B38400 rate, see above! - if( ! IsStandardRate( m_dcs.baud ) ) { - - SetBaudrateAny( m_dcs.baud ); - - } - } - return fd; - }; - - int SerialPort::Read(char* buf,size_t len) - { - if(m_fifo->items() > 0) { - return m_fifo->read(buf,len); - } - // Read() (using read() ) will return an 'error' EAGAIN as it is - // set to non-blocking. This is not a true error within the - // functionality of Read, and thus should be handled by the caller. - int n = read(fd,buf,len); - if((n < 0) && (errno == EAGAIN)) return 0; - return n; - }; - - int SerialPort::SendBreak(int duration) - { - // the parameter is equal with linux - return tcsendbreak(fd,duration); - }; - - /* - Note: The following hints are copied from the ftdi_sio.c sources of - the kernel modul for the USB to RS232 converter using an FTDI - chipset (FT232BM or similar). Thanks to all those people - contribute code and above all helpful comments to this modul. - */ - - /* - * The logic involved in setting the baudrate can be cleanly split in 3 steps. - * Obtaining the actual baud rate is a little tricky since unix traditionally - * somehow ignored the possibility to set non-standard baud rates. - * 1. Standard baud rates are set in tty->termios->c_cflag - * 2. If these are not enough, you can set any speed using alt_speed as - * follows: - * - set tty->termios->c_cflag speed to B38400 - * - set your real speed in tty->alt_speed; it gets ignored when - * alt_speed==0, (or) - * - call TIOCSSERIAL ioctl with (struct serial_struct) set as follows: - * flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP], this just - * sets alt_speed to (HI: 57600, VHI: 115200, SHI: 230400, WARP: 460800) - * ** Steps 1, 2 are done courtesy of tty_get_baud_rate - * 3. You can also set baud rate by setting custom divisor as follows - * - set tty->termios->c_cflag speed to B38400 - * - call TIOCSSERIAL ioctl with (struct serial_struct) set as follows: - * o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST - * o custom_divisor set to baud_base / your_new_baudrate - * ** Step 3 is done courtesy of code borrowed from serial.c - I should really - * spend some time and separate+move this common code to serial.c, it is - * replicated in nearly every serial driver you see. - */ - - int SerialPort::SetBaudrateAny( int baudrate ) - { - struct serial_struct ser_info; - - int result = ioctl( fd, TIOCGSERIAL, &ser_info ); - - ser_info.flags = ASYNC_SPD_CUST | ASYNC_LOW_LATENCY; - - ser_info.custom_divisor = ser_info.baud_base / baudrate; - - result = ioctl( fd, TIOCSSERIAL, &ser_info ); - - return result; - } - - int SerialPort::SetBaudrateStandard( int baudrate ) - { - speed_t baud = AdaptBaudrate( baudrate ); - // setting the input baudrate - if(cfsetspeed(&t,baud) < 0) { - return -1; - } - // take over - m_dcs.baud = baudrate; - - tcsetattr(fd,TCSANOW,&t); - - return tcgetattr( fd, &t ); - - }; - - int SerialPort::SetBaudrate( int baudrate ) - { - return IsStandardRate( baudrate ) ? - SetBaudrateStandard( baudrate ) : - SetBaudrateAny( baudrate ); - - } - - int SerialPort::SetLineState( SerialLineState flags ) - { - return ioctl(fd,TIOCMBIS,&flags); - }; - - int SerialPort::SetParityBit( bool parity ) - { - // waits until all output has been transmitted - tcdrain( fd ); - - // now read the current termios settings and manipulate - // the parity - tcgetattr( fd, &t ); - - if( parity ) { - - t.c_cflag |= PARENB | CMSPAR | PARODD; - - } - else { - - t.c_cflag |= PARENB | CMSPAR; - - t.c_cflag &= ~PARODD; - - } - - tcsetattr( fd,TCSANOW, &t ); - - tcgetattr( fd, &t ); - - return 0; - } - - int SerialPort::Write(char* buf,size_t len) - { - // Write() (using write() ) will return an 'error' EAGAIN as it is - // set to non-blocking. This is not a true error within the - // functionality of Write, and thus should be handled by the caller. - int n = write(fd,buf,len); - if((n < 0) && (errno == EAGAIN)) return 0; - return n; - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/timer.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/timer.cpp deleted file mode 100644 index f1c50f613b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/timer.cpp +++ /dev/null @@ -1,97 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: linux/timer.cpp -// Purpose: -// Author: Joachim Buermann -// Id: $Id: timer.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - - -#include "ctb-0.16/timer.h" -#include - -namespace ctb { - -// a dummy function, see below - static void timer_exit(void* arg) - { - }; - - static void* timer_fnc(void* arg) - { - // the timer thread should be canceled every time - // (asyncronously) - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); - // this is tricky, but absolutly necessarily to avoid segfaults - // if the destructor finished a running thread - pthread_cleanup_push(timer_exit,NULL); - timer_control *tc = (timer_control*)arg; - // linux allows a real sleep, means the timer thread will - // be sleeping (no reduce of the system performance) - usleep(tc->usecs); - // time is over, system reawake the thread. - // if there is an exit function, calling it - if(tc->exitfnc) tc->exitfnc(NULL); - // set the exit flag - if(tc->exitflag) *tc->exitflag = 1; - // deallocate the system resources (thread) - pthread_cleanup_pop(1); - return NULL; - }; - - // the constructor initiate the internal control struct - Timer::Timer( unsigned int msecs, int* exitflag, void*( *exitfnc )(void*) ) - { - control.usecs = msecs * 1000; - control.exitflag = exitflag; - control.exitfnc = exitfnc; - stopped = 1; - }; - - // if a timer instance leave it's valid range, it automaticaly will - // be finished - Timer::~Timer() - { - if(!stopped) { - // only a running thread may be canceled - stop(); - } - }; - - // starts the timer thread - int Timer::start() - { - stopped = 0; - if(pthread_create(&tid, // result parameter, covers the id - // of the new threads - NULL, // thread attribute object, NULL means - // the defaults - timer_fnc, // start function of the thread - &control // start function parameter, must refer - // as void* - ) == -1) { - return -1; // there was something going wrong - } - pthread_detach(tid); // thread status must be "detach". In the other - // case, the destructor call of a running - // thread throws a segfault - return 0; - }; - - // stop the timer thread - int Timer::stop() - { - if(control.exitflag && (*control.exitflag == 0)) { - pthread_cancel(tid); - } - stopped = 1; - return 0; - }; - - void sleepms(unsigned int ms) - { - usleep(ms * 1000); - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/portscan.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/portscan.cpp deleted file mode 100644 index f13766e9fa..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/portscan.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "ctb-0.16/ctb.h" -#include "ctb-0.16/portscan.h" - -#include - -#ifndef _WIN32 -# include -#endif - -namespace ctb { - - bool GetAvailablePorts( std::vector& result, - bool checkInUse ) - { -#ifdef _WIN32 - - std::stringstream devname; - - for( int i = 1; i < 100; i++ ) { - - devname.clear(); devname.str( "" ); - - // some systems like WinCE doesn't like the extended port numbering... - i < 10 ? devname << "com" << i : devname << "\\\\.\\com" << i; - - COMMCONFIG cc; - - DWORD dwSize = sizeof( cc ); - - if ( ::GetDefaultCommConfig( devname.str().c_str(), &cc, &dwSize ) ) { - - if( cc.dwProviderSubType == PST_RS232 ) { - - ctb::SerialPort com; - - if( com.Open( devname.str().c_str() ) < 0 ) { - - continue; - - } - - result.push_back( devname.str().c_str() ); - - } - } - } - -#else - glob_t globbuf; - - // search for standard serial ports - int res = glob( "/dev/ttyS*", GLOB_ERR, NULL, &globbuf ); - - if( res == 0 ) { - - // no error, glob was successful - for( int i = 0; i < globbuf.gl_pathc; i++ ) { - - if( checkInUse ) { - - ctb::SerialPort com; - - if( com.Open( globbuf.gl_pathv[ i ] ) < 0 ) { - - continue; - - } - - result.push_back( std::string( globbuf.gl_pathv[ i ] ) ); - - } - } - - } - globfree( &globbuf ); - - // search for USB to RS232 converters - res = glob( "/dev/ttyUSB*", GLOB_ERR, NULL, &globbuf ); - - if( res == 0 ) { - - // no error, glob was successful - for( int i = 0; i < globbuf.gl_pathc; i++ ) { - - if( checkInUse ) { - - ctb::SerialPort com; - - if( com.Open( globbuf.gl_pathv[ i ] ) < 0 ) { - - continue; - - } - - result.push_back( std::string( globbuf.gl_pathv[ i ] ) ); - - } - } - - } - - globfree( &globbuf ); -#endif - - return result.size(); - - } - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/serportx.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/serportx.cpp deleted file mode 100644 index c59bcc002f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/serportx.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "ctb-0.16/serportx.h" - -#include - -namespace ctb { - - int SerialPort_x::Open( const char* portname, int baudrate, - const char* protocol, - FlowControl flowControl ) - { - SerialPort_DCS dcs; - - dcs.baud = baudrate; - - // default wordlen is 8 - if( ( protocol[ 0 ] >= '5' ) && ( protocol[ 0 ] <= '8' )) { - - dcs.wordlen = protocol[ 0 ] - '0'; - - } - else { - - return -1; - - } - - // protocol is given as a string like "8N1", the first - // character specifies the data bits (5...8), the second - // the parity (None,Odd,Even,Mark,Space). - // The third character defines the stopbit (1...2). - switch( protocol[ 1 ] ) { - case 'N': case 'n': dcs.parity = ParityNone; break; - case 'O': case 'o': dcs.parity = ParityOdd; break; - case 'E': case 'e': dcs.parity = ParityEven; break; - case 'M': case 'm': dcs.parity = ParityMark; break; - case 'S': case 's': dcs.parity = ParitySpace; break; - // all other parameters cause an error! - default: return -1; - } - // default stopbits is 1 - if( ( protocol[ 2 ] >= '1' ) && ( protocol[ 2 ] <= '2' )) { - - dcs.stopbits = protocol[ 2 ] - '0'; - - } - else { - - return -1; - - } - // default flow control is disabled - dcs.rtscts = ( flowControl == RtsCtsFlowControl ); - - dcs.xonxoff = ( flowControl == XonXoffFlowControl ); - - // save the settings in the internal dcs for later use - m_dcs = dcs; - - return OpenDevice( portname, &m_dcs ); - - } - - int SerialPort_x::Open( const int portnumber, int baudrate, - const char* protocol, - FlowControl flowControl ) - { - // portnumbers start with 1 - if( portnumber < 1 ) { - - return -1; - - } - std::stringstream devname; - -#if defined ( WIN32 ) - // some systems like WinCE doesn't like the extended port numbering... - portnumber < 10 ? devname << "com" << portnumber : - devname << "\\\\.\\com" << portnumber; -#else - devname << "/dev/ttyS" << ( portnumber - 1 ); -#endif - - return Open( devname.str().c_str(), baudrate, protocol, flowControl ); - } - - bool SerialPort_x::IsStandardRate( int rate ) - { - const int rates[] = { - 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, - 115200, 230400, 460800, 921600 - }; - - for( unsigned int i = 0; i < ( sizeof( rates ) / sizeof( int ) ); i++ ) { - - if( rate == rates[ i ] ) { - - return true; - - } - } - return false; - } - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp deleted file mode 100644 index c8454b9bde..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp +++ /dev/null @@ -1,66 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: win32/getopt.cpp -// Purpose: -// Author: unknown, I found it in the internet -// Id: $Id: getopt.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 ? -// Licence: (I think Open Source) -///////////////////////////////////////////////////////////////////////////// - -#include -#include - -char *optarg; /* Global argument pointer. */ -int optind = 0; /* Global argv index. */ - -static char *scan = NULL; /* Private scan pointer. */ - -/* found char, or NULL if none */ -static char *index(const char* s,char charwanted) -{ - return(strchr((char*)s, charwanted)); -} - -int getopt(int argc, char* argv[], char* optstring) -{ - register char c; - register char *place; - - optarg = NULL; - - if (scan == NULL || *scan == '\0') { - if (optind == 0) - optind++; - - if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') - return(EOF); - if (strcmp(argv[optind], "--")==0) { - optind++; - return(EOF); - } - - scan = argv[optind]+1; - optind++; - } - - c = *scan++; - place = index(optstring, c); - - if (place == NULL || c == ':') { - fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); - return('?'); - } - - place++; - if (*place == ':') { - if (*scan != '\0') { - optarg = scan; - scan = NULL; - } else { - optarg = argv[optind]; - optind++; - } - } - - return(c); -} diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/serport.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/serport.cpp deleted file mode 100644 index 23b50ab32b..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/serport.cpp +++ /dev/null @@ -1,452 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: serport.cpp -// Purpose: -// Author: Joachim Buermann -// Id: $Id: serport.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include -#include "ctb-0.16/serport.h" - -#define SERIALPORT_BUFSIZE 4096 - -namespace ctb { - - const char* COM1 = "com1"; - const char* COM2 = "com2"; - const char* COM3 = "com3"; - const char* COM4 = "com4"; - const char* COM5 = "com5"; - const char* COM6 = "com6"; - const char* COM7 = "com7"; - const char* COM8 = "com8"; - const char* COM9 = "com9"; - const char* COM10 = "\\\\.\\com10"; - const char* COM11 = "\\\\.\\com11"; - const char* COM12 = "\\\\.\\com12"; - const char* COM13 = "\\\\.\\com13"; - const char* COM14 = "\\\\.\\com14"; - const char* COM15 = "\\\\.\\com15"; - const char* COM16 = "\\\\.\\com16"; - const char* COM17 = "\\\\.\\com17"; - const char* COM18 = "\\\\.\\com18"; - const char* COM19 = "\\\\.\\com19"; - const char* COM20 = "\\\\.\\com20"; - - SerialPort::SerialPort() - { - memset( &m_ov, 0, sizeof( OVERLAPPED ) ); - fd = INVALID_HANDLE_VALUE; - m_rtsdtr_state = LinestateNull; - }; - - SerialPort::~SerialPort() - { - Close(); - }; - - int SerialPort::CloseDevice() - { - if(fd != INVALID_HANDLE_VALUE) { - CloseHandle(m_ov.hEvent); - CloseHandle(fd); - fd = INVALID_HANDLE_VALUE; - } - return 0; - }; - - int SerialPort::ChangeLineState( SerialLineState flags ) - { - bool ok = false; - if(flags & LinestateDtr) { - if(m_rtsdtr_state & LinestateDtr) { - ok = EscapeCommFunction(fd,CLRDTR); - } - else { - ok = EscapeCommFunction(fd,SETDTR); - } - m_rtsdtr_state ^= LinestateDtr; - } - if(flags & LinestateRts) { - if(m_rtsdtr_state & LinestateRts) { - ok = EscapeCommFunction(fd,CLRRTS); - } - else { - ok = EscapeCommFunction(fd,SETRTS); - } - m_rtsdtr_state ^= LinestateRts; - } - if(!ok) return -1; - return 0; - }; - - int SerialPort::ClrLineState( SerialLineState flags ) - { - BOOL ok = false; - if(flags & LinestateDtr) { - ok = EscapeCommFunction(fd,CLRDTR); - m_rtsdtr_state &= ~LinestateDtr; - } - if(flags & LinestateRts) { - ok = EscapeCommFunction(fd,CLRRTS); - m_rtsdtr_state &= ~LinestateRts; - } - if(!ok) return -1; - return 0; - }; - - int SerialPort::GetLineState() - { - BOOL ok = false; - DWORD stat; - int flags = 0; - if(GetCommModemStatus(fd,&stat)) { - if(stat & MS_CTS_ON) - flags |= LinestateCts; - if(stat & MS_DSR_ON) - flags |= LinestateDsr; - if(stat & MS_RING_ON) - flags |= LinestateRing; - if(stat & MS_RLSD_ON) - flags |= LinestateDcd; - ok = true; - } - if(!ok) return -1; - return flags; - }; - - int SerialPort::Ioctl(int cmd,void* args) - { - COMSTAT comstat; - DWORD errors; - int result = 0; - bool brk; - switch(cmd) { - case CTB_RESET: - return SendBreak(0); - case CTB_SER_GETEINFO: - if(ClearCommError(fd,&errors,&comstat)) { - // actualize the last events - if(errors & CE_BREAK) einfo.brk++; - if(errors & CE_FRAME) einfo.frame++; - if(errors & CE_OVERRUN) einfo.overrun++; - if(errors & CE_RXPARITY) einfo.parity++; - *(SerialPort_EINFO*)args = einfo; - return 0; - } - case CTB_SER_GETBRK: - if(ClearCommError(fd,&errors,&comstat)) { - if(errors & CE_BREAK) result = 1; - einfo.brk += result; - *(int*)args = result; - return 0; - } - break; - case CTB_SER_GETFRM: - if(ClearCommError(fd,&errors,&comstat)) { - if(errors & CE_FRAME) result = 1; - einfo.frame += result; - *(int*)args = result; - return 0; - } - case CTB_SER_GETOVR: - if(ClearCommError(fd,&errors,&comstat)) { - if(errors & CE_OVERRUN) result = 1; - einfo.overrun += result; - *(int*)args = result; - return 0; - } - break; - case CTB_SER_GETPAR: - if(ClearCommError(fd,&errors,&comstat)) { - if(errors & CE_RXPARITY) result = 1; - einfo.parity += result; - *(int*)args = result; - return 0; - } - break; - case CTB_SER_GETINQUE: - if(ClearCommError(fd,&errors,&comstat)) { - *(int*)args = (int)comstat.cbInQue; - return 0; - } - break; - case CTB_SER_SETPAR: - return SetParityBit( *(int*)args == 1 ); - } - // error or unknown command - return -1; - }; - - int SerialPort::IsOpen() - { - return (fd != INVALID_HANDLE_VALUE); - }; - - int SerialPort::OpenDevice(const char* devname, void* dcs) - { - // if dcs isn't NULL, type cast - if(dcs) m_dcs = *(SerialPort_DCS*)dcs; - - fd = CreateFile(devname, // device name - GENERIC_READ | GENERIC_WRITE, // O_RDWR - 0, // not shared - NULL, // default value for object security ?!? - OPEN_EXISTING, // file (device) exists - FILE_FLAG_OVERLAPPED, // asynchron handling - NULL); // no more handle flags - - if(fd == INVALID_HANDLE_VALUE) { - return -1; - } - // save the device name - strncpy(m_devname,(char*)devname,sizeof(m_devname)); - // we write an eos to avoid a buffer overflow - m_devname[sizeof(m_devname)-1] = '\0'; - - // device control block - DCB dcb; - memset(&dcb,0,sizeof(dcb)); - dcb.DCBlength = sizeof(dcb); - dcb.BaudRate = m_dcs.baud; - dcb.fBinary = 1; - - m_rtsdtr_state = LinestateNull; - - // Specifies whether the CTS (clear-to-send) signal is monitored - // for output flow control. If this member is TRUE and CTS is turned - // off, output is suspended until CTS is sent again. - dcb.fOutxCtsFlow = m_dcs.rtscts; - - // Specifies the DTR (data-terminal-ready) flow control. - // This member can be one of the following values: - // DTR_CONTROL_DISABLE Disables the DTR line when the device is - // opened and leaves it disabled. - // DTR_CONTROL_ENABLE Enables the DTR line when the device is - // opened and leaves it on. - // DTR_CONTROL_HANDSHAKE Enables DTR handshaking. If handshaking is - // enabled, it is an error for the application - // to adjust the line by using the - // EscapeCommFunction function. - dcb.fDtrControl = DTR_CONTROL_DISABLE; - m_rtsdtr_state |= LinestateDtr; - // Specifies the RTS flow control. If this value is zero, the - // default is RTS_CONTROL_HANDSHAKE. This member can be one of - // the following values: - // RTS_CONTROL_DISABLE Disables the RTS line when device is - // opened and leaves it disabled. - // RTS_CONTROL_ENABLED Enables the RTS line when device is - // opened and leaves it on. - // RTS_CONTROL_HANDSHAKE Enables RTS handshaking. The driver - // raises the RTS line when the - // "type-ahead" (input)buffer is less than - // one-half full and lowers the RTS line - // when the buffer is more than three-quarters - // full. If handshaking is enabled, it is an - // error for the application to adjust the - // line by using the EscapeCommFunction function. - // RTS_CONTROL_TOGGLE Specifies that the RTS line will be high if - // bytes are available for transmission. After - // all buffered bytes have been send, the RTS - // line will be low. - if(m_dcs.rtscts) dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; - else { - dcb.fRtsControl = RTS_CONTROL_DISABLE; - m_rtsdtr_state |= LinestateRts; - } - // Specifies the XON/XOFF flow control. - // If fOutX is true (the default is false), transmission stops when the - // XOFF character is received and starts again, when the XON character - // is received. - dcb.fOutX = m_dcs.xonxoff; - // If fInX is true (default is false), the XOFF character is sent when - // the input buffer comes within XoffLim bytes of being full, and the - // XON character is sent, when the input buffer comes within XonLim - // bytes of being empty. - dcb.fInX = m_dcs.xonxoff; - // default character for XOFF is 0x13 (hex 13) - dcb.XoffChar = 0x13; - // default character for XON is 0x11 (hex 11) - dcb.XonChar = 0x11; - // set the minimum number of bytes allowed in the input buffer before - // the XON character is sent (3/4 of full size) - dcb.XonLim = (SERIALPORT_BUFSIZE >> 2) * 3; - // set the maximum number of free bytes in the input buffer, before the - // XOFF character is sent (3/4 of full size) - dcb.XoffLim = (SERIALPORT_BUFSIZE >> 2) * 3; - - // parity - switch( m_dcs.parity ) { - - case ParityOdd: dcb.Parity = ODDPARITY; break; - case ParityEven: dcb.Parity = EVENPARITY; break; - case ParityMark: dcb.Parity = MARKPARITY; break; - case ParitySpace: dcb.Parity = SPACEPARITY; break; - default: dcb.Parity = NOPARITY; - - } - // stopbits - if(m_dcs.stopbits == 2) dcb.StopBits = TWOSTOPBITS; - else dcb.StopBits = ONESTOPBIT; - // wordlen, valid values are 5,6,7,8 - dcb.ByteSize = m_dcs.wordlen; - - if(!SetCommState(fd,&dcb)) - return -2; - - // create event for overlapped I/O - // we need a event object, which inform us about the - // end of an operation (here reading device) - m_ov.hEvent = CreateEvent(NULL,// LPSECURITY_ATTRIBUTES lpsa - TRUE, // BOOL fManualReset - TRUE, // BOOL fInitialState - NULL); // LPTSTR lpszEventName - if(m_ov.hEvent == INVALID_HANDLE_VALUE) { - return -3; - } - - /* THIS IS OBSOLETE!!! - // event should be triggered, if there are some received data - if(!SetCommMask(fd,EV_RXCHAR)) - return -4; - */ - - COMMTIMEOUTS cto = {MAXDWORD,0,0,0,0}; - if(!SetCommTimeouts(fd,&cto)) - return -5; - - // for a better performance with win95/98 I increased the internal - // buffer to SERIALPORT_BUFSIZE (normal size is 1024, but this can - // be a little bit to small, if you use a higher baudrate like 115200) - if(!SetupComm(fd,SERIALPORT_BUFSIZE,SERIALPORT_BUFSIZE)) - return -6; - - // clear the internal error struct - memset(&einfo,0,sizeof(einfo)); - return 0; - }; - - int SerialPort::Read(char* buf,size_t len) - { - DWORD read; - int m = m_fifo->items(); - while(len) { - if(m_fifo->get(buf) == 1) { - len--; - buf++; - } - else { - break; - } - } - if(!ReadFile(fd,buf,len,&read,&m_ov)) { - // if we use a asynchrone reading, ReadFile gives always - // FALSE - // ERROR_IO_PENDING means ok, other values show an error - if(GetLastError() != ERROR_IO_PENDING) { - // oops..., error in communication - return -1; - } - } - else { - // ok, we have read all wanted bytes - return (int)read + m; - } - return 0; - }; - - int SerialPort::SendBreak(int duration) - { - if(duration <= 0) duration = 1; - if(!SetCommBreak(fd)) return -1; - // win32 Sleep parameter is ms - Sleep(duration * 250); - if(!ClearCommBreak(fd)) return -1; - // no error - return 0; - }; - -/* - FIXME! : We need some additional code to check the success of the - baudrate modulation (non-standard rates depend on the used - UART chipset). -*/ - int SerialPort::SetBaudrate( int baudrate ) - { - DCB dcb; - - // get the current dcb... - if(!GetCommState(fd,&dcb)) { - return -1; - } - dcb.BaudRate = baudrate; - // and write it back - if(!SetCommState(fd,&dcb)) { - return -1; - } - m_dcs.baud = baudrate; - return 0; - } - - int SerialPort::SetLineState( SerialLineState flags ) - { - BOOL ok = false; - if(flags & LinestateDtr) { - ok = EscapeCommFunction(fd,SETDTR); - // save the new state - m_rtsdtr_state |= LinestateDtr; - } - if(flags & LinestateRts) { - ok = EscapeCommFunction(fd,SETRTS); - // save the new state - m_rtsdtr_state |= LinestateRts; - } - if(!ok) return -1; - return 0; - }; - - int SerialPort::SetParityBit( bool parity ) - { - DCB dcb; - - if( ! GetCommState( fd, &dcb ) ) { - - return -1; - - } - - parity ? dcb.Parity = MARKPARITY : dcb.Parity = SPACEPARITY; - - if( ! SetCommState( fd, &dcb ) ) { - - return -2; - - } - return 0; - } - - int SerialPort::Write(char* buf,size_t len) - { - DWORD write; - if(!WriteFile(fd,buf,len,&write,&m_ov)) { - if(GetLastError() != ERROR_IO_PENDING) { - return -1; - } - else { - // VERY IMPORTANT to flush the data out of the internal - // buffer - FlushFileBuffers(fd); - // first you must call GetOverlappedResult, then you - // get the REALLY transmitted count of bytes - if(!GetOverlappedResult(fd,&m_ov,&write,TRUE)) { - // ooops... something is going wrong - return (int)write; - } - } - } - return write; - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/timer.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/timer.cpp deleted file mode 100644 index 617aa5b5ad..0000000000 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/timer.cpp +++ /dev/null @@ -1,85 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: win32/timer.cpp -// Purpose: -// Author: Joachim Buermann -// Id: $Id: timer.cpp,v 1.2 2004/11/30 12:39:17 jb Exp $ -// Copyright: (c) 2001 Joachim Buermann -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include -#include - -#ifdef WIN32 -#include -# ifndef DWORD_PTR -# define DWORD_PTR DWORD* -# endif -#endif - -#include "ctb-0.16/timer.h" - -namespace ctb { - - static void WINAPI timer_fnc(UINT uTimerID, - UINT uMsg, - DWORD_PTR dwUser, - DWORD_PTR dw1, - DWORD_PTR dw2) - { - timer_control *tc = (timer_control*)dwUser; - - if(tc->exitfnc) tc->exitfnc(NULL); - if(tc->exitflag) *tc->exitflag = 1; - tc->stop = 0; - }; - - Timer::Timer(unsigned int msecs,int* exitflag,void*(*exitfnc)(void*)) - { - control.msecs = msecs; - if(!control.msecs) control.msecs = 1; - control.exitflag = exitflag; - control.exitfnc = exitfnc; - control.stop = 0; - }; - - Timer::~Timer() - { - stop(); // stop the thread - }; - - int Timer::start() - { - stop(); - control.stop = timeSetEvent(control.msecs, - (control.msecs > 10) ? 5 : 1, - (LPTIMECALLBACK) timer_fnc, - (DWORD) &control, - TIME_ONESHOT | TIME_CALLBACK_FUNCTION); - return 0; - }; - - int Timer::stop() - { - if (control.stop) - timeKillEvent(control.stop); - control.stop = 0; - return 0; - }; - - void kill_all_timer() - { - }; - - void sleepms(unsigned int ms) - { - // set the granularity of Sleep() for the application, that - // calls it so Sleep(1) will truly sleep for just a millisecond, - // rather than the default 10! - // See: http://www.geisswerks.com/ryan/FAQS/timing.html - timeBeginPeriod(1); - SleepEx(ms,false); - timeEndPeriod(1); - }; - -} // namespace ctb diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2017.vcxproj b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2017.vcxproj deleted file mode 100644 index 2904f57a85..0000000000 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2017.vcxproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_gsmopen - {74B120FF-6935-4DFE-A142-CDB6BEA99C90} - mod_skypiax - Win32Proj - - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - false - - - - gsmlib\gsmlib-1.10-patched-13ubuntu;libctb-0.16\include;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - NO_ALSA;%(PreprocessorDefinitions) - - - Level4 - false - 4554;4324;4389;4244;4267;6340;6246;6011;6387;%(DisableSpecificWarnings) - false - - - false - - - %(AdditionalDependencies) - - - - - gsmlib\gsmlib-1.10-patched-13ubuntu;libctb-0.16\include;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - - - 4554;4324;4389;4244;4267;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - false - - - %(AdditionalDependencies) - - - - - X64 - - - gsmlib\gsmlib-1.10-patched-13ubuntu;libctb-0.16\include;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - NO_ALSA;%(PreprocessorDefinitions) - - - Level4 - false - 4554;4324;4389;4244;4267;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - false - - - MachineX64 - %(AdditionalDependencies) - - - - - X64 - - - gsmlib\gsmlib-1.10-patched-13ubuntu;libctb-0.16\include;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src\msvc;%(RootDir)%(Directory)..\..\..\..\libs\spandsp\src;%(RootDir)%(Directory)..\..\..\..\libs\jpeg-8d;%(AdditionalIncludeDirectories) - - - 4554;4324;4389;4244;4267;6340;6246;6011;6387;%(DisableSpecificWarnings) - - - false - - - %(AdditionalDependencies) - MachineX64 - - - - - - - - - - - - {1cbb0077-18c5-455f-801c-0a0ce7b0bbf5} - - - {77bc1dd2-c9a1-44d7-bffa-1320370cacb9} - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - {26c82fce-e0cf-4d10-a00c-d8e582ffeb53} - - - - - - \ No newline at end of file diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp deleted file mode 100644 index 20697adda4..0000000000 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ /dev/null @@ -1,3299 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * This module (mod_gsmopen) has been contributed by: - * - * Giovanni Maruzzelli - * - * Maintainer: Giovanni Maruzzelli - * - * mod_gsmopen.cpp -- GSM Modem compatible Endpoint Module - * - */ - -#include "gsmopen.h" - -SWITCH_BEGIN_EXTERN_C SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown); -SWITCH_MODULE_DEFINITION(mod_gsmopen, mod_gsmopen_load, mod_gsmopen_shutdown, NULL); -SWITCH_END_EXTERN_C -#define GSMOPEN_CHAT_PROTO "sms" -SWITCH_STANDARD_API(gsm_function); -#define GSM_SYNTAX "list [full] || console || AT_command || remove < interface_name | interface_id > || reload" -SWITCH_STANDARD_API(gsmopen_function); -#define GSMOPEN_SYNTAX "interface_name AT_command" - -SWITCH_STANDARD_API(gsmopen_boost_audio_function); -#define GSMOPEN_BOOST_AUDIO_SYNTAX "interface_name [ ]" -SWITCH_STANDARD_API(sendsms_function); -#define SENDSMS_SYNTAX "gsmopen_sendsms interface_name destination_number SMS_text" -SWITCH_STANDARD_API(gsmopen_dump_function); -#define GSMOPEN_DUMP_SYNTAX "gsmopen_dump " -SWITCH_STANDARD_API(gsmopen_ussd_function); -#define USSD_SYNTAX "gsmopen_ussd [nowait]" -#define FULL_RELOAD 0 -#define SOFT_RELOAD 1 - -const char *interface_status[] = { /* should match GSMOPEN_STATE_xxx in gsmopen.h */ - "IDLE", - "DOWN", - "RING", - "DIALING", - "BUSY", - "UP", - "RINGING", - "PRERING", - "DOUBLE", - "SELECTD", - "HANG_RQ", - "PREANSW" -}; - -const char *phone_callflow[] = { /* should match CALLFLOW_XXX in gsmopen.h */ - "CALL_IDLE", - "CALL_DOWN", - "INCOMING_RNG", - "CALL_DIALING", - "CALL_LINEBUSY", - "CALL_ACTIVE", - "INCOMING_HNG", - "CALL_RLEASD", - "CALL_NOCARR", - "CALL_INFLUX", - "CALL_INCOMING", - "CALL_FAILED", - "CALL_NOSRVC", - "CALL_OUTRESTR", - "CALL_SECFAIL", - "CALL_NOANSWER", - "STATUS_FNSHED", - "STATUS_CANCLED", - "STATUS_FAILED", - "STATUS_REFUSED", - "STATUS_RINGING", - "STATUS_INPROGRS", - "STATUS_UNPLACD", - "STATUS_ROUTING", - "STATUS_EARLYMD", - "INCOMING_CLID", - "STATUS_RMTEHOLD" -}; - -static struct { - int debug; - char *ip; - int port; - char *dialplan; - char *destination; - char *context; - char *codec_string; - char *codec_order[SWITCH_MAX_CODECS]; - int codec_order_last; - char *codec_rates_string; - char *codec_rates[SWITCH_MAX_CODECS]; - int codec_rates_last; - unsigned int flags; - int fd; - int calls; - int real_interfaces; - int next_interface; - char hold_music[256]; - private_t GSMOPEN_INTERFACES[GSMOPEN_MAX_INTERFACES]; - switch_mutex_t *mutex; - private_t *gsm_console; -} globals; - -switch_endpoint_interface_t *gsmopen_endpoint_interface; -switch_memory_pool_t *gsmopen_module_pool = NULL; -int running = 0; - -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_destination, globals.destination); - -static switch_status_t interface_exists(char *the_interface); -static switch_status_t remove_interface(char *the_interface); - -static switch_status_t channel_on_init(switch_core_session_t *session); -static switch_status_t channel_on_hangup(switch_core_session_t *session); -static switch_status_t channel_on_destroy(switch_core_session_t *session); -static switch_status_t channel_on_routing(switch_core_session_t *session); -static switch_status_t channel_on_exchange_media(switch_core_session_t *session); -static switch_status_t channel_on_consume_media(switch_core_session_t *session); -static switch_status_t channel_on_soft_execute(switch_core_session_t *session); -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause); -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); -static switch_status_t gsmopen_tech_init(private_t *tech_pvt, switch_core_session_t *session); - -static switch_status_t gsmopen_codec(private_t *tech_pvt, int sample_rate, int codec_ms) -{ - switch_core_session_t *session = NULL; - - if (switch_core_codec_init - (&tech_pvt->read_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - ERRORA("Can't load codec?\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - if (switch_core_codec_init - (&tech_pvt->write_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - ERRORA("Can't load codec?\n", GSMOPEN_P_LOG); - switch_core_codec_destroy(&tech_pvt->read_codec); - return SWITCH_STATUS_FALSE; - } - - tech_pvt->read_frame.rate = sample_rate; - tech_pvt->read_frame.codec = &tech_pvt->read_codec; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - - if (session) { - switch_core_session_set_read_codec(session, &tech_pvt->read_codec); - switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - switch_core_session_rwunlock(session); - } else { - ERRORA("no session\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t gsmopen_tech_init(private_t *tech_pvt, switch_core_session_t *session) -{ - - switch_assert(tech_pvt != NULL); - switch_assert(session != NULL); - tech_pvt->read_frame.data = tech_pvt->databuf; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); - switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_core_session_set_private(session, tech_pvt); - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str)); - if (!strlen(tech_pvt->session_uuid_str)) { - ERRORA("no tech_pvt->session_uuid_str\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - if (gsmopen_codec(tech_pvt, SAMPLERATE_GSMOPEN, 20) != SWITCH_STATUS_SUCCESS) { - ERRORA("gsmopen_codec FAILED\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - dtmf_rx_init(&tech_pvt->dtmf_state, NULL, NULL); - dtmf_rx_parms(&tech_pvt->dtmf_state, 0, 10, 10, -99); - -/* - if (tech_pvt->no_sound == 0) { - if (serial_audio_init(tech_pvt)) { - ERRORA("serial_audio_init failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - - } - } -*/ - - if (switch_core_timer_init(&tech_pvt->timer_read, "soft", 20, tech_pvt->read_codec.implementation->samples_per_packet, gsmopen_module_pool) != - SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_read); - - if (switch_core_timer_init(&tech_pvt->timer_write, "soft", 20, tech_pvt->write_codec.implementation->samples_per_packet, gsmopen_module_pool) != - SWITCH_STATUS_SUCCESS) { - ERRORA("setup timer failed\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_sync(&tech_pvt->timer_write); - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_HANGUP); - switch_mutex_unlock(tech_pvt->flag_mutex); - DEBUGA_GSMOPEN("gsmopen_codec SUCCESS\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches) -{ - int interface_id; - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - if (globals.GSMOPEN_INTERFACES[interface_id].running) { - switch_console_push_match(&my_matches, (const char *) globals.GSMOPEN_INTERFACES[interface_id].name); - } - } - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -static switch_status_t interface_exists(char *the_interface) -{ - int i; - int interface_id; - - if (*the_interface == '#') { /* look by interface id or interface name */ - the_interface++; - switch_assert(the_interface); - interface_id = atoi(the_interface); - - /* take a number as interface id */ - if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) { - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - return SWITCH_STATUS_SUCCESS; - } - } else { - /* interface name */ - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].name, the_interface) == 0) { - return SWITCH_STATUS_SUCCESS; - break; - } - } - } - } else { /* look by gsmopen_user */ - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].gsmopen_user)) { - if (strcmp(globals.GSMOPEN_INTERFACES[i].gsmopen_user, the_interface) == 0) { - return SWITCH_STATUS_SUCCESS; - } - } - } - } - return SWITCH_STATUS_FALSE; -} - -static switch_status_t remove_interface(char *the_interface) -{ - int x = 10; - int fd; -#ifdef WIN32 - switch_size_t howmany = 8; -#else - unsigned int howmany = 8; -#endif - - int interface_id = -1; - private_t *tech_pvt = NULL; - switch_status_t status; - - - switch_assert(the_interface); - interface_id = atoi(the_interface); - - if ((interface_id > 0 && interface_id < GSMOPEN_MAX_INTERFACES) || (interface_id == 0 && strcmp(the_interface, "0") == 0)) { - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - /* take a number as interface id */ - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - } - } else { - - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].name, the_interface) == 0) { - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - break; - } - } - } - - if (!tech_pvt) { - DEBUGA_GSMOPEN("interface '%s' does not exist\n", GSMOPEN_P_LOG, the_interface); - goto end; - } - - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].session_uuid_str)) { - DEBUGA_GSMOPEN("interface '%s' is busy\n", GSMOPEN_P_LOG, the_interface); - goto end; - } - - LOKKA(tech_pvt->controldev_lock); - - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { -#ifdef WIN32 - switch_file_write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die -#else /* WIN32 */ - howmany = write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", howmany); -#endif /* WIN32 */ - DEBUGA_GSMOPEN("HERE will shutdown gsmopen_signaling_thread of '%s'\n", GSMOPEN_P_LOG, the_interface); - } - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) { - DEBUGA_GSMOPEN("HERE will shutdown gsmopen_api_thread of '%s'\n", GSMOPEN_P_LOG, the_interface); - } - - while (x) { - x--; - switch_yield(50000); - } - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread); - } - - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread); - } - - fd = tech_pvt->controldevfd; - if (fd) { - tech_pvt->controldevfd = -1; - DEBUGA_GSMOPEN("SHUTDOWN tech_pvt->controldevfd=%d\n", GSMOPEN_P_LOG, tech_pvt->controldevfd); - } - - serial_audio_shutdown(tech_pvt); - - int res; - res = tech_pvt->serialPort_serial_control->Close(); - DEBUGA_GSMOPEN("serial_shutdown res=%d (controldevfd is %d)\n", GSMOPEN_P_LOG, res, tech_pvt->controldevfd); - -#ifndef WIN32 - shutdown(tech_pvt->audiogsmopenpipe[0], 2); - close(tech_pvt->audiogsmopenpipe[0]); - shutdown(tech_pvt->audiogsmopenpipe[1], 2); - close(tech_pvt->audiogsmopenpipe[1]); - shutdown(tech_pvt->audiopipe[0], 2); - close(tech_pvt->audiopipe[0]); - shutdown(tech_pvt->audiopipe[1], 2); - close(tech_pvt->audiopipe[1]); - shutdown(tech_pvt->GSMopenHandles.fdesc[0], 2); - close(tech_pvt->GSMopenHandles.fdesc[0]); - shutdown(tech_pvt->GSMopenHandles.fdesc[1], 2); - close(tech_pvt->GSMopenHandles.fdesc[1]); -#endif /* WIN32 */ - - UNLOCKA(tech_pvt->controldev_lock); - switch_mutex_lock(globals.mutex); - if (globals.gsm_console == &globals.GSMOPEN_INTERFACES[interface_id]) { - DEBUGA_GSMOPEN("interface '%s' no more console\n", GSMOPEN_P_LOG, the_interface); - globals.gsm_console = NULL; - } else { - DEBUGA_GSMOPEN("interface '%s' STILL console\n", GSMOPEN_P_LOG, the_interface); - } - memset(&globals.GSMOPEN_INTERFACES[interface_id], '\0', sizeof(private_t)); - globals.real_interfaces--; - switch_mutex_unlock(globals.mutex); - - DEBUGA_GSMOPEN("interface '%s' deleted successfully\n", GSMOPEN_P_LOG, the_interface); - - end: - return SWITCH_STATUS_SUCCESS; -} - -/* - State methods that get called when the state changes to the specific state - returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next - so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. -*/ -static switch_status_t channel_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - memset(tech_pvt->buffer2, 0, sizeof(tech_pvt->buffer2)); - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_IO); - switch_mutex_unlock(tech_pvt->flag_mutex); - - switch_mutex_lock(globals.mutex); - globals.calls++; - - switch_mutex_unlock(globals.mutex); - DEBUGA_GSMOPEN("%s CHANNEL INIT %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_destroy(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - - if (tech_pvt) { - DEBUGA_GSMOPEN("%s CHANNEL DESTROY %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - switch_core_timer_destroy(&tech_pvt->timer_read); - switch_core_timer_destroy(&tech_pvt->timer_write); - - if (tech_pvt->no_sound == 0) { - serial_audio_shutdown(tech_pvt); - } - - *tech_pvt->session_uuid_str = '\0'; - tech_pvt->interface_state = GSMOPEN_STATE_IDLE; - if (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED) { - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - } - memset(tech_pvt->buffer2, 0, sizeof(tech_pvt->buffer2)); - switch_core_session_set_private(session, NULL); - } else { - DEBUGA_GSMOPEN("!!!!!!NO tech_pvt!!!! CHANNEL DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(session)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - tech_pvt->phone_callflow = CALLFLOW_CALL_HANGUP_REQUESTED; - - if (!switch_channel_test_flag(channel, CF_ANSWERED)) { - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - tech_pvt->ob_failed_calls++; - } else { - tech_pvt->ib_failed_calls++; - } - } - - DEBUGA_GSMOPEN("%s CHANNEL HANGUP\n", GSMOPEN_P_LOG, tech_pvt->name); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_HANGUP); - switch_mutex_unlock(tech_pvt->flag_mutex); - - gsmopen_hangup(tech_pvt); - - //memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str)); - //*tech_pvt->session_uuid_str = '\0'; - DEBUGA_GSMOPEN("%s CHANNEL HANGUP\n", GSMOPEN_P_LOG, tech_pvt->name); - switch_mutex_lock(globals.mutex); - globals.calls--; - if (globals.calls < 0) { - globals.calls = 0; - } - - tech_pvt->interface_state = GSMOPEN_STATE_IDLE; - tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE; - switch_mutex_unlock(globals.mutex); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_routing(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL ROUTING\n", GSMOPEN_P_LOG, tech_pvt->name); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_execute(switch_core_session_t *session) -{ - - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL EXECUTE\n", GSMOPEN_P_LOG, tech_pvt->name); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL KILL_CHANNEL\n", GSMOPEN_P_LOG, tech_pvt->name); - switch (sig) { - case SWITCH_SIG_KILL: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_SIG_KILL\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_HANGUP); - switch_mutex_unlock(tech_pvt->flag_mutex); - break; - case SWITCH_SIG_BREAK: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_SIG_BREAK\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_BREAK); - switch_mutex_unlock(tech_pvt->flag_mutex); - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_consume_media(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - - if (tech_pvt) { - DEBUGA_GSMOPEN("%s CHANNEL CONSUME_MEDIA\n", GSMOPEN_P_LOG, tech_pvt->name); - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_exchange_media(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - tech_pvt = (private_t *) switch_core_session_get_private(session); - if (tech_pvt) { - DEBUGA_GSMOPEN("%s CHANNEL EXCHANGE_MEDIA\n", GSMOPEN_P_LOG, tech_pvt->name); - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_soft_execute(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - tech_pvt = (private_t *) switch_core_session_get_private(session); - if (tech_pvt) { - DEBUGA_GSMOPEN("%s CHANNEL SOFT_EXECUTE\n", GSMOPEN_P_LOG, tech_pvt->name); - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - private_t *tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - DEBUGA_GSMOPEN("%s CHANNEL SEND_DTMF\n", GSMOPEN_P_LOG, tech_pvt->name); - DEBUGA_GSMOPEN("DTMF: %c\n", GSMOPEN_P_LOG, dtmf->digit); - - gsmopen_senddigit(tech_pvt, dtmf->digit); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - switch_byte_t *data; - - int samples; - char digit_str[256]; - char buffer2[640]; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) { - ERRORA("channel not ready \n", GSMOPEN_P_LOG); - //TODO: kill the bastard - return SWITCH_STATUS_FALSE; - } - - tech_pvt->read_frame.flags = SFF_NONE; - *frame = NULL; - - if (switch_test_flag(tech_pvt, TFLAG_HANGUP)) { - return SWITCH_STATUS_FALSE; - } - - switch_core_timer_next(&tech_pvt->timer_read); - - if (tech_pvt->no_sound) { - goto cng; - } - memset(buffer2, 0, sizeof(buffer2)); - samples = tech_pvt->serialPort_serial_audio->Read(buffer2, 640); - - if (samples >= 320) { - tech_pvt->buffer2_full = 0; - - if (samples >= 640) { - DEBUGA_GSMOPEN("read more than 320, samples=%d\n", GSMOPEN_P_LOG, samples); - memcpy(tech_pvt->buffer2, buffer2 + 320, 320); - tech_pvt->buffer2_full = 1; - } - samples = 320; - memcpy(tech_pvt->read_frame.data, buffer2, 320); - } else { - if (samples != 0) { - DEBUGA_GSMOPEN("read less than 320, samples=%d\n", GSMOPEN_P_LOG, samples); - } - if (tech_pvt->buffer2_full) { - memcpy(tech_pvt->read_frame.data, tech_pvt->buffer2, 320); - tech_pvt->buffer2_full = 0; - samples = 320; - DEBUGA_GSMOPEN("samples=%d FROM BUFFER\n", GSMOPEN_P_LOG, samples); - memset(tech_pvt->buffer2, 0, sizeof(tech_pvt->buffer2)); - } - - } - - tech_pvt->read_frame.datalen = samples; - tech_pvt->read_frame.samples = samples / 2; - tech_pvt->read_frame.timestamp = tech_pvt->timer_read.samplecount; - - *frame = &tech_pvt->read_frame; - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_VOICE); - switch_mutex_unlock(tech_pvt->flag_mutex); - - if (samples != 320) { - memset(tech_pvt->buffer2, 0, sizeof(tech_pvt->buffer2)); - if (samples != 0) { - DEBUGA_GSMOPEN("samples=%d, goto cng\n", GSMOPEN_P_LOG, samples); - } - goto cng; - } - - memset(digit_str, 0, sizeof(digit_str)); - dtmf_rx(&tech_pvt->dtmf_state, (int16_t *) tech_pvt->read_frame.data, tech_pvt->read_frame.samples); - dtmf_rx_get(&tech_pvt->dtmf_state, digit_str, sizeof(digit_str)); - - gsmopen_sound_boost(tech_pvt->read_frame.data, tech_pvt->read_frame.samples, tech_pvt->capture_boost); - - if (digit_str[0]) { - switch_time_t new_dtmf_timestamp = switch_time_now(); - if ((new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp) > 350000) { //FIXME: make it configurable - char *p = digit_str; - - while (p && *p) { - switch_dtmf_t dtmf = { 0 }; - dtmf.digit = *p; - dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION; - switch_channel_queue_dtmf(channel, &dtmf); - p++; - } - DEBUGA_GSMOPEN("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", GSMOPEN_P_LOG, digit_str, (unsigned int) new_dtmf_timestamp, - (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp)); - tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp; - } - } - while (switch_test_flag(tech_pvt, TFLAG_IO)) { - if (switch_test_flag(tech_pvt, TFLAG_BREAK)) { - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_BREAK); - switch_mutex_unlock(tech_pvt->flag_mutex); - DEBUGA_GSMOPEN("BREAK: CHANNEL READ FRAME goto CNG\n", GSMOPEN_P_LOG); - goto cng; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - DEBUGA_GSMOPEN("CHANNEL READ FRAME not IO\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - } - - if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_mutex_unlock(tech_pvt->flag_mutex); - if (!tech_pvt->read_frame.datalen) { - DEBUGA_GSMOPEN("CHANNEL READ CONTINUE\n", GSMOPEN_P_LOG); - continue; - } - *frame = &tech_pvt->read_frame; -#ifdef BIGENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { - switch_swap_linear((int16_t *) (*frame)->data, (int) (*frame)->datalen / 2); - } -#endif - return SWITCH_STATUS_SUCCESS; - } - - DEBUGA_GSMOPEN("CHANNEL READ no TFLAG_VOICE\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - - } - - DEBUGA_GSMOPEN("CHANNEL READ FALSE\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_FALSE; - cng: - data = (switch_byte_t *) tech_pvt->read_frame.data; - data[0] = 65; - data[1] = 0; - tech_pvt->read_frame.datalen = 2; - tech_pvt->read_frame.flags = SFF_CNG; - *frame = &tech_pvt->read_frame; - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - unsigned int sent; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) { - ERRORA("channel not ready \n", GSMOPEN_P_LOG); - //TODO: kill the bastard - return SWITCH_STATUS_FALSE; - } -#ifdef BIGENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { -#ifdef WIN32 - switch_swap_linear((int16_t *) frame->data, (int) frame->datalen / 2); -#else - switch_swap_linear(frame->data, (int) frame->datalen / 2); -#endif //WIN32 - } -#endif - - gsmopen_sound_boost(frame->data, frame->samples, tech_pvt->playback_boost); - if (!tech_pvt->no_sound) { - if (!tech_pvt->serialPort_serial_audio_opened) { - serial_audio_init(tech_pvt); - } - sent = tech_pvt->serialPort_serial_audio->Write((char *) frame->data, (int) (frame->datalen)); - - if (sent && sent != frame->datalen && sent != -1) { - DEBUGA_GSMOPEN("sent %u\n", GSMOPEN_P_LOG, sent); - } - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_answer_channel(switch_core_session_t *session) -{ - private_t *tech_pvt; - switch_channel_t *channel = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_IO); - switch_mutex_unlock(tech_pvt->flag_mutex); - - gsmopen_serial_answer(tech_pvt); - - switch_mutex_lock(globals.mutex); - globals.calls++; - - switch_mutex_unlock(globals.mutex); - DEBUGA_GSMOPEN("%s CHANNEL ANSWER %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); - - - if (channel) { - switch_channel_mark_answered(channel); - } - - DEBUGA_GSMOPEN("ANSWERED! \n", GSMOPEN_P_LOG); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_ANSWER: - { - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_ANSWER\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - if (tech_pvt->interface_state != GSMOPEN_STATE_UP && tech_pvt->phone_callflow != CALLFLOW_CALL_ACTIVE) { - DEBUGA_GSMOPEN("MSG_ID=%d, TO BE ANSWERED!\n", GSMOPEN_P_LOG, msg->message_id); - channel_answer_channel(session); - } - } - break; - - case SWITCH_MESSAGE_INDICATE_PROGRESS: - { - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_PROGRESS\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - if (tech_pvt->interface_state != GSMOPEN_STATE_UP && tech_pvt->phone_callflow != CALLFLOW_CALL_ACTIVE) { - DEBUGA_GSMOPEN("MSG_ID=%d, TO BE ANSWERED!\n", GSMOPEN_P_LOG, msg->message_id); - channel_answer_channel(session); - } - } - break; - case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: - - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_AUDIO_SYNC\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - switch_core_timer_sync(&tech_pvt->timer_read); - switch_core_timer_sync(&tech_pvt->timer_write); - - break; - - case SWITCH_MESSAGE_INDICATE_TRANSFER: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_TRANSFER\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - break; - case SWITCH_MESSAGE_INDICATE_BRIDGE: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_BRIDGE\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - break; - case SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY: - DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - break; - default: - { - if (msg->message_id != SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC && msg->message_id != SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE) { - DEBUGA_GSMOPEN("MSG_ID=%d\n", GSMOPEN_P_LOG, msg->message_id); - } - } - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event) -{ - struct private_object *tech_pvt = (struct private_object *) switch_core_session_get_private(session); - char *body = switch_event_get_body(event); - switch_assert(tech_pvt != NULL); - - if (!body) { - body = (char *) ""; - } - - WARNINGA("event: |||%s|||\n", GSMOPEN_P_LOG, body); - - return SWITCH_STATUS_SUCCESS; -} - -switch_state_handler_table_t gsmopen_state_handlers = { - /*.on_init */ channel_on_init, - /*.on_routing */ channel_on_routing, - /*.on_execute */ channel_on_execute, - /*.on_hangup */ channel_on_hangup, - /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute, - /*.on_consume_media */ channel_on_consume_media, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ channel_on_destroy -}; - -switch_io_routines_t gsmopen_io_routines = { - /*.outgoing_channel */ channel_outgoing_channel, - /*.read_frame */ channel_read_frame, - /*.write_frame */ channel_write_frame, - /*.kill_channel */ channel_kill_channel, - /*.send_dtmf */ channel_send_dtmf, - /*.receive_message */ channel_receive_message, - /*.receive_event */ channel_receive_event -}; - -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause) -{ - private_t *tech_pvt = NULL; - int result; - - if ((*new_session = switch_core_session_request_uuid(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid"))) != 0) { - - switch_channel_t *channel = NULL; - switch_caller_profile_t *caller_profile; - char *rdest; - int found = 0; - char interface_name[256]; - - DEBUGA_GSMOPEN("1 SESSION_REQUEST %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_add_stream(*new_session, NULL); - - if (!zstr(outbound_profile->destination_number)) { - int i; - char *slash; - - switch_copy_string(interface_name, outbound_profile->destination_number, 255); - slash = strrchr(interface_name, '/'); - *slash = '\0'; - - switch_mutex_lock(globals.mutex); - if (strncmp("ANY", interface_name, strlen(interface_name)) == 0 || strncmp("RR", interface_name, strlen(interface_name)) == 0) { - /* we've been asked for the "ANY" interface, let's find the first idle interface */ - /* Find the first idle interface using Round Robin */ - DEBUGA_GSMOPEN("Finding one available gsmopen interface RR\n", GSMOPEN_P_LOG); - tech_pvt = find_available_gsmopen_interface_rr(NULL); - if (tech_pvt) { - found = 1; - DEBUGA_GSMOPEN("FOUND one available gsmopen interface RR\n", GSMOPEN_P_LOG); - } - } - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, interface_name, strlen(interface_name)) == 0)) { - if (strlen(globals.GSMOPEN_INTERFACES[i].session_uuid_str)) { - DEBUGA_GSMOPEN - ("globals.GSMOPEN_INTERFACES[%d].name=|||%s||| session_uuid_str=|||%s||| is BUSY\n", - GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].session_uuid_str); - DEBUGA_GSMOPEN("1 SESSION_DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - DEBUGA_GSMOPEN("globals.GSMOPEN_INTERFACES[%d].name=|||%s|||?\n", GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name); - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - found = 1; - break; - } - - } - - } else { - ERRORA("Doh! no destination number?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (!found) { - DEBUGA_GSMOPEN("Doh! no available interface for |||%s|||?\n", GSMOPEN_P_LOG, interface_name); - DEBUGA_GSMOPEN("2 SESSION_DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session)); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - channel = switch_core_session_get_channel(*new_session); - if (!channel) { - ERRORA("Doh! no channel?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - if (gsmopen_tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Doh! no tech_init?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (outbound_profile) { - char name[128]; - - snprintf(name, sizeof(name), "gsmopen/%s", outbound_profile->destination_number); - switch_channel_set_name(channel, name); - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - } else { - ERRORA("Doh! no caller profile\n", GSMOPEN_P_LOG); - switch_core_session_destroy(new_session); - switch_mutex_unlock(globals.mutex); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - tech_pvt->ob_calls++; - - rdest = strchr(caller_profile->destination_number, '/'); - *rdest++ = '\0'; - - - switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt->session_uuid_str)); - caller_profile = tech_pvt->caller_profile; - caller_profile->destination_number = rdest; - - switch_mutex_lock(tech_pvt->flag_mutex); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); - switch_mutex_unlock(tech_pvt->flag_mutex); - switch_channel_set_state(channel, CS_INIT); - result=gsmopen_call(tech_pvt, rdest, 30); - switch_mutex_unlock(globals.mutex); - if(result != 0){ - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - return SWITCH_CAUSE_SUCCESS; - } - - ERRORA("Doh! no new_session\n", GSMOPEN_P_LOG); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; -} - -/*! - * \brief This thread runs during a call, and monitor the interface for signaling, like hangup, caller id, etc most of signaling is handled inside the gsmopen_signaling_read function - * - */ - -static switch_status_t load_config(int reload_type) -{ - const char *cf = "gsmopen.conf"; - switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface; - private_t *tech_pvt = NULL; - -#ifdef WIN32 - DEBUGA_GSMOPEN("Windows CODEPAGE Input =%u\n", GSMOPEN_P_LOG, GetConsoleCP()); - SetConsoleCP(65001); - DEBUGA_GSMOPEN("Windows CODEPAGE Input =%u\n", GSMOPEN_P_LOG, GetConsoleCP()); - DEBUGA_GSMOPEN("Windows CODEPAGE Output =%u\n", GSMOPEN_P_LOG, GetConsoleOutputCP()); - SetConsoleOutputCP(65001); - DEBUGA_GSMOPEN("Windows CODEPAGE Output =%u\n", GSMOPEN_P_LOG, GetConsoleOutputCP()); - //let's hope to have unicode in console now. You need to use Lucida Console or, much better, Courier New font for the command prompt to show unicode -#endif // WIN32 - NOTICA("GSMOPEN Charset Output Test 0 %s\n", GSMOPEN_P_LOG, "èéòàù"); - NOTICA("GSMOPEN Charset Output Test 1 %s\n", GSMOPEN_P_LOG, "ç°§^£"); - NOTICA("GSMOPEN Charset Output Test 2 %s\n", GSMOPEN_P_LOG, "новости"); - NOTICA("GSMOPEN Charset Output Test 3 %s\n", GSMOPEN_P_LOG, "ﺎﻠﺠﻤﻋﺓ"); - NOTICA("GSMOPEN Charset Output Test 4 %s\n", GSMOPEN_P_LOG, "ראת"); - NOTICA("GSMOPEN Charset Output Test 5 %s\n", GSMOPEN_P_LOG, "לק"); - NOTICA("GSMOPEN Charset Output Test 6 %s\n", GSMOPEN_P_LOG, "人大"); - - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, gsmopen_module_pool); - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - ERRORA("open of %s failed\n", GSMOPEN_P_LOG, cf); - running = 0; - switch_xml_free(xml); - return SWITCH_STATUS_TERM; - } - - switch_mutex_lock(globals.mutex); - - set_global_dialplan("XML"); - DEBUGA_GSMOPEN("Default globals.dialplan=%s\n", GSMOPEN_P_LOG, globals.dialplan); - set_global_destination("5000"); - DEBUGA_GSMOPEN("Default globals.destination=%s\n", GSMOPEN_P_LOG, globals.destination); - set_global_context("default"); - DEBUGA_GSMOPEN("Default globals.context=%s\n", GSMOPEN_P_LOG, globals.context); - - if ((global_settings = switch_xml_child(cfg, "global_settings"))) { - for (param = switch_xml_child(global_settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "debug")) { - DEBUGA_GSMOPEN("globals.debug=%d\n", GSMOPEN_P_LOG, globals.debug); - globals.debug = atoi(val); - DEBUGA_GSMOPEN("globals.debug=%d\n", GSMOPEN_P_LOG, globals.debug); - } else if (!strcasecmp(var, "hold-music")) { - switch_set_string(globals.hold_music, val); - DEBUGA_GSMOPEN("globals.hold_music=%s\n", GSMOPEN_P_LOG, globals.hold_music); - } else if (!strcmp(var, "dialplan")) { - set_global_dialplan(val); - DEBUGA_GSMOPEN("globals.dialplan=%s\n", GSMOPEN_P_LOG, globals.dialplan); - } else if (!strcmp(var, "destination")) { - set_global_destination(val); - DEBUGA_GSMOPEN("globals.destination=%s\n", GSMOPEN_P_LOG, globals.destination); - } else if (!strcmp(var, "context")) { - set_global_context(val); - DEBUGA_GSMOPEN("globals.context=%s\n", GSMOPEN_P_LOG, globals.context); - - } - - } - } - - if ((interfaces = switch_xml_child(cfg, "per_interface_settings"))) { - int i = 0; - - for (myinterface = switch_xml_child(interfaces, "interface"); myinterface; myinterface = myinterface->next) { - char *id = (char *) switch_xml_attr(myinterface, "id"); - char *name = (char *) switch_xml_attr(myinterface, "name"); - const char *context = globals.context; - const char *dialplan = globals.dialplan; - const char *destination = globals.destination; - const char *controldevice_name = "/dev/ttyUSB3"; - const char *controldevice_audio_name = "/dev/ttyUSB2"; - char *digit_timeout = NULL; - char *max_digits = NULL; - char *hotline = NULL; - char *dial_regex = NULL; - char *hold_music = globals.hold_music; - char *fail_dial_regex = NULL; - const char *enable_callerid = "true"; - - const char *at_dial_pre_number = "ATD"; - const char *at_dial_post_number = ";"; - const char *at_dial_expect = "OK"; - const char *at_hangup = "ATH"; - const char *at_hangup_expect = "OK"; - const char *at_answer = "ATA"; - const char *at_answer_expect = "OK"; - const char *at_send_dtmf = "AT^DTMF"; - const char *at_preinit_1 = ""; - const char *at_preinit_1_expect = ""; - const char *at_preinit_2 = ""; - const char *at_preinit_2_expect = ""; - const char *at_preinit_3 = ""; - const char *at_preinit_3_expect = ""; - const char *at_preinit_4 = ""; - const char *at_preinit_4_expect = ""; - const char *at_preinit_5 = ""; - const char *at_preinit_5_expect = ""; - const char *at_postinit_1 = "at+cmic=0,9"; - const char *at_postinit_1_expect = "OK"; - const char *at_postinit_2 = "AT+CKPD=\"EEE\""; - const char *at_postinit_2_expect = "OK"; - const char *at_postinit_3 = "AT+CSSN=1,0"; - const char *at_postinit_3_expect = "OK"; - const char *at_postinit_4 = "at+sidet=0"; - const char *at_postinit_4_expect = "OK"; - const char *at_postinit_5 = "at+clvl=3"; - const char *at_postinit_5_expect = "OK"; - const char *at_query_battchg = "AT+CBC"; - const char *at_query_battchg_expect = "OK"; - const char *at_query_signal = "AT+CSQ"; - const char *at_query_signal_expect = "OK"; - const char *at_call_idle = "+MCST: 1"; - const char *at_call_incoming = "RING"; - const char *at_call_active = "^CONN:1,0"; - const char *at_call_failed = "+MCST: 65"; - const char *at_call_calling = "^ORIG:1,0"; - const char *at_indicator_noservice_string = "CIEV: 2;0"; - const char *at_indicator_nosignal_string = "CIEV: 5;0"; - const char *at_indicator_lowsignal_string = "CIEV: 5;1"; - const char *at_indicator_lowbattchg_string = "CIEV: 0;1"; - const char *at_indicator_nobattchg_string = "CIEV: 0;0"; - const char *at_indicator_callactive_string = "CIEV: 3;1"; - const char *at_indicator_nocallactive_string = "CIEV: 3;0"; - const char *at_indicator_nocallsetup_string = "CIEV: 6;0"; - const char *at_indicator_callsetupincoming_string = "CIEV: 6;1"; - const char *at_indicator_callsetupoutgoing_string = "CIEV: 6;2"; - const char *at_indicator_callsetupremoteringing_string = "CIEV: 6;3"; - const char *at_early_audio = "0"; - const char *at_after_preinit_pause = "500000"; - const char *at_initial_pause = "500000"; - const char *at_has_clcc = "0"; - const char *at_has_ecam = "0"; - const char *gsmopen_sound_rate = "8000"; - const char *capture_boost = "0"; - const char *playback_boost = "0"; - const char *no_sound = "0"; - const char *portaudiocindex = "1"; - const char *portaudiopindex = "1"; - const char *speexecho = "1"; - const char *speexpreprocess = "1"; - const char *ussd_request_encoding = "auto"; - const char *ussd_response_encoding = "auto"; - - uint32_t interface_id = 0; - int controldevice_speed = 115200; //FIXME TODO - //int controldevice_audio_speed = 115200; //FIXME TODO - uint32_t controldevprotocol = PROTOCOL_AT; //FIXME TODO - const char *gsmopen_serial_sync_period = "300"; //FIXME TODO - const char *imei = ""; - const char *imsi = ""; - - tech_pvt = NULL; - - for (param = switch_xml_child(myinterface, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "id")) { - id = val; - } else if (!strcasecmp(var, "name")) { - name = val; - } else if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "destination")) { - destination = val; - } else if (!strcasecmp(var, "controldevice_name")) { - controldevice_name = val; - } else if (!strcasecmp(var, "controldevice_audio_name")) { - controldevice_audio_name = val; - } else if (!strcasecmp(var, "digit_timeout")) { - digit_timeout = val; - } else if (!strcasecmp(var, "max_digits")) { - max_digits = val; - } else if (!strcasecmp(var, "hotline")) { - hotline = val; - } else if (!strcasecmp(var, "dial_regex")) { - dial_regex = val; - } else if (!strcasecmp(var, SWITCH_HOLD_MUSIC_VARIABLE)) { - hold_music = val; - } else if (!strcasecmp(var, "fail_dial_regex")) { - fail_dial_regex = val; - } else if (!strcasecmp(var, "enable_callerid")) { - enable_callerid = val; - } else if (!strcasecmp(var, "at_dial_pre_number")) { - at_dial_pre_number = val; - } else if (!strcasecmp(var, "at_dial_post_number")) { - at_dial_post_number = val; - } else if (!strcasecmp(var, "at_dial_expect")) { - at_dial_expect = val; - } else if (!strcasecmp(var, "at_hangup")) { - at_hangup = val; - } else if (!strcasecmp(var, "at_hangup_expect")) { - at_hangup_expect = val; - } else if (!strcasecmp(var, "at_answer")) { - at_answer = val; - } else if (!strcasecmp(var, "at_answer_expect")) { - at_answer_expect = val; - } else if (!strcasecmp(var, "at_send_dtmf")) { - at_send_dtmf = val; - } else if (!strcasecmp(var, "at_preinit_1")) { - at_preinit_1 = val; - } else if (!strcasecmp(var, "at_preinit_1_expect")) { - at_preinit_1_expect = val; - } else if (!strcasecmp(var, "at_preinit_2")) { - at_preinit_2 = val; - } else if (!strcasecmp(var, "at_preinit_2_expect")) { - at_preinit_2_expect = val; - } else if (!strcasecmp(var, "at_preinit_3")) { - at_preinit_3 = val; - } else if (!strcasecmp(var, "at_preinit_3_expect")) { - at_preinit_3_expect = val; - } else if (!strcasecmp(var, "at_preinit_4")) { - at_preinit_4 = val; - } else if (!strcasecmp(var, "at_preinit_4_expect")) { - at_preinit_4_expect = val; - } else if (!strcasecmp(var, "at_preinit_5")) { - at_preinit_5 = val; - } else if (!strcasecmp(var, "at_preinit_5_expect")) { - at_preinit_5_expect = val; - } else if (!strcasecmp(var, "at_postinit_1")) { - at_postinit_1 = val; - } else if (!strcasecmp(var, "at_postinit_1_expect")) { - at_postinit_1_expect = val; - } else if (!strcasecmp(var, "at_postinit_2")) { - at_postinit_2 = val; - } else if (!strcasecmp(var, "at_postinit_2_expect")) { - at_postinit_2_expect = val; - } else if (!strcasecmp(var, "at_postinit_3")) { - at_postinit_3 = val; - } else if (!strcasecmp(var, "at_postinit_3_expect")) { - at_postinit_3_expect = val; - } else if (!strcasecmp(var, "at_postinit_4")) { - at_postinit_4 = val; - } else if (!strcasecmp(var, "at_postinit_4_expect")) { - at_postinit_4_expect = val; - } else if (!strcasecmp(var, "at_postinit_5")) { - at_postinit_5 = val; - } else if (!strcasecmp(var, "at_postinit_5_expect")) { - at_postinit_5_expect = val; - } else if (!strcasecmp(var, "at_query_battchg")) { - at_query_battchg = val; - } else if (!strcasecmp(var, "at_query_battchg_expect")) { - at_query_battchg_expect = val; - } else if (!strcasecmp(var, "at_query_signal")) { - at_query_signal = val; - } else if (!strcasecmp(var, "at_query_signal_expect")) { - at_query_signal_expect = val; - } else if (!strcasecmp(var, "at_call_idle")) { - at_call_idle = val; - } else if (!strcasecmp(var, "at_call_incoming")) { - at_call_incoming = val; - } else if (!strcasecmp(var, "at_call_active")) { - at_call_active = val; - } else if (!strcasecmp(var, "at_call_failed")) { - at_call_failed = val; - } else if (!strcasecmp(var, "at_call_calling")) { - at_call_calling = val; - } else if (!strcasecmp(var, "at_indicator_noservice_string")) { - at_indicator_noservice_string = val; - } else if (!strcasecmp(var, "at_indicator_nosignal_string")) { - at_indicator_nosignal_string = val; - } else if (!strcasecmp(var, "at_indicator_lowsignal_string")) { - at_indicator_lowsignal_string = val; - } else if (!strcasecmp(var, "at_indicator_lowbattchg_string")) { - at_indicator_lowbattchg_string = val; - } else if (!strcasecmp(var, "at_indicator_nobattchg_string")) { - at_indicator_nobattchg_string = val; - } else if (!strcasecmp(var, "at_indicator_callactive_string")) { - at_indicator_callactive_string = val; - } else if (!strcasecmp(var, "at_indicator_nocallactive_string")) { - at_indicator_nocallactive_string = val; - } else if (!strcasecmp(var, "at_indicator_nocallsetup_string")) { - at_indicator_nocallsetup_string = val; - } else if (!strcasecmp(var, "at_indicator_callsetupincoming_string")) { - at_indicator_callsetupincoming_string = val; - } else if (!strcasecmp(var, "at_indicator_callsetupoutgoing_string")) { - at_indicator_callsetupoutgoing_string = val; - } else if (!strcasecmp(var, "at_indicator_callsetupremoteringing_string")) { - at_indicator_callsetupremoteringing_string = val; - } else if (!strcasecmp(var, "portaudiocindex")) { - portaudiocindex = val; - } else if (!strcasecmp(var, "portaudiopindex")) { - portaudiopindex = val; - } else if (!strcasecmp(var, "speexecho")) { - speexecho = val; - } else if (!strcasecmp(var, "speexpreprocess")) { - speexpreprocess = val; - } else if (!strcasecmp(var, "at_early_audio")) { - at_early_audio = val; - } else if (!strcasecmp(var, "at_after_preinit_pause")) { - at_after_preinit_pause = val; - } else if (!strcasecmp(var, "at_initial_pause")) { - at_initial_pause = val; - } else if (!strcasecmp(var, "at_has_clcc")) { - at_has_clcc = val; - } else if (!strcasecmp(var, "at_has_ecam")) { - at_has_ecam = val; - } else if (!strcasecmp(var, "gsmopen_sound_rate")) { - gsmopen_sound_rate = val; - } else if (!strcasecmp(var, "capture_boost")) { - capture_boost = val; - } else if (!strcasecmp(var, "playback_boost")) { - playback_boost = val; - } else if (!strcasecmp(var, "no_sound")) { - no_sound = val; - } else if (!strcasecmp(var, "imsi")) { - imsi = val; - } else if (!strcasecmp(var, "imei")) { - imei = val; - } else if (!strcasecmp(var, "gsmopen_serial_sync_period")) { - gsmopen_serial_sync_period = val; - } else if (!strcasecmp(var, "ussd_request_encoding")) { - ussd_request_encoding = val; - } else if (!strcasecmp(var, "ussd_response_encoding")) { - ussd_response_encoding = val; - } - - } - - if (reload_type == SOFT_RELOAD) { - char the_interface[256]; - sprintf(the_interface, "#%s", name); - - if (interface_exists(the_interface) == SWITCH_STATUS_SUCCESS) { - continue; - } - } - - if (!id) { - ERRORA("interface missing REQUIRED param 'id'\n", GSMOPEN_P_LOG); - continue; - } - - if (switch_is_number(id)) { - interface_id = atoi(id); - } else { - ERRORA("interface param 'id' MUST be a number, now id='%s'\n", GSMOPEN_P_LOG, id); - continue; - } - - if (!switch_is_number(at_early_audio)) { - ERRORA("interface param 'at_early_audio' MUST be a number, now at_early_audio='%s'\n", GSMOPEN_P_LOG, at_early_audio); - continue; - } - if (!switch_is_number(at_after_preinit_pause)) { - ERRORA("interface param 'at_after_preinit_pause' MUST be a number, now at_after_preinit_pause='%s'\n", GSMOPEN_P_LOG, - at_after_preinit_pause); - continue; - } - if (!switch_is_number(at_initial_pause)) { - ERRORA("interface param 'at_initial_pause' MUST be a number, now at_initial_pause='%s'\n", GSMOPEN_P_LOG, at_initial_pause); - continue; - } - if (!switch_is_number(at_has_clcc)) { - ERRORA("interface param 'at_has_clcc' MUST be a number, now at_has_clcc='%s'\n", GSMOPEN_P_LOG, at_has_clcc); - continue; - } - if (!switch_is_number(at_has_ecam)) { - ERRORA("interface param 'at_has_ecam' MUST be a number, now at_has_ecam='%s'\n", GSMOPEN_P_LOG, at_has_ecam); - continue; - } - if (!switch_is_number(gsmopen_sound_rate)) { - ERRORA("interface param 'gsmopen_sound_rate' MUST be a number, now gsmopen_sound_rate='%s'\n", GSMOPEN_P_LOG, gsmopen_sound_rate); - continue; - } - if (!switch_is_number(capture_boost)) { - ERRORA("interface param 'capture_boost' MUST be a number, now capture_boost='%s'\n", GSMOPEN_P_LOG, capture_boost); - continue; - } - if (!switch_is_number(playback_boost)) { - ERRORA("interface param 'playback_boost' MUST be a number, now playback_boost='%s'\n", GSMOPEN_P_LOG, playback_boost); - continue; - } - if (!switch_is_number(no_sound)) { - ERRORA("interface param 'no_sound' MUST be a number, now no_sound='%s'\n", GSMOPEN_P_LOG, no_sound); - continue; - } - if (!switch_is_number(gsmopen_serial_sync_period)) { - ERRORA("interface param 'gsmopen_serial_sync_period' MUST be a number, now gsmopen_serial_sync_period='%s'\n", GSMOPEN_P_LOG, - gsmopen_serial_sync_period); - continue; - } - - if (interface_id && interface_id < GSMOPEN_MAX_INTERFACES) { - private_t newconf; - //int res = 0; - - memset(&newconf, '\0', sizeof(newconf)); - globals.GSMOPEN_INTERFACES[interface_id] = newconf; - - switch_mutex_init(&globals.GSMOPEN_INTERFACES[interface_id].controldev_lock, SWITCH_MUTEX_NESTED, gsmopen_module_pool); - switch_mutex_init(&globals.GSMOPEN_INTERFACES[interface_id].controldev_audio_lock, SWITCH_MUTEX_NESTED, gsmopen_module_pool); - - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].id, id); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].name, name); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].context, context); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].dialplan, dialplan); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].destination, destination); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].controldevice_name, controldevice_name); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].controldevice_audio_name, controldevice_audio_name); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].dial_regex, dial_regex); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].hold_music, hold_music); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].fail_dial_regex, fail_dial_regex); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_pre_number, at_dial_pre_number); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_post_number, at_dial_post_number); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_expect, at_dial_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_hangup, at_hangup); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_hangup_expect, at_hangup_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_answer, at_answer); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_answer_expect, at_answer_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_send_dtmf, at_send_dtmf); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_1, at_preinit_1); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_1_expect, at_preinit_1_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_2, at_preinit_2); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_2_expect, at_preinit_2_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_3, at_preinit_3); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_3_expect, at_preinit_3_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_4, at_preinit_4); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_4_expect, at_preinit_4_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_5, at_preinit_5); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_5_expect, at_preinit_5_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_1, at_postinit_1); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_1_expect, at_postinit_1_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_2, at_postinit_2); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_2_expect, at_postinit_2_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_3, at_postinit_3); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_3_expect, at_postinit_3_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_4, at_postinit_4); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_4_expect, at_postinit_4_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_5, at_postinit_5); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_5_expect, at_postinit_5_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_battchg, at_query_battchg); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_battchg_expect, at_query_battchg_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_signal, at_query_signal); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_signal_expect, at_query_signal_expect); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_idle, at_call_idle); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_incoming, at_call_incoming); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_active, at_call_active); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_failed, at_call_failed); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_calling, at_call_calling); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_noservice_string, at_indicator_noservice_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nosignal_string, at_indicator_nosignal_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_lowsignal_string, at_indicator_lowsignal_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_lowbattchg_string, at_indicator_lowbattchg_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nobattchg_string, at_indicator_nobattchg_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callactive_string, at_indicator_callactive_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nocallactive_string, at_indicator_nocallactive_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nocallsetup_string, at_indicator_nocallsetup_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupincoming_string, at_indicator_callsetupincoming_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupoutgoing_string, at_indicator_callsetupoutgoing_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupremoteringing_string, - at_indicator_callsetupremoteringing_string); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].imsi, imsi); - switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].imei, imei); - globals.GSMOPEN_INTERFACES[interface_id].at_early_audio = atoi(at_early_audio); - globals.GSMOPEN_INTERFACES[interface_id].at_after_preinit_pause = atoi(at_after_preinit_pause); - globals.GSMOPEN_INTERFACES[interface_id].at_initial_pause = atoi(at_initial_pause); - globals.GSMOPEN_INTERFACES[interface_id].at_has_clcc = atoi(at_has_clcc); - globals.GSMOPEN_INTERFACES[interface_id].at_has_ecam = atoi(at_has_ecam); - globals.GSMOPEN_INTERFACES[interface_id].capture_boost = atoi(capture_boost); - globals.GSMOPEN_INTERFACES[interface_id].playback_boost = atoi(playback_boost); - globals.GSMOPEN_INTERFACES[interface_id].no_sound = atoi(no_sound); - globals.GSMOPEN_INTERFACES[interface_id].gsmopen_serial_sync_period = atoi(gsmopen_serial_sync_period); - - globals.GSMOPEN_INTERFACES[interface_id].ussd_request_encoding = - strcasecmp(ussd_request_encoding, "plain") == 0 ? USSD_ENCODING_PLAIN : - strcasecmp(ussd_request_encoding, "hex7") == 0 ? USSD_ENCODING_HEX_7BIT : - strcasecmp(ussd_request_encoding, "hex8") == 0 ? USSD_ENCODING_HEX_8BIT : - strcasecmp(ussd_request_encoding, "ucs2") == 0 ? USSD_ENCODING_UCS2 : USSD_ENCODING_AUTO; - - globals.GSMOPEN_INTERFACES[interface_id].ussd_response_encoding = - strcasecmp(ussd_response_encoding, "plain") == 0 ? USSD_ENCODING_PLAIN : - strcasecmp(ussd_response_encoding, "hex7") == 0 ? USSD_ENCODING_HEX_7BIT : - strcasecmp(ussd_response_encoding, "hex8") == 0 ? USSD_ENCODING_HEX_8BIT : - strcasecmp(ussd_response_encoding, "ucs2") == 0 ? USSD_ENCODING_UCS2 : USSD_ENCODING_AUTO; - - globals.GSMOPEN_INTERFACES[interface_id].controldevice_speed = controldevice_speed; //FIXME - globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol = controldevprotocol; //FIXME - globals.GSMOPEN_INTERFACES[interface_id].running = 1; //FIXME - - - gsmopen_store_boost((char *) capture_boost, &globals.GSMOPEN_INTERFACES[interface_id].capture_boost); //FIXME - gsmopen_store_boost((char *) playback_boost, &globals.GSMOPEN_INTERFACES[interface_id].playback_boost); //FIXME - - } else { - ERRORA("interface id %u is higher than GSMOPEN_MAX_INTERFACES (%d)\n", GSMOPEN_P_LOG, interface_id, GSMOPEN_MAX_INTERFACES); - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "interface id is higher than GSMOPEN_MAX_INTERFACES"); - continue; - } - - } - -#ifndef WIN32 - find_ttyusb_devices(NULL, "/sys/devices"); -#endif// WIN32 - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - - switch_threadattr_t *gsmopen_api_thread_attr = NULL; - int res = 0; - int interface_id = i; - - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - - if (strlen(globals.GSMOPEN_INTERFACES[i].name) && !globals.GSMOPEN_INTERFACES[i].active) { - - WARNINGA("STARTING interface_id=%u\n", GSMOPEN_P_LOG, interface_id); - DEBUGA_GSMOPEN("id=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].id); - DEBUGA_GSMOPEN("name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].name); - DEBUGA_GSMOPEN("hold-music=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].hold_music); - DEBUGA_GSMOPEN("context=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].context); - DEBUGA_GSMOPEN("dialplan=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].dialplan); - DEBUGA_GSMOPEN("destination=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].destination); - DEBUGA_GSMOPEN("imei=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].imei); - DEBUGA_GSMOPEN("imsi=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].imsi); - DEBUGA_GSMOPEN("controldevice_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].controldevice_name); - DEBUGA_GSMOPEN("controldevice_audio_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].controldevice_audio_name); - DEBUGA_GSMOPEN("gsmopen_serial_sync_period=%d\n", GSMOPEN_P_LOG, - (int) globals.GSMOPEN_INTERFACES[interface_id].gsmopen_serial_sync_period); - - /* init the serial port */ - if (globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol != PROTOCOL_NO_SERIAL) { - globals.GSMOPEN_INTERFACES[interface_id].controldevfd = - gsmopen_serial_init(&globals.GSMOPEN_INTERFACES[interface_id], globals.GSMOPEN_INTERFACES[interface_id].controldevice_speed); - if (globals.GSMOPEN_INTERFACES[interface_id].controldevfd == -1) { - ERRORA("STARTING interface_id=%u FAILED: gsmopen_serial_init failed\n", GSMOPEN_P_LOG, interface_id); - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_serial_init failed"); - globals.GSMOPEN_INTERFACES[interface_id].active = 0; - globals.GSMOPEN_INTERFACES[interface_id].name[0] = '\0'; - continue; - } - } - - /* config the phone/modem on the serial port */ - if (globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol != PROTOCOL_NO_SERIAL) { - res = gsmopen_serial_config(&globals.GSMOPEN_INTERFACES[interface_id]); - if (res) { - int count = 0; - ERRORA("gsmopen_serial_config failed, let's try again\n", GSMOPEN_P_LOG); - while (res && count < 5) { - switch_sleep(100000); //0.1 seconds - res = gsmopen_serial_config(&globals.GSMOPEN_INTERFACES[interface_id]); - count++; - if (res) { - ERRORA("%d: gsmopen_serial_config failed, let's try again\n", GSMOPEN_P_LOG, count); - } - } - if (res) { - ERRORA("STARTING interface_id=%u FAILED\n", GSMOPEN_P_LOG, interface_id); - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_serial_config failed"); - globals.GSMOPEN_INTERFACES[interface_id].active = 0; - globals.GSMOPEN_INTERFACES[interface_id].name[0] = '\0'; - continue; - } - } - } - - if (globals.GSMOPEN_INTERFACES[interface_id].no_sound == 0) { - if (serial_audio_init(&globals.GSMOPEN_INTERFACES[interface_id])) { - ERRORA("serial_audio_init failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%u FAILED\n", GSMOPEN_P_LOG, interface_id); - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "serial_audio_init failed"); - globals.GSMOPEN_INTERFACES[interface_id].active = 0; - globals.GSMOPEN_INTERFACES[interface_id].name[0] = '\0'; - continue; - - } - - if (serial_audio_shutdown(&globals.GSMOPEN_INTERFACES[interface_id])) { - ERRORA("serial_audio_shutdown failed\n", GSMOPEN_P_LOG); - ERRORA("STARTING interface_id=%u FAILED\n", GSMOPEN_P_LOG, interface_id); - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "serial_audio_shutdown failed"); - globals.GSMOPEN_INTERFACES[interface_id].active = 0; - globals.GSMOPEN_INTERFACES[interface_id].name[0] = '\0'; - continue; - - } - - } - - globals.GSMOPEN_INTERFACES[interface_id].active = 1; - - //gsmopen_store_boost((char *) capture_boost, &globals.GSMOPEN_INTERFACES[interface_id].capture_boost); //FIXME - //gsmopen_store_boost((char *) playback_boost, &globals.GSMOPEN_INTERFACES[interface_id].playback_boost); //FIXME - - switch_sleep(100000); - switch_threadattr_create(&gsmopen_api_thread_attr, gsmopen_module_pool); - switch_threadattr_stacksize_set(gsmopen_api_thread_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread, gsmopen_api_thread_attr, gsmopen_do_gsmopenapi_thread, - &globals.GSMOPEN_INTERFACES[interface_id], gsmopen_module_pool); - - switch_sleep(100000); - WARNINGA("STARTED interface_id=%u\n", GSMOPEN_P_LOG, interface_id); - - /* How many real intterfaces */ - globals.real_interfaces++; - - } - } - - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - - DEBUGA_GSMOPEN("id=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].id); - DEBUGA_GSMOPEN("name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].name); - DEBUGA_GSMOPEN("context=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].context); - DEBUGA_GSMOPEN("hold-music=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].hold_music); - DEBUGA_GSMOPEN("dialplan=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].dialplan); - DEBUGA_GSMOPEN("destination=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].destination); - DEBUGA_GSMOPEN("imei=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].imei); - DEBUGA_GSMOPEN("imsi=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].imsi); - DEBUGA_GSMOPEN("controldevice_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].controldevice_name); - DEBUGA_GSMOPEN("gsmopen_serial_sync_period=%d\n", GSMOPEN_P_LOG, (int) globals.GSMOPEN_INTERFACES[i].gsmopen_serial_sync_period); - DEBUGA_GSMOPEN("controldevice_audio_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].controldevice_audio_name); - } - } - } - - switch_mutex_unlock(globals.mutex); - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t chat_send(switch_event_t *message_event) -{ - char *user = NULL, *host, *f_user = NULL, *f_host = NULL, *f_resource = NULL; - private_t *tech_pvt = NULL; - int i = 0, found = 0; - - const char *proto; - const char *from; - const char *to; - const char *subject; - const char *body; - const char *hint; - - proto = switch_event_get_header(message_event, "proto"); - from = switch_event_get_header(message_event, "from"); - to = switch_event_get_header(message_event, "to"); - subject = switch_event_get_header(message_event, "subject"); - body = switch_event_get_body(message_event); - hint = switch_event_get_header(message_event, "hint"); - - switch_assert(proto != NULL); - - DEBUGA_GSMOPEN("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", GSMOPEN_P_LOG, proto, from, to, subject, body, - hint ? hint : "NULL"); - - if (!to || !strlen(to)) { - ERRORA("Missing To: header.\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if ((!from && !hint) || (!strlen(from) && !strlen(hint))) { - ERRORA("Missing From: AND Hint: headers.\n", GSMOPEN_P_LOG); - return SWITCH_STATUS_SUCCESS; - } - - if (from && (f_user = strdup(from))) { - if ((f_host = strchr(f_user, '@'))) { - *f_host++ = '\0'; - if ((f_resource = strchr(f_host, '/'))) { - *f_resource++ = '\0'; - } - } - } - - if (hint == NULL || !strlen(hint)) { //FIXME FIXME FIXME - hint = from; - } - if (subject == NULL || !strlen(subject)) { //FIXME FIXME FIXME - subject = "SIMPLE MESSAGE"; - } - if (to && (user = strdup(to))) { - if ((host = strchr(user, '@'))) { - *host++ = '\0'; - } - - DEBUGA_GSMOPEN("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", GSMOPEN_P_LOG, proto, from, to, subject, body, - hint ? hint : "NULL"); - if (hint && strlen(hint)) { - //in hint we receive the interface name to use - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, hint, strlen(hint)) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - DEBUGA_GSMOPEN("Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", GSMOPEN_P_LOG, i, - globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - } - } - if (!found) { - ERRORA("ERROR: A GSMopen interface with name='%s' or one with SIM_number='%s' was not found\n", GSMOPEN_P_LOG, hint ? hint : "NULL", - from ? from : "NULL"); - goto end; - } else { - if (strcasecmp(to, "ussd") == 0) { - gsmopen_ussd(tech_pvt, (char *) body, 0); - } else { - gsmopen_sendsms(tech_pvt, (char *) to, (char *) body); - } - - } - } - end: - switch_safe_free(user); - switch_safe_free(f_user); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t compat_chat_send(const char *proto, const char *from, const char *to, - const char *subject, const char *body, const char *type, const char *hint) -{ - switch_event_t *message_event; - switch_status_t status; - - if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type); - switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint); - - if (body) { - switch_event_add_body(message_event, "%s", body); - } - } else { - abort(); - } - - status = chat_send(message_event); - switch_event_destroy(&message_event); - - return status; - -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load) -{ - switch_api_interface_t *commands_api_interface; - switch_chat_interface_t *chat_interface; - - gsmopen_module_pool = pool; - memset(&globals, '\0', sizeof(globals)); - - running = 1; - - if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) { - running = 0; - return SWITCH_STATUS_FALSE; - } - - if (switch_event_reserve_subclass(MY_EVENT_INCOMING_SMS) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - gsmopen_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - gsmopen_endpoint_interface->interface_name = "gsmopen"; - gsmopen_endpoint_interface->io_routines = &gsmopen_io_routines; - gsmopen_endpoint_interface->state_handler = &gsmopen_state_handlers; - - if (running) { - - SWITCH_ADD_API(commands_api_interface, "gsm", "gsm console AT_command", gsm_function, GSM_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen", "gsmopen interface AT_command", gsmopen_function, GSMOPEN_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen_boost_audio", "gsmopen_boost_audio interface AT_command", gsmopen_boost_audio_function, - GSMOPEN_BOOST_AUDIO_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen_dump", "gsmopen_dump interface", gsmopen_dump_function, GSMOPEN_DUMP_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen_sendsms", "gsmopen_sendsms interface destination_number SMS_text", sendsms_function, - SENDSMS_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "gsmopen_ussd", "gsmopen_ussd interface ussd_code wait_seconds", gsmopen_ussd_function, - SENDSMS_SYNTAX); - SWITCH_ADD_CHAT(chat_interface, GSMOPEN_CHAT_PROTO, chat_send); - - switch_console_set_complete("add gsm list"); - switch_console_set_complete("add gsm list full"); - switch_console_set_complete("add gsm console ::gsm::list_interfaces"); - switch_console_set_complete("add gsm remove ::gsm::list_interfaces"); - switch_console_set_complete("add gsm reload"); - switch_console_set_complete("add gsmopen ::gsm::list_interfaces"); - switch_console_set_complete("add gsmopen_dump list"); - switch_console_set_complete("add gsmopen_dump ::gsm::list_interfaces"); - switch_console_set_complete("add gsmopen_ussd ::gsm::list_interfaces"); - switch_console_set_complete("add gsmopen_sendsms ::gsm::list_interfaces"); - switch_console_set_complete("add gsmopen_boost_audio ::gsm::list_interfaces"); - - switch_console_add_complete_func("::gsm::list_interfaces", list_interfaces); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; - } else - return SWITCH_STATUS_FALSE; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown) -{ - int x; - private_t *tech_pvt = NULL; - switch_status_t status; -#ifdef WIN32 - switch_size_t howmany = 8; -#else - unsigned int howmany = 8; -#endif - int interface_id; - int fd; - - running = 0; - - for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - WARNINGA("SHUTDOWN interface_id=%d\n", GSMOPEN_P_LOG, interface_id); - globals.GSMOPEN_INTERFACES[interface_id].running = 0; - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { -#ifdef WIN32 - switch_file_write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die -#else /* WIN32 */ - howmany = write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", howmany); -#endif /* WIN32 */ - } - x = 10; - while (x) { //FIXME 0.5 seconds? - x--; - switch_yield(50000); - } - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread); - } - if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) { - switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread); - } - - x = 10; - while (x) { //FIXME 0.5 seconds? - x--; - switch_yield(50000); - } - fd = tech_pvt->controldevfd; - if (fd) { - tech_pvt->controldevfd = -1; - DEBUGA_GSMOPEN("SHUTDOWN tech_pvt->controldevfd=%d\n", GSMOPEN_P_LOG, tech_pvt->controldevfd); - } - - if (!globals.GSMOPEN_INTERFACES[interface_id].no_sound) { - serial_audio_shutdown(tech_pvt); - } - - if (tech_pvt->serialPort_serial_control) { - int res; - res = tech_pvt->serialPort_serial_control->Close(); - DEBUGA_GSMOPEN("serial_shutdown res=%d (controldevfd is %d)\n", GSMOPEN_P_LOG, res, tech_pvt->controldevfd); - } - -#ifndef WIN32 - shutdown(tech_pvt->audiogsmopenpipe[0], 2); - close(tech_pvt->audiogsmopenpipe[0]); - shutdown(tech_pvt->audiogsmopenpipe[1], 2); - close(tech_pvt->audiogsmopenpipe[1]); - shutdown(tech_pvt->audiopipe[0], 2); - close(tech_pvt->audiopipe[0]); - shutdown(tech_pvt->audiopipe[1], 2); - close(tech_pvt->audiopipe[1]); - shutdown(tech_pvt->GSMopenHandles.fdesc[0], 2); - close(tech_pvt->GSMopenHandles.fdesc[0]); - shutdown(tech_pvt->GSMopenHandles.fdesc[1], 2); - close(tech_pvt->GSMopenHandles.fdesc[1]); -#endif /* WIN32 */ - } - - } - - switch_event_free_subclass(MY_EVENT_INCOMING_SMS); - - switch_safe_free(globals.dialplan); - switch_safe_free(globals.context); - switch_safe_free(globals.destination); - switch_safe_free(globals.codec_string); - switch_safe_free(globals.codec_rates_string); - - return SWITCH_STATUS_SUCCESS; -} - -void *SWITCH_THREAD_FUNC gsmopen_do_gsmopenapi_thread(switch_thread_t *thread, void *obj) -{ - return gsmopen_do_gsmopenapi_thread_func(obj); -} - -int dtmf_received(private_t *tech_pvt, char *value) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - session = switch_core_session_locate(tech_pvt->session_uuid_str); - channel = switch_core_session_get_channel(session); - - if (channel) { - - if (!switch_channel_test_flag(channel, CF_BRIDGED)) { - - switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; - DEBUGA_GSMOPEN("received DTMF %c on channel %s\n", GSMOPEN_P_LOG, dtmf.digit, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - //FIXME: why sometimes DTMFs from here do not seems to be get by FS? - switch_channel_queue_dtmf(channel, &dtmf); - switch_set_flag(tech_pvt, TFLAG_DTMF); - switch_mutex_unlock(tech_pvt->flag_mutex); - } else { - DEBUGA_GSMOPEN - ("received a DTMF on channel %s, but we're BRIDGED, so let's NOT relay it out of band\n", GSMOPEN_P_LOG, switch_channel_get_name(channel)); - } - } else { - WARNINGA("received %c DTMF, but no channel?\n", GSMOPEN_P_LOG, value[0]); - } - switch_core_session_rwunlock(session); - - return 0; -} - -int new_inbound_channel(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - switch_assert(tech_pvt != NULL); - tech_pvt->ib_calls++; - if ((session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)) != 0) { - DEBUGA_GSMOPEN("2 SESSION_REQUEST %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(session)); - switch_core_session_add_stream(session, NULL); - channel = switch_core_session_get_channel(session); - if (!channel) { - ERRORA("Doh! no channel?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - if (gsmopen_tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Doh! no tech_init?\n", GSMOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - - if ((tech_pvt->caller_profile = - switch_caller_profile_new(switch_core_session_get_pool(session), "gsmopen", - tech_pvt->dialplan, tech_pvt->callid_name, - tech_pvt->callid_number, NULL, NULL, NULL, NULL, "mod_gsmopen", tech_pvt->context, tech_pvt->destination)) != 0) { - char name[128]; - switch_snprintf(name, sizeof(name), "gsmopen/%s", tech_pvt->name); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - } - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - ERRORA("Error spawning thread\n", GSMOPEN_P_LOG); - switch_core_session_destroy(&session); - return 0; - } - } - - DEBUGA_GSMOPEN("EXITING new_inbound_channel\n", GSMOPEN_P_LOG); - - return 0; -} - -int remote_party_is_ringing(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - goto done; - } - if (channel) { - switch_channel_mark_ring_ready(channel); - DEBUGA_GSMOPEN("gsmopen_call: REMOTE PARTY RINGING\n", GSMOPEN_P_LOG); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - done: - return 0; -} - -int remote_party_is_early_media(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n\n\n", GSMOPEN_P_LOG); - //TODO: kill the bastard - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - switch_core_session_add_stream(session, NULL); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - //TODO: kill the bastard - goto done; - } - if (channel) { - switch_channel_mark_pre_answered(channel); - DEBUGA_GSMOPEN("gsmopen_call: REMOTE PARTY EARLY MEDIA\n", GSMOPEN_P_LOG); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - //TODO: kill the bastard - } - - switch_core_session_rwunlock(session); - - done: - return 0; -} - -int outbound_channel_answered(private_t *tech_pvt) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - - if (!zstr(tech_pvt->session_uuid_str)) { - session = switch_core_session_locate(tech_pvt->session_uuid_str); - } else { - ERRORA("No session???\n", GSMOPEN_P_LOG); - goto done; - } - if (session) { - channel = switch_core_session_get_channel(session); - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - goto done; - } - if (channel) { - switch_channel_mark_answered(channel); - tech_pvt->phone_callflow = GSMOPEN_STATE_UP; - tech_pvt->interface_state = GSMOPEN_STATE_UP; - } else { - ERRORA("No channel???\n", GSMOPEN_P_LOG); - } - - switch_core_session_rwunlock(session); - - done: - DEBUGA_GSMOPEN("outbound_channel_answered!\n", GSMOPEN_P_LOG); - - return 0; -} - -private_t *find_available_gsmopen_interface_rr(private_t *tech_pvt_calling) -{ - private_t *tech_pvt = NULL; - int i; - - switch_mutex_lock(globals.mutex); - - /* Fact is the real interface start from 1 */ - //XXX no, is just a convention, but you can have it start from 0. I do not, for aestetic reasons :-) - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - int interface_id; - - interface_id = globals.next_interface; - globals.next_interface = interface_id + 1 < GSMOPEN_MAX_INTERFACES ? interface_id + 1 : 0; - - if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) { - int gsmopen_state = 0; - - tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id]; - gsmopen_state = tech_pvt->interface_state; - DEBUGA_GSMOPEN("gsmopen interface: %d, name: %s, state: %d\n", GSMOPEN_P_LOG, interface_id, globals.GSMOPEN_INTERFACES[interface_id].name, - gsmopen_state); - if ((tech_pvt_calling ? strcmp(tech_pvt->gsmopen_user, tech_pvt_calling->gsmopen_user) : 1) - && (GSMOPEN_STATE_DOWN == gsmopen_state || 0 == gsmopen_state) && (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED - || 0 == tech_pvt->phone_callflow)) { - DEBUGA_GSMOPEN("returning as available gsmopen interface name: %s, state: %d callflow: %d\n", GSMOPEN_P_LOG, tech_pvt->name, gsmopen_state, - tech_pvt->phone_callflow); - if (tech_pvt_calling == NULL) { - tech_pvt->interface_state = GSMOPEN_STATE_SELECTED; - } - - switch_mutex_unlock(globals.mutex); - return tech_pvt; - } - } - } - - switch_mutex_unlock(globals.mutex); - return NULL; -} - -SWITCH_STANDARD_API(gsm_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (globals.gsm_console) - stream->write_function(stream, "gsm console is: |||%s|||\n", globals.gsm_console->name); - else - stream->write_function(stream, "gsm console is NOT yet assigned\n"); - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc || !argv[0]) { - stream->write_function(stream, "%s", GSM_SYNTAX); - goto end; - } - - if (!strcasecmp(argv[0], "list")) { - int i; - unsigned int ib = 0; - unsigned int ib_failed = 0; - unsigned int ob = 0; - unsigned int ob_failed = 0; - char next_flag_char = ' '; - - stream->write_function(stream, "F ID Name Operator IMEI IB (F/T) OB (F/T) State CallFlw UUID\n"); - stream->write_function(stream, "= == ========== ================ =============== ========= ========= ======= =============== ====\n"); - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - next_flag_char = i == globals.next_interface ? '*' : ' '; - ib += globals.GSMOPEN_INTERFACES[i].ib_calls; - ib_failed += globals.GSMOPEN_INTERFACES[i].ib_failed_calls; - ob += globals.GSMOPEN_INTERFACES[i].ob_calls; - ob_failed += globals.GSMOPEN_INTERFACES[i].ob_failed_calls; - - - stream->write_function(stream, - "%c %-2d %-10s %-16.16s %-15s %4u/%-4u %4u/%-4u %-7s %-15s %s\n", - next_flag_char, - i, globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].operator_name, - globals.GSMOPEN_INTERFACES[i].imei, - globals.GSMOPEN_INTERFACES[i].ib_failed_calls, - globals.GSMOPEN_INTERFACES[i].ib_calls, - globals.GSMOPEN_INTERFACES[i].ob_failed_calls, - globals.GSMOPEN_INTERFACES[i].ob_calls, - interface_status[globals.GSMOPEN_INTERFACES[i].interface_state], - phone_callflow[globals.GSMOPEN_INTERFACES[i].phone_callflow], globals.GSMOPEN_INTERFACES[i].session_uuid_str); - } else if (argc > 1 && !strcasecmp(argv[1], "full")) { - stream->write_function(stream, "%c %d\n", next_flag_char, i); - } - - } - stream->write_function(stream, "\nTotal Interfaces: %d IB Calls(Failed/Total): %u/%u OB Calls(Failed/Total): %u/%u\n", - globals.real_interfaces > 0 ? globals.real_interfaces : 0, ib_failed, ib, ob_failed, ob); - - } else if (!strcasecmp(argv[0], "console")) { - int i; - int found = 0; - - if (argc == 2) { - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[1], strlen(argv[1])) == 0)) { - globals.gsm_console = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "gsm console is now: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, - globals.GSMOPEN_INTERFACES[i].name); - stream->write_function(stream, "gsm console is: |||%s|||\n", globals.gsm_console->name); - found = 1; - break; - } - - } - if (!found) - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[1]); - } else { - - stream->write_function(stream, "-ERR Usage: gsm console interface_name\n"); - goto end; - } - - } else if (!strcasecmp(argv[0], "ciapalino")) { - - } else if (!strcasecmp(argv[0], "reload")) { - if (load_config(SOFT_RELOAD) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "gsm reload failed\n"); - } else { - stream->write_function(stream, "gsm reload success\n"); - } - } else if (!strcasecmp(argv[0], "remove")) { - if (argc == 2) { - if (remove_interface(argv[1]) == SWITCH_STATUS_SUCCESS) { - if (interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "gsm remove '%s' failed\n", argv[1]); - } else { - stream->write_function(stream, "gsm remove '%s' success\n", argv[1]); - } - } - } else { - stream->write_function(stream, "-ERR Usage: gsm remove interface_name\n"); - goto end; - } - - } else { - if (globals.gsm_console) - gsmopen_serial_write_AT_noack(globals.gsm_console, (char *) cmd); - else - stream->write_function(stream, "gsm console is NOT yet assigned\n"); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(gsmopen_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX); - goto end; - } - - if (argc < 2) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX); - goto end; - } - - if (argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; - } else { - gsmopen_serial_write_AT_noack(tech_pvt, (char *) &cmd[strlen(argv[0]) + 1]); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} -SWITCH_STANDARD_API(gsmopen_dump_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - char value[512]; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_DUMP_SYNTAX); - goto end; - } - if (argc == 1 && argv[0]) { - int found = 0; - int i = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - found = 1; - break; - } - - } - if (!found && (strcmp("list", argv[0]) == 0)) { - stream->write_function(stream, "gsmopen_dump LIST\n\n"); - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - if (strlen(globals.GSMOPEN_INTERFACES[i].name)) { - stream->write_function(stream, "dumping interface '%s'\n\n", globals.GSMOPEN_INTERFACES[i].name); - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - - stream->write_function(stream, "interface_name = %s\n", tech_pvt->name); - stream->write_function(stream, "interface_id = %s\n", tech_pvt->id); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->active); - stream->write_function(stream, "active = %s\n", value); - if (!tech_pvt->network_creg_not_supported) { - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->not_registered); - stream->write_function(stream, "not_registered = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->home_network_registered); - stream->write_function(stream, "home_network_registered = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->roaming_registered); - stream->write_function(stream, "roaming_registered = %s\n", value); - } else { - stream->write_function(stream, "not_registered = %s\n", "N/A"); - stream->write_function(stream, "home_network_registered = %s\n", "N/A"); - stream->write_function(stream, "roaming_registered = %s\n", "N/A"); - } - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->got_signal); - stream->write_function(stream, "got_signal = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->signal_strength); - stream->write_function(stream, "signal_strength = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->running); - stream->write_function(stream, "running = %s\n", value); - stream->write_function(stream, "subscriber_number = %s\n", tech_pvt->subscriber_number); - stream->write_function(stream, "device_manufacturer = %s\n", tech_pvt->device_mfg); - stream->write_function(stream, "device_model = %s\n", tech_pvt->device_model); - stream->write_function(stream, "device_firmware = %s\n", tech_pvt->device_firmware); - stream->write_function(stream, "operator = %s\n", tech_pvt->operator_name); - stream->write_function(stream, "imei = %s\n", tech_pvt->imei); - stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->controldev_dead); - stream->write_function(stream, "controldev_dead = %s\n", value); - stream->write_function(stream, "controldevice_name = %s\n", tech_pvt->controldevice_name); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->no_sound); - stream->write_function(stream, "no_sound = %s\n", value); - snprintf(value, sizeof(value) - 1, "%f", tech_pvt->playback_boost); - stream->write_function(stream, "playback_boost = %s\n", value); - snprintf(value, sizeof(value) - 1, "%f", tech_pvt->capture_boost); - stream->write_function(stream, "capture_boost = %s\n", value); - stream->write_function(stream, "dialplan = %s\n", tech_pvt->dialplan); - stream->write_function(stream, "context = %s\n", tech_pvt->context); - stream->write_function(stream, "destination = %s\n", tech_pvt->destination); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ib_calls); - stream->write_function(stream, "ib_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ob_calls); - stream->write_function(stream, "ob_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ib_failed_calls); - stream->write_function(stream, "ib_failed_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ob_failed_calls); - stream->write_function(stream, "ob_failed_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->interface_state); - stream->write_function(stream, "interface_state = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->phone_callflow); - stream->write_function(stream, "phone_callflow = %s\n", value); - stream->write_function(stream, "session_uuid_str = %s\n", tech_pvt->session_uuid_str); - stream->write_function(stream, "\n"); - - dump_event(tech_pvt); - } - - } - - } else if (found) { - stream->write_function(stream, "dumping interface '%s'\n\n", argv[0]); - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - - stream->write_function(stream, "interface_name = %s\n", tech_pvt->name); - stream->write_function(stream, "interface_id = %s\n", tech_pvt->id); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->active); - stream->write_function(stream, "active = %s\n", value); - if (!tech_pvt->network_creg_not_supported) { - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->not_registered); - stream->write_function(stream, "not_registered = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->home_network_registered); - stream->write_function(stream, "home_network_registered = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->roaming_registered); - stream->write_function(stream, "roaming_registered = %s\n", value); - } else { - stream->write_function(stream, "not_registered = %s\n", "N/A"); - stream->write_function(stream, "home_network_registered = %s\n", "N/A"); - stream->write_function(stream, "roaming_registered = %s\n", "N/A"); - } - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->got_signal); - stream->write_function(stream, "got_signal = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->signal_strength); - stream->write_function(stream, "signal_strength = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->running); - stream->write_function(stream, "running = %s\n", value); - stream->write_function(stream, "subscriber_number = %s\n", tech_pvt->subscriber_number); - stream->write_function(stream, "device_manufacturer = %s\n", tech_pvt->device_mfg); - stream->write_function(stream, "device_model = %s\n", tech_pvt->device_model); - stream->write_function(stream, "device_firmware = %s\n", tech_pvt->device_firmware); - stream->write_function(stream, "operator = %s\n", tech_pvt->operator_name); - stream->write_function(stream, "imei = %s\n", tech_pvt->imei); - stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->controldev_dead); - stream->write_function(stream, "controldev_dead = %s\n", value); - stream->write_function(stream, "controldevice_name = %s\n", tech_pvt->controldevice_name); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->no_sound); - stream->write_function(stream, "no_sound = %s\n", value); - snprintf(value, sizeof(value) - 1, "%f", tech_pvt->playback_boost); - stream->write_function(stream, "playback_boost = %s\n", value); - snprintf(value, sizeof(value) - 1, "%f", tech_pvt->capture_boost); - stream->write_function(stream, "capture_boost = %s\n", value); - stream->write_function(stream, "dialplan = %s\n", tech_pvt->dialplan); - stream->write_function(stream, "context = %s\n", tech_pvt->context); - stream->write_function(stream, "destination = %s\n", tech_pvt->destination); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ib_calls); - stream->write_function(stream, "ib_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ob_calls); - stream->write_function(stream, "ob_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ib_failed_calls); - stream->write_function(stream, "ib_failed_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ob_failed_calls); - stream->write_function(stream, "ob_failed_calls = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->interface_state); - stream->write_function(stream, "interface_state = %s\n", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->phone_callflow); - stream->write_function(stream, "phone_callflow = %s\n", value); - stream->write_function(stream, "session_uuid_str = %s\n", tech_pvt->session_uuid_str); - stream->write_function(stream, "\n"); - - dump_event(tech_pvt); - } else { - stream->write_function(stream, "interface '%s' was not found\n", argv[0]); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_DUMP_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(gsmopen_boost_audio_function) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if ((argc == 1 || argc == 3) && argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - - } else { - if (argc == 1) { - stream->write_function(stream, "[%s] capture boost is %f\n", globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].capture_boost); - stream->write_function(stream, "[%s] playback boost is %f\n", globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].playback_boost); - stream->write_function(stream, "%s usage: %s", argv[0], GSMOPEN_BOOST_AUDIO_SYNTAX); - goto end; - } else if ((strncmp("play", argv[1], strlen(argv[1])) == 0)) { - if (switch_is_number(argv[2])) { - stream->write_function(stream, "[%s] playback boost was %f\n", globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].playback_boost); - gsmopen_store_boost(argv[2], &globals.GSMOPEN_INTERFACES[i].playback_boost); //FIXME - stream->write_function(stream, "[%s] playback boost is now %f\n", globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].playback_boost); - } - } else if ((strncmp("capt", argv[1], strlen(argv[1])) == 0)) { - if (switch_is_number(argv[2])) { - stream->write_function(stream, "[%s] capture boost was %f\n", globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].capture_boost); - gsmopen_store_boost(argv[2], &globals.GSMOPEN_INTERFACES[i].capture_boost); //FIXME - stream->write_function(stream, "[%s] capture boost is now %f\n", globals.GSMOPEN_INTERFACES[i].name, - globals.GSMOPEN_INTERFACES[i].capture_boost); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_BOOST_AUDIO_SYNTAX); - } - } - } else { - stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_BOOST_AUDIO_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -void *gsmopen_do_gsmopenapi_thread_func(void *obj) -{ - - private_t *tech_pvt = (private_t *) obj; - time_t now_timestamp; - - while (running && tech_pvt && tech_pvt->running) { - int res; - res = gsmopen_serial_read(tech_pvt); - if (res == -1) { //manage the graceful interface shutdown - tech_pvt->controldev_dead = 1; - close(tech_pvt->controldevfd); - ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name); - tech_pvt->running = 0; - alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead"); - tech_pvt->active = 0; - tech_pvt->name[0] = '\0'; - switch_sleep(1000000); - } else if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL && tech_pvt->interface_state == GSMOPEN_STATE_RING - && tech_pvt->phone_callflow != CALLFLOW_CALL_HANGUP_REQUESTED) { - - gsmopen_ring(tech_pvt); - - } else if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL && tech_pvt->interface_state == GSMOPEN_STATE_DIALING) { - DEBUGA_GSMOPEN("WE'RE DIALING, let's take the earlymedia\n", GSMOPEN_P_LOG); - tech_pvt->interface_state = CALLFLOW_STATUS_EARLYMEDIA; - remote_party_is_early_media(tech_pvt); - - } else if (tech_pvt->interface_state == CALLFLOW_CALL_REMOTEANSWER) { - DEBUGA_GSMOPEN("REMOTE PARTY ANSWERED\n", GSMOPEN_P_LOG); - outbound_channel_answered(tech_pvt); - } - switch_sleep(100); //give other threads a chance - time(&now_timestamp); - - if ((now_timestamp - tech_pvt->gsmopen_serial_synced_timestamp) > tech_pvt->gsmopen_serial_sync_period) { //TODO find a sensible period. 5min? in config? - gsmopen_serial_sync(tech_pvt); - gsmopen_serial_getstatus_AT(tech_pvt); - } - } - DEBUGA_GSMOPEN("EXIT\n", GSMOPEN_P_LOG); - return NULL; - -} - -SWITCH_STANDARD_API(sendsms_function) -{ - char *mycmd = NULL, *argv[3] = { 0 }; - int argc = 0; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX); - goto end; - } - - if (argc < 3) { - stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX); - goto end; - } - - if (argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - stream->write_function(stream, "Trying to send your SMS: interface=%s, dest=%s, text=%s\n", argv[0], argv[1], argv[2]); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; - } else { - NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", GSMOPEN_P_LOG, GSMOPEN_CHAT_PROTO, tech_pvt->name, - argv[1], "SIMPLE MESSAGE", switch_str_nil(argv[2]), tech_pvt->name); - - compat_chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->name, argv[1], "SIMPLE MESSAGE", switch_str_nil(argv[2]), NULL, tech_pvt->name); - } - } else { - stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(gsmopen_ussd_function) -{ - char *mycmd = NULL, *argv[3] = { 0 }; - int argc = 0; - int waittime = 20; - private_t *tech_pvt = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "ERROR, usage: %s", USSD_SYNTAX); - goto end; - } - - if (argc < 2) { - stream->write_function(stream, "ERROR, usage: %s", USSD_SYNTAX); - goto end; - } - - if (argc >= 3 && strcasecmp(argv[2], "nowait")==0) { - waittime = 0; - } - - if (argv[0]) { - int i; - int found = 0; - - for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) { - /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ - if (strlen(globals.GSMOPEN_INTERFACES[i].name) - && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; - NOTICA("Trying to send USSD request: interface=%s, ussd=%s\n", GSMOPEN_P_LOG, argv[0], argv[1]); - found = 1; - break; - } - - } - if (!found) { - stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]); - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; - } else { - int err = gsmopen_ussd(tech_pvt, (char *) argv[1], waittime); - if (err == AT_ERROR) { - stream->write_function(stream, "ERROR: command failed\n"); - } else if (!waittime) { - stream->write_function(stream, "USSD request has been sent\n"); - } else if (err) { - stream->write_function(stream, "ERROR: USSD request timeout (%d)\n", err); - } else if (!tech_pvt->ussd_received) { - stream->write_function(stream, "ERROR: no response received\n"); - } else { - stream->write_function(stream, "Status: %d%s\n", tech_pvt->ussd_status, - tech_pvt->ussd_status == 0 ? " - completed" : - tech_pvt->ussd_status == 1 ? " - action required" : - tech_pvt->ussd_status == 2 ? " - error" : ""); - if (strlen(tech_pvt->ussd_message) != 0) - stream->write_function(stream, "Text: %s\n", tech_pvt->ussd_message); - } - } - } else { - stream->write_function(stream, "ERROR, usage: %s", USSD_SYNTAX); - } - end: - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -int dump_event_full(private_t *tech_pvt, int is_alarm, int alarm_code, const char *alarm_message) -{ - switch_event_t *event; - char value[512]; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - switch_status_t status; - - if (!tech_pvt) { - return -1; - } - session = switch_core_session_locate(tech_pvt->session_uuid_str); - if (session) { - channel = switch_core_session_get_channel(session); - } - - if (is_alarm) { - ERRORA("ALARM on interface %s: \n", GSMOPEN_P_LOG, tech_pvt->name); - status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ALARM); - } else { - DEBUGA_GSMOPEN("DUMP on interface %s: \n", GSMOPEN_P_LOG, tech_pvt->name); - status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_DUMP); - } - if (status == SWITCH_STATUS_SUCCESS) { - if (is_alarm) { - snprintf(value, sizeof(value) - 1, "%d", alarm_code); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm_code", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm_message", alarm_message); - } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_name", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_id", tech_pvt->id); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->active); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "active", value); - if (!tech_pvt->network_creg_not_supported) { - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->not_registered); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "not_registered", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->home_network_registered); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "home_network_registered", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->roaming_registered); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "roaming_registered", value); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "not_registered", "N/A"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "home_network_registered", "N/A"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "roaming_registered", "N/A"); - } - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->got_signal); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "got_signal", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->signal_strength); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "signal_strength", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->running); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "running", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subscriber_number", tech_pvt->subscriber_number); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device_manufacturer", tech_pvt->device_mfg); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device_model", tech_pvt->device_model); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device_firmware", tech_pvt->device_firmware); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "operator", tech_pvt->operator_name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imei", tech_pvt->imei); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imsi", tech_pvt->imsi); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->controldev_dead); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "controldev_dead", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "controldevice_name", tech_pvt->controldevice_name); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->no_sound); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "no_sound", value); - snprintf(value, sizeof(value) - 1, "%f", tech_pvt->playback_boost); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "playback_boost", value); - snprintf(value, sizeof(value) - 1, "%f", tech_pvt->capture_boost); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "capture_boost", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialplan", tech_pvt->dialplan); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", tech_pvt->context); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "destination", tech_pvt->destination); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ib_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ib_calls", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ob_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ob_calls", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ib_failed_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ib_failed_calls", value); - snprintf(value, sizeof(value) - 1, "%lu", tech_pvt->ob_failed_calls); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ob_failed_calls", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->interface_state); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_state", value); - snprintf(value, sizeof(value) - 1, "%d", tech_pvt->phone_callflow); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "phone_callflow", value); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "session_uuid_str", tech_pvt->session_uuid_str); - if (strlen(tech_pvt->session_uuid_str)) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true"); - } else { //no session - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false"); - } - if (channel) { - switch_channel_event_set_data(channel, event); - } - switch_event_fire(&event); - } else { - ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name); - } - - if (session) { - switch_core_session_rwunlock(session); - } - return 0; -} - -int dump_event(private_t *tech_pvt) -{ - return dump_event_full(tech_pvt, 0, 0, NULL); -} - -int alarm_event(private_t *tech_pvt, int alarm_code, const char *alarm_message) -{ - return dump_event_full(tech_pvt, 1, alarm_code, alarm_message); -} - -int sms_incoming(private_t *tech_pvt) -{ - switch_event_t *event; - - if (!tech_pvt) { - return -1; - } - NOTICA("received SMS on interface %s: DATE=%s, SENDER=%s, BODY=|%s|\n", GSMOPEN_P_LOG, tech_pvt->name, tech_pvt->sms_date, tech_pvt->sms_sender, - tech_pvt->sms_body); - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", GSMOPEN_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->sms_sender); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "date", tech_pvt->sms_date); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "userdataheader", tech_pvt->sms_userdataheader); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "datacodingscheme", tech_pvt->sms_datacodingscheme); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "servicecentreaddress", tech_pvt->sms_servicecentreaddress); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "messagetype", "%d", tech_pvt->sms_messagetype); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_proto", GSMOPEN_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", tech_pvt->sms_sender); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_user", tech_pvt->name); - switch_event_add_body(event, "%s\n", tech_pvt->sms_body); - switch_core_chat_send("GLOBAL", event); /* mod_sms */ - } else { - - ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name); - } - - memset(tech_pvt->sms_message, '\0', sizeof(tech_pvt->sms_message)); - memset(tech_pvt->sms_sender, '\0', sizeof(tech_pvt->sms_sender)); - memset(tech_pvt->sms_date, '\0', sizeof(tech_pvt->sms_date)); - memset(tech_pvt->sms_userdataheader, '\0', sizeof(tech_pvt->sms_userdataheader)); - memset(tech_pvt->sms_body, '\0', sizeof(tech_pvt->sms_body)); - memset(tech_pvt->sms_datacodingscheme, '\0', sizeof(tech_pvt->sms_datacodingscheme)); - memset(tech_pvt->sms_servicecentreaddress, '\0', sizeof(tech_pvt->sms_servicecentreaddress)); - - return 0; -} - -int ussd_incoming(private_t *tech_pvt) -{ - switch_event_t *event; - - DEBUGA_GSMOPEN("received USSD on interface %s: TEXT=%s|\n", GSMOPEN_P_LOG, tech_pvt->name, tech_pvt->ussd_message); - -/* mod_sms begin */ - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", GSMOPEN_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", "ussd"); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "date", tech_pvt->sms_date); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "datacodingscheme", tech_pvt->ussd_dcs); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "servicecentreaddress", tech_pvt->sms_servicecentreaddress); - //switch_event_add_header(event, SWITCH_STACK_BOTTOM, "messagetype", "%d", tech_pvt->sms_messagetype); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "USSD MESSAGE"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_proto", GSMOPEN_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", "ussd"); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_host", "from_host"); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", "from_full"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_user", tech_pvt->name); - //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_host", "to_host"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ussd_status", "%d", tech_pvt->ussd_status); - switch_event_add_body(event, "%s\n", tech_pvt->ussd_message); - //switch_core_chat_send("GLOBAL", event); /* mod_sms */ - switch_core_chat_send("GLOBAL", event); /* mod_sms */ - } else { - - ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name); - } - /* mod_sms end */ - - return 0; -} - -#ifndef WIN32 -#define PATH_MAX_GIOVA PATH_MAX -static struct { -char path_idvendor[PATH_MAX_GIOVA]; -char path_idproduct[PATH_MAX_GIOVA]; -char tty_base[PATH_MAX_GIOVA]; -char idvendor[PATH_MAX_GIOVA]; -char idproduct[PATH_MAX_GIOVA]; -char tty_data_dir[PATH_MAX_GIOVA]; -char tty_audio_dir[PATH_MAX_GIOVA]; -char data_dev_id[256]; -char audio_dev_id[256]; -char delimiter[256]; -char txt_saved[PATH_MAX_GIOVA]; -char tty_base_copied[PATH_MAX_GIOVA]; -char tty_data_device_file[PATH_MAX_GIOVA]; -char tty_data_device[256]; -char tty_audio_device_file[PATH_MAX_GIOVA]; -char tty_audio_device[256]; -char answer[AT_BUFSIZ]; -char imei[256]; -char imsi[256]; -} f; -/* -int times=0; -int conta=0; -*/ -void find_ttyusb_devices(private_t *tech_pvt, const char *dirname) -{ - DIR *dir; - struct dirent *entry; - - memset( f.path_idvendor, 0, sizeof(f.path_idvendor) ); - memset( f.path_idproduct, 0, sizeof(f.path_idproduct) ); - memset( f.tty_base, 0, sizeof(f.tty_base) ); - memset( f.idvendor, 0, sizeof(f.idvendor) ); - memset( f.idproduct, 0, sizeof(f.idproduct) ); - memset( f.tty_data_dir, 0, sizeof(f.tty_data_dir) ); - memset( f.tty_audio_dir, 0, sizeof(f.tty_audio_dir) ); - memset( f.data_dev_id, 0, sizeof(f.data_dev_id) ); - memset( f.audio_dev_id, 0, sizeof(f.audio_dev_id) ); - memset( f.delimiter, 0, sizeof(f.delimiter) ); - memset( f.txt_saved, 0, sizeof(f.txt_saved) ); - memset( f.tty_base_copied, 0, sizeof(f.tty_base_copied) ); - memset( f.tty_data_device_file, 0, sizeof(f.tty_data_device_file) ); - memset( f.tty_data_device, 0, sizeof(f.tty_data_device) ); - memset( f.tty_audio_device_file, 0, sizeof(f.tty_audio_device_file) ); - memset( f.tty_audio_device, 0, sizeof(f.tty_audio_device) ); - - if (!(dir = opendir(dirname))){ - ERRORA("ERRORA! dirname=%s\n", GSMOPEN_P_LOG, dirname); - closedir(dir); - //conta--; - return; - } - if (!(entry = readdir(dir))){ - ERRORA("ERRORA!\n", GSMOPEN_P_LOG); - closedir(dir); - //conta--; - return; - } - - //conta++; - do { - if (entry->d_type == DT_DIR) { - char path[PATH_MAX_GIOVA]; - int len; - - //times++; - len = snprintf(path, sizeof(path)-1, "%s/%s", dirname, entry->d_name); - path[len] = 0; - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - find_ttyusb_devices(tech_pvt, path); - } else{ - int fd=-1; - int len2=-1; - DIR *dir2=NULL; - struct dirent *entry2=NULL; - int counter; - char *scratch=NULL; - char *txt=NULL; - - if (strcmp(entry->d_name, "idVendor") == 0){ - sprintf(f.tty_base, "%s", dirname); - sprintf(f.path_idvendor, "%s/%s", dirname, entry->d_name); - sprintf(f.path_idproduct, "%s/idProduct", dirname); - - fd = open(f.path_idvendor, O_RDONLY); - len2=read(fd, f.idvendor, sizeof(f.idvendor)); - close(fd); - - if(f.idvendor[len2-1]=='\n'){ - f.idvendor[len2-1]='\0'; - } - if (strcmp(f.idvendor, "12d1") == 0){ - - fd = open(f.path_idproduct, O_RDONLY); - len2=read(fd, f.idproduct, sizeof(f.idproduct)); - close(fd); - - if(f.idproduct[len2-1]=='\n'){ - f.idproduct[len2-1]='\0'; - } - if (strcmp(f.idproduct, "1001") == 0 || strcmp(f.idproduct, "140c") == 0 || strcmp(f.idproduct, "1436") == 0 || strcmp(f.idproduct, "1506") == 0 || strcmp(f.idproduct, "14ac") == 0 ){ - if (strcmp(f.idproduct, "1001") == 0){ - strcpy(f.data_dev_id, "2"); - strcpy(f.audio_dev_id, "1"); - }else if (strcmp(f.idproduct, "140c") == 0){ - strcpy(f.data_dev_id, "3"); - strcpy(f.audio_dev_id, "2"); - }else if (strcmp(f.idproduct, "1436") == 0){ - strcpy(f.data_dev_id, "4"); - strcpy(f.audio_dev_id, "3"); - }else if (strcmp(f.idproduct, "1506") == 0){ - strcpy(f.data_dev_id, "1"); - strcpy(f.audio_dev_id, "2"); - }else if (strcmp(f.idproduct, "14ac") == 0){ - strcpy(f.data_dev_id, "4"); - strcpy(f.audio_dev_id, "3"); - }else{ - //not possible - } - strcpy(f.delimiter, "/"); - strcpy(f.tty_base_copied, f.tty_base); - counter=0; - while((txt = strtok_r(!counter ? f.tty_base_copied : NULL, f.delimiter, &scratch))) - { - strcpy(f.txt_saved, txt); - counter++; - } - sprintf(f.tty_data_dir, "%s/%s:1.%s", f.tty_base, f.txt_saved, f.data_dev_id); - sprintf(f.tty_audio_dir, "%s/%s:1.%s", f.tty_base, f.txt_saved, f.audio_dev_id); - - if (!(dir2 = opendir(f.tty_data_dir))) { - ERRORA("ERRORA!\n", GSMOPEN_P_LOG); - } - if (!(entry2 = readdir(dir2))){ - ERRORA("ERRORA!\n", GSMOPEN_P_LOG); - } - do { - if (strncmp(entry2->d_name, "ttyUSB", 6) == 0){ - //char f.answer[AT_BUFSIZ]; - ctb::SerialPort *serialPort_serial_control; - int res; - int read_count; - char at_command[256]; - - sprintf(f.tty_data_device_file, "%s/%s", f.tty_data_dir, entry2->d_name); - sprintf(f.tty_data_device, "/dev/%s", entry2->d_name); - - memset(f.answer,0,sizeof(f.answer)); - memset(f.imei,0,sizeof(f.imei)); - memset(f.imsi,0,sizeof(f.imsi)); - - serialPort_serial_control = new ctb::SerialPort(); - if (serialPort_serial_control->Open(f.tty_data_device, 115200, "8N1", ctb::SerialPort::NoFlowControl) >= 0) { - sprintf(at_command, "AT\r\n"); - res = serialPort_serial_control->Write(at_command, 4); - usleep(20000); //0.02 seconds - res = serialPort_serial_control->Write(at_command, 4); - usleep(20000); //0.02 seconds - sprintf(at_command, "ATE1\r\n"); - res = serialPort_serial_control->Write(at_command, 6); - usleep(20000); //0.02 seconds - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - sprintf(at_command, "AT\r\n"); - res = serialPort_serial_control->Write(at_command, 4); - usleep(20000); //0.02 seconds - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - memset(f.answer,0,sizeof(f.answer)); - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - memset(f.answer,0,sizeof(f.answer)); - - /* IMEI */ - sprintf(at_command, "AT+GSN\r\n"); - res = serialPort_serial_control->Write(at_command, 8); - if (res != 8) { - ERRORA("writing AT+GSN failed: %d\n", GSMOPEN_P_LOG, res); - }else { - usleep(200000); //0.2 seconds - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - if (read_count < 32) { - ERRORA("reading AT+GSN failed: |%s|, read_count=%d, probably harmless in 'gsm reload'\n", GSMOPEN_P_LOG, f.answer, read_count); - } else { - strncpy(f.imei, f.answer+9, 15); - sprintf(at_command, "AT\r\n"); - res = serialPort_serial_control->Write(at_command, 4); - usleep(20000); //0.02 seconds - res = serialPort_serial_control->Write(at_command, 4); - usleep(20000); //0.02 seconds - sprintf(at_command, "ATE1\r\n"); - res = serialPort_serial_control->Write(at_command, 6); - usleep(20000); //0.02 seconds - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - sprintf(at_command, "AT\r\n"); - res = serialPort_serial_control->Write(at_command, 4); - usleep(20000); //0.02 seconds - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - memset(f.answer,0,sizeof(f.answer)); - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - memset(f.answer,0,sizeof(f.answer)); - - /* IMSI */ - sprintf(at_command, "AT+CIMI\r\n"); - res = serialPort_serial_control->Write(at_command, 9); - if (res != 9) { - ERRORA("writing AT+CIMI failed: %d\n", GSMOPEN_P_LOG, res); - }else { - usleep(200000); //0.2 seconds - read_count = serialPort_serial_control->Read(f.answer, AT_BUFSIZ); - if (read_count < 33) { - ERRORA("reading AT+CIMI failed: |%s|, read_count=%d\n", GSMOPEN_P_LOG, f.answer, read_count); - } else { - strncpy(f.imsi, f.answer+10, 15); - } - } - } - } - res = serialPort_serial_control->Close(); - } else { - ERRORA("port %s, NOT open\n", GSMOPEN_P_LOG, f.tty_data_device); - } - } - } while ((entry2 = readdir(dir2))); - closedir(dir2); - - if (!(dir2 = opendir(f.tty_audio_dir))) { - ERRORA("ERRORA!\n", GSMOPEN_P_LOG); - } - if (!(entry2 = readdir(dir2))){ - ERRORA("ERRORA!\n", GSMOPEN_P_LOG); - } - do { - if (strncmp(entry2->d_name, "ttyUSB", 6) == 0){ - int i; - sprintf(f.tty_audio_device_file, "%s/%s", f.tty_audio_dir, entry2->d_name); - sprintf(f.tty_audio_device, "/dev/%s", entry2->d_name); - - NOTICA("************************************************\n", GSMOPEN_P_LOG, f.imei); - NOTICA("f.imei=|%s|\n", GSMOPEN_P_LOG, f.imei); - NOTICA("f.imsi=|%s|\n", GSMOPEN_P_LOG, f.imsi); - NOTICA("f.tty_data_device = |%s|\n", GSMOPEN_P_LOG, f.tty_data_device); - NOTICA("f.tty_audio_device = |%s|\n", GSMOPEN_P_LOG, f.tty_audio_device); - NOTICA("************************************************\n", GSMOPEN_P_LOG, f.imei); - - for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) { - switch_threadattr_t *gsmopen_api_thread_attr = NULL; - int res = 0; - int interface_id = i; - - if (strlen(globals.GSMOPEN_INTERFACES[i].name) && (strlen(globals.GSMOPEN_INTERFACES[i].imsi) || strlen(globals.GSMOPEN_INTERFACES[i].imei)) ) { - //NOTICA("globals.GSMOPEN_INTERFACES[i].imei)=%s strlen(globals.GSMOPEN_INTERFACES[i].imei)=%d (strcmp(globals.GSMOPEN_INTERFACES[i].imei, f.imei) == 0)=%d \n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].imei, strlen(globals.GSMOPEN_INTERFACES[i].imei), (strcmp(globals.GSMOPEN_INTERFACES[i].imei, f.imei) == 0) ); - if( ( strlen(globals.GSMOPEN_INTERFACES[i].imei) ? (strcmp(globals.GSMOPEN_INTERFACES[i].imei, f.imei) == 0) : 1) ) { - if ( (strlen(globals.GSMOPEN_INTERFACES[i].imsi) ? (strcmp(globals.GSMOPEN_INTERFACES[i].imsi, f.imsi) == 0) : 1) ){ - strcpy(globals.GSMOPEN_INTERFACES[i].controldevice_audio_name, f.tty_audio_device); - strcpy(globals.GSMOPEN_INTERFACES[i].controldevice_name, f.tty_data_device); - NOTICA("name = |%s|, controldevice_audio_name = |%s|, controldevice_name = |%s|\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].controldevice_audio_name, globals.GSMOPEN_INTERFACES[i].controldevice_name); - break; - } - } - } - } - } - } while ((entry2 = readdir(dir2))); - closedir(dir2); - } - } - } - } - } while ((entry = readdir(dir))); - closedir(dir); -/* - if(f.conta < 0){ - ERRORA("f.conta=%d, dirs=%d, mem=%d\n", GSMOPEN_P_LOG, conta, times, conta*PATH_MAX_GIOVA); - }else{ - NOTICA("f.conta=%d, dirs=%d, mem=%d\n", GSMOPEN_P_LOG, conta, times, conta*PATH_MAX_GIOVA); - } - conta--; -*/ -} -#endif// WIN32 - - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet expandtab: - */ diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv.c b/src/mod/endpoints/mod_gsmopen/win_iconv.c deleted file mode 100644 index e60f714889..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv.c +++ /dev/null @@ -1,1986 +0,0 @@ -/* - * iconv library using Win32 API to conversion. - * - * This file is placed in the public domain. - * - * Last Change: 2009-07-06 - * - * ENVIRONMENT VARIABLE: - * WINICONV_LIBICONV_DLL - * If $WINICONV_LIBICONV_DLL is set, win_iconv uses the DLL. If - * loading the DLL or iconv_open() failed, falls back to internal - * conversion. If a few DLL are specified as comma separated list, - * the first loadable DLL is used. The DLL should have iconv_open(), - * iconv_close() and iconv(). Or libiconv_open(), libiconv_close() - * and libiconv(). - * (only available when USE_LIBICONV_DLL is defined at compile time) - * - * Win32 API does not support strict encoding conversion for some - * codepage. And MLang function drop or replace invalid bytes and does - * not return useful error status as iconv. This implementation cannot - * be used for encoding validation purpose. - */ - -/* for WC_NO_BEST_FIT_CHARS */ -#ifndef WINVER -# define WINVER 0x0500 -#endif - -#include -#include -#include -#include - -#if 0 -# define MAKE_EXE -# define MAKE_DLL -# define USE_LIBICONV_DLL -#endif - -#if !defined(DEFAULT_LIBICONV_DLL) -# define DEFAULT_LIBICONV_DLL "" -#endif - -#define MB_CHAR_MAX 16 - -#define UNICODE_MODE_BOM_DONE 1 -#define UNICODE_MODE_SWAPPED 2 - -#define FLAG_USE_BOM 1 -#define FLAG_TRANSLIT 2 /* //TRANSLIT */ -#define FLAG_IGNORE 4 /* //IGNORE (not implemented) */ - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; - -typedef void* iconv_t; - -iconv_t iconv_open(const char *tocode, const char *fromcode); -int iconv_close(iconv_t cd); -size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - -/* libiconv interface for vim */ -#if defined(MAKE_DLL) -int -iconvctl (iconv_t cd, int request, void* argument) -{ - /* not supported */ - return 0; -} -#endif - -typedef struct compat_t compat_t; -typedef struct csconv_t csconv_t; -typedef struct rec_iconv_t rec_iconv_t; - -typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode); -typedef int (*f_iconv_close)(iconv_t cd); -typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); -typedef int* (*f_errno)(void); -typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize); -typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize); - -#define COMPAT_IN 1 -#define COMPAT_OUT 2 - -/* unicode mapping for compatibility with other conversion table. */ -struct compat_t { - uint in; - uint out; - uint flag; -}; - -struct csconv_t { - int codepage; - int flags; - f_mbtowc mbtowc; - f_wctomb wctomb; - f_mblen mblen; - f_flush flush; - DWORD mode; - compat_t *compat; -}; - -struct rec_iconv_t { - iconv_t cd; - f_iconv_close iconv_close; - f_iconv iconv; - f_errno _errno; - csconv_t from; - csconv_t to; -#if defined(USE_LIBICONV_DLL) - HMODULE hlibiconv; -#endif -}; - -static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); -static int win_iconv_close(iconv_t cd); -static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - -static int load_mlang(); -static int make_csconv(const char *name, csconv_t *cv); -static int name_to_codepage(const char *name); -static uint utf16_to_ucs4(const ushort *wbuf); -static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize); -static int mbtowc_flags(int codepage); -static int must_use_null_useddefaultchar(int codepage); -static char *strrstr(const char *str, const char *token); -static char *xstrndup(const char *s, size_t n); -static int seterror(int err); - -#if defined(USE_LIBICONV_DLL) -static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); -static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size); -static HMODULE find_imported_module_by_funcname(HMODULE hModule, const char *funcname); - -static HMODULE hwiniconv; -#endif - -static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize); - -static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize); - -static struct { - int codepage; - const char *name; -} codepage_alias[] = { - {65001, "CP65001"}, - {65001, "UTF8"}, - {65001, "UTF-8"}, - - {1200, "CP1200"}, - {1200, "UTF16LE"}, - {1200, "UTF-16LE"}, - {1200, "UCS-2LE"}, - - {1201, "CP1201"}, - {1201, "UTF16BE"}, - {1201, "UTF-16BE"}, - {1201, "UCS-2BE"}, - {1201, "unicodeFFFE"}, - - {12000, "CP12000"}, - {12000, "UTF32LE"}, - {12000, "UTF-32LE"}, - - {12001, "CP12001"}, - {12001, "UTF32BE"}, - {12001, "UTF-32BE"}, - -#ifndef GLIB_COMPILATION - /* - * Default is big endian. - * See rfc2781 4.3 Interpreting text labelled as UTF-16. - */ - {1201, "UTF16"}, - {1201, "UTF-16"}, - {12001, "UTF32"}, - {12001, "UTF-32"}, -#else - /* Default is little endian, because the platform is */ - {1200, "UTF16"}, - {1200, "UTF-16"}, - {1200, "UCS-2"}, - {12000, "UTF32"}, - {12000, "UTF-32"}, -#endif - - /* copy from libiconv `iconv -l` */ - /* !IsValidCodePage(367) */ - {20127, "ANSI_X3.4-1968"}, - {20127, "ANSI_X3.4-1986"}, - {20127, "ASCII"}, - {20127, "CP367"}, - {20127, "IBM367"}, - {20127, "ISO-IR-6"}, - {20127, "ISO646-US"}, - {20127, "ISO_646.IRV:1991"}, - {20127, "US"}, - {20127, "US-ASCII"}, - {20127, "CSASCII"}, - - /* !IsValidCodePage(819) */ - {1252, "CP819"}, - {1252, "IBM819"}, - {28591, "ISO-8859-1"}, - {28591, "ISO-IR-100"}, - {28591, "ISO8859-1"}, - {28591, "ISO_8859-1"}, - {28591, "ISO_8859-1:1987"}, - {28591, "L1"}, - {28591, "LATIN1"}, - {28591, "CSISOLATIN1"}, - - {1250, "CP1250"}, - {1250, "MS-EE"}, - {1250, "WINDOWS-1250"}, - - {1251, "CP1251"}, - {1251, "MS-CYRL"}, - {1251, "WINDOWS-1251"}, - - {1252, "CP1252"}, - {1252, "MS-ANSI"}, - {1252, "WINDOWS-1252"}, - - {1253, "CP1253"}, - {1253, "MS-GREEK"}, - {1253, "WINDOWS-1253"}, - - {1254, "CP1254"}, - {1254, "MS-TURK"}, - {1254, "WINDOWS-1254"}, - - {1255, "CP1255"}, - {1255, "MS-HEBR"}, - {1255, "WINDOWS-1255"}, - - {1256, "CP1256"}, - {1256, "MS-ARAB"}, - {1256, "WINDOWS-1256"}, - - {1257, "CP1257"}, - {1257, "WINBALTRIM"}, - {1257, "WINDOWS-1257"}, - - {1258, "CP1258"}, - {1258, "WINDOWS-1258"}, - - {850, "850"}, - {850, "CP850"}, - {850, "IBM850"}, - {850, "CSPC850MULTILINGUAL"}, - - /* !IsValidCodePage(862) */ - {862, "862"}, - {862, "CP862"}, - {862, "IBM862"}, - {862, "CSPC862LATINHEBREW"}, - - {866, "866"}, - {866, "CP866"}, - {866, "IBM866"}, - {866, "CSIBM866"}, - - /* !IsValidCodePage(154) */ - {154, "CP154"}, - {154, "CYRILLIC-ASIAN"}, - {154, "PT154"}, - {154, "PTCP154"}, - {154, "CSPTCP154"}, - - /* !IsValidCodePage(1133) */ - {1133, "CP1133"}, - {1133, "IBM-CP1133"}, - - {874, "CP874"}, - {874, "WINDOWS-874"}, - - /* !IsValidCodePage(51932) */ - {51932, "CP51932"}, - {51932, "MS51932"}, - {51932, "WINDOWS-51932"}, - {51932, "EUC-JP"}, - - {932, "CP932"}, - {932, "MS932"}, - {932, "SHIFFT_JIS"}, - {932, "SHIFFT_JIS-MS"}, - {932, "SJIS"}, - {932, "SJIS-MS"}, - {932, "SJIS-OPEN"}, - {932, "SJIS-WIN"}, - {932, "WINDOWS-31J"}, - {932, "WINDOWS-932"}, - {932, "CSWINDOWS31J"}, - - {50221, "CP50221"}, - {50221, "ISO-2022-JP"}, - {50221, "ISO-2022-JP-MS"}, - {50221, "ISO2022-JP"}, - {50221, "ISO2022-JP-MS"}, - {50221, "MS50221"}, - {50221, "WINDOWS-50221"}, - - {936, "CP936"}, - {936, "GBK"}, - {936, "MS936"}, - {936, "WINDOWS-936"}, - - {950, "CP950"}, - {950, "BIG5"}, - - {949, "CP949"}, - {949, "UHC"}, - {949, "EUC-KR"}, - - {1361, "CP1361"}, - {1361, "JOHAB"}, - - {437, "437"}, - {437, "CP437"}, - {437, "IBM437"}, - {437, "CSPC8CODEPAGE437"}, - - {737, "CP737"}, - - {775, "CP775"}, - {775, "IBM775"}, - {775, "CSPC775BALTIC"}, - - {852, "852"}, - {852, "CP852"}, - {852, "IBM852"}, - {852, "CSPCP852"}, - - /* !IsValidCodePage(853) */ - {853, "CP853"}, - - {855, "855"}, - {855, "CP855"}, - {855, "IBM855"}, - {855, "CSIBM855"}, - - {857, "857"}, - {857, "CP857"}, - {857, "IBM857"}, - {857, "CSIBM857"}, - - /* !IsValidCodePage(858) */ - {858, "CP858"}, - - {860, "860"}, - {860, "CP860"}, - {860, "IBM860"}, - {860, "CSIBM860"}, - - {861, "861"}, - {861, "CP-IS"}, - {861, "CP861"}, - {861, "IBM861"}, - {861, "CSIBM861"}, - - {863, "863"}, - {863, "CP863"}, - {863, "IBM863"}, - {863, "CSIBM863"}, - - {864, "CP864"}, - {864, "IBM864"}, - {864, "CSIBM864"}, - - {865, "865"}, - {865, "CP865"}, - {865, "IBM865"}, - {865, "CSIBM865"}, - - {869, "869"}, - {869, "CP-GR"}, - {869, "CP869"}, - {869, "IBM869"}, - {869, "CSIBM869"}, - - /* !IsValidCodePage(1152) */ - {1125, "CP1125"}, - - /* - * Code Page Identifiers - * http://msdn2.microsoft.com/en-us/library/ms776446.aspx - */ - {37, "IBM037"}, /* IBM EBCDIC US-Canada */ - {437, "IBM437"}, /* OEM United States */ - {500, "IBM500"}, /* IBM EBCDIC International */ - {708, "ASMO-708"}, /* Arabic (ASMO 708) */ - /* 709 Arabic (ASMO-449+, BCON V4) */ - /* 710 Arabic - Transparent Arabic */ - {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */ - {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */ - {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */ - {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */ - {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */ - {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */ - {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */ - {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */ - {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */ - {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */ - {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */ - {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */ - {864, "IBM864"}, /* OEM Arabic; Arabic (864) */ - {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */ - {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */ - {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */ - {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */ - {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */ - {875, "cp875"}, /* IBM EBCDIC Greek Modern */ - {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */ - {932, "shift-jis"}, /* alternative name for it */ - {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */ - {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */ - {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */ - {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */ - {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */ - {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */ - {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */ - {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */ - {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */ - {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */ - {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */ - {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */ - {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */ - {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */ - {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */ - {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */ - {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */ - {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */ - {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */ - {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */ - {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */ - {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */ - {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */ - {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */ - {1361, "Johab"}, /* Korean (Johab) */ - {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */ - {10001, "x-mac-japanese"}, /* Japanese (Mac) */ - {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */ - {10003, "x-mac-korean"}, /* Korean (Mac) */ - {10004, "x-mac-arabic"}, /* Arabic (Mac) */ - {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */ - {10006, "x-mac-greek"}, /* Greek (Mac) */ - {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */ - {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */ - {10010, "x-mac-romanian"}, /* Romanian (Mac) */ - {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */ - {10021, "x-mac-thai"}, /* Thai (Mac) */ - {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */ - {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */ - {10081, "x-mac-turkish"}, /* Turkish (Mac) */ - {10082, "x-mac-croatian"}, /* Croatian (Mac) */ - {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */ - {20001, "x-cp20001"}, /* TCA Taiwan */ - {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */ - {20003, "x-cp20003"}, /* IBM5550 Taiwan */ - {20004, "x-cp20004"}, /* TeleText Taiwan */ - {20005, "x-cp20005"}, /* Wang Taiwan */ - {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */ - {20106, "x-IA5-German"}, /* IA5 German (7-bit) */ - {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */ - {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */ - {20127, "us-ascii"}, /* US-ASCII (7-bit) */ - {20261, "x-cp20261"}, /* T.61 */ - {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */ - {20273, "IBM273"}, /* IBM EBCDIC Germany */ - {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */ - {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */ - {20280, "IBM280"}, /* IBM EBCDIC Italy */ - {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */ - {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */ - {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */ - {20297, "IBM297"}, /* IBM EBCDIC France */ - {20420, "IBM420"}, /* IBM EBCDIC Arabic */ - {20423, "IBM423"}, /* IBM EBCDIC Greek */ - {20424, "IBM424"}, /* IBM EBCDIC Hebrew */ - {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */ - {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */ - {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */ - {20871, "IBM871"}, /* IBM EBCDIC Icelandic */ - {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */ - {20905, "IBM905"}, /* IBM EBCDIC Turkish */ - {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */ - {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */ - {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */ - {20949, "x-cp20949"}, /* Korean Wansung */ - {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */ - /* 21027 (deprecated) */ - {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */ - {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ - {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ - {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ - {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ - {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */ - {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */ - {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */ - {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */ - {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */ - {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */ - {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */ - {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */ - {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */ - {28597, "iso8859-7"}, /* ISO 8859-7 Greek */ - {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ - {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ - {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */ - {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */ - {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */ - {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */ - {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */ - {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */ - {29001, "x-Europa"}, /* Europa 3 */ - {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ - {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ - {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */ - {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */ - {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */ - {50225, "iso-2022-kr"}, /* ISO 2022 Korean */ - {50225, "iso2022-kr"}, /* ISO 2022 Korean */ - {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */ - /* 50229 ISO 2022 Traditional Chinese */ - /* 50930 EBCDIC Japanese (Katakana) Extended */ - /* 50931 EBCDIC US-Canada and Japanese */ - /* 50933 EBCDIC Korean Extended and Korean */ - /* 50935 EBCDIC Simplified Chinese Extended and Simplified Chinese */ - /* 50936 EBCDIC Simplified Chinese */ - /* 50937 EBCDIC US-Canada and Traditional Chinese */ - /* 50939 EBCDIC Japanese (Latin) Extended and Japanese */ - {51932, "euc-jp"}, /* EUC Japanese */ - {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */ - {51949, "euc-kr"}, /* EUC Korean */ - /* 51950 EUC Traditional Chinese */ - {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */ - {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */ - {57002, "x-iscii-de"}, /* ISCII Devanagari */ - {57003, "x-iscii-be"}, /* ISCII Bengali */ - {57004, "x-iscii-ta"}, /* ISCII Tamil */ - {57005, "x-iscii-te"}, /* ISCII Telugu */ - {57006, "x-iscii-as"}, /* ISCII Assamese */ - {57007, "x-iscii-or"}, /* ISCII Oriya */ - {57008, "x-iscii-ka"}, /* ISCII Kannada */ - {57009, "x-iscii-ma"}, /* ISCII Malayalam */ - {57010, "x-iscii-gu"}, /* ISCII Gujarati */ - {57011, "x-iscii-pa"}, /* ISCII Punjabi */ - - {0, NULL} -}; - -/* - * SJIS SHIFTJIS table CP932 table - * ---- --------------------------- -------------------------------- - * 5C U+00A5 YEN SIGN U+005C REVERSE SOLIDUS - * 7E U+203E OVERLINE U+007E TILDE - * 815C U+2014 EM DASH U+2015 HORIZONTAL BAR - * 815F U+005C REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS - * 8160 U+301C WAVE DASH U+FF5E FULLWIDTH TILDE - * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO - * 817C U+2212 MINUS SIGN U+FF0D FULLWIDTH HYPHEN-MINUS - * 8191 U+00A2 CENT SIGN U+FFE0 FULLWIDTH CENT SIGN - * 8192 U+00A3 POUND SIGN U+FFE1 FULLWIDTH POUND SIGN - * 81CA U+00AC NOT SIGN U+FFE2 FULLWIDTH NOT SIGN - * - * EUC-JP and ISO-2022-JP should be compatible with CP932. - * - * Kernel and MLang have different Unicode mapping table. Make sure - * which API is used. - */ -static compat_t cp932_compat[] = { - {0x00A5, 0x005C, COMPAT_OUT}, - {0x203E, 0x007E, COMPAT_OUT}, - {0x2014, 0x2015, COMPAT_OUT}, - {0x301C, 0xFF5E, COMPAT_OUT}, - {0x2016, 0x2225, COMPAT_OUT}, - {0x2212, 0xFF0D, COMPAT_OUT}, - {0x00A2, 0xFFE0, COMPAT_OUT}, - {0x00A3, 0xFFE1, COMPAT_OUT}, - {0x00AC, 0xFFE2, COMPAT_OUT}, - {0, 0, 0} -}; - -static compat_t cp20932_compat[] = { - {0x00A5, 0x005C, COMPAT_OUT}, - {0x203E, 0x007E, COMPAT_OUT}, - {0x2014, 0x2015, COMPAT_OUT}, - {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN}, - {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN}, - {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN}, - {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN}, - {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN}, - {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN}, - {0, 0, 0} -}; - -static compat_t *cp51932_compat = cp932_compat; - -/* cp20932_compat for kernel. cp932_compat for mlang. */ -static compat_t *cp5022x_compat = cp932_compat; - -typedef HRESULT (WINAPI *CONVERTINETSTRING)( - LPDWORD lpdwMode, - DWORD dwSrcEncoding, - DWORD dwDstEncoding, - LPCSTR lpSrcStr, - LPINT lpnSrcSize, - LPBYTE lpDstStr, - LPINT lpnDstSize -); -typedef HRESULT (WINAPI *CONVERTINETMULTIBYTETOUNICODE)( - LPDWORD lpdwMode, - DWORD dwSrcEncoding, - LPCSTR lpSrcStr, - LPINT lpnMultiCharCount, - LPWSTR lpDstStr, - LPINT lpnWideCharCount -); -typedef HRESULT (WINAPI *CONVERTINETUNICODETOMULTIBYTE)( - LPDWORD lpdwMode, - DWORD dwEncoding, - LPCWSTR lpSrcStr, - LPINT lpnWideCharCount, - LPSTR lpDstStr, - LPINT lpnMultiCharCount -); -typedef HRESULT (WINAPI *ISCONVERTINETSTRINGAVAILABLE)( - DWORD dwSrcEncoding, - DWORD dwDstEncoding -); -typedef HRESULT (WINAPI *LCIDTORFC1766A)( - LCID Locale, - LPSTR pszRfc1766, - int nChar -); -typedef HRESULT (WINAPI *LCIDTORFC1766W)( - LCID Locale, - LPWSTR pszRfc1766, - int nChar -); -typedef HRESULT (WINAPI *RFC1766TOLCIDA)( - LCID *pLocale, - LPSTR pszRfc1766 -); -typedef HRESULT (WINAPI *RFC1766TOLCIDW)( - LCID *pLocale, - LPWSTR pszRfc1766 -); -static CONVERTINETSTRING ConvertINetString; -static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode; -static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte; -static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable; -static LCIDTORFC1766A LcidToRfc1766A; -static RFC1766TOLCIDA Rfc1766ToLcidA; - -static int -load_mlang() -{ - HMODULE h; - if (ConvertINetString != NULL) - return TRUE; - h = LoadLibrary("mlang.dll"); - if (!h) - return FALSE; - ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString"); - ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode"); - ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte"); - IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddress(h, "IsConvertINetStringAvailable"); - LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddress(h, "LcidToRfc1766A"); - Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddress(h, "Rfc1766ToLcidA"); - return TRUE; -} - -iconv_t -iconv_open(const char *tocode, const char *fromcode) -{ - rec_iconv_t *cd; - - cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t)); - if (cd == NULL) - return (iconv_t)(-1); - -#if defined(USE_LIBICONV_DLL) - errno = 0; - if (libiconv_iconv_open(cd, tocode, fromcode)) - return (iconv_t)cd; -#endif - - /* reset the errno to prevent reporting wrong error code. - * 0 for unsorted error. */ - errno = 0; - if (win_iconv_open(cd, tocode, fromcode)) - return (iconv_t)cd; - - free(cd); - - return (iconv_t)(-1); -} - -int -iconv_close(iconv_t _cd) -{ - rec_iconv_t *cd = (rec_iconv_t *)_cd; - int r = cd->iconv_close(cd->cd); - int e = *(cd->_errno()); -#if defined(USE_LIBICONV_DLL) - if (cd->hlibiconv != NULL) - FreeLibrary(cd->hlibiconv); -#endif - free(cd); - errno = e; - return r; -} - -size_t -iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) -{ - rec_iconv_t *cd = (rec_iconv_t *)_cd; - size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft); - errno = *(cd->_errno()); - return r; -} - -static int -win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) -{ - if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to)) - return FALSE; - cd->iconv_close = win_iconv_close; - cd->iconv = win_iconv; - cd->_errno = _errno; - cd->cd = (iconv_t)cd; - return TRUE; -} - -static int -win_iconv_close(iconv_t cd) -{ - return 0; -} - -static size_t -win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) -{ - rec_iconv_t *cd = (rec_iconv_t *)_cd; - ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */ - int insize; - int outsize; - int wsize; - DWORD frommode; - DWORD tomode; - uint wc; - compat_t *cp; - int i; - - if (inbuf == NULL || *inbuf == NULL) - { - if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL) - { - tomode = cd->to.mode; - outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft); - if (outsize == -1) - { - cd->to.mode = tomode; - return (size_t)(-1); - } - *outbuf += outsize; - *outbytesleft -= outsize; - } - cd->from.mode = 0; - cd->to.mode = 0; - return 0; - } - - while (*inbytesleft != 0) - { - frommode = cd->from.mode; - tomode = cd->to.mode; - wsize = MB_CHAR_MAX; - - insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize); - if (insize == -1) - { - cd->from.mode = frommode; - return (size_t)(-1); - } - - if (wsize == 0) - { - *inbuf += insize; - *inbytesleft -= insize; - continue; - } - - if (cd->from.compat != NULL) - { - wc = utf16_to_ucs4(wbuf); - cp = cd->from.compat; - for (i = 0; cp[i].in != 0; ++i) - { - if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc) - { - ucs4_to_utf16(cp[i].in, wbuf, &wsize); - break; - } - } - } - - if (cd->to.compat != NULL) - { - wc = utf16_to_ucs4(wbuf); - cp = cd->to.compat; - for (i = 0; cp[i].in != 0; ++i) - { - if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc) - { - ucs4_to_utf16(cp[i].out, wbuf, &wsize); - break; - } - } - } - - outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft); - if (outsize == -1) - { - cd->from.mode = frommode; - cd->to.mode = tomode; - return (size_t)(-1); - } - - *inbuf += insize; - *outbuf += outsize; - *inbytesleft -= insize; - *outbytesleft -= outsize; - } - - return 0; -} - -static int -make_csconv(const char *_name, csconv_t *cv) -{ - CPINFOEX cpinfoex; - int use_compat = TRUE; - int flag = 0; - char *name; - char *p; - - name = xstrndup(_name, strlen(_name)); - if (name == NULL) - return FALSE; - - /* check for option "enc_name//opt1//opt2" */ - while ((p = strrstr(name, "//")) != NULL) - { - if (_stricmp(p + 2, "nocompat") == 0) - use_compat = FALSE; - else if (_stricmp(p + 2, "translit") == 0) - flag |= FLAG_TRANSLIT; - else if (_stricmp(p + 2, "ignore") == 0) - flag |= FLAG_IGNORE; - *p = 0; - } - - cv->mode = 0; - cv->flags = flag; - cv->mblen = NULL; - cv->flush = NULL; - cv->compat = NULL; - cv->codepage = name_to_codepage(name); - if (cv->codepage == 1200 || cv->codepage == 1201) - { - cv->mbtowc = utf16_mbtowc; - cv->wctomb = utf16_wctomb; - if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0) - cv->flags |= FLAG_USE_BOM; - } - else if (cv->codepage == 12000 || cv->codepage == 12001) - { - cv->mbtowc = utf32_mbtowc; - cv->wctomb = utf32_wctomb; - if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0) - cv->flags |= FLAG_USE_BOM; - } - else if (cv->codepage == 65001) - { - cv->mbtowc = kernel_mbtowc; - cv->wctomb = kernel_wctomb; - cv->mblen = utf8_mblen; - } - else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang()) - { - cv->mbtowc = iso2022jp_mbtowc; - cv->wctomb = iso2022jp_wctomb; - cv->flush = iso2022jp_flush; - } - else if (cv->codepage == 51932 && load_mlang()) - { - cv->mbtowc = mlang_mbtowc; - cv->wctomb = mlang_wctomb; - cv->mblen = eucjp_mblen; - } - else if (IsValidCodePage(cv->codepage) - && GetCPInfoEx(cv->codepage, 0, &cpinfoex) != 0) - { - cv->mbtowc = kernel_mbtowc; - cv->wctomb = kernel_wctomb; - if (cpinfoex.MaxCharSize == 1) - cv->mblen = sbcs_mblen; - else if (cpinfoex.MaxCharSize == 2) - cv->mblen = dbcs_mblen; - else - cv->mblen = mbcs_mblen; - } - else - { - /* not supported */ - free(name); - errno = EINVAL; - return FALSE; - } - - if (use_compat) - { - switch (cv->codepage) - { - case 932: cv->compat = cp932_compat; break; - case 20932: cv->compat = cp20932_compat; break; - case 51932: cv->compat = cp51932_compat; break; - case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break; - } - } - - free(name); - - return TRUE; -} - -static int -name_to_codepage(const char *name) -{ - int i; - - if (*name == '\0' || - strcmp(name, "char") == 0) - return GetACP(); - else if (strcmp(name, "wchar_t") == 0) - return 1200; - else if (_strnicmp(name, "cp", 2) == 0) - return atoi(name + 2); /* CP123 */ - else if ('0' <= name[0] && name[0] <= '9') - return atoi(name); /* 123 */ - else if (_strnicmp(name, "xx", 2) == 0) - return atoi(name + 2); /* XX123 for debug */ - - for (i = 0; codepage_alias[i].name != NULL; ++i) - if (_stricmp(name, codepage_alias[i].name) == 0) - return codepage_alias[i].codepage; - return -1; -} - -/* - * http://www.faqs.org/rfcs/rfc2781.html - */ -static uint -utf16_to_ucs4(const ushort *wbuf) -{ - uint wc = wbuf[0]; - if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) - wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000; - return wc; -} - -static void -ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize) -{ - if (wc < 0x10000) - { - wbuf[0] = wc; - *wbufsize = 1; - } - else - { - wc -= 0x10000; - wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF); - wbuf[1] = 0xDC00 | (wc & 0x3FF); - *wbufsize = 2; - } -} - -/* - * Check if codepage is one of those for which the dwFlags parameter - * to MultiByteToWideChar() must be zero. Return zero or - * MB_ERR_INVALID_CHARS. The docs in Platform SDK for for Windows - * Server 2003 R2 claims that also codepage 65001 is one of these, but - * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave - * out 65001 (UTF-8), and that indeed seems to be the case on XP, it - * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting - * from UTF-8. - */ -static int -mbtowc_flags(int codepage) -{ - return (codepage == 50220 || codepage == 50221 || - codepage == 50222 || codepage == 50225 || - codepage == 50227 || codepage == 50229 || - codepage == 52936 || codepage == 54936 || - (codepage >= 57002 && codepage <= 57011) || - codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS; -} - -/* - * Check if codepage is one those for which the lpUsedDefaultChar - * parameter to WideCharToMultiByte() must be NULL. The docs in - * Platform SDK for for Windows Server 2003 R2 claims that this is the - * list below, while the MSDN docs for MSVS2008 claim that it is only - * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform - * SDK seems to be correct, at least for XP. - */ -static int -must_use_null_useddefaultchar(int codepage) -{ - return (codepage == 65000 || codepage == 65001 || - codepage == 50220 || codepage == 50221 || - codepage == 50222 || codepage == 50225 || - codepage == 50227 || codepage == 50229 || - codepage == 52936 || codepage == 54936 || - (codepage >= 57002 && codepage <= 57011) || - codepage == 42); -} - -static char * -strrstr(const char *str, const char *token) -{ - int len = strlen(token); - const char *p = str + strlen(str); - - while (str <= --p) - if (p[0] == token[0] && strncmp(p, token, len) == 0) - return (char *)p; - return NULL; -} - -static char * -xstrndup(const char *s, size_t n) -{ - char *p; - - p = (char *)malloc(n + 1); - if (p == NULL) - return NULL; - memcpy(p, s, n); - p[n] = '\0'; - return p; -} - -static int -seterror(int err) -{ - errno = err; - return -1; -} - -#if defined(USE_LIBICONV_DLL) -static int -libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) -{ - HMODULE hlibiconv = NULL; - HMODULE hmsvcrt = NULL; - char *dllname; - const char *p; - const char *e; - f_iconv_open _iconv_open; - - /* - * always try to load dll, so that we can switch dll in runtime. - */ - - /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */ - p = getenv("WINICONV_LIBICONV_DLL"); - if (p == NULL) - p = DEFAULT_LIBICONV_DLL; - /* parse comma separated value */ - for ( ; *p != 0; p = (*e == ',') ? e + 1 : e) - { - e = strchr(p, ','); - if (p == e) - continue; - else if (e == NULL) - e = p + strlen(p); - dllname = xstrndup(p, e - p); - if (dllname == NULL) - return FALSE; - hlibiconv = LoadLibrary(dllname); - free(dllname); - if (hlibiconv != NULL) - { - if (hlibiconv == hwiniconv) - { - FreeLibrary(hlibiconv); - hlibiconv = NULL; - continue; - } - break; - } - } - - if (hlibiconv == NULL) - goto failed; - - hmsvcrt = find_imported_module_by_funcname(hlibiconv, "_errno"); - if (hmsvcrt == NULL) - goto failed; - - _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "libiconv_open"); - if (_iconv_open == NULL) - _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "iconv_open"); - cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "libiconv_close"); - if (cd->iconv_close == NULL) - cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "iconv_close"); - cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "libiconv"); - if (cd->iconv == NULL) - cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "iconv"); - cd->_errno = (f_errno)GetProcAddress(hmsvcrt, "_errno"); - if (_iconv_open == NULL || cd->iconv_close == NULL - || cd->iconv == NULL || cd->_errno == NULL) - goto failed; - - cd->cd = _iconv_open(tocode, fromcode); - if (cd->cd == (iconv_t)(-1)) - goto failed; - - cd->hlibiconv = hlibiconv; - return TRUE; - -failed: - if (hlibiconv != NULL) - FreeLibrary(hlibiconv); - /* do not free hmsvcrt which is obtained by GetModuleHandle() */ - return FALSE; -} - -/* - * Reference: - * http://forums.belution.com/ja/vc/000/234/78s.shtml - * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html - * - * The formal way is - * imagehlp.h or dbghelp.h - * imagehlp.lib or dbghelp.lib - * ImageDirectoryEntryToData() - */ -#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base)) -#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew)) -static PVOID -MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size) -{ - /* TODO: MappedAsImage? */ - PIMAGE_DATA_DIRECTORY p; - p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry; - if (p->VirtualAddress == 0) { - *Size = 0; - return NULL; - } - *Size = p->Size; - return (PVOID)((LPBYTE)Base + p->VirtualAddress); -} - -static HMODULE -find_imported_module_by_funcname(HMODULE hModule, const char *funcname) -{ - DWORD Base; - ULONG Size; - PIMAGE_IMPORT_DESCRIPTOR Imp; - PIMAGE_THUNK_DATA Name; /* Import Name Table */ - PIMAGE_IMPORT_BY_NAME ImpName; - - Base = (DWORD)hModule; - Imp = MyImageDirectoryEntryToData( - (LPVOID)Base, - TRUE, - IMAGE_DIRECTORY_ENTRY_IMPORT, - &Size); - if (Imp == NULL) - return NULL; - for ( ; Imp->OriginalFirstThunk != 0; ++Imp) - { - Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk); - for ( ; Name->u1.Ordinal != 0; ++Name) - { - if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal)) - { - ImpName = (PIMAGE_IMPORT_BY_NAME) - (Base + (DWORD)Name->u1.AddressOfData); - if (strcmp((char *)ImpName->Name, funcname) == 0) - return GetModuleHandle((char *)(Base + Imp->Name)); - } - } - } - return NULL; -} -#endif - -static int -sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - return 1; -} - -static int -dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1; - if (bufsize < len) - return seterror(EINVAL); - return len; -} - -static int -mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - int len = 0; - - if (cv->codepage == 54936) { - if (buf[0] <= 0x7F) len = 1; - else if (buf[0] >= 0x81 && buf[0] <= 0xFE && - bufsize >= 2 && - ((buf[1] >= 0x40 && buf[1] <= 0x7E) || - (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2; - else if (buf[0] >= 0x81 && buf[0] <= 0xFE && - bufsize >= 4 && - buf[1] >= 0x30 && buf[1] <= 0x39) len = 4; - else - return seterror(EINVAL); - return len; - } - else - return seterror(EINVAL); -} - -static int -utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - int len = 0; - - if (buf[0] < 0x80) len = 1; - else if ((buf[0] & 0xE0) == 0xC0) len = 2; - else if ((buf[0] & 0xF0) == 0xE0) len = 3; - else if ((buf[0] & 0xF8) == 0xF0) len = 4; - else if ((buf[0] & 0xFC) == 0xF8) len = 5; - else if ((buf[0] & 0xFE) == 0xFC) len = 6; - - if (len == 0) - return seterror(EILSEQ); - else if (bufsize < len) - return seterror(EINVAL); - return len; -} - -static int -eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - if (buf[0] < 0x80) /* ASCII */ - return 1; - else if (buf[0] == 0x8E) /* JIS X 0201 */ - { - if (bufsize < 2) - return seterror(EINVAL); - else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF)) - return seterror(EILSEQ); - return 2; - } - else if (buf[0] == 0x8F) /* JIS X 0212 */ - { - if (bufsize < 3) - return seterror(EINVAL); - else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE) - || !(0xA1 <= buf[2] && buf[2] <= 0xFE)) - return seterror(EILSEQ); - return 3; - } - else /* JIS X 0208 */ - { - if (bufsize < 2) - return seterror(EINVAL); - else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE) - || !(0xA1 <= buf[1] && buf[1] <= 0xFE)) - return seterror(EILSEQ); - return 2; - } -} - -static int -kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int len; - - len = cv->mblen(cv, buf, bufsize); - if (len == -1) - return -1; - *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage), - (const char *)buf, len, (wchar_t *)wbuf, *wbufsize); - if (*wbufsize == 0) - return seterror(EILSEQ); - return len; -} - -static int -kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - BOOL usedDefaultChar = 0; - BOOL *p = NULL; - int flags = 0; - int len; - - if (bufsize == 0) - return seterror(E2BIG); - if (!must_use_null_useddefaultchar(cv->codepage)) - { - p = &usedDefaultChar; -#ifdef WC_NO_BEST_FIT_CHARS - if (!(cv->flags & FLAG_TRANSLIT)) - flags |= WC_NO_BEST_FIT_CHARS; -#endif - } - len = WideCharToMultiByte(cv->codepage, flags, - (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p); - if (len == 0) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - return seterror(E2BIG); - return seterror(EILSEQ); - } - else if (usedDefaultChar) - return seterror(EILSEQ); - else if (cv->mblen(cv, buf, len) != len) /* validate result */ - return seterror(EILSEQ); - return len; -} - -/* - * It seems that the mode (cv->mode) is fixnum. - * For example, when converting iso-2022-jp(cp50221) to unicode: - * in ascii sequence: mode=0xC42C0000 - * in jisx0208 sequence: mode=0xC42C0001 - * "C42C" is same for each convert session. - * It should be: ((codepage-1)<<16)|state - */ -static int -mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int len; - int insize; - HRESULT hr; - - len = cv->mblen(cv, buf, bufsize); - if (len == -1) - return -1; - insize = len; - hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage, - (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize); - if (hr != S_OK || insize != len) - return seterror(EILSEQ); - return len; -} - -static int -mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */ - int tmpsize = MB_CHAR_MAX; - int insize = wbufsize; - HRESULT hr; - - hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage, - (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize); - if (hr != S_OK || insize != wbufsize) - return seterror(EILSEQ); - else if (bufsize < tmpsize) - return seterror(E2BIG); - else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize) - return seterror(EILSEQ); - memcpy(buf, tmpbuf, tmpsize); - return tmpsize; -} - -static int -utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int codepage = cv->codepage; - - /* swap endian: 1200 <-> 1201 */ - if (cv->mode & UNICODE_MODE_SWAPPED) - codepage ^= 1; - - if (bufsize < 2) - return seterror(EINVAL); - if (codepage == 1200) /* little endian */ - wbuf[0] = (buf[1] << 8) | buf[0]; - else if (codepage == 1201) /* big endian */ - wbuf[0] = (buf[0] << 8) | buf[1]; - - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - cv->mode |= UNICODE_MODE_BOM_DONE; - if (wbuf[0] == 0xFFFE) - { - cv->mode |= UNICODE_MODE_SWAPPED; - *wbufsize = 0; - return 2; - } - else if (wbuf[0] == 0xFEFF) - { - *wbufsize = 0; - return 2; - } - } - - if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF) - return seterror(EILSEQ); - if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) - { - if (bufsize < 4) - return seterror(EINVAL); - if (codepage == 1200) /* little endian */ - wbuf[1] = (buf[3] << 8) | buf[2]; - else if (codepage == 1201) /* big endian */ - wbuf[1] = (buf[2] << 8) | buf[3]; - if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF)) - return seterror(EILSEQ); - *wbufsize = 2; - return 4; - } - *wbufsize = 1; - return 2; -} - -static int -utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - int r; - - cv->mode |= UNICODE_MODE_BOM_DONE; - if (bufsize < 2) - return seterror(E2BIG); - if (cv->codepage == 1200) /* little endian */ - memcpy(buf, "\xFF\xFE", 2); - else if (cv->codepage == 1201) /* big endian */ - memcpy(buf, "\xFE\xFF", 2); - - r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2); - if (r == -1) - return -1; - return r + 2; - } - - if (bufsize < 2) - return seterror(E2BIG); - if (cv->codepage == 1200) /* little endian */ - { - buf[0] = (wbuf[0] & 0x00FF); - buf[1] = (wbuf[0] & 0xFF00) >> 8; - } - else if (cv->codepage == 1201) /* big endian */ - { - buf[0] = (wbuf[0] & 0xFF00) >> 8; - buf[1] = (wbuf[0] & 0x00FF); - } - if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) - { - if (bufsize < 4) - return seterror(E2BIG); - if (cv->codepage == 1200) /* little endian */ - { - buf[2] = (wbuf[1] & 0x00FF); - buf[3] = (wbuf[1] & 0xFF00) >> 8; - } - else if (cv->codepage == 1201) /* big endian */ - { - buf[2] = (wbuf[1] & 0xFF00) >> 8; - buf[3] = (wbuf[1] & 0x00FF); - } - return 4; - } - return 2; -} - -static int -utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int codepage = cv->codepage; - uint wc = 0; - - /* swap endian: 12000 <-> 12001 */ - if (cv->mode & UNICODE_MODE_SWAPPED) - codepage ^= 1; - - if (bufsize < 4) - return seterror(EINVAL); - if (codepage == 12000) /* little endian */ - wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - else if (codepage == 12001) /* big endian */ - wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - cv->mode |= UNICODE_MODE_BOM_DONE; - if (wc == 0xFFFE0000) - { - cv->mode |= UNICODE_MODE_SWAPPED; - *wbufsize = 0; - return 4; - } - else if (wc == 0x0000FEFF) - { - *wbufsize = 0; - return 4; - } - } - - if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc) - return seterror(EILSEQ); - ucs4_to_utf16(wc, wbuf, wbufsize); - return 4; -} - -static int -utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - uint wc; - - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - int r; - - cv->mode |= UNICODE_MODE_BOM_DONE; - if (bufsize < 4) - return seterror(E2BIG); - if (cv->codepage == 12000) /* little endian */ - memcpy(buf, "\xFF\xFE\x00\x00", 4); - else if (cv->codepage == 12001) /* big endian */ - memcpy(buf, "\x00\x00\xFE\xFF", 4); - - r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4); - if (r == -1) - return -1; - return r + 4; - } - - if (bufsize < 4) - return seterror(E2BIG); - wc = utf16_to_ucs4(wbuf); - if (cv->codepage == 12000) /* little endian */ - { - buf[0] = wc & 0x000000FF; - buf[1] = (wc & 0x0000FF00) >> 8; - buf[2] = (wc & 0x00FF0000) >> 16; - buf[3] = (wc & 0xFF000000) >> 24; - } - else if (cv->codepage == 12001) /* big endian */ - { - buf[0] = (wc & 0xFF000000) >> 24; - buf[1] = (wc & 0x00FF0000) >> 16; - buf[2] = (wc & 0x0000FF00) >> 8; - buf[3] = wc & 0x000000FF; - } - return 4; -} - -/* - * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) - * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow - * 1 byte Kana) - * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte - * Kana - SO/SI) - * - * MultiByteToWideChar() and WideCharToMultiByte() behave differently - * depending on Windows version. On XP, WideCharToMultiByte() doesn't - * terminate result sequence with ascii escape. But Vista does. - * Use MLang instead. - */ - -#define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift)) -#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF) -#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF) - -#define ISO2022_SI 0 -#define ISO2022_SO 1 - -/* shift in */ -static const char iso2022_SI_seq[] = "\x0F"; -/* shift out */ -static const char iso2022_SO_seq[] = "\x0E"; - -typedef struct iso2022_esc_t iso2022_esc_t; -struct iso2022_esc_t { - const char *esc; - int esc_len; - int len; - int cs; -}; - -#define ISO2022JP_CS_ASCII 0 -#define ISO2022JP_CS_JISX0201_ROMAN 1 -#define ISO2022JP_CS_JISX0201_KANA 2 -#define ISO2022JP_CS_JISX0208_1978 3 -#define ISO2022JP_CS_JISX0208_1983 4 -#define ISO2022JP_CS_JISX0212 5 - -static iso2022_esc_t iso2022jp_esc[] = { - {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII}, - {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN}, - {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA}, - {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */ - {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983}, - {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212}, - {NULL, 0, 0, 0} -}; - -static int -iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - iso2022_esc_t *iesc = iso2022jp_esc; - char tmp[MB_CHAR_MAX]; - int insize; - HRESULT hr; - DWORD dummy = 0; - int len; - int esc_len; - int cs; - int shift; - int i; - - if (buf[0] == 0x1B) - { - for (i = 0; iesc[i].esc != NULL; ++i) - { - esc_len = iesc[i].esc_len; - if (bufsize < esc_len) - { - if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0) - return seterror(EINVAL); - } - else - { - if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0) - { - cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI); - *wbufsize = 0; - return esc_len; - } - } - } - /* not supported escape sequence */ - return seterror(EILSEQ); - } - else if (buf[0] == iso2022_SO_seq[0]) - { - cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SO); - *wbufsize = 0; - return 1; - } - else if (buf[0] == iso2022_SI_seq[0]) - { - cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SI); - *wbufsize = 0; - return 1; - } - - cs = ISO2022_MODE_CS(cv->mode); - shift = ISO2022_MODE_SHIFT(cv->mode); - - /* reset the mode for informal sequence */ - if (buf[0] < 0x20) - { - cs = ISO2022JP_CS_ASCII; - shift = ISO2022_SI; - } - - len = iesc[cs].len; - if (bufsize < len) - return seterror(EINVAL); - for (i = 0; i < len; ++i) - if (!(buf[i] < 0x80)) - return seterror(EILSEQ); - esc_len = iesc[cs].esc_len; - memcpy(tmp, iesc[cs].esc, esc_len); - if (shift == ISO2022_SO) - { - memcpy(tmp + esc_len, iso2022_SO_seq, 1); - esc_len += 1; - } - memcpy(tmp + esc_len, buf, len); - - if ((cv->codepage == 50220 || cv->codepage == 50221 - || cv->codepage == 50222) && shift == ISO2022_SO) - { - /* XXX: shift-out cannot be used for mbtowc (both kernel and - * mlang) */ - esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len; - memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len); - memcpy(tmp + esc_len, buf, len); - } - - insize = len + esc_len; - hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage, - (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize); - if (hr != S_OK || insize != len + esc_len) - return seterror(EILSEQ); - - /* Check for conversion error. Assuming defaultChar is 0x3F. */ - /* ascii should be converted from ascii */ - if (wbuf[0] == buf[0] - && cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) - return seterror(EILSEQ); - - /* reset the mode for informal sequence */ - if (cv->mode != ISO2022_MODE(cs, shift)) - cv->mode = ISO2022_MODE(cs, shift); - - return len; -} - -static int -iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - iso2022_esc_t *iesc = iso2022jp_esc; - char tmp[MB_CHAR_MAX]; - int tmpsize = MB_CHAR_MAX; - int insize = wbufsize; - HRESULT hr; - DWORD dummy = 0; - int len; - int esc_len = 0; - int cs = 0; - int shift; - int i; - - /* - * MultiByte = [escape sequence] + character + [escape sequence] - * - * Whether trailing escape sequence is added depends on which API is - * used (kernel or MLang, and its version). - */ - hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage, - (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize); - if (hr != S_OK || insize != wbufsize) - return seterror(EILSEQ); - else if (bufsize < tmpsize) - return seterror(E2BIG); - - if (tmpsize == 1) - { - cs = ISO2022JP_CS_ASCII; - esc_len = 0; - } - else - { - for (i = 1; iesc[i].esc != NULL; ++i) - { - esc_len = iesc[i].esc_len; - if (strncmp(tmp, iesc[i].esc, esc_len) == 0) - { - cs = iesc[i].cs; - break; - } - } - if (iesc[i].esc == NULL) - /* not supported escape sequence */ - return seterror(EILSEQ); - } - - shift = ISO2022_SI; - if (tmp[esc_len] == iso2022_SO_seq[0]) - { - shift = ISO2022_SO; - esc_len += 1; - } - - len = iesc[cs].len; - - /* Check for converting error. Assuming defaultChar is 0x3F. */ - /* ascii should be converted from ascii */ - if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80)) - return seterror(EILSEQ); - else if (tmpsize < esc_len + len) - return seterror(EILSEQ); - - if (cv->mode == ISO2022_MODE(cs, shift)) - { - /* remove escape sequence */ - if (esc_len != 0) - memmove(tmp, tmp + esc_len, len); - esc_len = 0; - } - else - { - if (cs == ISO2022JP_CS_ASCII) - { - esc_len = iesc[ISO2022JP_CS_ASCII].esc_len; - memmove(tmp + esc_len, tmp, len); - memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len); - } - if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO) - { - /* shift-in before changing to other mode */ - memmove(tmp + 1, tmp, len + esc_len); - memcpy(tmp, iso2022_SI_seq, 1); - esc_len += 1; - } - } - - if (bufsize < len + esc_len) - return seterror(E2BIG); - memcpy(buf, tmp, len + esc_len); - cv->mode = ISO2022_MODE(cs, shift); - return len + esc_len; -} - -static int -iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize) -{ - iso2022_esc_t *iesc = iso2022jp_esc; - int esc_len; - - if (cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) - { - esc_len = 0; - if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) - esc_len += 1; - if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) - esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; - if (bufsize < esc_len) - return seterror(E2BIG); - - esc_len = 0; - if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) - { - memcpy(buf, iso2022_SI_seq, 1); - esc_len += 1; - } - if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) - { - memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc, - iesc[ISO2022JP_CS_ASCII].esc_len); - esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; - } - return esc_len; - } - return 0; -} - -#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL) -BOOL WINAPI -DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) -{ - switch( fdwReason ) - { - case DLL_PROCESS_ATTACH: - hwiniconv = (HMODULE)hinstDLL; - break; - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} -#endif - -#if defined(MAKE_EXE) -#include -#include -#include -int -main(int argc, char **argv) -{ - char *fromcode = NULL; - char *tocode = NULL; - int i; - char inbuf[BUFSIZ]; - char outbuf[BUFSIZ]; - const char *pin; - char *pout; - size_t inbytesleft; - size_t outbytesleft; - size_t rest = 0; - iconv_t cd; - size_t r; - FILE *in = stdin; - - _setmode(_fileno(stdin), _O_BINARY); - _setmode(_fileno(stdout), _O_BINARY); - - for (i = 1; i < argc; ++i) - { - if (strcmp(argv[i], "-l") == 0) - { - for (i = 0; codepage_alias[i].name != NULL; ++i) - printf("%s\n", codepage_alias[i].name); - return 0; - } - - if (strcmp(argv[i], "-f") == 0) - fromcode = argv[++i]; - else if (strcmp(argv[i], "-t") == 0) - tocode = argv[++i]; - else - { - in = fopen(argv[i], "rb"); - if (in == NULL) - { - fprintf(stderr, "cannot open %s\n", argv[i]); - return 1; - } - break; - } - } - - if (fromcode == NULL || tocode == NULL) - { - printf("usage: %s -f from-enc -t to-enc [file]\n", argv[0]); - return 0; - } - - cd = iconv_open(tocode, fromcode); - if (cd == (iconv_t)(-1)) - { - perror("iconv_open error"); - return 1; - } - - while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0 - || rest != 0) - { - inbytesleft += rest; - pin = inbuf; - pout = outbuf; - outbytesleft = sizeof(outbuf); - r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft); - fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout); - if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in))) - { - perror("conversion error"); - return 1; - } - memmove(inbuf, pin, inbytesleft); - rest = inbytesleft; - } - pout = outbuf; - outbytesleft = sizeof(outbuf); - r = iconv(cd, NULL, NULL, &pout, &outbytesleft); - fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout); - if (r == (size_t)(-1)) - { - perror("conversion error"); - return 1; - } - - iconv_close(cd); - - return 0; -} -#endif - diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/Makefile b/src/mod/endpoints/mod_gsmopen/win_iconv/Makefile deleted file mode 100644 index c0969f607f..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/Makefile +++ /dev/null @@ -1,72 +0,0 @@ - -# comma separated list (e.g. "iconv.dll,libiconv.dll") -DEFAULT_LIBICONV_DLL ?= \"\" - -CFLAGS += -pedantic -Wall -CFLAGS += -DUSE_LIBICONV_DLL -CFLAGS += -DDEFAULT_LIBICONV_DLL=$(DEFAULT_LIBICONV_DLL) - -all: iconv.dll libiconv.a win_iconv.exe - -dist: test win_iconv.zip - -iconv.dll: win_iconv.c - gcc $(CFLAGS) -c win_iconv.c -DMAKE_DLL - dllwrap --dllname iconv.dll --def iconv.def win_iconv.o $(SPECS_FLAGS) - strip iconv.dll - -libiconv.a: win_iconv.c - gcc $(CFLAGS) -c win_iconv.c - ar rcs libiconv.a win_iconv.o - ranlib libiconv.a - -win_iconv.exe: win_iconv.c - gcc $(CFLAGS) -s -o win_iconv.exe win_iconv.c -DMAKE_EXE - -libmlang.a: mlang.def - dlltool --kill-at --input-def mlang.def --output-lib libmlang.a - -test: - gcc $(CFLAGS) -s -o win_iconv_test.exe win_iconv_test.c - ./win_iconv_test.exe - -win_iconv.zip: msvcrt msvcr70 msvcr71 - rm -rf win_iconv - svn export . win_iconv - cp msvcrt/iconv.dll msvcrt/win_iconv.exe win_iconv/ - mkdir win_iconv/msvcr70 - cp msvcr70/iconv.dll win_iconv/msvcr70/ - mkdir win_iconv/msvcr71 - cp msvcr71/iconv.dll win_iconv/msvcr71/ - zip -r win_iconv.zip win_iconv - -msvcrt: - svn export . msvcrt; \ - cd msvcrt; \ - $(MAKE); - -msvcr70: - svn export . msvcr70; \ - cd msvcr70; \ - gcc -dumpspecs | sed s/-lmsvcrt/-lmsvcr70/ > specs; \ - $(MAKE) "SPECS_FLAGS=-specs=$$PWD/specs"; - -msvcr71: - svn export . msvcr71; \ - cd msvcr71; \ - gcc -dumpspecs | sed s/-lmsvcrt/-lmsvcr71/ > specs; \ - $(MAKE) "SPECS_FLAGS=-specs=$$PWD/specs"; - -clean: - rm -f win_iconv.exe - rm -f win_iconv.o - rm -f iconv.dll - rm -f libiconv.a - rm -f win_iconv_test.exe - rm -f libmlang.a - rm -rf win_iconv - rm -rf win_iconv.zip - rm -rf msvcrt - rm -rf msvcr70 - rm -rf msvcr71 - diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/iconv.def b/src/mod/endpoints/mod_gsmopen/win_iconv/iconv.def deleted file mode 100644 index f609c86a59..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/iconv.def +++ /dev/null @@ -1,24 +0,0 @@ -LIBRARY ICONV.DLL -EXPORTS - iconv - iconv_open - iconv_close - iconvctl - libiconv=iconv - libiconv_open=iconv_open - libiconv_close=iconv_close - libiconvctl=iconvctl -;; libiconv-1.11.dll -;; TODO for binary compatibility -; _libiconv_version @1 -; aliases2_lookup @2 -; aliases_lookup @3 -; iconv_canonicalize @4 -; libiconv @5 -; libiconv_close @6 -; libiconv_open @7 -; libiconv_relocate @8 -; libiconv_set_relocation_prefix @9 -; libiconvctl @10 -; libiconvlist @11 -; locale_charset @12 diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/iconv.h b/src/mod/endpoints/mod_gsmopen/win_iconv/iconv.h deleted file mode 100644 index 455be3b6b7..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/iconv.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -typedef void* iconv_t; -iconv_t iconv_open(const char *tocode, const char *fromcode); -int iconv_close(iconv_t cd); -size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/mlang.def b/src/mod/endpoints/mod_gsmopen/win_iconv/mlang.def deleted file mode 100644 index cb475aeea8..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/mlang.def +++ /dev/null @@ -1,11 +0,0 @@ -LIBRARY MLANG.DLL -EXPORTS - ConvertINetMultiByteToUnicode@24 - ;; ConvertINetReset (not documented) - ConvertINetString@28 - ConvertINetUnicodeToMultiByte@24 - IsConvertINetStringAvailable@8 - LcidToRfc1766A@12 - LcidToRfc1766W@12 - Rfc1766ToLcidA@8 - Rfc1766ToLcidW@8 diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/mlang.h b/src/mod/endpoints/mod_gsmopen/win_iconv/mlang.h deleted file mode 100644 index 5cbf779c92..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/mlang.h +++ /dev/null @@ -1,54 +0,0 @@ -HRESULT WINAPI ConvertINetString( - LPDWORD lpdwMode, - DWORD dwSrcEncoding, - DWORD dwDstEncoding, - LPCSTR lpSrcStr, - LPINT lpnSrcSize, - LPBYTE lpDstStr, - LPINT lpnDstSize -); - -HRESULT WINAPI ConvertINetMultiByteToUnicode( - LPDWORD lpdwMode, - DWORD dwSrcEncoding, - LPCSTR lpSrcStr, - LPINT lpnMultiCharCount, - LPWSTR lpDstStr, - LPINT lpnWideCharCount -); - -HRESULT WINAPI ConvertINetUnicodeToMultiByte( - LPDWORD lpdwMode, - DWORD dwEncoding, - LPCWSTR lpSrcStr, - LPINT lpnWideCharCount, - LPSTR lpDstStr, - LPINT lpnMultiCharCount -); - -HRESULT WINAPI IsConvertINetStringAvailable( - DWORD dwSrcEncoding, - DWORD dwDstEncoding -); - -HRESULT WINAPI LcidToRfc1766A( - LCID Locale, - LPSTR pszRfc1766, - int nChar -); - -HRESULT WINAPI LcidToRfc1766W( - LCID Locale, - LPWSTR pszRfc1766, - int nChar -); - -HRESULT WINAPI Rfc1766ToLcidA( - LCID *pLocale, - LPSTR pszRfc1766 -); - -HRESULT WINAPI Rfc1766ToLcidW( - LCID *pLocale, - LPWSTR pszRfc1766 -); diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/readme.txt b/src/mod/endpoints/mod_gsmopen/win_iconv/readme.txt deleted file mode 100644 index 31f423dc75..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -win_iconv is a iconv library using Win32 API to conversion. -win_iconv is placed in the public domain. -Yukihiro Nakadaira diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv.c b/src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv.c deleted file mode 100644 index 7a3eda3e10..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv.c +++ /dev/null @@ -1,1986 +0,0 @@ -/* - * iconv library using Win32 API to conversion. - * - * This file is placed in the public domain. - * - * Last Change: 2009-07-06 - * - * ENVIRONMENT VARIABLE: - * WINICONV_LIBICONV_DLL - * If $WINICONV_LIBICONV_DLL is set, win_iconv uses the DLL. If - * loading the DLL or iconv_open() failed, falls back to internal - * conversion. If a few DLL are specified as comma separated list, - * the first loadable DLL is used. The DLL should have iconv_open(), - * iconv_close() and iconv(). Or libiconv_open(), libiconv_close() - * and libiconv(). - * (only available when USE_LIBICONV_DLL is defined at compile time) - * - * Win32 API does not support strict encoding conversion for some - * codepage. And MLang function drop or replace invalid bytes and does - * not return useful error status as iconv. This implementation cannot - * be used for encoding validation purpose. - */ - -/* for WC_NO_BEST_FIT_CHARS */ -#ifndef WINVER -# define WINVER 0x0500 -#endif - -#include -#include -#include -#include - -#if 0 -# define MAKE_EXE -# define MAKE_DLL -# define USE_LIBICONV_DLL -#endif - -#if !defined(DEFAULT_LIBICONV_DLL) -# define DEFAULT_LIBICONV_DLL "" -#endif - -#define MB_CHAR_MAX 16 - -#define UNICODE_MODE_BOM_DONE 1 -#define UNICODE_MODE_SWAPPED 2 - -#define FLAG_USE_BOM 1 -#define FLAG_TRANSLIT 2 /* //TRANSLIT */ -#define FLAG_IGNORE 4 /* //IGNORE (not implemented) */ - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; - -typedef void* iconv_t; - -iconv_t iconv_open(const char *tocode, const char *fromcode); -int iconv_close(iconv_t cd); -size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - -/* libiconv interface for vim */ -#if defined(MAKE_DLL) -int -iconvctl (iconv_t cd, int request, void* argument) -{ - /* not supported */ - return 0; -} -#endif - -typedef struct compat_t compat_t; -typedef struct csconv_t csconv_t; -typedef struct rec_iconv_t rec_iconv_t; - -typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode); -typedef int (*f_iconv_close)(iconv_t cd); -typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); -typedef int* (*f_errno)(void); -typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize); -typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize); - -#define COMPAT_IN 1 -#define COMPAT_OUT 2 - -/* unicode mapping for compatibility with other conversion table. */ -struct compat_t { - uint in; - uint out; - uint flag; -}; - -struct csconv_t { - int codepage; - int flags; - f_mbtowc mbtowc; - f_wctomb wctomb; - f_mblen mblen; - f_flush flush; - DWORD mode; - compat_t *compat; -}; - -struct rec_iconv_t { - iconv_t cd; - f_iconv_close iconv_close; - f_iconv iconv; - f_errno _errno; - csconv_t from; - csconv_t to; -#if defined(USE_LIBICONV_DLL) - HMODULE hlibiconv; -#endif -}; - -static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); -static int win_iconv_close(iconv_t cd); -static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - -static int load_mlang(); -static int make_csconv(const char *name, csconv_t *cv); -static int name_to_codepage(const char *name); -static uint utf16_to_ucs4(const ushort *wbuf); -static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize); -static int mbtowc_flags(int codepage); -static int must_use_null_useddefaultchar(int codepage); -static char *strrstr(const char *str, const char *token); -static char *xstrndup(const char *s, size_t n); -static int seterror(int err); - -#if defined(USE_LIBICONV_DLL) -static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); -static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size); -static HMODULE find_imported_module_by_funcname(HMODULE hModule, const char *funcname); - -static HMODULE hwiniconv; -#endif - -static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize); -static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize); - -static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); -static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); -static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize); - -static struct { - int codepage; - const char *name; -} codepage_alias[] = { - {65001, "CP65001"}, - {65001, "UTF8"}, - {65001, "UTF-8"}, - - {1200, "CP1200"}, - {1200, "UTF16LE"}, - {1200, "UTF-16LE"}, - {1200, "UCS-2LE"}, - - {1201, "CP1201"}, - {1201, "UTF16BE"}, - {1201, "UTF-16BE"}, - {1201, "UCS-2BE"}, - {1201, "unicodeFFFE"}, - - {12000, "CP12000"}, - {12000, "UTF32LE"}, - {12000, "UTF-32LE"}, - - {12001, "CP12001"}, - {12001, "UTF32BE"}, - {12001, "UTF-32BE"}, - -#ifndef GLIB_COMPILATION - /* - * Default is big endian. - * See rfc2781 4.3 Interpreting text labelled as UTF-16. - */ - {1201, "UTF16"}, - {1201, "UTF-16"}, - {12001, "UTF32"}, - {12001, "UTF-32"}, -#else - /* Default is little endian, because the platform is */ - {1200, "UTF16"}, - {1200, "UTF-16"}, - {1200, "UCS-2"}, - {12000, "UTF32"}, - {12000, "UTF-32"}, -#endif - - /* copy from libiconv `iconv -l` */ - /* !IsValidCodePage(367) */ - {20127, "ANSI_X3.4-1968"}, - {20127, "ANSI_X3.4-1986"}, - {20127, "ASCII"}, - {20127, "CP367"}, - {20127, "IBM367"}, - {20127, "ISO-IR-6"}, - {20127, "ISO646-US"}, - {20127, "ISO_646.IRV:1991"}, - {20127, "US"}, - {20127, "US-ASCII"}, - {20127, "CSASCII"}, - - /* !IsValidCodePage(819) */ - {1252, "CP819"}, - {1252, "IBM819"}, - {28591, "ISO-8859-1"}, - {28591, "ISO-IR-100"}, - {28591, "ISO8859-1"}, - {28591, "ISO_8859-1"}, - {28591, "ISO_8859-1:1987"}, - {28591, "L1"}, - {28591, "LATIN1"}, - {28591, "CSISOLATIN1"}, - - {1250, "CP1250"}, - {1250, "MS-EE"}, - {1250, "WINDOWS-1250"}, - - {1251, "CP1251"}, - {1251, "MS-CYRL"}, - {1251, "WINDOWS-1251"}, - - {1252, "CP1252"}, - {1252, "MS-ANSI"}, - {1252, "WINDOWS-1252"}, - - {1253, "CP1253"}, - {1253, "MS-GREEK"}, - {1253, "WINDOWS-1253"}, - - {1254, "CP1254"}, - {1254, "MS-TURK"}, - {1254, "WINDOWS-1254"}, - - {1255, "CP1255"}, - {1255, "MS-HEBR"}, - {1255, "WINDOWS-1255"}, - - {1256, "CP1256"}, - {1256, "MS-ARAB"}, - {1256, "WINDOWS-1256"}, - - {1257, "CP1257"}, - {1257, "WINBALTRIM"}, - {1257, "WINDOWS-1257"}, - - {1258, "CP1258"}, - {1258, "WINDOWS-1258"}, - - {850, "850"}, - {850, "CP850"}, - {850, "IBM850"}, - {850, "CSPC850MULTILINGUAL"}, - - /* !IsValidCodePage(862) */ - {862, "862"}, - {862, "CP862"}, - {862, "IBM862"}, - {862, "CSPC862LATINHEBREW"}, - - {866, "866"}, - {866, "CP866"}, - {866, "IBM866"}, - {866, "CSIBM866"}, - - /* !IsValidCodePage(154) */ - {154, "CP154"}, - {154, "CYRILLIC-ASIAN"}, - {154, "PT154"}, - {154, "PTCP154"}, - {154, "CSPTCP154"}, - - /* !IsValidCodePage(1133) */ - {1133, "CP1133"}, - {1133, "IBM-CP1133"}, - - {874, "CP874"}, - {874, "WINDOWS-874"}, - - /* !IsValidCodePage(51932) */ - {51932, "CP51932"}, - {51932, "MS51932"}, - {51932, "WINDOWS-51932"}, - {51932, "EUC-JP"}, - - {932, "CP932"}, - {932, "MS932"}, - {932, "SHIFFT_JIS"}, - {932, "SHIFFT_JIS-MS"}, - {932, "SJIS"}, - {932, "SJIS-MS"}, - {932, "SJIS-OPEN"}, - {932, "SJIS-WIN"}, - {932, "WINDOWS-31J"}, - {932, "WINDOWS-932"}, - {932, "CSWINDOWS31J"}, - - {50221, "CP50221"}, - {50221, "ISO-2022-JP"}, - {50221, "ISO-2022-JP-MS"}, - {50221, "ISO2022-JP"}, - {50221, "ISO2022-JP-MS"}, - {50221, "MS50221"}, - {50221, "WINDOWS-50221"}, - - {936, "CP936"}, - {936, "GBK"}, - {936, "MS936"}, - {936, "WINDOWS-936"}, - - {950, "CP950"}, - {950, "BIG5"}, - - {949, "CP949"}, - {949, "UHC"}, - {949, "EUC-KR"}, - - {1361, "CP1361"}, - {1361, "JOHAB"}, - - {437, "437"}, - {437, "CP437"}, - {437, "IBM437"}, - {437, "CSPC8CODEPAGE437"}, - - {737, "CP737"}, - - {775, "CP775"}, - {775, "IBM775"}, - {775, "CSPC775BALTIC"}, - - {852, "852"}, - {852, "CP852"}, - {852, "IBM852"}, - {852, "CSPCP852"}, - - /* !IsValidCodePage(853) */ - {853, "CP853"}, - - {855, "855"}, - {855, "CP855"}, - {855, "IBM855"}, - {855, "CSIBM855"}, - - {857, "857"}, - {857, "CP857"}, - {857, "IBM857"}, - {857, "CSIBM857"}, - - /* !IsValidCodePage(858) */ - {858, "CP858"}, - - {860, "860"}, - {860, "CP860"}, - {860, "IBM860"}, - {860, "CSIBM860"}, - - {861, "861"}, - {861, "CP-IS"}, - {861, "CP861"}, - {861, "IBM861"}, - {861, "CSIBM861"}, - - {863, "863"}, - {863, "CP863"}, - {863, "IBM863"}, - {863, "CSIBM863"}, - - {864, "CP864"}, - {864, "IBM864"}, - {864, "CSIBM864"}, - - {865, "865"}, - {865, "CP865"}, - {865, "IBM865"}, - {865, "CSIBM865"}, - - {869, "869"}, - {869, "CP-GR"}, - {869, "CP869"}, - {869, "IBM869"}, - {869, "CSIBM869"}, - - /* !IsValidCodePage(1152) */ - {1125, "CP1125"}, - - /* - * Code Page Identifiers - * http://msdn2.microsoft.com/en-us/library/ms776446.aspx - */ - {37, "IBM037"}, /* IBM EBCDIC US-Canada */ - {437, "IBM437"}, /* OEM United States */ - {500, "IBM500"}, /* IBM EBCDIC International */ - {708, "ASMO-708"}, /* Arabic (ASMO 708) */ - /* 709 Arabic (ASMO-449+, BCON V4) */ - /* 710 Arabic - Transparent Arabic */ - {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */ - {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */ - {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */ - {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */ - {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */ - {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */ - {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */ - {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */ - {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */ - {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */ - {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */ - {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */ - {864, "IBM864"}, /* OEM Arabic; Arabic (864) */ - {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */ - {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */ - {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */ - {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */ - {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */ - {875, "cp875"}, /* IBM EBCDIC Greek Modern */ - {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */ - {932, "shift-jis"}, /* alternative name for it */ - {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */ - {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */ - {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */ - {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */ - {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */ - {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */ - {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */ - {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */ - {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */ - {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */ - {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */ - {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */ - {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */ - {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */ - {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */ - {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */ - {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */ - {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */ - {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */ - {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */ - {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */ - {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */ - {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */ - {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */ - {1361, "Johab"}, /* Korean (Johab) */ - {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */ - {10001, "x-mac-japanese"}, /* Japanese (Mac) */ - {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */ - {10003, "x-mac-korean"}, /* Korean (Mac) */ - {10004, "x-mac-arabic"}, /* Arabic (Mac) */ - {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */ - {10006, "x-mac-greek"}, /* Greek (Mac) */ - {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */ - {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */ - {10010, "x-mac-romanian"}, /* Romanian (Mac) */ - {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */ - {10021, "x-mac-thai"}, /* Thai (Mac) */ - {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */ - {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */ - {10081, "x-mac-turkish"}, /* Turkish (Mac) */ - {10082, "x-mac-croatian"}, /* Croatian (Mac) */ - {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */ - {20001, "x-cp20001"}, /* TCA Taiwan */ - {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */ - {20003, "x-cp20003"}, /* IBM5550 Taiwan */ - {20004, "x-cp20004"}, /* TeleText Taiwan */ - {20005, "x-cp20005"}, /* Wang Taiwan */ - {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */ - {20106, "x-IA5-German"}, /* IA5 German (7-bit) */ - {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */ - {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */ - {20127, "us-ascii"}, /* US-ASCII (7-bit) */ - {20261, "x-cp20261"}, /* T.61 */ - {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */ - {20273, "IBM273"}, /* IBM EBCDIC Germany */ - {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */ - {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */ - {20280, "IBM280"}, /* IBM EBCDIC Italy */ - {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */ - {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */ - {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */ - {20297, "IBM297"}, /* IBM EBCDIC France */ - {20420, "IBM420"}, /* IBM EBCDIC Arabic */ - {20423, "IBM423"}, /* IBM EBCDIC Greek */ - {20424, "IBM424"}, /* IBM EBCDIC Hebrew */ - {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */ - {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */ - {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */ - {20871, "IBM871"}, /* IBM EBCDIC Icelandic */ - {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */ - {20905, "IBM905"}, /* IBM EBCDIC Turkish */ - {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */ - {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */ - {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */ - {20949, "x-cp20949"}, /* Korean Wansung */ - {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */ - /* 21027 (deprecated) */ - {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */ - {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ - {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ - {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ - {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ - {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */ - {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */ - {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */ - {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */ - {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */ - {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */ - {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */ - {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */ - {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */ - {28597, "iso8859-7"}, /* ISO 8859-7 Greek */ - {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ - {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ - {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */ - {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */ - {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */ - {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */ - {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */ - {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */ - {29001, "x-Europa"}, /* Europa 3 */ - {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ - {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ - {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */ - {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */ - {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */ - {50225, "iso-2022-kr"}, /* ISO 2022 Korean */ - {50225, "iso2022-kr"}, /* ISO 2022 Korean */ - {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */ - /* 50229 ISO 2022 Traditional Chinese */ - /* 50930 EBCDIC Japanese (Katakana) Extended */ - /* 50931 EBCDIC US-Canada and Japanese */ - /* 50933 EBCDIC Korean Extended and Korean */ - /* 50935 EBCDIC Simplified Chinese Extended and Simplified Chinese */ - /* 50936 EBCDIC Simplified Chinese */ - /* 50937 EBCDIC US-Canada and Traditional Chinese */ - /* 50939 EBCDIC Japanese (Latin) Extended and Japanese */ - {51932, "euc-jp"}, /* EUC Japanese */ - {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */ - {51949, "euc-kr"}, /* EUC Korean */ - /* 51950 EUC Traditional Chinese */ - {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */ - {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */ - {57002, "x-iscii-de"}, /* ISCII Devanagari */ - {57003, "x-iscii-be"}, /* ISCII Bengali */ - {57004, "x-iscii-ta"}, /* ISCII Tamil */ - {57005, "x-iscii-te"}, /* ISCII Telugu */ - {57006, "x-iscii-as"}, /* ISCII Assamese */ - {57007, "x-iscii-or"}, /* ISCII Oriya */ - {57008, "x-iscii-ka"}, /* ISCII Kannada */ - {57009, "x-iscii-ma"}, /* ISCII Malayalam */ - {57010, "x-iscii-gu"}, /* ISCII Gujarati */ - {57011, "x-iscii-pa"}, /* ISCII Punjabi */ - - {0, NULL} -}; - -/* - * SJIS SHIFTJIS table CP932 table - * ---- --------------------------- -------------------------------- - * 5C U+00A5 YEN SIGN U+005C REVERSE SOLIDUS - * 7E U+203E OVERLINE U+007E TILDE - * 815C U+2014 EM DASH U+2015 HORIZONTAL BAR - * 815F U+005C REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS - * 8160 U+301C WAVE DASH U+FF5E FULLWIDTH TILDE - * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO - * 817C U+2212 MINUS SIGN U+FF0D FULLWIDTH HYPHEN-MINUS - * 8191 U+00A2 CENT SIGN U+FFE0 FULLWIDTH CENT SIGN - * 8192 U+00A3 POUND SIGN U+FFE1 FULLWIDTH POUND SIGN - * 81CA U+00AC NOT SIGN U+FFE2 FULLWIDTH NOT SIGN - * - * EUC-JP and ISO-2022-JP should be compatible with CP932. - * - * Kernel and MLang have different Unicode mapping table. Make sure - * which API is used. - */ -static compat_t cp932_compat[] = { - {0x00A5, 0x005C, COMPAT_OUT}, - {0x203E, 0x007E, COMPAT_OUT}, - {0x2014, 0x2015, COMPAT_OUT}, - {0x301C, 0xFF5E, COMPAT_OUT}, - {0x2016, 0x2225, COMPAT_OUT}, - {0x2212, 0xFF0D, COMPAT_OUT}, - {0x00A2, 0xFFE0, COMPAT_OUT}, - {0x00A3, 0xFFE1, COMPAT_OUT}, - {0x00AC, 0xFFE2, COMPAT_OUT}, - {0, 0, 0} -}; - -static compat_t cp20932_compat[] = { - {0x00A5, 0x005C, COMPAT_OUT}, - {0x203E, 0x007E, COMPAT_OUT}, - {0x2014, 0x2015, COMPAT_OUT}, - {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN}, - {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN}, - {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN}, - {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN}, - {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN}, - {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN}, - {0, 0, 0} -}; - -static compat_t *cp51932_compat = cp932_compat; - -/* cp20932_compat for kernel. cp932_compat for mlang. */ -static compat_t *cp5022x_compat = cp932_compat; - -typedef HRESULT (WINAPI *CONVERTINETSTRING)( - LPDWORD lpdwMode, - DWORD dwSrcEncoding, - DWORD dwDstEncoding, - LPCSTR lpSrcStr, - LPINT lpnSrcSize, - LPBYTE lpDstStr, - LPINT lpnDstSize -); -typedef HRESULT (WINAPI *CONVERTINETMULTIBYTETOUNICODE)( - LPDWORD lpdwMode, - DWORD dwSrcEncoding, - LPCSTR lpSrcStr, - LPINT lpnMultiCharCount, - LPWSTR lpDstStr, - LPINT lpnWideCharCount -); -typedef HRESULT (WINAPI *CONVERTINETUNICODETOMULTIBYTE)( - LPDWORD lpdwMode, - DWORD dwEncoding, - LPCWSTR lpSrcStr, - LPINT lpnWideCharCount, - LPSTR lpDstStr, - LPINT lpnMultiCharCount -); -typedef HRESULT (WINAPI *ISCONVERTINETSTRINGAVAILABLE)( - DWORD dwSrcEncoding, - DWORD dwDstEncoding -); -typedef HRESULT (WINAPI *LCIDTORFC1766A)( - LCID Locale, - LPSTR pszRfc1766, - int nChar -); -typedef HRESULT (WINAPI *LCIDTORFC1766W)( - LCID Locale, - LPWSTR pszRfc1766, - int nChar -); -typedef HRESULT (WINAPI *RFC1766TOLCIDA)( - LCID *pLocale, - LPSTR pszRfc1766 -); -typedef HRESULT (WINAPI *RFC1766TOLCIDW)( - LCID *pLocale, - LPWSTR pszRfc1766 -); -static CONVERTINETSTRING ConvertINetString; -static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode; -static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte; -static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable; -static LCIDTORFC1766A LcidToRfc1766A; -static RFC1766TOLCIDA Rfc1766ToLcidA; - -static int -load_mlang() -{ - HMODULE h; - if (ConvertINetString != NULL) - return TRUE; - h = LoadLibrary("mlang.dll"); - if (!h) - return FALSE; - ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString"); - ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode"); - ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte"); - IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddress(h, "IsConvertINetStringAvailable"); - LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddress(h, "LcidToRfc1766A"); - Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddress(h, "Rfc1766ToLcidA"); - return TRUE; -} - -iconv_t -iconv_open(const char *tocode, const char *fromcode) -{ - rec_iconv_t *cd; - - cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t)); - if (cd == NULL) - return (iconv_t)(-1); - -#if defined(USE_LIBICONV_DLL) - errno = 0; - if (libiconv_iconv_open(cd, tocode, fromcode)) - return (iconv_t)cd; -#endif - - /* reset the errno to prevent reporting wrong error code. - * 0 for unsorted error. */ - errno = 0; - if (win_iconv_open(cd, tocode, fromcode)) - return (iconv_t)cd; - - free(cd); - - return (iconv_t)(-1); -} - -int -iconv_close(iconv_t _cd) -{ - rec_iconv_t *cd = (rec_iconv_t *)_cd; - int r = cd->iconv_close(cd->cd); - int e = *(cd->_errno()); -#if defined(USE_LIBICONV_DLL) - if (cd->hlibiconv != NULL) - FreeLibrary(cd->hlibiconv); -#endif - free(cd); - errno = e; - return r; -} - -size_t -iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) -{ - rec_iconv_t *cd = (rec_iconv_t *)_cd; - size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft); - errno = *(cd->_errno()); - return r; -} - -static int -win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) -{ - if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to)) - return FALSE; - cd->iconv_close = win_iconv_close; - cd->iconv = win_iconv; - cd->_errno = _errno; - cd->cd = (iconv_t)cd; - return TRUE; -} - -static int -win_iconv_close(iconv_t cd) -{ - return 0; -} - -static size_t -win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) -{ - rec_iconv_t *cd = (rec_iconv_t *)_cd; - ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */ - int insize; - int outsize; - int wsize; - DWORD frommode; - DWORD tomode; - uint wc; - compat_t *cp; - int i; - - if (inbuf == NULL || *inbuf == NULL) - { - if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL) - { - tomode = cd->to.mode; - outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft); - if (outsize == -1) - { - cd->to.mode = tomode; - return (size_t)(-1); - } - *outbuf += outsize; - *outbytesleft -= outsize; - } - cd->from.mode = 0; - cd->to.mode = 0; - return 0; - } - - while (*inbytesleft != 0) - { - frommode = cd->from.mode; - tomode = cd->to.mode; - wsize = MB_CHAR_MAX; - - insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize); - if (insize == -1) - { - cd->from.mode = frommode; - return (size_t)(-1); - } - - if (wsize == 0) - { - *inbuf += insize; - *inbytesleft -= insize; - continue; - } - - if (cd->from.compat != NULL) - { - wc = utf16_to_ucs4(wbuf); - cp = cd->from.compat; - for (i = 0; cp[i].in != 0; ++i) - { - if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc) - { - ucs4_to_utf16(cp[i].in, wbuf, &wsize); - break; - } - } - } - - if (cd->to.compat != NULL) - { - wc = utf16_to_ucs4(wbuf); - cp = cd->to.compat; - for (i = 0; cp[i].in != 0; ++i) - { - if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc) - { - ucs4_to_utf16(cp[i].out, wbuf, &wsize); - break; - } - } - } - - outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft); - if (outsize == -1) - { - cd->from.mode = frommode; - cd->to.mode = tomode; - return (size_t)(-1); - } - - *inbuf += insize; - *outbuf += outsize; - *inbytesleft -= insize; - *outbytesleft -= outsize; - } - - return 0; -} - -static int -make_csconv(const char *_name, csconv_t *cv) -{ - CPINFOEX cpinfoex; - int use_compat = TRUE; - int flag = 0; - char *name; - char *p; - - name = xstrndup(_name, strlen(_name)); - if (name == NULL) - return FALSE; - - /* check for option "enc_name//opt1//opt2" */ - while ((p = strrstr(name, "//")) != NULL) - { - if (_stricmp(p + 2, "nocompat") == 0) - use_compat = FALSE; - else if (_stricmp(p + 2, "translit") == 0) - flag |= FLAG_TRANSLIT; - else if (_stricmp(p + 2, "ignore") == 0) - flag |= FLAG_IGNORE; - *p = 0; - } - - cv->mode = 0; - cv->flags = flag; - cv->mblen = NULL; - cv->flush = NULL; - cv->compat = NULL; - cv->codepage = name_to_codepage(name); - if (cv->codepage == 1200 || cv->codepage == 1201) - { - cv->mbtowc = utf16_mbtowc; - cv->wctomb = utf16_wctomb; - if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0) - cv->flags |= FLAG_USE_BOM; - } - else if (cv->codepage == 12000 || cv->codepage == 12001) - { - cv->mbtowc = utf32_mbtowc; - cv->wctomb = utf32_wctomb; - if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0) - cv->flags |= FLAG_USE_BOM; - } - else if (cv->codepage == 65001) - { - cv->mbtowc = kernel_mbtowc; - cv->wctomb = kernel_wctomb; - cv->mblen = utf8_mblen; - } - else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang()) - { - cv->mbtowc = iso2022jp_mbtowc; - cv->wctomb = iso2022jp_wctomb; - cv->flush = iso2022jp_flush; - } - else if (cv->codepage == 51932 && load_mlang()) - { - cv->mbtowc = mlang_mbtowc; - cv->wctomb = mlang_wctomb; - cv->mblen = eucjp_mblen; - } - else if (IsValidCodePage(cv->codepage) - && GetCPInfoEx(cv->codepage, 0, &cpinfoex) != 0) - { - cv->mbtowc = kernel_mbtowc; - cv->wctomb = kernel_wctomb; - if (cpinfoex.MaxCharSize == 1) - cv->mblen = sbcs_mblen; - else if (cpinfoex.MaxCharSize == 2) - cv->mblen = dbcs_mblen; - else - cv->mblen = mbcs_mblen; - } - else - { - /* not supported */ - free(name); - errno = EINVAL; - return FALSE; - } - - if (use_compat) - { - switch (cv->codepage) - { - case 932: cv->compat = cp932_compat; break; - case 20932: cv->compat = cp20932_compat; break; - case 51932: cv->compat = cp51932_compat; break; - case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break; - } - } - - free(name); - - return TRUE; -} - -static int -name_to_codepage(const char *name) -{ - int i; - - if (*name == '\0' || - strcmp(name, "char") == 0) - return GetACP(); - else if (strcmp(name, "wchar_t") == 0) - return 1200; - else if (_strnicmp(name, "cp", 2) == 0) - return atoi(name + 2); /* CP123 */ - else if ('0' <= name[0] && name[0] <= '9') - return atoi(name); /* 123 */ - else if (_strnicmp(name, "xx", 2) == 0) - return atoi(name + 2); /* XX123 for debug */ - - for (i = 0; codepage_alias[i].name != NULL; ++i) - if (_stricmp(name, codepage_alias[i].name) == 0) - return codepage_alias[i].codepage; - return -1; -} - -/* - * http://www.faqs.org/rfcs/rfc2781.html - */ -static uint -utf16_to_ucs4(const ushort *wbuf) -{ - uint wc = wbuf[0]; - if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) - wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000; - return wc; -} - -static void -ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize) -{ - if (wc < 0x10000) - { - wbuf[0] = wc; - *wbufsize = 1; - } - else - { - wc -= 0x10000; - wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF); - wbuf[1] = 0xDC00 | (wc & 0x3FF); - *wbufsize = 2; - } -} - -/* - * Check if codepage is one of those for which the dwFlags parameter - * to MultiByteToWideChar() must be zero. Return zero or - * MB_ERR_INVALID_CHARS. The docs in Platform SDK for for Windows - * Server 2003 R2 claims that also codepage 65001 is one of these, but - * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave - * out 65001 (UTF-8), and that indeed seems to be the case on XP, it - * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting - * from UTF-8. - */ -static int -mbtowc_flags(int codepage) -{ - return (codepage == 50220 || codepage == 50221 || - codepage == 50222 || codepage == 50225 || - codepage == 50227 || codepage == 50229 || - codepage == 52936 || codepage == 54936 || - (codepage >= 57002 && codepage <= 57011) || - codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS; -} - -/* - * Check if codepage is one those for which the lpUsedDefaultChar - * parameter to WideCharToMultiByte() must be NULL. The docs in - * Platform SDK for for Windows Server 2003 R2 claims that this is the - * list below, while the MSDN docs for MSVS2008 claim that it is only - * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform - * SDK seems to be correct, at least for XP. - */ -static int -must_use_null_useddefaultchar(int codepage) -{ - return (codepage == 65000 || codepage == 65001 || - codepage == 50220 || codepage == 50221 || - codepage == 50222 || codepage == 50225 || - codepage == 50227 || codepage == 50229 || - codepage == 52936 || codepage == 54936 || - (codepage >= 57002 && codepage <= 57011) || - codepage == 42); -} - -static char * -strrstr(const char *str, const char *token) -{ - int len = strlen(token); - const char *p = str + strlen(str); - - while (str <= --p) - if (p[0] == token[0] && strncmp(p, token, len) == 0) - return (char *)p; - return NULL; -} - -static char * -xstrndup(const char *s, size_t n) -{ - char *p; - - p = (char *)malloc(n + 1); - if (p == NULL) - return NULL; - memcpy(p, s, n); - p[n] = '\0'; - return p; -} - -static int -seterror(int err) -{ - errno = err; - return -1; -} - -#if defined(USE_LIBICONV_DLL) -static int -libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) -{ - HMODULE hlibiconv = NULL; - HMODULE hmsvcrt = NULL; - char *dllname; - const char *p; - const char *e; - f_iconv_open _iconv_open; - - /* - * always try to load dll, so that we can switch dll in runtime. - */ - - /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */ - p = getenv("WINICONV_LIBICONV_DLL"); - if (p == NULL) - p = DEFAULT_LIBICONV_DLL; - /* parse comma separated value */ - for ( ; *p != 0; p = (*e == ',') ? e + 1 : e) - { - e = strchr(p, ','); - if (p == e) - continue; - else if (e == NULL) - e = p + strlen(p); - dllname = xstrndup(p, e - p); - if (dllname == NULL) - return FALSE; - hlibiconv = LoadLibrary(dllname); - free(dllname); - if (hlibiconv != NULL) - { - if (hlibiconv == hwiniconv) - { - FreeLibrary(hlibiconv); - hlibiconv = NULL; - continue; - } - break; - } - } - - if (hlibiconv == NULL) - goto failed; - - hmsvcrt = find_imported_module_by_funcname(hlibiconv, "_errno"); - if (hmsvcrt == NULL) - goto failed; - - _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "libiconv_open"); - if (_iconv_open == NULL) - _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "iconv_open"); - cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "libiconv_close"); - if (cd->iconv_close == NULL) - cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "iconv_close"); - cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "libiconv"); - if (cd->iconv == NULL) - cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "iconv"); - cd->_errno = (f_errno)GetProcAddress(hmsvcrt, "_errno"); - if (_iconv_open == NULL || cd->iconv_close == NULL - || cd->iconv == NULL || cd->_errno == NULL) - goto failed; - - cd->cd = _iconv_open(tocode, fromcode); - if (cd->cd == (iconv_t)(-1)) - goto failed; - - cd->hlibiconv = hlibiconv; - return TRUE; - -failed: - if (hlibiconv != NULL) - FreeLibrary(hlibiconv); - /* do not free hmsvcrt which is obtained by GetModuleHandle() */ - return FALSE; -} - -/* - * Reference: - * http://forums.belution.com/ja/vc/000/234/78s.shtml - * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html - * - * The formal way is - * imagehlp.h or dbghelp.h - * imagehlp.lib or dbghelp.lib - * ImageDirectoryEntryToData() - */ -#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base)) -#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew)) -static PVOID -MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size) -{ - /* TODO: MappedAsImage? */ - PIMAGE_DATA_DIRECTORY p; - p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry; - if (p->VirtualAddress == 0) { - *Size = 0; - return NULL; - } - *Size = p->Size; - return (PVOID)((LPBYTE)Base + p->VirtualAddress); -} - -static HMODULE -find_imported_module_by_funcname(HMODULE hModule, const char *funcname) -{ - DWORD Base; - ULONG Size; - PIMAGE_IMPORT_DESCRIPTOR Imp; - PIMAGE_THUNK_DATA Name; /* Import Name Table */ - PIMAGE_IMPORT_BY_NAME ImpName; - - Base = (DWORD)hModule; - Imp = MyImageDirectoryEntryToData( - (LPVOID)Base, - TRUE, - IMAGE_DIRECTORY_ENTRY_IMPORT, - &Size); - if (Imp == NULL) - return NULL; - for ( ; Imp->OriginalFirstThunk != 0; ++Imp) - { - Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk); - for ( ; Name->u1.Ordinal != 0; ++Name) - { - if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal)) - { - ImpName = (PIMAGE_IMPORT_BY_NAME) - (Base + (DWORD)Name->u1.AddressOfData); - if (strcmp((char *)ImpName->Name, funcname) == 0) - return GetModuleHandle((char *)(Base + Imp->Name)); - } - } - } - return NULL; -} -#endif - -static int -sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - return 1; -} - -static int -dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1; - if (bufsize < len) - return seterror(EINVAL); - return len; -} - -static int -mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - int len = 0; - - if (cv->codepage == 54936) { - if (buf[0] <= 0x7F) len = 1; - else if (buf[0] >= 0x81 && buf[0] <= 0xFE && - bufsize >= 2 && - ((buf[1] >= 0x40 && buf[1] <= 0x7E) || - (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2; - else if (buf[0] >= 0x81 && buf[0] <= 0xFE && - bufsize >= 4 && - buf[1] >= 0x30 && buf[1] <= 0x39) len = 4; - else - return seterror(EINVAL); - return len; - } - else - return seterror(EINVAL); -} - -static int -utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - int len = 0; - - if (buf[0] < 0x80) len = 1; - else if ((buf[0] & 0xE0) == 0xC0) len = 2; - else if ((buf[0] & 0xF0) == 0xE0) len = 3; - else if ((buf[0] & 0xF8) == 0xF0) len = 4; - else if ((buf[0] & 0xFC) == 0xF8) len = 5; - else if ((buf[0] & 0xFE) == 0xFC) len = 6; - - if (len == 0) - return seterror(EILSEQ); - else if (bufsize < len) - return seterror(EINVAL); - return len; -} - -static int -eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize) -{ - if (buf[0] < 0x80) /* ASCII */ - return 1; - else if (buf[0] == 0x8E) /* JIS X 0201 */ - { - if (bufsize < 2) - return seterror(EINVAL); - else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF)) - return seterror(EILSEQ); - return 2; - } - else if (buf[0] == 0x8F) /* JIS X 0212 */ - { - if (bufsize < 3) - return seterror(EINVAL); - else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE) - || !(0xA1 <= buf[2] && buf[2] <= 0xFE)) - return seterror(EILSEQ); - return 3; - } - else /* JIS X 0208 */ - { - if (bufsize < 2) - return seterror(EINVAL); - else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE) - || !(0xA1 <= buf[1] && buf[1] <= 0xFE)) - return seterror(EILSEQ); - return 2; - } -} - -static int -kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int len; - - len = cv->mblen(cv, buf, bufsize); - if (len == -1) - return -1; - *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage), - (const char *)buf, len, (wchar_t *)wbuf, *wbufsize); - if (*wbufsize == 0) - return seterror(EILSEQ); - return len; -} - -static int -kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - BOOL usedDefaultChar = 0; - BOOL *p = NULL; - int flags = 0; - int len; - - if (bufsize == 0) - return seterror(E2BIG); - if (!must_use_null_useddefaultchar(cv->codepage)) - { - p = &usedDefaultChar; -#ifdef WC_NO_BEST_FIT_CHARS - if (!(cv->flags & FLAG_TRANSLIT)) - flags |= WC_NO_BEST_FIT_CHARS; -#endif - } - len = WideCharToMultiByte(cv->codepage, flags, - (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p); - if (len == 0) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - return seterror(E2BIG); - return seterror(EILSEQ); - } - else if (usedDefaultChar) - return seterror(EILSEQ); - else if (cv->mblen(cv, buf, len) != len) /* validate result */ - return seterror(EILSEQ); - return len; -} - -/* - * It seems that the mode (cv->mode) is fixnum. - * For example, when converting iso-2022-jp(cp50221) to unicode: - * in ascii sequence: mode=0xC42C0000 - * in jisx0208 sequence: mode=0xC42C0001 - * "C42C" is same for each convert session. - * It should be: ((codepage-1)<<16)|state - */ -static int -mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int len; - int insize; - HRESULT hr; - - len = cv->mblen(cv, buf, bufsize); - if (len == -1) - return -1; - insize = len; - hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage, - (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize); - if (hr != S_OK || insize != len) - return seterror(EILSEQ); - return len; -} - -static int -mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */ - int tmpsize = MB_CHAR_MAX; - int insize = wbufsize; - HRESULT hr; - - hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage, - (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize); - if (hr != S_OK || insize != wbufsize) - return seterror(EILSEQ); - else if (bufsize < tmpsize) - return seterror(E2BIG); - else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize) - return seterror(EILSEQ); - memcpy(buf, tmpbuf, tmpsize); - return tmpsize; -} - -static int -utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int codepage = cv->codepage; - - /* swap endian: 1200 <-> 1201 */ - if (cv->mode & UNICODE_MODE_SWAPPED) - codepage ^= 1; - - if (bufsize < 2) - return seterror(EINVAL); - if (codepage == 1200) /* little endian */ - wbuf[0] = (buf[1] << 8) | buf[0]; - else if (codepage == 1201) /* big endian */ - wbuf[0] = (buf[0] << 8) | buf[1]; - - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - cv->mode |= UNICODE_MODE_BOM_DONE; - if (wbuf[0] == 0xFFFE) - { - cv->mode |= UNICODE_MODE_SWAPPED; - *wbufsize = 0; - return 2; - } - else if (wbuf[0] == 0xFEFF) - { - *wbufsize = 0; - return 2; - } - } - - if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF) - return seterror(EILSEQ); - if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) - { - if (bufsize < 4) - return seterror(EINVAL); - if (codepage == 1200) /* little endian */ - wbuf[1] = (buf[3] << 8) | buf[2]; - else if (codepage == 1201) /* big endian */ - wbuf[1] = (buf[2] << 8) | buf[3]; - if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF)) - return seterror(EILSEQ); - *wbufsize = 2; - return 4; - } - *wbufsize = 1; - return 2; -} - -static int -utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - int r; - - cv->mode |= UNICODE_MODE_BOM_DONE; - if (bufsize < 2) - return seterror(E2BIG); - if (cv->codepage == 1200) /* little endian */ - memcpy(buf, "\xFF\xFE", 2); - else if (cv->codepage == 1201) /* big endian */ - memcpy(buf, "\xFE\xFF", 2); - - r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2); - if (r == -1) - return -1; - return r + 2; - } - - if (bufsize < 2) - return seterror(E2BIG); - if (cv->codepage == 1200) /* little endian */ - { - buf[0] = (wbuf[0] & 0x00FF); - buf[1] = (wbuf[0] & 0xFF00) >> 8; - } - else if (cv->codepage == 1201) /* big endian */ - { - buf[0] = (wbuf[0] & 0xFF00) >> 8; - buf[1] = (wbuf[0] & 0x00FF); - } - if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) - { - if (bufsize < 4) - return seterror(E2BIG); - if (cv->codepage == 1200) /* little endian */ - { - buf[2] = (wbuf[1] & 0x00FF); - buf[3] = (wbuf[1] & 0xFF00) >> 8; - } - else if (cv->codepage == 1201) /* big endian */ - { - buf[2] = (wbuf[1] & 0xFF00) >> 8; - buf[3] = (wbuf[1] & 0x00FF); - } - return 4; - } - return 2; -} - -static int -utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - int codepage = cv->codepage; - uint wc; - - /* swap endian: 12000 <-> 12001 */ - if (cv->mode & UNICODE_MODE_SWAPPED) - codepage ^= 1; - - if (bufsize < 4) - return seterror(EINVAL); - if (codepage == 12000) /* little endian */ - wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - else if (codepage == 12001) /* big endian */ - wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - cv->mode |= UNICODE_MODE_BOM_DONE; - if (wc == 0xFFFE0000) - { - cv->mode |= UNICODE_MODE_SWAPPED; - *wbufsize = 0; - return 4; - } - else if (wc == 0x0000FEFF) - { - *wbufsize = 0; - return 4; - } - } - - if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc) - return seterror(EILSEQ); - ucs4_to_utf16(wc, wbuf, wbufsize); - return 4; -} - -static int -utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - uint wc; - - if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) - { - int r; - - cv->mode |= UNICODE_MODE_BOM_DONE; - if (bufsize < 4) - return seterror(E2BIG); - if (cv->codepage == 12000) /* little endian */ - memcpy(buf, "\xFF\xFE\x00\x00", 4); - else if (cv->codepage == 12001) /* big endian */ - memcpy(buf, "\x00\x00\xFE\xFF", 4); - - r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4); - if (r == -1) - return -1; - return r + 4; - } - - if (bufsize < 4) - return seterror(E2BIG); - wc = utf16_to_ucs4(wbuf); - if (cv->codepage == 12000) /* little endian */ - { - buf[0] = wc & 0x000000FF; - buf[1] = (wc & 0x0000FF00) >> 8; - buf[2] = (wc & 0x00FF0000) >> 16; - buf[3] = (wc & 0xFF000000) >> 24; - } - else if (cv->codepage == 12001) /* big endian */ - { - buf[0] = (wc & 0xFF000000) >> 24; - buf[1] = (wc & 0x00FF0000) >> 16; - buf[2] = (wc & 0x0000FF00) >> 8; - buf[3] = wc & 0x000000FF; - } - return 4; -} - -/* - * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) - * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow - * 1 byte Kana) - * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte - * Kana - SO/SI) - * - * MultiByteToWideChar() and WideCharToMultiByte() behave differently - * depending on Windows version. On XP, WideCharToMultiByte() doesn't - * terminate result sequence with ascii escape. But Vista does. - * Use MLang instead. - */ - -#define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift)) -#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF) -#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF) - -#define ISO2022_SI 0 -#define ISO2022_SO 1 - -/* shift in */ -static const char iso2022_SI_seq[] = "\x0F"; -/* shift out */ -static const char iso2022_SO_seq[] = "\x0E"; - -typedef struct iso2022_esc_t iso2022_esc_t; -struct iso2022_esc_t { - const char *esc; - int esc_len; - int len; - int cs; -}; - -#define ISO2022JP_CS_ASCII 0 -#define ISO2022JP_CS_JISX0201_ROMAN 1 -#define ISO2022JP_CS_JISX0201_KANA 2 -#define ISO2022JP_CS_JISX0208_1978 3 -#define ISO2022JP_CS_JISX0208_1983 4 -#define ISO2022JP_CS_JISX0212 5 - -static iso2022_esc_t iso2022jp_esc[] = { - {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII}, - {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN}, - {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA}, - {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */ - {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983}, - {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212}, - {NULL, 0, 0, 0} -}; - -static int -iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) -{ - iso2022_esc_t *iesc = iso2022jp_esc; - char tmp[MB_CHAR_MAX]; - int insize; - HRESULT hr; - DWORD dummy = 0; - int len; - int esc_len; - int cs; - int shift; - int i; - - if (buf[0] == 0x1B) - { - for (i = 0; iesc[i].esc != NULL; ++i) - { - esc_len = iesc[i].esc_len; - if (bufsize < esc_len) - { - if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0) - return seterror(EINVAL); - } - else - { - if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0) - { - cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI); - *wbufsize = 0; - return esc_len; - } - } - } - /* not supported escape sequence */ - return seterror(EILSEQ); - } - else if (buf[0] == iso2022_SO_seq[0]) - { - cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SO); - *wbufsize = 0; - return 1; - } - else if (buf[0] == iso2022_SI_seq[0]) - { - cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SI); - *wbufsize = 0; - return 1; - } - - cs = ISO2022_MODE_CS(cv->mode); - shift = ISO2022_MODE_SHIFT(cv->mode); - - /* reset the mode for informal sequence */ - if (buf[0] < 0x20) - { - cs = ISO2022JP_CS_ASCII; - shift = ISO2022_SI; - } - - len = iesc[cs].len; - if (bufsize < len) - return seterror(EINVAL); - for (i = 0; i < len; ++i) - if (!(buf[i] < 0x80)) - return seterror(EILSEQ); - esc_len = iesc[cs].esc_len; - memcpy(tmp, iesc[cs].esc, esc_len); - if (shift == ISO2022_SO) - { - memcpy(tmp + esc_len, iso2022_SO_seq, 1); - esc_len += 1; - } - memcpy(tmp + esc_len, buf, len); - - if ((cv->codepage == 50220 || cv->codepage == 50221 - || cv->codepage == 50222) && shift == ISO2022_SO) - { - /* XXX: shift-out cannot be used for mbtowc (both kernel and - * mlang) */ - esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len; - memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len); - memcpy(tmp + esc_len, buf, len); - } - - insize = len + esc_len; - hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage, - (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize); - if (hr != S_OK || insize != len + esc_len) - return seterror(EILSEQ); - - /* Check for conversion error. Assuming defaultChar is 0x3F. */ - /* ascii should be converted from ascii */ - if (wbuf[0] == buf[0] - && cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) - return seterror(EILSEQ); - - /* reset the mode for informal sequence */ - if (cv->mode != ISO2022_MODE(cs, shift)) - cv->mode = ISO2022_MODE(cs, shift); - - return len; -} - -static int -iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) -{ - iso2022_esc_t *iesc = iso2022jp_esc; - char tmp[MB_CHAR_MAX]; - int tmpsize = MB_CHAR_MAX; - int insize = wbufsize; - HRESULT hr; - DWORD dummy = 0; - int len; - int esc_len; - int cs; - int shift; - int i; - - /* - * MultiByte = [escape sequence] + character + [escape sequence] - * - * Whether trailing escape sequence is added depends on which API is - * used (kernel or MLang, and its version). - */ - hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage, - (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize); - if (hr != S_OK || insize != wbufsize) - return seterror(EILSEQ); - else if (bufsize < tmpsize) - return seterror(E2BIG); - - if (tmpsize == 1) - { - cs = ISO2022JP_CS_ASCII; - esc_len = 0; - } - else - { - for (i = 1; iesc[i].esc != NULL; ++i) - { - esc_len = iesc[i].esc_len; - if (strncmp(tmp, iesc[i].esc, esc_len) == 0) - { - cs = iesc[i].cs; - break; - } - } - if (iesc[i].esc == NULL) - /* not supported escape sequence */ - return seterror(EILSEQ); - } - - shift = ISO2022_SI; - if (tmp[esc_len] == iso2022_SO_seq[0]) - { - shift = ISO2022_SO; - esc_len += 1; - } - - len = iesc[cs].len; - - /* Check for converting error. Assuming defaultChar is 0x3F. */ - /* ascii should be converted from ascii */ - if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80)) - return seterror(EILSEQ); - else if (tmpsize < esc_len + len) - return seterror(EILSEQ); - - if (cv->mode == ISO2022_MODE(cs, shift)) - { - /* remove escape sequence */ - if (esc_len != 0) - memmove(tmp, tmp + esc_len, len); - esc_len = 0; - } - else - { - if (cs == ISO2022JP_CS_ASCII) - { - esc_len = iesc[ISO2022JP_CS_ASCII].esc_len; - memmove(tmp + esc_len, tmp, len); - memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len); - } - if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO) - { - /* shift-in before changing to other mode */ - memmove(tmp + 1, tmp, len + esc_len); - memcpy(tmp, iso2022_SI_seq, 1); - esc_len += 1; - } - } - - if (bufsize < len + esc_len) - return seterror(E2BIG); - memcpy(buf, tmp, len + esc_len); - cv->mode = ISO2022_MODE(cs, shift); - return len + esc_len; -} - -static int -iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize) -{ - iso2022_esc_t *iesc = iso2022jp_esc; - int esc_len; - - if (cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) - { - esc_len = 0; - if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) - esc_len += 1; - if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) - esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; - if (bufsize < esc_len) - return seterror(E2BIG); - - esc_len = 0; - if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) - { - memcpy(buf, iso2022_SI_seq, 1); - esc_len += 1; - } - if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) - { - memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc, - iesc[ISO2022JP_CS_ASCII].esc_len); - esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; - } - return esc_len; - } - return 0; -} - -#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL) -BOOL WINAPI -DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) -{ - switch( fdwReason ) - { - case DLL_PROCESS_ATTACH: - hwiniconv = (HMODULE)hinstDLL; - break; - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} -#endif - -#if defined(MAKE_EXE) -#include -#include -#include -int -main(int argc, char **argv) -{ - char *fromcode = NULL; - char *tocode = NULL; - int i; - char inbuf[BUFSIZ]; - char outbuf[BUFSIZ]; - const char *pin; - char *pout; - size_t inbytesleft; - size_t outbytesleft; - size_t rest = 0; - iconv_t cd; - size_t r; - FILE *in = stdin; - - _setmode(_fileno(stdin), _O_BINARY); - _setmode(_fileno(stdout), _O_BINARY); - - for (i = 1; i < argc; ++i) - { - if (strcmp(argv[i], "-l") == 0) - { - for (i = 0; codepage_alias[i].name != NULL; ++i) - printf("%s\n", codepage_alias[i].name); - return 0; - } - - if (strcmp(argv[i], "-f") == 0) - fromcode = argv[++i]; - else if (strcmp(argv[i], "-t") == 0) - tocode = argv[++i]; - else - { - in = fopen(argv[i], "rb"); - if (in == NULL) - { - fprintf(stderr, "cannot open %s\n", argv[i]); - return 1; - } - break; - } - } - - if (fromcode == NULL || tocode == NULL) - { - printf("usage: %s -f from-enc -t to-enc [file]\n", argv[0]); - return 0; - } - - cd = iconv_open(tocode, fromcode); - if (cd == (iconv_t)(-1)) - { - perror("iconv_open error"); - return 1; - } - - while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0 - || rest != 0) - { - inbytesleft += rest; - pin = inbuf; - pout = outbuf; - outbytesleft = sizeof(outbuf); - r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft); - fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout); - if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in))) - { - perror("conversion error"); - return 1; - } - memmove(inbuf, pin, inbytesleft); - rest = inbytesleft; - } - pout = outbuf; - outbytesleft = sizeof(outbuf); - r = iconv(cd, NULL, NULL, &pout, &outbytesleft); - fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout); - if (r == (size_t)(-1)) - { - perror("conversion error"); - return 1; - } - - iconv_close(cd); - - return 0; -} -#endif - diff --git a/src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv_test.c b/src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv_test.c deleted file mode 100644 index b2aafa4a57..0000000000 --- a/src/mod/endpoints/mod_gsmopen/win_iconv/win_iconv_test.c +++ /dev/null @@ -1,261 +0,0 @@ - -#include "win_iconv.c" -#include - -const char * -tohex(const char *str, int size) -{ - static char buf[BUFSIZ]; - char *pbuf = buf; - int i; - buf[0] = 0; - for (i = 0; i < size; ++i) - pbuf += sprintf(pbuf, "%02X", str[i] & 0xFF); - return buf; -} - -const char * -errstr(int errcode) -{ - static char buf[BUFSIZ]; - switch (errcode) - { - case 0: return "NOERROR"; - case EINVAL: return "EINVAL"; - case EILSEQ: return "EILSEQ"; - case E2BIG: return "E2BIG"; - } - sprintf(buf, "%d\n", errcode); - return buf; -} - -#ifdef USE_LIBICONV_DLL -int use_dll; - -int -setdll(const char *dllpath) -{ - char buf[BUFSIZ]; - rec_iconv_t cd; - - sprintf(buf, "WINICONV_LIBICONV_DLL=%s", dllpath); - putenv(buf); - if (libiconv_iconv_open(&cd, "ascii", "ascii")) - { - FreeLibrary(cd.hlibiconv); - use_dll = TRUE; - return TRUE; - } - use_dll = FALSE; - return FALSE; -} -#endif - -/* - * We can test the codepage that is installed in the system. - */ -int -check_enc(const char *encname, int codepage) -{ - iconv_t cd; - int cp; - cd = iconv_open("utf-8", encname); - if (cd == (iconv_t)(-1)) - { - printf("%s(%d) IS NOT SUPPORTED: SKIP THE TEST\n", encname, codepage); - return FALSE; - } - cp = ((rec_iconv_t *)cd)->from.codepage; - if (cp != codepage) - { - printf("%s(%d) ALIAS IS MAPPED TO DIFFERENT CODEPAGE (%d)\n", encname, codepage, cp); - exit(1); - } - iconv_close(cd); - return TRUE; -} - -int use_dll; - -void -test(const char *from, const char *fromstr, int fromsize, const char *to, const char *tostr, int tosize, int errcode, int bufsize, int line) -{ - char outbuf[BUFSIZ]; - const char *pin; - char *pout; - size_t inbytesleft; - size_t outbytesleft; - iconv_t cd; - size_t r; - char dllpath[_MAX_PATH]; - - cd = iconv_open(to, from); - if (cd == (iconv_t)(-1)) - { - printf("%s -> %s: NG: INVALID ENCODING NAME: line=%d\n", from, to, line); - exit(1); - } - -#ifdef USE_LIBICONV_DLL - if (((rec_iconv_t *)cd)->hlibiconv != NULL) - GetModuleFileName(((rec_iconv_t *)cd)->hlibiconv, dllpath, sizeof(dllpath)); - - if (use_dll && ((rec_iconv_t *)cd)->hlibiconv == NULL) - { - printf("%s: %s -> %s: NG: FAILED TO USE DLL: line=%d\n", dllpath, from, to, line); - exit(1); - } - else if (!use_dll && ((rec_iconv_t *)cd)->hlibiconv != NULL) - { - printf("%s: %s -> %s: NG: DLL IS LOADED UNEXPECTEDLY: line=%d\n", dllpath, from, to, line); - exit(1); - } -#endif - - errno = 0; - - pin = fromstr; - pout = outbuf; - inbytesleft = fromsize; - outbytesleft = bufsize; - r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft); - if (r != (size_t)(-1)) - r = iconv(cd, NULL, NULL, &pout, &outbytesleft); - *pout = 0; - -#ifdef USE_LIBICONV_DLL - if (use_dll) - printf("%s: ", dllpath); -#endif - printf("%s(%s) -> ", from, tohex(fromstr, fromsize)); - printf("%s(%s%s%s): ", to, tohex(tostr, tosize), - errcode == 0 ? "" : ":", - errcode == 0 ? "" : errstr(errcode)); - if (strcmp(outbuf, tostr) == 0 && errno == errcode) - printf("OK\n"); - else - { - printf("RESULT(%s:%s): ", tohex(outbuf, sizeof(outbuf) - outbytesleft), - errstr(errno)); - printf("NG: line=%d\n", line); - exit(1); - } -} - -#define STATIC_STRLEN(arr) (sizeof(arr) - 1) - -#define success(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), 0, BUFSIZ, __LINE__) -#define einval(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), EINVAL, BUFSIZ, __LINE__) -#define eilseq(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), EILSEQ, BUFSIZ, __LINE__) -#define e2big(from, fromstr, to, tostr, bufsize) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), E2BIG, bufsize, __LINE__) - -int -main(int argc, char **argv) -{ -#ifdef USE_LIBICONV_DLL - /* test use of dll if $DEFAULT_LIBICONV_DLL was defined. */ - if (setdll("")) - { - success("ascii", "ABC", "ascii", "ABC"); - success("ascii", "ABC", "utf-16be", "\x00\x41\x00\x42\x00\x43"); - } - else - { - printf("\nDLL TEST IS SKIPPED\n\n"); - } - - setdll("none"); -#endif - - if (check_enc("ascii", 20127)) - { - success("ascii", "ABC", "ascii", "ABC"); - /* MSB is dropped. Hmm... */ - success("ascii", "\x80\xFF", "ascii", "\x00\x7F"); - } - - /* unicode (CP1200 CP1201 CP12000 CP12001 CP65001) */ - if (check_enc("utf-8", 65001) - && check_enc("utf-16be", 1201) && check_enc("utf-16le", 1200) - && check_enc("utf-32be", 12001) && check_enc("utf-32le", 12000) - ) - { - /* Test the BOM behavior - * 1. Remove the BOM when "fromcode" is utf-16 or utf-32. - * 2. Add the BOM when "tocode" is utf-16 or utf-32. */ - success("utf-16", "\xFE\xFF\x01\x02", "utf-16be", "\x01\x02"); - success("utf-16", "\xFF\xFE\x02\x01", "utf-16be", "\x01\x02"); - success("utf-32", "\x00\x00\xFE\xFF\x00\x00\x01\x02", "utf-32be", "\x00\x00\x01\x02"); - success("utf-32", "\xFF\xFE\x00\x00\x02\x01\x00\x00", "utf-32be", "\x00\x00\x01\x02"); - success("utf-16", "\xFE\xFF\x00\x01", "utf-8", "\x01"); -#ifndef GLIB_COMPILATION - success("utf-8", "\x01", "utf-16", "\xFE\xFF\x00\x01"); - success("utf-8", "\x01", "utf-32", "\x00\x00\xFE\xFF\x00\x00\x00\x01"); -#else - success("utf-8", "\x01", "utf-16", "\xFF\xFE\x01\x00"); - success("utf-8", "\x01", "utf-32", "\xFF\xFE\x00\x00\x01\x00\x00\x00"); -#endif - - success("utf-16be", "\xFE\xFF\x01\x02", "utf-16be", "\xFE\xFF\x01\x02"); - success("utf-16le", "\xFF\xFE\x02\x01", "utf-16be", "\xFE\xFF\x01\x02"); - success("utf-32be", "\x00\x00\xFE\xFF\x00\x00\x01\x02", "utf-32be", "\x00\x00\xFE\xFF\x00\x00\x01\x02"); - success("utf-32le", "\xFF\xFE\x00\x00\x02\x01\x00\x00", "utf-32be", "\x00\x00\xFE\xFF\x00\x00\x01\x02"); - success("utf-16be", "\xFE\xFF\x00\x01", "utf-8", "\xEF\xBB\xBF\x01"); - success("utf-8", "\xEF\xBB\xBF\x01", "utf-8", "\xEF\xBB\xBF\x01"); - - success("utf-16be", "\x01\x02", "utf-16le", "\x02\x01"); - success("utf-16le", "\x02\x01", "utf-16be", "\x01\x02"); - success("utf-16be", "\xFE\xFF", "utf-16le", "\xFF\xFE"); - success("utf-16le", "\xFF\xFE", "utf-16be", "\xFE\xFF"); - success("utf-32be", "\x00\x00\x03\x04", "utf-32le", "\x04\x03\x00\x00"); - success("utf-32le", "\x04\x03\x00\x00", "utf-32be", "\x00\x00\x03\x04"); - success("utf-32be", "\x00\x00\xFF\xFF", "utf-16be", "\xFF\xFF"); - success("utf-16be", "\xFF\xFF", "utf-32be", "\x00\x00\xFF\xFF"); - success("utf-32be", "\x00\x01\x00\x00", "utf-16be", "\xD8\x00\xDC\x00"); - success("utf-16be", "\xD8\x00\xDC\x00", "utf-32be", "\x00\x01\x00\x00"); - success("utf-32be", "\x00\x10\xFF\xFF", "utf-16be", "\xDB\xFF\xDF\xFF"); - success("utf-16be", "\xDB\xFF\xDF\xFF", "utf-32be", "\x00\x10\xFF\xFF"); - eilseq("utf-32be", "\x00\x11\x00\x00", "utf-16be", ""); - eilseq("utf-16be", "\xDB\xFF\xE0\x00", "utf-32be", ""); - success("utf-8", "\xE3\x81\x82", "utf-16be", "\x30\x42"); - einval("utf-8", "\xE3", "utf-16be", ""); - } - - /* Japanese (CP932 CP20932 CP50220 CP50221 CP50222 CP51932) */ - if (check_enc("cp932", 932) - && check_enc("cp20932", 20932) && check_enc("euc-jp", 51932) - && check_enc("cp50220", 50220) && check_enc("cp50221", 50221) - && check_enc("cp50222", 50222) && check_enc("iso-2022-jp", 50221)) - { - /* Test the compatibility for each other Japanese codepage. - * And validate the escape sequence handling for iso-2022-jp. */ - success("utf-16be", "\xFF\x5E", "cp932", "\x81\x60"); - success("utf-16be", "\x30\x1C", "cp932", "\x81\x60"); - success("utf-16be", "\xFF\x5E", "cp932//nocompat", "\x81\x60"); - eilseq("utf-16be", "\x30\x1C", "cp932//nocompat", ""); - success("euc-jp", "\xA4\xA2", "utf-16be", "\x30\x42"); - einval("euc-jp", "\xA4\xA2\xA4", "utf-16be", "\x30\x42"); - eilseq("euc-jp", "\xA4\xA2\xFF\xFF", "utf-16be", "\x30\x42"); - success("cp932", "\x81\x60", "iso-2022-jp", "\x1B\x24\x42\x21\x41\x1B\x28\x42"); - success("UTF-16BE", "\xFF\x5E", "iso-2022-jp", "\x1B\x24\x42\x21\x41\x1B\x28\x42"); - eilseq("UTF-16BE", "\x30\x1C", "iso-2022-jp//nocompat", ""); - success("UTF-16BE", "\x30\x42\x30\x44", "iso-2022-jp", "\x1B\x24\x42\x24\x22\x24\x24\x1B\x28\x42"); - success("iso-2022-jp", "\x1B\x24\x42\x21\x41\x1B\x28\x42", "UTF-16BE", "\xFF\x5E"); - } - - /* - * test for //translit - * U+FF41 (FULLWIDTH LATIN SMALL LETTER A) <-> U+0062 (LATIN SMALL LETTER A) - */ - eilseq("UTF-16BE", "\xFF\x41", "iso-8859-1", ""); - success("UTF-16BE", "\xFF\x41", "iso-8859-1//translit", "a"); - - /* - * TODO: - * Test for state after iconv() failed. - * Ensure iconv() error is safe and continuable. - */ - - return 0; -} - diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index ef66d7c2e8..5bd65cfa18 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -521,14 +521,6 @@ Binaries;Content;Satellites INSTALLFOLDER - - mod_gsmopen - {74b120ff-6935-4dfe-a142-cdb6bea99c90} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_loopback {b3f424ec-3d8f-417c-b244-3919d5e1a577} From 1944260c7be8732f0e6146fc4629e2a84114b5cf Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 27 Aug 2024 16:45:57 +0000 Subject: [PATCH 181/205] [mod_sangoma_codec] Remove from tree --- LICENSE | 3 +- build/modules.conf.in | 1 - build/modules.conf.most | 1 - ci.sh | 1 - .../autoload_configs/sangoma_codec.conf.xml | 37 - configure.ac | 3 +- debian/bootstrap.sh | 1 - debian/control-modules | 5 - debian/copyright | 6 - freeswitch.spec | 39 - src/mod/codecs/mod_sangoma_codec/Makefile.am | 8 - .../mod_sangoma_codec/mod_sangoma_codec.c | 1536 ----------------- 12 files changed, 2 insertions(+), 1639 deletions(-) mode change 100644 => 100755 build/modules.conf.in mode change 100644 => 100755 build/modules.conf.most delete mode 100644 conf/vanilla/autoload_configs/sangoma_codec.conf.xml mode change 100644 => 100755 configure.ac mode change 100644 => 100755 debian/control-modules mode change 100644 => 100755 debian/copyright mode change 100644 => 100755 freeswitch.spec delete mode 100644 src/mod/codecs/mod_sangoma_codec/Makefile.am delete mode 100644 src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c diff --git a/LICENSE b/LICENSE index 7d64386fb2..d106a66b4f 100644 --- a/LICENSE +++ b/LICENSE @@ -1582,8 +1582,7 @@ Files: libs/libcodec2/src/pack.c Copyright: 2010 Perens LLC License: GPL-3+ -Files: src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c - src/include/switch_profile.h +Files: src/include/switch_profile.h src/switch_profile.c Copyright: 2009,2010, Sangoma Technologies License: BSD-3-clause diff --git a/build/modules.conf.in b/build/modules.conf.in old mode 100644 new mode 100755 index d114df88f5..62156fa785 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -75,7 +75,6 @@ codecs/mod_h26x #codecs/mod_isac #codecs/mod_mp4v codecs/mod_opus -#codecs/mod_sangoma_codec #codecs/mod_silk #codecs/mod_siren #codecs/mod_theora diff --git a/build/modules.conf.most b/build/modules.conf.most old mode 100644 new mode 100755 index 43a5290057..77cdfc346b --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -72,7 +72,6 @@ codecs/mod_ilbc codecs/mod_isac codecs/mod_mp4v codecs/mod_opus -codecs/mod_sangoma_codec codecs/mod_silk codecs/mod_siren codecs/mod_theora diff --git a/ci.sh b/ci.sh index e2ebe67ea1..d7322c4432 100755 --- a/ci.sh +++ b/ci.sh @@ -96,7 +96,6 @@ configure_freeswitch() -e '/mod_mp4/s/^/#/g' \ -e '/mod_mongo/s/^/#/g' \ -e '/mod_pocketsphinx/s/^/#/g' \ - -e '/mod_sangoma_codec/s/^/#/g' \ -e '/mod_siren/s/^/#/g' \ -e '/mod_avmd/s/^/#/g' \ -e '/mod_basic/s/^/#/g' \ diff --git a/conf/vanilla/autoload_configs/sangoma_codec.conf.xml b/conf/vanilla/autoload_configs/sangoma_codec.conf.xml deleted file mode 100644 index eed9d673e1..0000000000 --- a/conf/vanilla/autoload_configs/sangoma_codec.conf.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - diff --git a/configure.ac b/configure.ac old mode 100644 new mode 100755 index ed3eb4f32b..8de0226b7d --- a/configure.ac +++ b/configure.ac @@ -1079,7 +1079,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xclang" ; then fi # Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready -# Untested modules : mod_osp mod_soundtouch mod_sangoma_codec mod_opal mod_h323 mod_khomp +# Untested modules : mod_osp mod_soundtouch mod_opal mod_h323 mod_khomp # mod_cepstral mod_erlang_event mod_snmp mod_perl mod_java mod_managed # #saved_CFLAGS="$CFLAGS" @@ -2171,7 +2171,6 @@ AC_CONFIG_FILES([Makefile src/mod/codecs/mod_mp4v/Makefile src/mod/codecs/mod_opus/Makefile src/mod/codecs/mod_openh264/Makefile - src/mod/codecs/mod_sangoma_codec/Makefile src/mod/codecs/mod_silk/Makefile src/mod/codecs/mod_siren/Makefile src/mod/codecs/mod_skel_codec/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 484ba54555..05ee167c51 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -46,7 +46,6 @@ avoid_mods=( codecs/mod_com_g729 codecs/mod_openh264 codecs/mod_siren - codecs/mod_sangoma_codec codecs/mod_skel_codec endpoints/mod_h323 endpoints/mod_khomp diff --git a/debian/control-modules b/debian/control-modules old mode 100644 new mode 100755 index 291ffc1940..50880ae56c --- a/debian/control-modules +++ b/debian/control-modules @@ -360,11 +360,6 @@ Description: mod_opus Adds mod_opus. Build-Depends: libopus-dev -Module: codecs/mod_sangoma_codec -Description: mod_sangoma_codec - Adds mod_sangoma_codec. -Build-Depends: libsngtc-dev - Module: codecs/mod_silk Description: mod_silk Adds mod_silk. diff --git a/debian/copyright b/debian/copyright old mode 100644 new mode 100755 index a2860ea7b9..18b2f92ddc --- a/debian/copyright +++ b/debian/copyright @@ -1582,12 +1582,6 @@ Files: libs/libcodec2/src/pack.c Copyright: 2010 Perens LLC License: GPL-3+ -Files: src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c - src/include/switch_profile.h - src/switch_profile.c -Copyright: 2009,2010, Sangoma Technologies -License: BSD-3-clause - Files: src/mod/codecs/mod_isac/* Copyright: 2011-2012 The WebRTC project authors License: BSD-3-clause diff --git a/freeswitch.spec b/freeswitch.spec old mode 100644 new mode 100755 index 9a28d21324..a3ddd6efc2 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -29,17 +29,11 @@ # ###################################################################################################################### # Module build settings -%define build_sng_isdn 0 -%define build_sng_ss7 0 -%define build_sng_tc 0 %define build_py26_esl 0 %define build_timerfd 0 %define build_mod_esl 0 %define build_mod_v8 0 -%{?with_sang_tc:%define build_sng_tc 1 } -%{?with_sang_isdn:%define build_sng_isdn 1 } -%{?with_sang_ss7:%define build_sng_ss7 1 } %{?with_py26_esl:%define build_py26_esl 1 } %{?with_timerfd:%define build_timerfd 1 } %{?with_mod_esl:%define build_mod_esl 1 } @@ -746,19 +740,6 @@ BuildRequires: opus-devel >= 1.1 %description codec-opus OPUS Codec support for FreeSWITCH open source telephony platform -%if %{build_sng_tc} -%package sangoma-codec -Summary: Sangoma D100 and D500 Codec Card Support -Group: System/Libraries -Requires: %{name} = %{version}-%{release} -Requires: sng-tc-linux -BuildRequires: sng-tc-linux - -%description sangoma-codec -Sangoma D100 and D500 Codec Card Support - -%endif - %package codec-silk Summary: Silk Codec support for FreeSWITCH open source telephony platform Group: System/Libraries @@ -1394,9 +1375,6 @@ CODECS_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_bv codecs/mod_codec2 codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_mp4v codecs/mod_opus codecs/mod_silk \ codecs/mod_siren codecs/mod_theora" # -%if %{build_sng_tc} -CODECS_MODULES+="codecs/mod_sangoma_codec" -%endif ###################################################################################################################### # @@ -1648,17 +1626,6 @@ cd ../.. # ###################################################################################################################### -%if %{build_sng_ss7} -#do not delete a thing -%else -%{__rm} -f %{buildroot}/%{MODINSTDIR}/ftmod_sangoma_ss7* -%endif -%if %{build_sng_isdn} -#do not delete a thing -%else -%{__rm} -f %{buildroot}/%{MODINSTDIR}/ftmod_sangoma_isdn* -%endif - %{__rm} -f %{buildroot}/%{LIBDIR}/*.la %{__rm} -f %{buildroot}/%{MODINSTDIR}/*.la @@ -1886,7 +1853,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/redis.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/rss.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/rtmp.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/sangoma_codec.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/shout.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/signalwire.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/skinny.conf.xml @@ -2140,11 +2106,6 @@ fi %{MODINSTDIR}/mod_opus.so* %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opus.conf.xml -%if %{build_sng_tc} -%files sangoma-codec -%{MODINSTDIR}/mod_sangoma_codec.so* -%endif - %files codec-silk %{MODINSTDIR}/mod_silk.so* diff --git a/src/mod/codecs/mod_sangoma_codec/Makefile.am b/src/mod/codecs/mod_sangoma_codec/Makefile.am deleted file mode 100644 index eff90fe297..0000000000 --- a/src/mod/codecs/mod_sangoma_codec/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_sangoma_codec - -mod_LTLIBRARIES = mod_sangoma_codec.la -mod_sangoma_codec_la_SOURCES = mod_sangoma_codec.c -mod_sangoma_codec_la_CFLAGS = $(AM_CFLAGS) -mod_sangoma_codec_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_sangoma_codec_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lsngtc_node diff --git a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c b/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c deleted file mode 100644 index 0eb9eac2fe..0000000000 --- a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "switch.h" - -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_sangoma_codec_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sangoma_codec_shutdown); -SWITCH_MODULE_DEFINITION(mod_sangoma_codec, mod_sangoma_codec_load, mod_sangoma_codec_shutdown, NULL); - -#define SANGOMA_SESS_HASH_KEY_FORMAT "sngtc%lu" - -/* it seemed we need higher PTIME than the calling parties, so we assume nobody will use higher ptime than 40 */ -#define SANGOMA_DEFAULT_SAMPLING_RATE 80 -#define SANGOMA_TRANSCODE_CONFIG "sangoma_codec.conf" - -/* \brief vocallos configuration */ -static sngtc_init_cfg_t g_init_cfg; - -/* configured RTP IP */ -static int g_rtpip = 0; - -static char g_soap_url[255] = ""; - -/* \brief protect vocallo session creation and destroy */ -static switch_mutex_t *g_sessions_lock = NULL; - -/* \brief next unique session id (protected by g_sessions_lock) */ -unsigned long long g_next_session_id = 0; - -/* hash of sessions (I think a linked list suits better here, but FS does not have the data type) */ -static switch_hash_t *g_sessions_hash = NULL; - -typedef struct vocallo_codec_s { - int codec_id; /* vocallo codec ID */ - int iana; /* IANA code to register in FS */ - const char *iana_name; /* IANA name to register in FS */ - const char *fs_name; - int maxms; /* max supported ms (WARNING: codec impl from 10ms up to this value will be registered if autoinit=1) */ - int bps; /* bits per second */ - - /* following values must be set assuming frames of 10ms */ - int mpf; /* microseconds per frame */ - int spf; /* samples per frame */ - int bpfd; /* bytes per frame decompressed */ - int bpfc; /* bytes per frame compressed */ - - int sampling_rate; /* declared sampling rate */ - int actual_sampling_rate; /* true sampling rate */ - int autoinit; /* initialize on start loop or manually */ -} vocallo_codec_t; - -vocallo_codec_t g_codec_map[] = -{ - /* auto-init codecs */ - { SNGTC_CODEC_PCMU, IANA_PCMU_A_8000_1, "PCMU", "Sangoma PCMU", 40, 64000, 10000, 80, 160, 80, 8000, 8000, 1 }, - { SNGTC_CODEC_PCMA, IANA_PCMA_A_8000_1, "PCMA", "Sangoma PCMA", 40, 64000, 10000, 80, 160, 80, 8000, 8000, 1 }, - { SNGTC_CODEC_L16_1, IANA_L16_A_8000_1, "L16", "Sangoma L16", 40, 120000, 10000, 80, 160, 160, 8000, 8000, 0 }, - { SNGTC_CODEC_L16_2, IANA_L16_A_16000_1, "L16", "Sangoma L16 2", 40, 320000, 10000, 160, 320, 320, 16000, 16000, 0 }, - { SNGTC_CODEC_G726_32, IANA_G726_32_8000_1, "G726-32", "Sangoma G.726 32k", 40, 32000, 10000, 80, 160, 40, 8000, 8000, 1 }, - { SNGTC_CODEC_G722, IANA_G722_A_8000_1, "G722", "Sangoma G722", 20, 64000, 10000, 80, 160, 80, 8000, 8000, 1 }, - - /* manually initialized */ - { SNGTC_CODEC_GSM_FR, IANA_GSM_A_8000_1, "GSM", "Sangoma GSM", 20, 13200, 20000, 160, 320, 33, 8000, 8000, 0 }, - { SNGTC_CODEC_G723_1_63, IANA_G723_A_8000_1, "G723", "Sangoma G723", 90, 6300, 30000, 240, 480, 24, 8000, 8000, 0 }, - { SNGTC_CODEC_G729AB, IANA_G729_AB_8000_1, "G729", "Sangoma G729", 50, 8000, 10000, 80, 160, 10, 8000, 8000, 0 }, - { SNGTC_CODEC_AMR_1220, IANA_AMR_A_8000_1, "AMR", "Sangoma AMR", 20, 12200, 20000, 160, 320, 0, 8000, 8000, 0 }, - { SNGTC_CODEC_SIREN7_24, IANA_SIREN7, "G7221", "Sangoma G722.1", 20, 24000, 20000, 320, 640, 60, 16000, 16000, 0 }, - { SNGTC_CODEC_SIREN7_32, IANA_SIREN7, "G7221", "Sangoma G722.1", 20, 32000, 20000, 320, 640, 80, 16000, 16000, 0 }, - { SNGTC_CODEC_ILBC_133, IANA_ILBC_133_8000_1, "iLBC", "Sangoma iLBC", 30, 13330, 30000, 240, 480, 50, 8000, 8000, 0 }, - { SNGTC_CODEC_ILBC_152, IANA_ILBC_152_8000_1, "iLBC", "Sangoma iLBC", 20, 15200, 20000, 160, 320, 38, 8000, 8000, 0 }, - { -1, -1, NULL, NULL, -1, -1, -1, -1, -1, -1, -1, -1, 0 }, -}; - -/* RFC3389 RTP Payload for Comfort Noise */ -#define IANACODE_CN 13 - -/* default codec list to load, users may override, special codec 'all' registers everything available unless listed in noregister */ -static char g_codec_register_list[1024] = "G729"; - -/* default codec list to NOT load, users may override */ -static char g_codec_noregister_list[1024] = ""; - -#define SANGOMA_RTP_QUEUE_SIZE 4 -struct sangoma_rtp_payload { - uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; - int32_t datalen; -}; - -struct codec_data { - /* sngtc request and reply */ - sngtc_codec_request_t request; - sngtc_codec_reply_t reply; - - /* rtp streams */ - void *txrtp; - void *rxrtp; - - /* packet counters */ - unsigned long tx; - unsigned long rx; - unsigned long ticks; - - /* Lost packets */ - long lastrxseqno; - unsigned long rxlost; - - /* discarded silence packets */ - unsigned long rxdiscarded; - - /* avg Rx time */ - switch_time_t avgrxus; - switch_time_t last_rx_time; - switch_time_t last_func_call_time; - - /* RTP queue. The bigger the queue, the bigger the possible delay */ - struct sangoma_rtp_payload rtp_queue[SANGOMA_RTP_QUEUE_SIZE]; - uint8_t queue_windex; - uint8_t queue_rindex; - uint8_t queue_size; - uint8_t queue_max_ever; - unsigned debug_timing:1; -}; - -struct sangoma_transcoding_session { - /* unique session id */ - unsigned long sessid; - char hashkey[25]; - - /* encoder and decoder */ - struct codec_data encoder; - struct codec_data decoder; - - /* codec implementation */ - const switch_codec_implementation_t *impl; - - /* memory pool */ - switch_memory_pool_t *pool; -}; - -static int codec_id_to_iana(int codec_id) -{ - int i; - for (i = 0; g_codec_map[i].codec_id != -1; i++) { - if (codec_id == g_codec_map[i].codec_id) { - return g_codec_map[i].iana; - } - } - return -1; -} - -static vocallo_codec_t *get_codec_from_iana(int iana, int bitrate) -{ - int i; - for (i = 0; g_codec_map[i].codec_id != -1; i++) { - if (iana == g_codec_map[i].iana && !bitrate) { - return &g_codec_map[i]; - } - if (iana == g_codec_map[i].iana && bitrate == g_codec_map[i].bps) { - return &g_codec_map[i]; - } - } - return NULL; -} - -static vocallo_codec_t *get_codec_from_id(int id) -{ - int i; - for (i = 0; g_codec_map[i].codec_id != -1; i++) { - if (id == g_codec_map[i].codec_id) { - return &g_codec_map[i]; - } - } - return NULL; -} - -static int sangoma_create_rtp_port(void *usr_priv, uint32_t host_ip, uint32_t *p_rtp_port, void **rtp_fd) -{ - struct in_addr local_ip_addr = { 0 }; - char local_ip[255]; - switch_port_t rtp_port; - - local_ip_addr.s_addr = htonl(host_ip); - - switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip)); - - /* request a port */ - if (!(rtp_port = switch_rtp_request_port(local_ip))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate RTP port for IP %s\n", local_ip); - return -1; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "New allocated port %d for IP %s/%d.%d.%d.%d\n", rtp_port, local_ip, - SNGTC_NIPV4(host_ip)); - *p_rtp_port = rtp_port; - *rtp_fd = NULL; - return 0; -} - -static int sangoma_release_rtp_port(void *usr_priv, uint32_t host_ip, uint32_t p_rtp_port, void *rtp_fd) -{ - struct in_addr local_ip_addr = { 0 }; - char local_ip[255]; - switch_port_t rtp_port = p_rtp_port; - - local_ip_addr.s_addr = htonl(host_ip); - - switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip)); - - /* release the port */ - switch_rtp_release_port(local_ip, rtp_port); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Released port %d for IP %s/%d.%d.%d.%d\n", rtp_port, local_ip, - SNGTC_NIPV4(host_ip)); - return 0; -} - -static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_req_leg, sngtc_codec_reply_leg_t* codec_reply_leg, void **rtp_fd) -{ - switch_status_t status; - switch_memory_pool_t *sesspool = NULL; - switch_rtp_t *rtp_session = NULL; - char codec_ip[255]; - switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0}; - int iana = 0; - const char *err = NULL; - struct in_addr local_ip_addr = { 0 }; - char local_ip[255]; - switch_port_t rtp_port; - struct sangoma_transcoding_session *sess = usr_priv; - - rtp_port = codec_req_leg->host_udp_port; - *rtp_fd = NULL; - - /* - * We *MUST* use a new pool - * Do not use the session pool since the session may go away while the RTP socket should linger around - * until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call) - * also do not use the module pool otherwise memory would keep growing because switch_rtp_destroy does not - * free the memory used (is assumed it'll be freed when the pool is destroyed) - */ - status = switch_core_new_memory_pool(&sesspool); - if (status != SWITCH_STATUS_SUCCESS) { - return -1; - } - - local_ip_addr.s_addr = htonl(codec_req_leg->host_ip); - switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip)); - sngtc_codec_ipv4_hex_to_str(codec_reply_leg->codec_ip, codec_ip); - - iana = codec_id_to_iana(codec_req_leg->codec_id); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Creating RTP session for host (%s/%d) vocallo(%s/%d) Iana=%d CodecId=%d ms=%d idx=%lu\n", - local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana, codec_req_leg->codec_id, - codec_req_leg->ms*1000, sess->sessid); - - /* create the RTP socket */ - rtp_session = switch_rtp_new(local_ip, rtp_port, - codec_ip, codec_reply_leg->codec_udp_port, - iana, - sess->impl->samples_per_packet, - codec_req_leg->ms * 1000, /* microseconds per packet */ - flags, NULL, &err, sesspool, 0, 0); - - if (!rtp_session) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create switch rtp session: %s\n", err); - switch_core_destroy_memory_pool(&sesspool); - return -1; - } - switch_rtp_set_private(rtp_session, sesspool); - *rtp_fd = rtp_session; - - return 0; -} - -static int sangoma_destroy_rtp(void *usr_priv, void *fd) -{ - switch_memory_pool_t *sesspool; - switch_rtp_t *rtp = fd; - if (!rtp) { - return 0; - } - sesspool = switch_rtp_get_private(rtp); - switch_rtp_destroy(&rtp); - switch_core_destroy_memory_pool(&sesspool); - return 0; -} - -static switch_status_t switch_sangoma_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - uint32_t encoding, decoding; - struct sangoma_transcoding_session *sess = NULL; - vocallo_codec_t *vcodec; - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sangoma init called (encoding = %d, decoding = %d, iana = %d)\n", encoding ? 1 : 0, decoding ? 1 : 0, codec->implementation->ianacode); - - if (!(encoding || decoding)) { - return SWITCH_STATUS_FALSE; - } - - if (!(sess = switch_core_alloc(codec->memory_pool, sizeof(*sess)))) { - return SWITCH_STATUS_FALSE; - } - sess->encoder.lastrxseqno = -1; - sess->decoder.lastrxseqno = -1; - - sess->pool = codec->memory_pool; - sess->impl = codec->implementation; - switch_assert(sess->pool); - switch_assert(sess->impl); - - vcodec = get_codec_from_iana(codec->implementation->ianacode, codec->implementation->bits_per_second); - - if (encoding) { - sess->encoder.request.usr_priv = sess; - sess->encoder.request.a.host_ip = g_rtpip; - sess->encoder.request.a.codec_id = vcodec->actual_sampling_rate == 16000 - ? SNGTC_CODEC_L16_2 : SNGTC_CODEC_L16_1; - sess->encoder.request.a.ms = codec->implementation->microseconds_per_packet/1000; - - sess->encoder.request.b.host_ip = g_rtpip; - sess->encoder.request.b.codec_id = vcodec->codec_id; - sess->encoder.request.b.ms = codec->implementation->microseconds_per_packet/1000; - } - - if (decoding) { - sess->decoder.request.usr_priv = sess; - sess->decoder.request.a.host_ip = g_rtpip; - sess->decoder.request.a.codec_id = vcodec->codec_id; - sess->decoder.request.a.ms = codec->implementation->microseconds_per_packet/1000; - - sess->decoder.request.b.host_ip = g_rtpip; - sess->decoder.request.b.codec_id = vcodec->actual_sampling_rate == 16000 - ? SNGTC_CODEC_L16_2 : SNGTC_CODEC_L16_1; - sess->decoder.request.b.ms = codec->implementation->microseconds_per_packet/1000; - - } - - switch_mutex_lock(g_sessions_lock); - - sess->sessid = g_next_session_id++; - switch_snprintf(sess->hashkey, sizeof(sess->hashkey), SANGOMA_SESS_HASH_KEY_FORMAT, sess->sessid); - switch_core_hash_insert(g_sessions_hash, sess->hashkey, sess); - - switch_mutex_unlock(g_sessions_lock); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sangoma init done for codec %s/%s, iana = %d\n", codec->implementation->iananame, vcodec->fs_name, codec->implementation->ianacode); - codec->private_info = sess; - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_sangoma_init_ilbc(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - int mode = codec->implementation->microseconds_per_packet / 1000; - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "mode")) { - mode = atoi(arg); - } - } - } - } - codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode); - return switch_sangoma_init(codec, flags, codec_settings); -} - -static switch_status_t switch_sangoma_init_siren7(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - int bit_rate = codec->implementation->bits_per_second; - codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate); - return switch_sangoma_init(codec, flags, codec_settings); -} - -static switch_status_t switch_sangoma_init_g729(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - if (codec->fmtp_in) { - codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); - } - - return switch_sangoma_init(codec, flags, codec_settings); -} - -static void flush_rtp(switch_rtp_t *rtp) -{ - switch_status_t sres; - switch_frame_t read_frame; - int flushed = 0; - int sanity = 1000; - while (sanity--) { - sres = switch_rtp_zerocopy_read_frame(rtp, &read_frame, SWITCH_IO_FLAG_NOBLOCK); - if (sres == SWITCH_STATUS_GENERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session while flushing: %d\n", sres); - return; - } - if (!read_frame.datalen) { - break; - } - flushed++; - } - if (!sanity) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Insanely big UDP queue!\n"); - } -} - -#define SAFE_INDEX_INC(array, index) \ - (index)++; \ - if ((index) == switch_arraylen((array))) { \ - (index) = 0; \ - } - -static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec_t *other_codec, /* codec that was used by the other side */ - void *decoded_data, /* decoded data that we must encode */ - uint32_t decoded_data_len /* decoded data length */ , - uint32_t decoded_rate /* rate of the decoded data */ , - void *encoded_data, /* here we will store the encoded data */ - uint32_t *encoded_data_len, /* here we will set the length of the encoded data */ - uint32_t *encoded_rate /* here we will set the rate of the encoded data */ , - unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ ) -{ - /* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check - * whether the buffer passed in by the core (encoded_data) will be big enough */ - switch_frame_t linear_frame; - switch_frame_t encoded_frame; - switch_status_t sres = SWITCH_STATUS_FALSE; - uint16_t decoded_byteswapped_data[SWITCH_RECOMMENDED_BUFFER_SIZE]; - uint16_t *decoded_data_linear = decoded_data; - switch_time_t now_time = 0, difftime = 0; - switch_time_t func_start_time = 0, func_end_time = 0; - int i = 0; - int res = 0; - int linear_payload = codec->implementation->actual_samples_per_second == 8000 ? IANA_L16_A_8000_1 : IANA_L16_A_16000_1; - struct sangoma_transcoding_session *sess = codec->private_info; - - if (sess->encoder.debug_timing) { - func_start_time = switch_micro_time_now(); - } - - sess->encoder.ticks++; - - /* start assuming we will not encode anything */ - *encoded_data_len = 0; - - /* initialize on first use */ - if (!sess->encoder.txrtp) { - int err = 0; - switch_mutex_lock(g_sessions_lock); - err = sngtc_create_transcoding_session(&sess->encoder.request, &sess->encoder.reply, 0); - if (err) { - memset(&sess->encoder, 0, sizeof(sess->encoder)); - switch_mutex_unlock(g_sessions_lock); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create Sangoma encoding session.\n"); - return SWITCH_STATUS_FALSE; - } - sess->encoder.txrtp = sess->encoder.reply.tx_fd; - sess->encoder.rxrtp = sess->encoder.reply.rx_fd; - switch_mutex_unlock(g_sessions_lock); - flush_rtp(sess->encoder.rxrtp); - } - - if (sess->encoder.debug_timing && sess->encoder.last_func_call_time) { - difftime = func_start_time - sess->encoder.last_func_call_time; - if (difftime > 25000 || difftime < 15000) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%ldus since last read on encoding session %lu\n", (long)difftime, sess->sessid); - } - } - - /* do the writing */ - memset(&linear_frame, 0, sizeof(linear_frame)); - linear_frame.source = __SWITCH_FUNC__; - linear_frame.data = decoded_byteswapped_data; - linear_frame.datalen = decoded_data_len; - linear_frame.payload = linear_payload; - - /* copy and byte-swap */ - for (i = 0; i < decoded_data_len/2; i++) { - decoded_byteswapped_data[i] = (decoded_data_linear[i] << 8) | (decoded_data_linear[i] >> 8); - } - - - res = switch_rtp_write_frame(sess->encoder.txrtp, &linear_frame); - if (-1 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to Sangoma encoder RTP session.\n"); - return SWITCH_STATUS_FALSE; - } - - if (res < i) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Requested to write %d bytes to Sangoma encoder RTP session, but wrote %d bytes.\n", i, res); - return SWITCH_STATUS_FALSE; - } - sess->encoder.tx++; - - /* do the reading */ - for ( ; ; ) { -#if 0 - prevread_time = switch_micro_time_now(); -#endif - sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK); - if (sres == SWITCH_STATUS_GENERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres); - return SWITCH_STATUS_FALSE; - } - -#if 0 - afterread_time = switch_micro_time_now(); - difftime = afterread_time - prevread_time; - if (difftime > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%ldus to read on encoding session %lu.\n", (long)difftime, sess->sessid); - } -#endif - if (0 == encoded_frame.datalen) { - break; - } - - if (encoded_frame.payload == IANACODE_CN) { - /* confort noise is treated as silence by us */ - continue; - } - - if (codec->implementation->encoded_bytes_per_packet && encoded_frame.datalen != codec->implementation->encoded_bytes_per_packet) { - /* seen when silence suppression is enabled */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring encoded frame of %d bytes intead of %d bytes\n", encoded_frame.datalen, codec->implementation->encoded_bytes_per_packet); - continue; - } - - if (encoded_frame.payload != codec->implementation->ianacode) { - if (sess->encoder.request.b.codec_id == SNGTC_CODEC_ILBC_152 || sess->encoder.request.b.codec_id == SNGTC_CODEC_ILBC_133) { - /* since we moved to SOAP based communications, the mapping between vocallo IANA and our IANA does not work, - * some codecs checks cannot be completely done, like iLBC */ - if (encoded_frame.payload != IANA_ILBC_152_8000_1 && encoded_frame.payload != IANA_ILBC_133_8000_1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting either %d or %d\n", - encoded_frame.payload, IANA_ILBC_152_8000_1, IANA_ILBC_133_8000_1); - break; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n", - encoded_frame.payload, codec->implementation->ianacode); - break; - } - } - - if (sess->encoder.queue_windex == sess->encoder.queue_rindex) { - if (sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen) { - /* if there is something where we want to write, we're dropping it */ - sess->encoder.rxdiscarded++; -#if 0 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Discarding encoded frame of %d bytes from RTP session %lu, windex = %d, rindex = %d\n", - sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen, sess->sessid, sess->encoder.queue_windex, sess->encoder.queue_rindex); -#endif - SAFE_INDEX_INC(sess->encoder.rtp_queue, sess->encoder.queue_rindex); - sess->encoder.queue_size--; - } - } - - memcpy(sess->encoder.rtp_queue[sess->encoder.queue_windex].data, encoded_frame.data, encoded_frame.datalen); - sess->encoder.rtp_queue[sess->encoder.queue_windex].datalen = encoded_frame.datalen; - SAFE_INDEX_INC(sess->encoder.rtp_queue, sess->encoder.queue_windex); - - /* monitor the queue size */ - sess->encoder.queue_size++; - if (sess->encoder.queue_size > sess->encoder.queue_max_ever) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoder Rx queue for RTP session %lu is now %d, windex = %d, rindex = %d\n", sess->sessid, sess->encoder.queue_size, - sess->encoder.queue_windex, sess->encoder.queue_rindex); - sess->encoder.queue_max_ever = sess->encoder.queue_size; - } - } - - /* update encoding stats if we have a frame to give */ - if (sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen) { - sess->encoder.rx++; - now_time = switch_micro_time_now(); - if (!sess->encoder.last_rx_time) { - sess->encoder.last_rx_time = now_time; - } else { - difftime = now_time - sess->encoder.last_rx_time; - sess->encoder.avgrxus = sess->encoder.avgrxus ? ((sess->encoder.avgrxus + difftime)/2) : difftime; - sess->encoder.last_rx_time = now_time; - } - - /* check sequence and bump lost rx packets count if needed */ - if (sess->encoder.lastrxseqno >= 0) { - if (encoded_frame.seq > (sess->encoder.lastrxseqno + 2) ) { - sess->encoder.rxlost += encoded_frame.seq - sess->encoder.lastrxseqno - 1; - } - } - sess->encoder.lastrxseqno = encoded_frame.seq; - - /* pop the data from the queue */ - *encoded_data_len = sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen; - memcpy(encoded_data, sess->encoder.rtp_queue[sess->encoder.queue_rindex].data, *encoded_data_len); - sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen = 0; - SAFE_INDEX_INC(sess->encoder.rtp_queue, sess->encoder.queue_rindex); - sess->encoder.queue_size--; - if (codec->implementation->encoded_bytes_per_packet && *encoded_data_len != codec->implementation->encoded_bytes_per_packet) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Returning odd encoded frame of %d bytes intead of %d bytes\n", *encoded_data_len, codec->implementation->encoded_bytes_per_packet); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output from sangoma encoder\n"); - } - - if (sess->encoder.debug_timing) { - func_end_time = switch_micro_time_now(); - difftime = func_end_time - func_start_time; - if (difftime > 5000) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%ldus to execute encoding function in session %lu.\n", (long)difftime, sess->sessid); - } - sess->encoder.last_func_call_time = func_end_time; - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_sangoma_decode(switch_codec_t *codec, /* codec session handle */ - switch_codec_t *other_codec, /* what is this? */ - void *encoded_data, /* data that we must decode into slinear and put it in decoded_data */ - uint32_t encoded_data_len, /* length in bytes of the encoded data */ - uint32_t encoded_rate, /* at which rate was the data encoded */ - void *decoded_data, /* buffer where we must put the decoded data */ - uint32_t *decoded_data_len, /* we must set this value to the size of the decoded data */ - uint32_t *decoded_rate, /* rate of the decoded data */ - unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ ) -{ - /* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check - * whether the buffer passed in by the core will be enough */ - switch_frame_t encoded_frame; - switch_frame_t linear_frame; - switch_status_t sres = SWITCH_STATUS_FALSE; - switch_time_t now_time = 0, difftime = 0; - switch_time_t func_start_time = 0, func_end_time = 0; - uint16_t *dbuf_linear; - uint16_t *linear_frame_data; - uint16_t *rtp_data_linear; - int res = 0; - int i = 0; - int linear_payload = codec->implementation->actual_samples_per_second == 8000 ? IANA_L16_A_8000_1 : IANA_L16_A_16000_1; - struct sangoma_transcoding_session *sess = codec->private_info; - - if (sess->decoder.debug_timing) { - func_start_time = switch_micro_time_now(); - } - - dbuf_linear = decoded_data; - sess->decoder.ticks++; - - /* start assuming we will not decode anything */ - *decoded_data_len = 0; - if (*flag & SWITCH_CODEC_FLAG_SILENCE) { - memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet); - *decoded_data_len = codec->implementation->decoded_bytes_per_packet; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Returned silence on request\n"); - return SWITCH_STATUS_SUCCESS; - } - - /* initialize on first use */ - if (!sess->decoder.txrtp) { - int err = 0; - switch_mutex_lock(g_sessions_lock); - err = sngtc_create_transcoding_session(&sess->decoder.request, &sess->decoder.reply, 0); - if (err) { - memset(&sess->decoder, 0, sizeof(sess->decoder)); - switch_mutex_unlock(g_sessions_lock); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create Sangoma decoding session.\n"); - return SWITCH_STATUS_FALSE; - } - sess->decoder.txrtp = sess->decoder.reply.tx_fd; - sess->decoder.rxrtp = sess->decoder.reply.rx_fd; - switch_mutex_unlock(g_sessions_lock); - flush_rtp(sess->decoder.rxrtp); - } - - if (sess->decoder.debug_timing && sess->decoder.last_func_call_time) { - difftime = func_start_time - sess->decoder.last_func_call_time; - if (difftime > 25000 || difftime < 15000) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%ldms since last read on decoding session %lu.\n", (long)difftime, sess->sessid); - } - } - - /* do the writing */ - memset(&encoded_frame, 0, sizeof(encoded_frame)); - encoded_frame.source = __SWITCH_FUNC__; - encoded_frame.data = encoded_data; - encoded_frame.datalen = encoded_data_len; - encoded_frame.payload = codec->implementation->ianacode; - - res = switch_rtp_write_frame(sess->decoder.txrtp, &encoded_frame); - if (-1 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to Sangoma decoder RTP session.\n"); - return SWITCH_STATUS_FALSE; - } - - if (res < encoded_data_len) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Requested to write %d bytes to Sangoma decoder RTP session, but wrote %d bytes.\n", - encoded_data_len, res); - return SWITCH_STATUS_FALSE; - } - sess->decoder.tx++; - - /* do the reading */ - for ( ; ; ) { -#if 0 - prevread_time = switch_micro_time_now(); -#endif - sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &linear_frame, SWITCH_IO_FLAG_NOBLOCK); - if (sres == SWITCH_STATUS_GENERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma decoder RTP session: %d\n", sres); - return SWITCH_STATUS_FALSE; - } - -#if 0 - afterread_time = switch_micro_time_now(); - difftime = afterread_time - prevread_time; - if (difftime > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%ldus to read on decoding session %lu.\n", (long)difftime, sess->sessid); - } -#endif - if (0 == linear_frame.datalen) { - break; - } - - if (linear_frame.payload == IANACODE_CN) { - /* confort noise is treated as silence by us */ - continue; - } - - if (linear_frame.payload != linear_payload) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma decoder RTP session, expecting %d\n", - linear_frame.payload, linear_payload); - break; - } - - - if (sess->decoder.queue_windex == sess->decoder.queue_rindex) { - if (sess->decoder.rtp_queue[sess->decoder.queue_rindex].datalen) { - /* if there is something where we want to write, we're dropping it */ - sess->decoder.rxdiscarded++; -#if 0 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Discarding decoded frame of %d bytes from RTP session %lu, windex = %d, rindex = %d\n", - sess->decoder.rtp_queue[sess->decoder.queue_rindex].datalen, sess->sessid, sess->decoder.queue_windex, sess->decoder.queue_rindex); -#endif - SAFE_INDEX_INC(sess->decoder.rtp_queue, sess->decoder.queue_rindex); - sess->decoder.queue_size--; - } - } - - /* byteswap the received data */ - rtp_data_linear = (unsigned short *)sess->decoder.rtp_queue[sess->decoder.queue_windex].data; - linear_frame_data = linear_frame.data; - for (i = 0; i < linear_frame.datalen/2; i++) { - rtp_data_linear[i] = (linear_frame_data[i] << 8) | (linear_frame_data[i] >> 8); - } - sess->decoder.rtp_queue[sess->decoder.queue_windex].datalen = linear_frame.datalen; - - SAFE_INDEX_INC(sess->decoder.rtp_queue, sess->decoder.queue_windex); - - /* monitor the queue size */ - sess->decoder.queue_size++; - if (sess->decoder.queue_size > sess->decoder.queue_max_ever) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoder Rx queue for RTP session %lu is now %d, windex = %d, rindex = %d\n", sess->sessid, sess->decoder.queue_size, - sess->decoder.queue_windex, sess->decoder.queue_rindex); - sess->decoder.queue_max_ever = sess->decoder.queue_size; - } - } - - if (sess->decoder.rtp_queue[sess->decoder.queue_rindex].datalen) { - /* update decoding stats */ - sess->decoder.rx++; - - now_time = switch_micro_time_now(); - if (!sess->decoder.last_rx_time) { - sess->decoder.last_rx_time = now_time; - } else { - difftime = now_time - sess->decoder.last_rx_time; - sess->decoder.avgrxus = sess->decoder.avgrxus ? ((sess->decoder.avgrxus + difftime)/2) : difftime; - sess->decoder.last_rx_time = now_time; - } - - /* check sequence and bump lost rx packets count if needed */ - if (sess->decoder.lastrxseqno >= 0) { - if (linear_frame.seq > (sess->decoder.lastrxseqno + 2) ) { - sess->decoder.rxlost += linear_frame.seq - sess->decoder.lastrxseqno - 1; - } - } - sess->decoder.lastrxseqno = linear_frame.seq; - - /* pop the data from the queue */ - memcpy(dbuf_linear, sess->decoder.rtp_queue[sess->decoder.queue_rindex].data, sess->decoder.rtp_queue[sess->decoder.queue_rindex].datalen); - *decoded_data_len = sess->decoder.rtp_queue[sess->decoder.queue_rindex].datalen; - sess->decoder.rtp_queue[sess->decoder.queue_rindex].datalen = 0; - SAFE_INDEX_INC(sess->decoder.rtp_queue, sess->decoder.queue_rindex); - sess->decoder.queue_size--; - - if (*decoded_data_len != codec->implementation->decoded_bytes_per_packet) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Returning odd decoded frame of %d bytes intead of %d bytes\n", *decoded_data_len, codec->implementation->decoded_bytes_per_packet); - } - } else { - *decoded_data_len = codec->implementation->decoded_bytes_per_packet; - memset(dbuf_linear, 0, *decoded_data_len); - } - - if (sess->decoder.debug_timing) { - func_end_time = switch_micro_time_now(); - difftime = func_end_time - func_start_time; - if (difftime > 5000) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%ldus to execute decoding function in session %lu.\n", (long)difftime, sess->sessid); - } - sess->decoder.last_func_call_time = func_end_time; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_sangoma_destroy(switch_codec_t *codec) -{ - struct sangoma_transcoding_session *sess = codec->private_info; - /* things that you may do here is closing files, sockets or other resources used during the codec session - * no need to free memory allocated from the pool though, the owner of the pool takes care of that */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sangoma destroy called.\n"); - - switch_mutex_lock(g_sessions_lock); - - if (sess->encoder.txrtp) { - sngtc_free_transcoding_session(&sess->encoder.reply); - } - if (sess->decoder.txrtp) { - sngtc_free_transcoding_session(&sess->decoder.reply); - } - - switch_core_hash_delete(g_sessions_hash, sess->hashkey); - memset(sess, 0, sizeof(*sess)); - - switch_mutex_unlock(g_sessions_lock); - return SWITCH_STATUS_SUCCESS; -} - -static struct sangoma_transcoding_session *sangoma_find_session(unsigned long sessid) -{ - char hashkey[50]; - snprintf(hashkey, sizeof(hashkey), SANGOMA_SESS_HASH_KEY_FORMAT, sessid); - return switch_core_hash_find(g_sessions_hash, hashkey); -} - -static void sangoma_print_stats(switch_stream_handle_t *stream, switch_rtp_numbers_t *stats) -{ - stream->write_function(stream, "Raw bytes: %lu\n", stats->raw_bytes); - stream->write_function(stream, "Media bytes: %lu\n", stats->media_bytes); - stream->write_function(stream, "Packet count: %lu\n", stats->packet_count); - stream->write_function(stream, "Media packet count: %lu\n", stats->media_packet_count); - stream->write_function(stream, "Skip packet count: %lu\n", stats->skip_packet_count); - stream->write_function(stream, "Jitter buffer packet count: %lu\n", stats->jb_packet_count); - stream->write_function(stream, "DTMF packet count: %lu\n", stats->dtmf_packet_count); - stream->write_function(stream, "CNG packet count: %lu\n", stats->cng_packet_count); - stream->write_function(stream, "Flush packet count: %lu\n\n\n", stats->flush_packet_count); -} - -#define SANGOMA_SYNTAX "settings|sessions|stats |debug |nodebug " -SWITCH_STANDARD_API(sangoma_function) -{ - char *argv[10] = { 0 }; - int argc = 0; - char *mycmd = NULL; - switch_bool_t locked = SWITCH_FALSE; - - if (zstr(cmd)) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - return SWITCH_STATUS_SUCCESS; - } - - if (!(mycmd = strdup(cmd))) { - return SWITCH_STATUS_MEMERR; - } - - if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) || !argv[0]) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; - } - - /* Most operations in this API require the global session lock anyways since sessions can disappear at any moment ... */ - switch_mutex_lock(g_sessions_lock); - locked = SWITCH_TRUE; - - if (!strcasecmp(argv[0], "settings")) { - char addrbuff[50]; - int addr; - addr = htonl(g_rtpip); - stream->write_function(stream, "\tRTP IP Address: %s\n", - switch_inet_ntop(AF_INET, &addr, addrbuff, sizeof(addrbuff))); - } else if (!strcasecmp(argv[0], "sessions")) { - /* iterate over sessions hash */ - switch_hash_index_t *hi; - const void *var; - void *val; - unsigned totalsess = 0; -#define STATS_FORMAT "%-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-15.15s %-15.15s\n" - stream->write_function(stream, STATS_FORMAT, - "Session", "Codec", "Enc", "Dec", "Enc Tx", "Enc Rx", "Dec Tx", "Dec Rx", "Enc Lost", "Dec Lost", "Enc AvgRxMs", "Dec AvgRxMs"); - for (hi = switch_core_hash_first(g_sessions_hash); hi; hi = switch_core_hash_next(&hi)) { - struct sangoma_transcoding_session *sess; - char sessid_str[25]; - char encoder_tx_str[25]; - char encoder_rx_str[25]; - char decoder_tx_str[25]; - char decoder_rx_str[25]; - char encoder_lostrx_str[25]; - char decoder_lostrx_str[25]; - char encoder_avgrxus_str[25]; - char decoder_avgrxus_str[25]; - - switch_core_hash_this(hi, &var, NULL, &val); - sess = val; - - snprintf(sessid_str, sizeof(sessid_str), "%lu", sess->sessid); - snprintf(encoder_tx_str, sizeof(encoder_tx_str), "%lu", sess->encoder.tx); - snprintf(encoder_rx_str, sizeof(encoder_rx_str), "%lu", sess->encoder.rx); - snprintf(decoder_tx_str, sizeof(decoder_tx_str), "%lu", sess->decoder.tx); - snprintf(decoder_rx_str, sizeof(decoder_rx_str), "%lu", sess->decoder.rx); - snprintf(encoder_lostrx_str, sizeof(encoder_lostrx_str), "%lu", sess->encoder.rxlost); - snprintf(decoder_lostrx_str, sizeof(decoder_lostrx_str), "%lu", sess->decoder.rxlost); - snprintf(encoder_avgrxus_str, sizeof(encoder_avgrxus_str), "%ld", (long)(sess->encoder.avgrxus/1000)); - snprintf(decoder_avgrxus_str, sizeof(encoder_avgrxus_str), "%ld", (long)(sess->decoder.avgrxus/1000)); - - - stream->write_function(stream, STATS_FORMAT, - sessid_str, - sess->impl->iananame, - sess->encoder.txrtp ? "Yes" : "No", - sess->decoder.txrtp ? "Yes" : "No", - encoder_tx_str, - encoder_rx_str, - decoder_tx_str, - decoder_rx_str, - encoder_lostrx_str, - decoder_lostrx_str, - encoder_avgrxus_str, - decoder_avgrxus_str); - totalsess++; - } - stream->write_function(stream, "Total sessions: %d\n", totalsess); - } else if (!strcasecmp(argv[0], "stats")) { - struct sangoma_transcoding_session *sess; - unsigned long sessid = 0; - switch_rtp_stats_t *stats = NULL; - int ret = 0; - if (argc < 2) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - goto done; - } - ret = sscanf(argv[1], "%lu", &sessid); - if (ret != 1) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - goto done; - } - - sess = sangoma_find_session(sessid); - if (!sess) { - stream->write_function(stream, "Failed to find session %lu\n", sessid); - goto done; - } - stream->write_function(stream, "Stats for transcoding session: %lu\n", sessid); - - if (sess->encoder.rxrtp) { - stats = switch_rtp_get_stats(sess->encoder.rxrtp, NULL); - stream->write_function(stream, "=== %s Encoder ===\n", sess->impl->iananame); - - stream->write_function(stream, "Tx L16 from %d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n\n", SNGTC_NIPV4(sess->encoder.reply.a.host_ip), sess->encoder.reply.a.host_udp_port, - SNGTC_NIPV4(sess->encoder.reply.a.codec_ip), sess->encoder.reply.a.codec_udp_port); - stream->write_function(stream, "Rx %s at %d.%d.%d.%d:%d from %d.%d.%d.%d:%d\n\n", sess->impl->iananame, SNGTC_NIPV4(sess->encoder.reply.b.host_ip), sess->encoder.reply.b.host_udp_port, - SNGTC_NIPV4(sess->encoder.reply.b.codec_ip), sess->encoder.reply.b.codec_udp_port); - - stream->write_function(stream, "Ticks: %lu\n", sess->encoder.ticks); - - stream->write_function(stream, "-- Inbound Stats --\n"); - stream->write_function(stream, "Rx Discarded: %lu\n", sess->encoder.rxdiscarded); - sangoma_print_stats(stream, &stats->inbound); - - - stats = switch_rtp_get_stats(sess->encoder.txrtp, NULL); - stream->write_function(stream, "-- Outbound Stats --\n"); - sangoma_print_stats(stream, &stats->outbound); - } - - if (sess->decoder.rxrtp) { - stats = switch_rtp_get_stats(sess->decoder.rxrtp, NULL); - - stream->write_function(stream, "=== %s Decoder ===\n", sess->impl->iananame); - stream->write_function(stream, "Tx %s from %d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n\n", sess->impl->iananame, SNGTC_NIPV4(sess->decoder.reply.a.host_ip), sess->decoder.reply.a.host_udp_port, - SNGTC_NIPV4(sess->decoder.reply.a.codec_ip), sess->decoder.reply.a.codec_udp_port); - stream->write_function(stream, "Rx L16 at %d.%d.%d.%d:%d from %d.%d.%d.%d:%d\n\n", SNGTC_NIPV4(sess->decoder.reply.b.host_ip), sess->decoder.reply.b.host_udp_port, - SNGTC_NIPV4(sess->decoder.reply.b.codec_ip), sess->decoder.reply.b.codec_udp_port); - stream->write_function(stream, "Ticks: %lu\n", sess->decoder.ticks); - - stream->write_function(stream, "-- Inbound Stats --\n"); - stream->write_function(stream, "Rx Discarded: %lu\n", sess->decoder.rxdiscarded); - sangoma_print_stats(stream, &stats->inbound); - - stats = switch_rtp_get_stats(sess->decoder.txrtp, NULL); - stream->write_function(stream, "-- Outbound Stats --\n"); - sangoma_print_stats(stream, &stats->outbound); - } - } else if (!strcasecmp(argv[0], "debug")) { - struct sangoma_transcoding_session *sess; - unsigned long sessid = 0; - int ret = 0; - if (argc < 2) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - goto done; - } - ret = sscanf(argv[1], "%lu", &sessid); - if (ret != 1) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - goto done; - } - sess = sangoma_find_session(sessid); - if (!sess) { - stream->write_function(stream, "Failed to find session %lu\n", sessid); - goto done; - } - sess->encoder.debug_timing = 1; - sess->decoder.debug_timing = 1; - stream->write_function(stream, "Debug enabled for transcoding session: %lu\n", sessid); - } else if (!strcasecmp(argv[0], "nodebug")) { - struct sangoma_transcoding_session *sess; - unsigned long sessid = 0; - int ret = 0; - if (argc < 2) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - goto done; - } - ret = sscanf(argv[1], "%lu", &sessid); - if (ret != 1) { - stream->write_function(stream, "%s", SANGOMA_SYNTAX); - goto done; - } - sess = sangoma_find_session(sessid); - if (!sess) { - stream->write_function(stream, "Failed to find session %lu\n", sessid); - goto done; - } - sess->encoder.debug_timing = 0; - sess->decoder.debug_timing = 0; - stream->write_function(stream, "Debug disabled for transcoding session: %lu\n", sessid); - } else { - stream->write_function(stream, "Unknown Command [%s]\n", argv[0]); - } - -done: - if (locked) { - switch_mutex_unlock(g_sessions_lock); - } - switch_safe_free(mycmd); - - return SWITCH_STATUS_SUCCESS; -} - -static int sangoma_logger(int level, char *fmt, ...) -{ - char *data; - int ret = 0; - va_list ap; - - va_start(ap, fmt); - ret = switch_vasprintf(&data, fmt, ap); - if (ret == -1) { - return -1; - } - va_end(ap); - - switch (level) { - case SNGTC_LOGLEVEL_DEBUG: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", data); - break; - case SNGTC_LOGLEVEL_WARN: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s\n", data); - break; - case SNGTC_LOGLEVEL_INFO: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", data); - break; - case SNGTC_LOGLEVEL_STATS: - break; - case SNGTC_LOGLEVEL_ERROR: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", data); - break; - case SNGTC_LOGLEVEL_CRIT: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s\n", data); - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unexpected msg with loglevel %d: %s\n", level, data); - } - - free(data); - return 0; -} - -static int sangoma_parse_config(void) -{ - switch_xml_t cfg, settings, param, xml; - struct in_addr rtpaddr; - char localip[255]; - int mask = 0; - int rc = 0; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reading sangoma codec configuration\n"); - if (!(xml = switch_xml_open_cfg(SANGOMA_TRANSCODE_CONFIG, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to open sangoma codec configuration %s\n", SANGOMA_TRANSCODE_CONFIG); - return -1; - } - - memset(&g_init_cfg, 0, sizeof(g_init_cfg)); - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *)switch_xml_attr_soft(param, "name"); - char *val = (char *)switch_xml_attr_soft(param, "value"); - - /* this parameter overrides the default list of codecs to load */ - if (!strcasecmp(var, "register")) { - strncpy(g_codec_register_list, val, sizeof(g_codec_register_list)-1); - g_codec_register_list[sizeof(g_codec_register_list)-1] = 0; - } else if (!strcasecmp(var, "noregister")) { - strncpy(g_codec_noregister_list, val, sizeof(g_codec_noregister_list)-1); - g_codec_noregister_list[sizeof(g_codec_noregister_list)-1] = 0; - } else if (!strcasecmp(var, "soapserver")) { - strncpy(g_soap_url, val, sizeof(g_soap_url)-1); - g_soap_url[sizeof(g_soap_url)-1] = 0; - } else if (!strcasecmp(var, "rtpip")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma RTP IP %s\n", val); - if (switch_inet_pton(AF_INET, val, &rtpaddr) <= 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Sangoma RTP IP %s\n", val); - break; - } - g_rtpip = ntohl(rtpaddr.s_addr); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma codec setting %s\n", var); - } - } - } - - if (!g_rtpip) { - if (SWITCH_STATUS_SUCCESS != switch_find_local_ip(localip, sizeof(localip), &mask, AF_INET)) { - rc = -1; - goto done; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "No RTP IP specified, using %s\n", localip); - switch_inet_pton(AF_INET, localip, &rtpaddr); - g_rtpip = ntohl(rtpaddr.s_addr); - } - -done: - switch_xml_free(xml); - - g_init_cfg.host_nic_vocallo_sz = 0; - - return rc; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sangoma_codec_shutdown) -{ - switch_core_hash_destroy(&g_sessions_hash); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_sangoma_codec_load) -{ - /* the codec interface that will be registered with the core */ - switch_codec_interface_t *codec_interface = NULL; - switch_api_interface_t *api_interface = NULL; - int i = 0, c = 0; - int ilbc_done = 0; - int siren_done = 0; - vocallo_codec_t *ilbc_codec = NULL; - vocallo_codec_t *siren_codec = NULL; - int detected = 0, activated = 0; - - /* make sure we have valid configuration */ - if (sangoma_parse_config()) { - return SWITCH_STATUS_FALSE; - } - - g_init_cfg.log = sangoma_logger; - g_init_cfg.create_rtp = sangoma_create_rtp; - g_init_cfg.create_rtp_port = sangoma_create_rtp_port; - g_init_cfg.destroy_rtp = sangoma_destroy_rtp; - g_init_cfg.release_rtp_port = sangoma_release_rtp_port; - - if (sngtc_detect_init_modules(&g_init_cfg, &detected)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to detect vocallo modules\n"); - return SWITCH_STATUS_FALSE; - } - - if (sngtc_activate_modules(&g_init_cfg, &activated)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to activate vocallo modules\n"); - return SWITCH_STATUS_FALSE; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Detected %d and activated %d Sangoma codec vocallo modules\n", detected, activated); - - if (strlen(g_soap_url)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Using %s SOAP server\n", g_soap_url); - sngtc_set_soap_server_url(g_soap_url); - } - - switch_mutex_init(&g_sessions_lock, SWITCH_MUTEX_UNNESTED, pool); - - switch_core_hash_init(&g_sessions_hash); - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading codecs, register='%s', noregister='%s'\n", g_codec_register_list, g_codec_noregister_list); - for (c = 0; g_codec_map[c].codec_id != -1; c++) { - - if (g_codec_map[c].codec_id == SNGTC_CODEC_L16_1 || g_codec_map[c].codec_id == SNGTC_CODEC_L16_2) { - /* registering L16 does not make any sense */ - continue; - } - - /* check if the codec is in the load list, otherwise skip it */ - if (strcasecmp(g_codec_register_list, "all") && !strcasestr(g_codec_register_list, g_codec_map[c].iana_name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Not loading codec %s because was not found in the load list\n", - g_codec_map[c].iana_name); - continue; - } - - /* load it unless is named in the noload list */ - if (strcasestr(g_codec_noregister_list, g_codec_map[c].iana_name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Not loading codec %s because was not found in the noload list\n", - g_codec_map[c].iana_name); - continue; - } - - /* special check for iLBC to add a single codec interface for both ILBC bitrate versions */ - if ((g_codec_map[c].codec_id == SNGTC_CODEC_ILBC_152 || g_codec_map[c].codec_id == SNGTC_CODEC_ILBC_133) && ilbc_done) { - continue; - } - - /* special check for siren to add a single codec interface for all siren bitrate versions */ - if ((g_codec_map[c].codec_id == SNGTC_CODEC_SIREN7_24 || g_codec_map[c].codec_id == SNGTC_CODEC_SIREN7_32) && siren_done) { - continue; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Registering implementations for codec %s\n", g_codec_map[c].iana_name); - - /* SWITCH_ADD_CODEC allocates a codec interface structure from the pool the core gave us and adds it to the internal interface - * list the core keeps, gets a codec id and set the given codec name to it. - * At this point there is an empty shell codec interface registered, but not yet implementations */ - SWITCH_ADD_CODEC(codec_interface, g_codec_map[c].fs_name); - - /* Now add as many codec implementations as needed, just up to 200ms for now */ - if (g_codec_map[c].autoinit) { - int ms = 0; - for (i = 1; i <= 20; i++) { - ms = i * 10; - if (g_codec_map[c].maxms < ms) { - break; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding %dms implementation of codec %s\n", ms, g_codec_map[c].fs_name); - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - g_codec_map[c].iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - g_codec_map[c].iana_name, /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - g_codec_map[c].sampling_rate, /* samples transferred per second */ - g_codec_map[c].actual_sampling_rate, /* actual samples transferred per second */ - g_codec_map[c].bps, /* bits transferred per second */ - g_codec_map[c].mpf * i, /* microseconds per frame */ - g_codec_map[c].spf * i, /* samples per frame */ - g_codec_map[c].bpfd * i, /* number of bytes per frame decompressed */ - g_codec_map[c].bpfc * i, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - g_codec_map[c].spf * i, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - - } - } else { - - /* custom implementation for some codecs */ - switch (g_codec_map[c].codec_id) { - case SNGTC_CODEC_GSM_FR: - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - g_codec_map[c].iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - g_codec_map[c].iana_name, /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - 8000, /* samples transferred per second */ - 8000, /* actual samples transferred per second */ - g_codec_map[c].bps, /* bits transferred per second */ - g_codec_map[c].mpf, /* microseconds per frame */ - g_codec_map[c].spf, /* samples per frame */ - g_codec_map[c].bpfd, /* number of bytes per frame decompressed */ - g_codec_map[c].bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - g_codec_map[c].spf, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - - break; - case SNGTC_CODEC_ILBC_133: - case SNGTC_CODEC_ILBC_152: - ilbc_codec = get_codec_from_id(SNGTC_CODEC_ILBC_152); - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - ilbc_codec->iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - ilbc_codec->iana_name, /* the IANA code name */ - "mode=20", /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - 8000, /* samples transferred per second */ - 8000, /* actual samples transferred per second */ - 15200, /* bits transferred per second */ - 20000, /* microseconds per frame */ - 160, /* samples per frame */ - 320, /* number of bytes per frame decompressed */ - 38, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init_ilbc, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - - ilbc_codec = get_codec_from_id(SNGTC_CODEC_ILBC_133); - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - ilbc_codec->iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - ilbc_codec->iana_name, /* the IANA code name */ - "mode=30", /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - 8000, /* samples transferred per second */ - 8000, /* actual samples transferred per second */ - 13330, /* bits transferred per second */ - 30000, /* microseconds per frame */ - 240, /* samples per frame */ - 480, /* number of bytes per frame decompressed */ - 50, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init_ilbc, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - ilbc_done = 1; - break; - - case SNGTC_CODEC_G723_1_63: - - for (i = 1; i <= 3; i++) { - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - g_codec_map[c].iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - g_codec_map[c].iana_name, /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - g_codec_map[c].sampling_rate, /* samples transferred per second */ - g_codec_map[c].actual_sampling_rate, /* actual samples transferred per second */ - g_codec_map[c].bps, /* bits transferred per second */ - g_codec_map[c].mpf * i, /* microseconds per frame */ - g_codec_map[c].spf * i, /* samples per frame */ - g_codec_map[c].bpfd * i, /* number of bytes per frame decompressed */ - g_codec_map[c].bpfc * i, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - g_codec_map[c].spf * i, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - } - - break; - - case SNGTC_CODEC_AMR_1220: - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - g_codec_map[c].iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - g_codec_map[c].iana_name, /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - g_codec_map[c].sampling_rate, /* samples transferred per second */ - g_codec_map[c].actual_sampling_rate, /* actual samples transferred per second */ - g_codec_map[c].bps, /* bits transferred per second */ - g_codec_map[c].mpf, /* microseconds per frame */ - g_codec_map[c].spf, /* samples per frame */ - g_codec_map[c].bpfd, /* number of bytes per frame decompressed */ - g_codec_map[c].bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - g_codec_map[c].spf, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - break; - - case SNGTC_CODEC_SIREN7_24: - case SNGTC_CODEC_SIREN7_32: - - siren_codec = get_codec_from_id(SNGTC_CODEC_SIREN7_24); - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - siren_codec->iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - siren_codec->iana_name, /* the IANA code name */ - "bitrate=24000", /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - siren_codec->sampling_rate, /* samples transferred per second */ - siren_codec->actual_sampling_rate, /* actual samples transferred per second */ - siren_codec->bps, /* bits transferred per second */ - siren_codec->mpf, /* microseconds per frame */ - siren_codec->spf, /* samples per frame */ - siren_codec->bpfd, /* number of bytes per frame decompressed */ - siren_codec->bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - siren_codec->spf, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init_siren7, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - - siren_codec = get_codec_from_id(SNGTC_CODEC_SIREN7_32); - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - siren_codec->iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - siren_codec->iana_name, /* the IANA code name */ - "bitrate=32000", /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - siren_codec->sampling_rate, /* samples transferred per second */ - siren_codec->actual_sampling_rate, /* actual samples transferred per second */ - siren_codec->bps, /* bits transferred per second */ - siren_codec->mpf, /* microseconds per frame */ - siren_codec->spf, /* samples per frame */ - siren_codec->bpfd, /* number of bytes per frame decompressed */ - siren_codec->bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - siren_codec->spf, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init_siren7, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - siren_done = 1; - break; - - case SNGTC_CODEC_G729AB: - for (i = 1; i <= 20; i++) { - if (g_codec_map[c].maxms < (i * 10)) { - break; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding %dms implementation of codec %s\n", (i * 10), g_codec_map[c].fs_name); - switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */ - SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - g_codec_map[c].iana, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */ - g_codec_map[c].iana_name, /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */ - g_codec_map[c].sampling_rate, /* samples transferred per second */ - g_codec_map[c].actual_sampling_rate, /* actual samples transferred per second */ - g_codec_map[c].bps, /* bits transferred per second */ - g_codec_map[c].mpf * i, /* microseconds per frame */ - g_codec_map[c].spf * i, /* samples per frame */ - g_codec_map[c].bpfd * i, /* number of bytes per frame decompressed */ - g_codec_map[c].bpfc * i, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - g_codec_map[c].spf * i, /* number of frames per network packet (I dont think this is used at all) */ - switch_sangoma_init_g729, /* function to initialize a codec session using this implementation */ - switch_sangoma_encode, /* function to encode slinear data into encoded data */ - switch_sangoma_decode, /* function to decode encoded data into slinear data */ - switch_sangoma_destroy); /* deinitalize a codec handle using this implementation */ - } - break; - - default: - break; - } - } - } - - - SWITCH_ADD_API(api_interface, "sangoma_codec", "Sangoma Codec Commands", sangoma_function, SANGOMA_SYNTAX); - switch_console_set_complete("add sangoma_codec"); - switch_console_set_complete("add sangoma_codec settings"); - switch_console_set_complete("add sangoma_codec sessions"); - switch_console_set_complete("add sangoma_codec stats"); - switch_console_set_complete("add sangoma_codec debug"); - switch_console_set_complete("add sangoma_codec nodebug"); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ From 4475a54127ba98f20a0a9601f149cc95cebd908e Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 27 Aug 2024 19:13:47 +0000 Subject: [PATCH 182/205] [mod_ladspa] Remove from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - .../vanilla/autoload_configs/modules.conf.xml | 3 - conf/vanilla/dialplan/default/00_ladspa.xml | 77 -- configure.ac | 1 - debian/control-modules | 6 - src/mod/applications/mod_ladspa/Makefile.am | 8 - .../mod_ladspa/conf/dialplan/00_ladspa.xml | 77 -- src/mod/applications/mod_ladspa/docs/README | 4 - src/mod/applications/mod_ladspa/load.c | 173 ----- src/mod/applications/mod_ladspa/mod_ladspa.c | 694 ------------------ src/mod/applications/mod_ladspa/utils.h | 72 -- 12 files changed, 1117 deletions(-) mode change 100644 => 100755 conf/vanilla/autoload_configs/modules.conf.xml delete mode 100644 conf/vanilla/dialplan/default/00_ladspa.xml delete mode 100644 src/mod/applications/mod_ladspa/Makefile.am delete mode 100644 src/mod/applications/mod_ladspa/conf/dialplan/00_ladspa.xml delete mode 100644 src/mod/applications/mod_ladspa/docs/README delete mode 100644 src/mod/applications/mod_ladspa/load.c delete mode 100644 src/mod/applications/mod_ladspa/mod_ladspa.c delete mode 100644 src/mod/applications/mod_ladspa/utils.h diff --git a/build/modules.conf.in b/build/modules.conf.in index 62156fa785..a2e027d4ab 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -26,7 +26,6 @@ applications/mod_hash #applications/mod_hiredis applications/mod_httapi #applications/mod_http_cache -#applications/mod_ladspa #applications/mod_lcr #applications/mod_memcache #applications/mod_mongo diff --git a/build/modules.conf.most b/build/modules.conf.most index 77cdfc346b..d489f2d51f 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -26,7 +26,6 @@ applications/mod_hash applications/mod_hiredis applications/mod_httapi applications/mod_http_cache -#applications/mod_ladspa applications/mod_lcr applications/mod_memcache applications/mod_mongo diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml old mode 100644 new mode 100755 index b5a58d1580..9df8209d1b --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -81,9 +81,6 @@ - - - diff --git a/conf/vanilla/dialplan/default/00_ladspa.xml b/conf/vanilla/dialplan/default/00_ladspa.xml deleted file mode 100644 index a26b193ef5..0000000000 --- a/conf/vanilla/dialplan/default/00_ladspa.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/configure.ac b/configure.ac index 8de0226b7d..6246f1b5a8 100755 --- a/configure.ac +++ b/configure.ac @@ -2119,7 +2119,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_hiredis/Makefile src/mod/applications/mod_httapi/Makefile src/mod/applications/mod_http_cache/Makefile - src/mod/applications/mod_ladspa/Makefile src/mod/applications/mod_lcr/Makefile src/mod/applications/mod_limit/Makefile src/mod/applications/mod_memcache/Makefile diff --git a/debian/control-modules b/debian/control-modules index 50880ae56c..05820b0b72 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -130,12 +130,6 @@ Description: HTTP GET with caching This module provides an API for making HTTP GET requests where the result is cached. -Module: applications/mod_ladspa -Description: LADSPA - This module provides an API for accessing LADSPA plugins. -Build-Depends: ladspa-sdk -Suggests: tap-plugins, swh-plugins, autotalent - Module: applications/mod_lcr Description: LCR This module adds a facility for least-cost routing. diff --git a/src/mod/applications/mod_ladspa/Makefile.am b/src/mod/applications/mod_ladspa/Makefile.am deleted file mode 100644 index 04dcfb662a..0000000000 --- a/src/mod/applications/mod_ladspa/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_ladspa - -mod_LTLIBRARIES = mod_ladspa.la -mod_ladspa_la_SOURCES = mod_ladspa.c load.c -mod_ladspa_la_CFLAGS = $(AM_CFLAGS) -mod_ladspa_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_ladspa_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/applications/mod_ladspa/conf/dialplan/00_ladspa.xml b/src/mod/applications/mod_ladspa/conf/dialplan/00_ladspa.xml deleted file mode 100644 index c950e1b3c0..0000000000 --- a/src/mod/applications/mod_ladspa/conf/dialplan/00_ladspa.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/applications/mod_ladspa/docs/README b/src/mod/applications/mod_ladspa/docs/README deleted file mode 100644 index 3a6337d344..0000000000 --- a/src/mod/applications/mod_ladspa/docs/README +++ /dev/null @@ -1,4 +0,0 @@ -mod_ladspa is a module that allow to use Linux Audio Developer's Simple Plugin API inside freeswitch in realtime. -see http://wiki.freeswitch.org/wiki/Mod_ladspa for installation and configuration documentation. - -Please Note Currently this module only works on Linux. diff --git a/src/mod/applications/mod_ladspa/load.c b/src/mod/applications/mod_ladspa/load.c deleted file mode 100644 index e8976bfa64..0000000000 --- a/src/mod/applications/mod_ladspa/load.c +++ /dev/null @@ -1,173 +0,0 @@ -/* load.c - - Free software by Richard W.E. Furse. Do with as you will. No - warranty. */ - -/*****************************************************************************/ - -#include "switch.h" -#include -#include -#include -#include - -/*****************************************************************************/ - -#include "ladspa.h" -#include "utils.h" -#include "inttypes.h" -/*****************************************************************************/ - -/* This function provides a wrapping of dlopen(). When the filename is - not an absolute path (i.e. does not begin with / character), this - routine will search the LADSPA_PATH for the file. */ -static void *dlopenLADSPA(const char *pcFilename, int iFlag) -{ - - char *pcBuffer; - const char *pcEnd; - const char *pcLADSPAPath; - const char *pcStart; - int iEndsInSO; - int iNeedSlash; - size_t iFilenameLength; - void *pvResult; - - iFilenameLength = strlen(pcFilename); - pvResult = NULL; - - if (pcFilename[0] == '/') { - - /* The filename is absolute. Assume the user knows what he/she is - doing and simply dlopen() it. */ - - pvResult = dlopen(pcFilename, iFlag); - if (pvResult != NULL) - return pvResult; - - } else { - - /* If the filename is not absolute then we wish to check along the - LADSPA_PATH path to see if we can find the file there. We do - NOT call dlopen() directly as this would find plugins on the - LD_LIBRARY_PATH, whereas the LADSPA_PATH is the correct place - to search. */ - - pcLADSPAPath = getenv("LADSPA_PATH"); - - if (pcLADSPAPath) { - - pcStart = pcLADSPAPath; - while (*pcStart != '\0') { - pcEnd = pcStart; - while (*pcEnd != ':' && *pcEnd != '\0') - pcEnd++; - - pcBuffer = malloc(iFilenameLength + 2 + (pcEnd - pcStart)); - if (pcEnd > pcStart) - strncpy(pcBuffer, pcStart, pcEnd - pcStart); - iNeedSlash = 0; - if (pcEnd > pcStart) - if (*(pcEnd - 1) != '/') { - iNeedSlash = 1; - pcBuffer[pcEnd - pcStart] = '/'; - } - strcpy(pcBuffer + iNeedSlash + (pcEnd - pcStart), pcFilename); - - pvResult = dlopen(pcBuffer, iFlag); - - free(pcBuffer); - if (pvResult != NULL) - return pvResult; - - pcStart = pcEnd; - if (*pcStart == ':') - pcStart++; - } - } - } - - /* As a last ditch effort, check if filename does not end with - ".so". In this case, add this suffix and recurse. */ - iEndsInSO = 0; - if (iFilenameLength > 3) - iEndsInSO = (strcmp(pcFilename + iFilenameLength - 3, ".so") == 0); - if (!iEndsInSO) { - pcBuffer = malloc(iFilenameLength + 4); - strcpy(pcBuffer, pcFilename); - strcat(pcBuffer, ".so"); - pvResult = dlopenLADSPA(pcBuffer, iFlag); - free(pcBuffer); - } - - if (pvResult != NULL) - return pvResult; - - /* If nothing has worked, then at least we can make sure we set the - correct error message - and this should correspond to a call to - dlopen() with the actual filename requested. The dlopen() manual - page does not specify whether the first or last error message - will be kept when multiple calls are made to dlopen(). We've - covered the former case - now we can handle the latter by calling - dlopen() again here. */ - return dlopen(pcFilename, iFlag); -} - -/*****************************************************************************/ - -void *loadLADSPAPluginLibrary(const char *pcPluginFilename) -{ - - void *pvPluginHandle; - - pvPluginHandle = dlopenLADSPA(pcPluginFilename, RTLD_NOW); - if (!pvPluginHandle) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load plugin \"%s\": %s\n", pcPluginFilename, dlerror()); - } - - return pvPluginHandle; -} - -/*****************************************************************************/ - -void unloadLADSPAPluginLibrary(void *pvLADSPAPluginLibrary) -{ - dlclose(pvLADSPAPluginLibrary); -} - -/*****************************************************************************/ - -const LADSPA_Descriptor *findLADSPAPluginDescriptor(void *pvLADSPAPluginLibrary, const char *pcPluginLibraryFilename, const char *pcPluginLabel) -{ - - const LADSPA_Descriptor *psDescriptor; - LADSPA_Descriptor_Function pfDescriptorFunction; - unsigned long lPluginIndex; - - dlerror(); - pfDescriptorFunction = (LADSPA_Descriptor_Function) (intptr_t)dlsym(pvLADSPAPluginLibrary, "ladspa_descriptor"); - if (!pfDescriptorFunction) { - const char *pcError = dlerror(); - if (pcError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Unable to find ladspa_descriptor() function in plugin " - "library file \"%s\": %s.\n" "Are you sure this is a LADSPA plugin file?\n", pcPluginLibraryFilename, pcError); - return NULL; - } - } - - for (lPluginIndex = 0;; lPluginIndex++) { - psDescriptor = pfDescriptorFunction(lPluginIndex); - if (psDescriptor == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Unable to find label \"%s\" in plugin library file \"%s\".\n", pcPluginLabel, pcPluginLibraryFilename); - return NULL; - } - if (strcmp(psDescriptor->Label, pcPluginLabel) == 0) - return psDescriptor; - } -} - -/*****************************************************************************/ - -/* EOF */ diff --git a/src/mod/applications/mod_ladspa/mod_ladspa.c b/src/mod/applications/mod_ladspa/mod_ladspa.c deleted file mode 100644 index 6e04e414a9..0000000000 --- a/src/mod/applications/mod_ladspa/mod_ladspa.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * mod_ladspa.c -- LADSPA - * - */ -#include -#include "ladspa.h" -#include "utils.h" - -/* Prototypes */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_ladspa_shutdown); -SWITCH_MODULE_RUNTIME_FUNCTION(mod_ladspa_runtime); -SWITCH_MODULE_LOAD_FUNCTION(mod_ladspa_load); - -/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) - * Defines a switch_loadable_module_function_table_t and a static const char[] modname - */ -SWITCH_MODULE_DEFINITION(mod_ladspa, mod_ladspa_load, mod_ladspa_shutdown, NULL); - -#define MAX_INDEX 256 - -typedef struct { - switch_core_session_t *session; - char *plugin_name; - char *label_name; - void *library_handle; - const LADSPA_Descriptor *ldesc; - LADSPA_Handle handle; - LADSPA_Data config[MAX_INDEX]; - int num_idx; - char *str_config[MAX_INDEX]; - int str_idx; - uint8_t has_config[MAX_INDEX]; - int skip; - LADSPA_Data in_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - LADSPA_Data file_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - LADSPA_Data out_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - LADSPA_Data out_ports[MAX_INDEX]; - switch_file_handle_t fh; -} switch_ladspa_t; - - - -int check_range(const LADSPA_Descriptor *ldesc, int i, LADSPA_Data val) -{ - if (ldesc->PortRangeHints[i].LowerBound && ldesc->PortRangeHints[i].UpperBound && - (val < ldesc->PortRangeHints[i].LowerBound || val > ldesc->PortRangeHints[i].UpperBound)) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Param %f out of bounds %f-%f\n", - val, ldesc->PortRangeHints[i].LowerBound, ldesc->PortRangeHints[i].UpperBound); - return 0; - } - - return 1; -} - -int find_default(const LADSPA_Descriptor *ldesc, int i, LADSPA_Data *ptr) - -{ - LADSPA_Data dftval = 0; - int fail = 0; - - LADSPA_PortRangeHintDescriptor port_hint = ldesc->PortRangeHints[i].HintDescriptor; - - switch (port_hint & LADSPA_HINT_DEFAULT_MASK) { - case LADSPA_HINT_DEFAULT_NONE: - break; - case LADSPA_HINT_DEFAULT_MINIMUM: - dftval = ldesc->PortRangeHints[i].LowerBound; - break; - case LADSPA_HINT_DEFAULT_LOW: - if (LADSPA_IS_HINT_LOGARITHMIC(port_hint)) { - dftval = exp(log(ldesc->PortRangeHints[i].LowerBound) - * 0.75 + log(ldesc->PortRangeHints[i].UpperBound) - * 0.25); - } else { - dftval = (ldesc->PortRangeHints[i].LowerBound * 0.75 + ldesc->PortRangeHints[i].UpperBound * 0.25); - } - break; - case LADSPA_HINT_DEFAULT_MIDDLE: - if (LADSPA_IS_HINT_LOGARITHMIC(port_hint)) { - dftval = sqrt(ldesc->PortRangeHints[i].LowerBound * ldesc->PortRangeHints[i].UpperBound); - } else { - dftval = 0.5 * (ldesc->PortRangeHints[i].LowerBound + ldesc->PortRangeHints[i].UpperBound); - } - break; - case LADSPA_HINT_DEFAULT_HIGH: - if (LADSPA_IS_HINT_LOGARITHMIC(port_hint)) { - dftval = exp(log(ldesc->PortRangeHints[i].LowerBound) - * 0.25 + log(ldesc->PortRangeHints[i].UpperBound) - * 0.75); - } else { - dftval = (ldesc->PortRangeHints[i].LowerBound * 0.25 + ldesc->PortRangeHints[i].UpperBound * 0.75); - } - break; - case LADSPA_HINT_DEFAULT_MAXIMUM: - dftval = ldesc->PortRangeHints[i].UpperBound; - break; - case LADSPA_HINT_DEFAULT_0: - dftval = 0; - break; - case LADSPA_HINT_DEFAULT_1: - dftval = 1; - break; - case LADSPA_HINT_DEFAULT_100: - dftval = 100; - break; - case LADSPA_HINT_DEFAULT_440: - dftval = 440; - break; - default: - fail = 1; - break; - } - - if (!fail) { - *ptr = dftval; - } - - return !fail; -} - -static void dump_info(const LADSPA_Descriptor *ldesc) -{ - int i = 0; - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Plugin Name: \"%s\"\n", ldesc->Name); - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Plugin Label: \"%s\"\n", ldesc->Label); - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Plugin Unique ID: %lu\n", ldesc->UniqueID); - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Maker: \"%s\"\n", ldesc->Maker); - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Copyright: \"%s\"\n", ldesc->Copyright); - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Must Run Real-Time: "); - if (LADSPA_IS_REALTIME(ldesc->Properties)) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n"); - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Has activate() Function: "); - if (ldesc->activate != NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n"); - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Has deactivate() Function: "); - if (ldesc->deactivate != NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n"); - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Has run_adding() Function: "); - if (ldesc->run_adding != NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n"); - - if (ldesc->instantiate == NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO INSTANTIATE FUNCTION.\n"); - if (ldesc->connect_port == NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO CONNECT_PORT FUNCTION.\n"); - if (ldesc->run == NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO RUN FUNCTION.\n"); - if (ldesc->run_adding != NULL && ldesc->set_run_adding_gain == NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS RUN_ADDING FUNCTION BUT " "NOT SET_RUN_ADDING_GAIN.\n"); - if (ldesc->run_adding == NULL && ldesc->set_run_adding_gain != NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS SET_RUN_ADDING_GAIN FUNCTION BUT " "NOT RUN_ADDING.\n"); - if (ldesc->cleanup == NULL) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO CLEANUP FUNCTION.\n"); - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Environment: "); - if (LADSPA_IS_HARD_RT_CAPABLE(ldesc->Properties)) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Normal or Hard Real-Time\n"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Normal\n"); - - if (LADSPA_IS_INPLACE_BROKEN(ldesc->Properties)) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "This plugin cannot use in-place processing. " "It will not work with all hosts.\n"); - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Ports:"); - - if (ldesc->PortCount == 0) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\tERROR: PLUGIN HAS NO PORTS.\n"); - - for (i = 0; i < ldesc->PortCount; i++) { - LADSPA_Data dft = 0.0f; - int found = 0; - - if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i])) { - found = find_default(ldesc, i, &dft); - } - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n \"%s\" ", ldesc->PortNames[i]); - - if (LADSPA_IS_PORT_INPUT(ldesc->PortDescriptors[i]) - && LADSPA_IS_PORT_OUTPUT(ldesc->PortDescriptors[i])) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: INPUT AND OUTPUT"); - else if (LADSPA_IS_PORT_INPUT(ldesc->PortDescriptors[i])) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "input"); - else if (LADSPA_IS_PORT_OUTPUT(ldesc->PortDescriptors[i])) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "output"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: NEITHER INPUT NOR OUTPUT"); - - if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i]) - && LADSPA_IS_PORT_AUDIO(ldesc->PortDescriptors[i])) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", ERROR: CONTROL AND AUDIO"); - else if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i])) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", control"); - else if (LADSPA_IS_PORT_AUDIO(ldesc->PortDescriptors[i])) - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", audio"); - else - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", ERROR: NEITHER CONTROL NOR AUDIO"); - - if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i])) { - if (found) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n RANGE: %f-%f DEFAULT: %f\n", - ldesc->PortRangeHints[i].LowerBound, ldesc->PortRangeHints[i].UpperBound, dft); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n RANGE: %f-%f DEFAULT: none.\n", - ldesc->PortRangeHints[i].LowerBound, ldesc->PortRangeHints[i].UpperBound); - } - } - - - - } - - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n\n"); -} - - - - - -static switch_bool_t ladspa_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) -{ - switch_ladspa_t *pvt = (switch_ladspa_t *) user_data; - //switch_frame_t *frame = NULL; - switch_channel_t *channel = switch_core_session_get_channel(pvt->session); - - switch (type) { - case SWITCH_ABC_TYPE_INIT: - { - switch_codec_implementation_t read_impl = { 0 }; - LADSPA_PortDescriptor port_desc; - int i = 0, j = 0, k = 0, str_idx = 0; - - switch_core_session_get_read_impl(pvt->session, &read_impl); - - if (!(pvt->library_handle = loadLADSPAPluginLibrary(pvt->plugin_name))) { - return SWITCH_FALSE; - } - - if (!(pvt->ldesc = findLADSPAPluginDescriptor(pvt->library_handle, pvt->plugin_name, pvt->label_name))) { - return SWITCH_FALSE; - } - - - pvt->handle = pvt->ldesc->instantiate(pvt->ldesc, read_impl.actual_samples_per_second); - - dump_info(pvt->ldesc); - - - for (i = 0; i < pvt->ldesc->PortCount; i++) { - port_desc = pvt->ldesc->PortDescriptors[i]; - - if (LADSPA_IS_PORT_CONTROL(port_desc) && LADSPA_IS_PORT_INPUT(port_desc)) { - LADSPA_Data dft = 0.0f; - int found = find_default(pvt->ldesc, i, &dft); - - if (found && !pvt->has_config[j]) { - pvt->config[j] = dft; - pvt->has_config[j] = 1; - } - - if (pvt->has_config[j]) { - if (!check_range(pvt->ldesc, i, pvt->config[j])) { - pvt->config[j] = dft; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_WARNING, "FALLING TO DEFAULT PARAM %d [%s] (%f)\n", - j+1, - pvt->ldesc->PortNames[i], - pvt->config[j]); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "ADDING PARAM %d [%s] (%f)\n", - j+1, - pvt->ldesc->PortNames[i], - pvt->config[j]); - pvt->ldesc->connect_port(pvt->handle, i, &pvt->config[j++]); - usleep(10000); - } - } - - if (LADSPA_IS_PORT_INPUT(port_desc) && LADSPA_IS_PORT_AUDIO(port_desc)) { - int mapped = 0; - - if (pvt->str_idx && !zstr(pvt->str_config[str_idx])) { - - if (!strcasecmp(pvt->str_config[str_idx], "none")) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT NOTHING to port: %s\n", - pvt->ldesc->PortNames[i] - ); - mapped = 1; - } else if (!strncasecmp(pvt->str_config[str_idx], "file:", 5)) { - char *file = pvt->str_config[str_idx] + 5; - - if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), - SWITCH_LOG_ERROR, "CAN'T CONNECT FILE [%s] File already mapped\n", file); - } else { - if (switch_core_file_open(&pvt->fh, - file, - read_impl.number_of_channels, - read_impl.actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot open file: %s\n", file); - return SWITCH_FALSE; - } - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT FILE [%s] to port: %s\n", - file, - pvt->ldesc->PortNames[i] - ); - - pvt->ldesc->connect_port(pvt->handle, i, pvt->file_buf); - mapped = 1; - } - } - - str_idx++; - } - - if (!mapped) { - pvt->ldesc->connect_port(pvt->handle, i, pvt->in_buf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT CHANNEL AUDIO to port: %s\n", - pvt->ldesc->PortNames[i] - ); - } - - } - - if (LADSPA_IS_PORT_OUTPUT(port_desc)) { - if (LADSPA_IS_PORT_AUDIO(port_desc)) { - pvt->ldesc->connect_port(pvt->handle, i, pvt->out_buf); - } else if (k < MAX_INDEX) { - pvt->ldesc->connect_port(pvt->handle, i, &pvt->out_ports[k++]); - } - } - } - - if (pvt->ldesc->activate) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "ACTIVATE\n"); - pvt->ldesc->activate(pvt->handle); - } - } - - break; - - case SWITCH_ABC_TYPE_CLOSE: - { - - if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) { - switch_core_file_close(&pvt->fh); - } - - if (pvt->handle && pvt->ldesc) { - if (pvt->ldesc->deactivate) { - pvt->ldesc->deactivate(pvt->handle); - } - - pvt->ldesc->cleanup(pvt->handle); - } - - if (pvt->library_handle) { - unloadLADSPAPluginLibrary(pvt->library_handle); - } - } - break; - - case SWITCH_ABC_TYPE_WRITE_REPLACE: - case SWITCH_ABC_TYPE_READ_REPLACE: - { - switch_frame_t *rframe; - int16_t *slin, abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; - switch_size_t olen = 0; - - - if (type == SWITCH_ABC_TYPE_READ_REPLACE) { - rframe = switch_core_media_bug_get_read_replace_frame(bug); - } else { - rframe = switch_core_media_bug_get_write_replace_frame(bug); - } - - slin = rframe->data; - - if (switch_channel_media_ready(channel)) { - switch_short_to_float(slin, pvt->in_buf, rframe->samples); - - if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) { - olen = rframe->samples; - if (switch_core_file_read(&pvt->fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { - switch_codec_implementation_t read_impl = { 0 }; - char *file = switch_core_session_strdup(pvt->session, pvt->fh.file_path); - switch_core_session_get_read_impl(pvt->session, &read_impl); - - switch_core_file_close(&pvt->fh); - - if (switch_core_file_open(&pvt->fh, - file, - read_impl.number_of_channels, - read_impl.actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot open file: %s\n", file); - return SWITCH_FALSE; - } - - olen = rframe->samples; - if (switch_core_file_read(&pvt->fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot READ file: %s\n", file); - return SWITCH_FALSE; - } - } - - switch_short_to_float(abuf, pvt->file_buf, olen); - } - - pvt->ldesc->run(pvt->handle, rframe->samples); - - switch_float_to_short(pvt->out_buf, slin, rframe->samples); - } - - if (type == SWITCH_ABC_TYPE_READ_REPLACE) { - switch_core_media_bug_set_read_replace_frame(bug, rframe); - } else { - switch_core_media_bug_set_write_replace_frame(bug, rframe); - } - - if (pvt->skip && !--pvt->skip) { - return SWITCH_FALSE; - } - - } - break; - case SWITCH_ABC_TYPE_WRITE: - default: - break; - } - - return SWITCH_TRUE; -} - -switch_status_t stop_ladspa_session(switch_core_session_t *session) -{ - switch_media_bug_t *bug; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if ((bug = switch_channel_get_private(channel, "ladspa"))) { - switch_channel_set_private(channel, "ladspa", NULL); - switch_core_media_bug_remove(session, &bug); - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; -} - -switch_status_t ladspa_session(switch_core_session_t *session, const char *flags, const char *plugin_name, const char *label, const char *params) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_media_bug_t *bug; - switch_status_t status; - switch_ladspa_t *pvt = { 0 }; - switch_codec_implementation_t read_impl = { 0 }; - int i, bflags = SMBF_READ_REPLACE | SMBF_ANSWER_REQ; - char *pstr; - int argc; - char *argv[50]; - char *dparams = NULL; - - if (zstr(plugin_name)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s INVALID PLUGIN\n", switch_channel_get_name(channel)); - return SWITCH_STATUS_FALSE; - } - - if (zstr(flags)) { - flags = "r"; - } - - if (strchr(flags, 'w')) { - bflags = SMBF_WRITE_REPLACE; - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FLAGS: %s PLUGIN: %s LABEL: %s PARAMS: %s\n", - flags, plugin_name, label, params); - - switch_core_session_get_read_impl(session, &read_impl); - - pvt = switch_core_session_alloc(session, sizeof(*pvt)); - - pvt->session = session; - if (!zstr(label)) { - pvt->label_name = switch_core_session_strdup(session, label); - } else { - char *p; - pvt->label_name = switch_core_session_strdup(session, plugin_name); - if ((p = strrchr(pvt->label_name, '.'))) { - *p = '\0'; - } - } - - if (strstr(plugin_name, ".so")) { - pvt->plugin_name = switch_core_session_strdup(session, plugin_name); - } else { - pvt->plugin_name = switch_core_session_sprintf(session, "%s.so", plugin_name); - } - - dparams = switch_core_session_strdup(session, params); - - argc = switch_split(dparams, ' ', argv); - - for (i = 0; i < argc; i++) { - if (switch_is_number(argv[i])) { - if (pvt->num_idx < MAX_INDEX) { - pvt->config[pvt->num_idx] = atof(argv[i]); - pvt->has_config[pvt->num_idx] = 1; - pvt->num_idx++; - } - } else { - if (pvt->str_idx < MAX_INDEX) { - pvt->str_config[pvt->str_idx++] = switch_core_session_strdup(session, argv[i]); - } - } - } - - if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; - } - - pstr = switch_core_session_sprintf(session, "%s|%s|%s|%s", flags, plugin_name, label, params); - - if ((status = switch_core_media_bug_add(session, "ladspa", pstr, - ladspa_callback, pvt, 0, bflags | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) { - return status; - } - - switch_channel_set_private(channel, "ladspa", bug); - - return SWITCH_STATUS_SUCCESS; -} - - -static void ladspa_parse(switch_core_session_t *session, const char *data) -{ - char *argv[5] = { 0 }; - char *lbuf; - - if (data) { - lbuf = strdup(data); - switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0]))); - ladspa_session(session, argv[0], argv[1], argv[2], argv[3]); - free(lbuf); - } -} - -#define APP_SYNTAX "||

");
-		}
-
-		switch_mutex_lock(globals.pa_mutex);
-		func(&argv[lead], argc - lead, stream);
-		status = SWITCH_STATUS_SUCCESS; /*if func was defined we want to always return success as the command was found */
-		switch_mutex_unlock(globals.pa_mutex);
-
-		if (http) {
-			stream->write_function(stream, "\n\n
"); - } - } - - done: - if (http) { - stream->write_function(stream, - "

\n" - "

\n" - " " - " " - " " - " " - " " - " " - " " - " " - "
" - " " - " " - " " - " " - " " - " " - "

" - "\n" - "" - "" - "\n" - "\n" - "" - "" - "\n" - "\n" - "" - "" - "\n" - "\n" - "" - "" - "\n" - "\n" "
" "

\n"); - } - - switch_safe_free(mycmd); - return status; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c b/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c deleted file mode 100644 index 00e5f3a982..0000000000 --- a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * $Id: pa_ringbuffer.c 1164 2006-12-21 15:34:50Z bjornroche $ - * Portable Audio I/O Library - * Ring Buffer utility. - * - * Author: Phil Burk, http://www.softsynth.com - * modified for SMP safety on Mac OS X by Bjorn Roche - * modified for SMP safety on Linux by Leland Lucius - * also, allowed for const where possible - * Note that this is safe only for a single-thread reader and a - * single-thread writer. - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** - @file - @ingroup common_src -*/ - -#include -#include -#include -#include -#include "pa_ringbuffer.h" - -/**************** - * First, we'll define some memory barrier primitives based on the system. - * right now only OS X, FreeBSD, and Linux are supported. In addition to providing - * memory barriers, these functions should ensure that data cached in registers - * is written out to cache where it can be snooped by other CPUs. (ie, the volatile - * keyword should not be required) - * - * the primitives that must be defined are: - * - * PaUtil_FullMemoryBarrier() - * PaUtil_ReadMemoryBarrier() - * PaUtil_WriteMemoryBarrier() - * - ****************/ -#define __VIA_HACK__ -#if defined(__VIA_HACK__) -#define NO_BARRIER -#endif - -#if defined(NO_BARRIER) -# define PaUtil_FullMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() -#else - -#if defined(__APPLE__) //|| defined(__FreeBSD__) -# include - /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide - full memory barriers, so the three types of barriers are the same. */ -# define PaUtil_FullMemoryBarrier() OSMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() OSMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() OSMemoryBarrier() -#elif defined(__GNUC__) - - /* GCC understands volatile asm and "memory" to mean it - * should not reorder memory read/writes */ -# if defined( __PPC__ ) -# define PaUtil_FullMemoryBarrier() __asm__ volatile("sync":::"memory") -# define PaUtil_ReadMemoryBarrier() __asm__ volatile("sync":::"memory") -# define PaUtil_WriteMemoryBarrier() __asm__ volatile("sync":::"memory") -# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined(__x86_64__) -# define PaUtil_FullMemoryBarrier() __asm__ volatile("mfence":::"memory") -# define PaUtil_ReadMemoryBarrier() __asm__ volatile("lfence":::"memory") -# define PaUtil_WriteMemoryBarrier() __asm__ volatile("sfence":::"memory") -# else -# define PaUtil_FullMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() -# endif -#elif defined(_MSC_VER) -# include -# pragma intrinsic(_ReadWriteBarrier) -# pragma intrinsic(_ReadBarrier) -# pragma intrinsic(_WriteBarrier) -# define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() -# define PaUtil_ReadMemoryBarrier() _ReadBarrier() -# define PaUtil_WriteMemoryBarrier() _WriteBarrier() -#else -# define PaUtil_FullMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() -#endif -#endif -/*************************************************************************** - * Initialize FIFO. - * numBytes must be power of 2, returns -1 if not. - */ -long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr) -{ - if (((numBytes - 1) & numBytes) != 0) - return -1; /* Not Power of two. */ - rbuf->bufferSize = numBytes; - rbuf->buffer = (char *) dataPtr; - PaUtil_FlushRingBuffer(rbuf); - rbuf->bigMask = (numBytes * 2) - 1; - rbuf->smallMask = (numBytes) - 1; - return 0; -} - -/*************************************************************************** -** Return number of bytes available for reading. */ -long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf) -{ - PaUtil_ReadMemoryBarrier(); - return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask); -} - -/*************************************************************************** -** Return number of bytes available for writing. */ -long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf) -{ - /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */ - return (rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf)); -} - -/*************************************************************************** -** Clear buffer. Should only be called when buffer is NOT being read. */ -void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf) -{ - rbuf->writeIndex = rbuf->readIndex = 0; -} - -/*************************************************************************** -** Get address of region(s) to which we can write data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2) -{ - long index; - long available = PaUtil_GetRingBufferWriteAvailable(rbuf); - if (numBytes > available) - numBytes = available; - /* Check to see if write is not contiguous. */ - index = rbuf->writeIndex & rbuf->smallMask; - if ((index + numBytes) > rbuf->bufferSize) { - /* Write data in two blocks that wrap the buffer. */ - long firstHalf = rbuf->bufferSize - index; - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = firstHalf; - *dataPtr2 = &rbuf->buffer[0]; - *sizePtr2 = numBytes - firstHalf; - } else { - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = numBytes; - *dataPtr2 = NULL; - *sizePtr2 = 0; - } - return numBytes; -} - - -/*************************************************************************** -*/ -long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes) -{ - /* we need to ensure that previous writes are seen before we update the write index */ - PaUtil_WriteMemoryBarrier(); - return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask; -} - -/*************************************************************************** -** Get address of region(s) from which we can read data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2) -{ - long index; - long available = PaUtil_GetRingBufferReadAvailable(rbuf); - if (numBytes > available) - numBytes = available; - /* Check to see if read is not contiguous. */ - index = rbuf->readIndex & rbuf->smallMask; - if ((index + numBytes) > rbuf->bufferSize) { - /* Write data in two blocks that wrap the buffer. */ - long firstHalf = rbuf->bufferSize - index; - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = firstHalf; - *dataPtr2 = &rbuf->buffer[0]; - *sizePtr2 = numBytes - firstHalf; - } else { - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = numBytes; - *dataPtr2 = NULL; - *sizePtr2 = 0; - } - return numBytes; -} - -/*************************************************************************** -*/ -long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes) -{ - /* we need to ensure that previous writes are always seen before updating the index. */ - PaUtil_WriteMemoryBarrier(); - return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask; -} - -/*************************************************************************** -** Return bytes written. */ -long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes) -{ - long size1, size2, numWritten; - void *data1, *data2; - numWritten = PaUtil_GetRingBufferWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2); - if (size2 > 0) { - - memcpy(data1, data, size1); - data = ((char *) data) + size1; - memcpy(data2, data, size2); - } else { - memcpy(data1, data, size1); - } - PaUtil_AdvanceRingBufferWriteIndex(rbuf, numWritten); - return numWritten; -} - -/*************************************************************************** -** Return bytes read. */ -long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes) -{ - long size1, size2, numRead; - void *data1, *data2; - numRead = PaUtil_GetRingBufferReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2); - if (size2 > 0) { - memcpy(data, data1, size1); - data = ((char *) data) + size1; - memcpy(data, data2, size2); - } else { - memcpy(data, data1, size1); - } - PaUtil_AdvanceRingBufferReadIndex(rbuf, numRead); - return numRead; -} diff --git a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h b/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h deleted file mode 100644 index 05e0602529..0000000000 --- a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef PA_RINGBUFFER_H -#define PA_RINGBUFFER_H -/* - * $Id: pa_ringbuffer.h 1151 2006-11-29 02:11:16Z leland_lucius $ - * Portable Audio I/O Library - * Ring Buffer utility. - * - * Author: Phil Burk, http://www.softsynth.com - * modified for SMP safety on OS X by Bjorn Roche. - * also allowed for const where possible. - * Note that this is safe only for a single-thread reader - * and a single-thread writer. - * - * This program is distributed with the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup common_src -*/ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - typedef struct PaUtilRingBuffer { - long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ - long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */ - long readIndex; /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */ - long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */ - long smallMask; /* Used for fitting indices to buffer. */ - char *buffer; - } PaUtilRingBuffer; - -/** Initialize Ring Buffer. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes in the buffer and must be power of 2. - - @param dataPtr A pointer to a previously allocated area where the data - will be maintained. It must be numBytes long. - - @return -1 if numBytes is not a power of 2, otherwise 0. -*/ - long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr); - -/** Clear buffer. Should only be called when buffer is NOT being read. - - @param rbuf The ring buffer. -*/ - void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf); - -/** Retrieve the number of bytes available in the ring buffer for writing. - - @param rbuf The ring buffer. - - @return The number of bytes available for writing. -*/ - long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf); - -/** Retrieve the number of bytes available in the ring buffer for reading. - - @param rbuf The ring buffer. - - @return The number of bytes available for reading. -*/ - long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf); - -/** Write data to the ring buffer. - - @param rbuf The ring buffer. - - @param data The address of new data to write to the buffer. - - @param numBytes The number of bytes to be written. - - @return The number of bytes written. -*/ - long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes); - -/** Read data from the ring buffer. - - @param rbuf The ring buffer. - - @param data The address where the data should be stored. - - @param numBytes The number of bytes to be read. - - @return The number of bytes read. -*/ - long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes); - -/** Get address of region(s) to which we can write data. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes desired. - - @param dataPtr1 The address where the first (or only) region pointer will be - stored. - - @param sizePtr1 The address where the first (or only) region length will be - stored. - - @param dataPtr2 The address where the second region pointer will be stored if - the first region is too small to satisfy numBytes. - - @param sizePtr2 The address where the second region length will be stored if - the first region is too small to satisfy numBytes. - - @return The room available to be written or numBytes, whichever is smaller. -*/ - long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2); - -/** Advance the write index to the next location to be written. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes to advance. - - @return The new position. -*/ - long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes); - -/** Get address of region(s) from which we can write data. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes desired. - - @param dataPtr1 The address where the first (or only) region pointer will be - stored. - - @param sizePtr1 The address where the first (or only) region length will be - stored. - - @param dataPtr2 The address where the second region pointer will be stored if - the first region is too small to satisfy numBytes. - - @param sizePtr2 The address where the second region length will be stored if - the first region is too small to satisfy numBytes. - - @return The number of bytes available for reading. -*/ - long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2); - -/** Advance the read index to the next location to be read. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes to advance. - - @return The new position. -*/ - long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_RINGBUFFER_H */ diff --git a/src/mod/endpoints/mod_portaudio/pablio.c b/src/mod/endpoints/mod_portaudio/pablio.c deleted file mode 100644 index aae15eb00c..0000000000 --- a/src/mod/endpoints/mod_portaudio/pablio.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * $Id: pablio.c 1151 2006-11-29 02:11:16Z leland_lucius $ - * pablio.c - * Portable Audio Blocking Input/Output utility. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "pa_ringbuffer.h" -#include "pablio.h" - -/************************************************************************/ -/******** Prototypes ****************************************************/ -/************************************************************************/ - -static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, - void *userData); -static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, - PaStreamCallbackFlags statusFlags, void *userData); - -static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, - void *userData); - -static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame); -static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf); - -/************************************************************************/ -/******** Functions *****************************************************/ -/************************************************************************/ - -/* Called from PortAudio. - * Read and write data - */ -static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData) -{ - int c = 0, i = 0, j = 0; - PABLIO_Stream *data = (PABLIO_Stream *) userData; - long numBytes = data->bytesPerFrame * framesPerBuffer; - const int16_t *inputSamples = inputBuffer; - int16_t *chanSamples = (int16_t*)data->iobuff; - - /* This may get called with NULL inputBuffer during initial setup. */ - if (inputBuffer != NULL) { - /* retrieve the data for each channel and put it in the ring buffer */ - for (c = 0; c < data->channelCount; c++) { - for (i = 0, j = c; i < (int)framesPerBuffer; j += data->channelCount, i++) { - chanSamples[i] = inputSamples[j]; - } - if (PaUtil_WriteRingBuffer(&data->inFIFOs[c], chanSamples, numBytes) != numBytes) { - PaUtil_FlushRingBuffer(&data->inFIFOs[c]); - PaUtil_WriteRingBuffer(&data->inFIFOs[c], chanSamples, numBytes); - } - } - } - - return 0; -} - -static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData) -{ - PABLIO_Stream *data = (PABLIO_Stream *) userData; - long numBytes = data->bytesPerFrame * framesPerBuffer; - int16_t *outputSamples = outputBuffer; - int16_t *chanSamples = (short *)data->iobuff; - int c = 0, i = 0, j = 0; - - if (outputBuffer != NULL) { - for (c = 0; c < data->channelCount; c++) { - int numRead = PaUtil_ReadRingBuffer(&data->outFIFOs[c], chanSamples, numBytes); - numRead = numRead / sizeof(int16_t); - for (i = 0, j = c; i < (int)framesPerBuffer; j += data->channelCount, i++) { - if (i < numRead) { - outputSamples[j] = chanSamples[i]; - } else { - outputSamples[j] = 0; - } - } - } - } - - return 0; -} - -static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, - void *userData) -{ - iblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData); - oblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData); - return 0; -} - -/* Allocate buffer. */ -static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame) -{ - long numBytes = numFrames * bytesPerFrame; - char *buffer = (char *) malloc(numBytes); - if (buffer == NULL) - return paInsufficientMemory; - memset(buffer, 0, numBytes); - return (PaError) PaUtil_InitializeRingBuffer(rbuf, numBytes, buffer); -} - -/* Free buffer. */ -static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf) -{ - if (rbuf->buffer) - free(rbuf->buffer); - rbuf->buffer = NULL; - return paNoError; -} - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer) -{ - long bytesWritten; - char *p = (char *) data; - long numBytes = aStream->bytesPerFrame * numFrames; - - switch_core_timer_next(timer); - - bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFOs[chan], p, numBytes); - numBytes -= bytesWritten; - - if (numBytes > 0) { - PaUtil_FlushRingBuffer(&aStream->outFIFOs[chan]); - return 0; - } - return numFrames; -} - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer) -{ - long bytesRead = 0; - char *p = (char *) data; - long avail, totalBytes = 0, neededBytes = aStream->bytesPerFrame * numFrames; - int max = 5000; - - switch_core_timer_next(timer); - - while (totalBytes < neededBytes && --max > 0) { - - avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[chan]); - //printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max); - if (avail >= neededBytes * 6) { - PaUtil_FlushRingBuffer(&aStream->inFIFOs[chan]); - } else { - - bytesRead = 0; - - if (totalBytes < neededBytes && avail >= neededBytes) { - bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFOs[chan], p, neededBytes); - totalBytes += bytesRead; - } - - if (bytesRead) { - p += bytesRead; - } else { - switch_cond_next(); - } - } - } - - return totalBytes / aStream->bytesPerFrame; -} - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long GetAudioStreamWriteable(PABLIO_Stream * aStream, int chan) -{ - int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[chan]); - return bytesEmpty / aStream->bytesPerFrame; -} - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long GetAudioStreamReadable(PABLIO_Stream * aStream, int chan) -{ - int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[chan]); - return bytesFull / aStream->bytesPerFrame; -} - -/***********************************************************/ -static unsigned long RoundUpToNextPowerOf2(unsigned long n) -{ - long numBits = 0; - if (((n - 1) & n) == 0) - return n; - while (n > 0) { - n = n >> 1; - numBits++; - } - return (1 << numBits); -} - - - -/************************************************************ - * Opens a PortAudio stream with default characteristics. - * Allocates PABLIO_Stream structure. - * - */ -PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, - const PaStreamParameters * inputParameters, - const PaStreamParameters * outputParameters, double sampleRate, PaStreamFlags streamFlags, long samples_per_packet, int do_dual) -{ - long bytesPerSample = 2; - PaError err; - PABLIO_Stream *aStream; - long numFrames; - //long numBytes; - int c = 0; - int channels = 1; - - if (!(inputParameters || outputParameters)) { - return -1; - } - - /* Allocate PABLIO_Stream structure for caller. */ - aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream)); - switch_assert(aStream); - memset(aStream, 0, sizeof(PABLIO_Stream)); - - if (inputParameters) { - channels = inputParameters->channelCount; - } else if (outputParameters) { - channels = outputParameters->channelCount; - } - - numFrames = RoundUpToNextPowerOf2(samples_per_packet * 5); - aStream->bytesPerFrame = bytesPerSample; - aStream->channelCount = channels; - - /* Initialize Ring Buffers */ - - if (inputParameters) { - for (c = 0; c < channels; c++) { - err = PABLIO_InitFIFO(&aStream->inFIFOs[c], numFrames, aStream->bytesPerFrame); - if (err != paNoError) { - goto error; - } - } - aStream->has_in = 1; - } - - if (outputParameters) { - for (c = 0; c < channels; c++) { - err = PABLIO_InitFIFO(&aStream->outFIFOs[c], numFrames, aStream->bytesPerFrame); - if (err != paNoError) { - goto error; - } - } - aStream->has_out = 1; - } - - /* Open a PortAudio stream that we will use to communicate with the underlying - * audio drivers. */ - - aStream->do_dual = do_dual; - - if (aStream->do_dual) { - err = Pa_OpenStream(&aStream->istream, inputParameters, NULL, sampleRate, samples_per_packet, streamFlags, iblockingIOCallback, aStream); - if (err != paNoError) { - goto error; - } - err = Pa_OpenStream(&aStream->ostream, NULL, outputParameters, sampleRate, samples_per_packet, streamFlags, oblockingIOCallback, aStream); - if (err != paNoError) { - goto error; - } - } else { - err = - Pa_OpenStream(&aStream->iostream, inputParameters, outputParameters, sampleRate, samples_per_packet, streamFlags, ioblockingIOCallback, - aStream); - } - - if (err != paNoError) { - goto error; - } - - if (aStream->do_dual) { - err = Pa_StartStream(aStream->istream); - - if (err != paNoError) { - goto error; - } - - err = Pa_StartStream(aStream->ostream); - - if (err != paNoError) { - goto error; - } - - } else { - err = Pa_StartStream(aStream->iostream); - } - - if (err != paNoError) { - goto error; - } - - *rwblPtr = aStream; - - switch_yield(500000); - - return paNoError; - - error: - - CloseAudioStream(aStream); - - *rwblPtr = NULL; - return err; -} - -/************************************************************/ -PaError CloseAudioStream(PABLIO_Stream * aStream) -{ - int bytesEmpty; - int byteSize; - int c = 0; - - - if (aStream->has_out) { - - for (c = 0; c < aStream->channelCount; c++) { - byteSize = aStream->outFIFOs[c].bufferSize; - - /* If we are writing data, make sure we play everything written. */ - if (byteSize > 0) { - bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]); - while (bytesEmpty < byteSize) { - Pa_Sleep(10); - bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]); - } - } - } - } - - if (aStream->do_dual) { - if (aStream->has_in && aStream->istream) { - if (Pa_IsStreamActive(aStream->istream)) { - Pa_StopStream(aStream->istream); - } - - Pa_CloseStream(aStream->istream); - aStream->istream = NULL; - } - - if (aStream->has_out && aStream->ostream) { - if (Pa_IsStreamActive(aStream->ostream)) { - Pa_StopStream(aStream->ostream); - } - - Pa_CloseStream(aStream->ostream); - aStream->ostream = NULL; - } - - } else { - if (aStream->iostream) { - if (Pa_IsStreamActive(aStream->iostream)) { - Pa_StopStream(aStream->iostream); - } - - Pa_CloseStream(aStream->iostream); - aStream->iostream = NULL; - } - } - - if (aStream->has_in) { - for (c = 0; c < aStream->channelCount; c++) { - PABLIO_TermFIFO(&aStream->inFIFOs[c]); - } - } - - if (aStream->has_out) { - for (c = 0; c < aStream->channelCount; c++) { - PABLIO_TermFIFO(&aStream->outFIFOs[c]); - } - } - - free(aStream); - switch_yield(500000); - - return paNoError; -} - diff --git a/src/mod/endpoints/mod_portaudio/pablio.h b/src/mod/endpoints/mod_portaudio/pablio.h deleted file mode 100644 index c40aac7a16..0000000000 --- a/src/mod/endpoints/mod_portaudio/pablio.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef PORTAUDIO_PABLIO_H -#define PORTAUDIO_PABLIO_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * $Id: pablio.h 1083 2006-08-23 07:30:49Z rossb $ - * PABLIO.h - * Portable Audio Blocking read/write utility. - * - * Author: Phil Burk, http://www.softsynth.com/portaudio/ - * - * Include file for PABLIO, the Portable Audio Blocking I/O Library. - * PABLIO is built on top of PortAudio, the Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include -#include -#include "pa_ringbuffer.h" - -/*! Maximum number of channels per stream */ -#define MAX_IO_CHANNELS 2 - -/*! Maximum numer of milliseconds per packet */ -#define MAX_IO_MS 100 - -/*! Maximum sampling rate (48Khz) */ -#define MAX_SAMPLING_RATE 48000 - -/* Maximum size of a read */ -#define MAX_IO_BUFFER (((MAX_IO_MS * MAX_SAMPLING_RATE)/1000)*sizeof(int16_t)) -typedef struct { - PaStream *istream; - PaStream *ostream; - PaStream *iostream; - int bytesPerFrame; - int do_dual; - int has_in; - int has_out; - PaUtilRingBuffer inFIFOs[MAX_IO_CHANNELS]; - PaUtilRingBuffer outFIFOs[MAX_IO_CHANNELS]; - int channelCount; - char iobuff[MAX_IO_BUFFER]; -} PABLIO_Stream; - -/* Values for flags for OpenAudioStream(). */ -#define PABLIO_READ (1<<0) -#define PABLIO_WRITE (1<<1) -#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE) -#define PABLIO_MONO (1<<2) -#define PABLIO_STEREO (1<<3) - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer); - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer); - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long GetAudioStreamWriteable(PABLIO_Stream * aStream, int chan); - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long GetAudioStreamReadable(PABLIO_Stream * aStream, int chan); - -/************************************************************ - * Opens a PortAudio stream with default characteristics. - * Allocates PABLIO_Stream structure. - * - * flags parameter can be an ORed combination of: - * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE, - * and either PABLIO_MONO or PABLIO_STEREO - */ -PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, - const PaStreamParameters * inputParameters, - const PaStreamParameters * outputParameters, - double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_packet, int do_dual); - -PaError CloseAudioStream(PABLIO_Stream * aStream); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _PABLIO_H */ diff --git a/src/mod/formats/mod_portaudio_stream/Makefile.am b/src/mod/formats/mod_portaudio_stream/Makefile.am deleted file mode 100644 index 207a1b792f..0000000000 --- a/src/mod/formats/mod_portaudio_stream/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_portaudio_stream -MODPA_DIR=$(switch_srcdir)/src/mod/endpoints/mod_portaudio - -if HAVE_PORTAUDIO -mod_LTLIBRARIES = mod_portaudio_stream.la -mod_portaudio_stream_la_SOURCES = mod_portaudio_stream.c ../../endpoints/mod_portaudio/pablio.c ../../endpoints/mod_portaudio/pa_ringbuffer.c -mod_portaudio_stream_la_CFLAGS = $(AM_CFLAGS) -mod_portaudio_stream_la_CPPFLAGS = -I. -I$(MODPA_DIR) $(PORTAUDIO_CFLAGS) $(AM_CPPFLAGS) -mod_portaudio_stream_la_LIBADD = $(PORTAUDIO_LIBS) $(switch_builddir)/libfreeswitch.la -mod_portaudio_stream_la_LDFLAGS = -avoid-version -module -no-undefined -shared -if ISMAC -mod_portaudio_stream_la_LDFLAGS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -endif -else -install: error -all: error -error: - $(error You must install portaudio19-dev to build $(MODNAME)) -endif diff --git a/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c b/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c deleted file mode 100644 index e0878a0fe7..0000000000 --- a/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * mod_portaudio_stream.c -- Portaudio Streaming interface Audio - * - */ -#include "switch.h" -#include -#include -#include -#include -#include "pablio.h" - -#define DEFAULT_PREBUFFER_SIZE 1024 * 64 -#define SAMPLE_TYPE paInt16 -#define PREFERRED_RATE 8000 - -SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_stream_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_stream_shutdown); -SWITCH_MODULE_DEFINITION(mod_portaudio_stream, mod_portaudio_stream_load, mod_portaudio_stream_shutdown, NULL); -static switch_memory_pool_t *module_pool = NULL; - -struct portaudio_stream_source; - -static struct { - int running; - int threads; - switch_mutex_t *mutex; - switch_hash_t *source_hash; - -} globals; - - -struct portaudio_stream_context { - struct portaudio_stream_source *source; - switch_mutex_t *audio_mutex; - switch_buffer_t *audio_buffer; - int err; - const char *func; - const char *file; - int line; - switch_file_handle_t *handle; - struct portaudio_stream_context *next; -}; - -typedef struct portaudio_stream_context portaudio_stream_context_t; - -struct portaudio_stream_source { - char *sourcename; - int sourcedev; - int rate; - int interval; - char *timer_name; - int total; - int ready; - int stopped; - uint8_t channels; - switch_size_t samples; - uint32_t prebuf; - portaudio_stream_context_t *context_list; - switch_mutex_t *mutex; - switch_memory_pool_t *pool; - switch_thread_rwlock_t *rwlock; - PABLIO_Stream *audio_stream; - switch_frame_t read_frame; - switch_timer_t timer; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_mutex_t *device_lock; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; -}; - -typedef struct portaudio_stream_source portaudio_stream_source_t; - - - -static int get_dev_by_number(char *numstr, int in) -{ - int numDevices = Pa_GetDeviceCount(); - const PaDeviceInfo *pdi; - char *end_ptr; - int number; - - number = (int) strtol(numstr, &end_ptr, 10); - - if (end_ptr == numstr || number < 0) { - return -1; - } - - if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) { - if (in && pdi->maxInputChannels) { - return number; - } else if (!in && pdi->maxOutputChannels) { - return number; - } - } - - return -1; -} - -static int get_dev_by_name(char *name, int in) -{ - int i; - int numDevices; - const PaDeviceInfo *pdi; - numDevices = Pa_GetDeviceCount(); - - if (numDevices < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices); - return -2; - } - - for (i = 0; i < numDevices; i++) { - int match = 0; - pdi = Pa_GetDeviceInfo(i); - - if (zstr(name)) { - match = 1; - } else if (pdi && pdi->name && strstr(pdi->name, name)) { - match = 1; - } - - if (match) { - if (in && pdi->maxInputChannels) { - return i; - } else if (!in && pdi->maxOutputChannels) { - return i; - } - } - } - - return -1; -} - -static switch_status_t engage_device(portaudio_stream_source_t *source, int restart) -{ - PaStreamParameters inputParameters, outputParameters; - PaError err; - int sample_rate = source->rate; - int codec_ms = source->interval; - - switch_mutex_init(&source->device_lock, SWITCH_MUTEX_NESTED, module_pool); - - if (source->timer.timer_interface) { - switch_core_timer_sync(&source->timer); - } - - if (source->audio_stream) { - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_core_codec_ready(&source->read_codec)) { - if (switch_core_codec_init(&source->read_codec, - "L16", - NULL, NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, - NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n"); - return SWITCH_STATUS_FALSE; - } - } - - switch_assert(source->read_codec.implementation); - - if (!switch_core_codec_ready(&source->write_codec)) { - if (switch_core_codec_init(&source->write_codec, - "L16", - NULL, NULL, - sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n"); - switch_core_codec_destroy(&source->read_codec); - return SWITCH_STATUS_FALSE; - } - } - - - if (!source->timer.timer_interface) { - if (switch_core_timer_init(&source->timer, - source->timer_name, codec_ms, source->read_codec.implementation->samples_per_packet, - module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); - switch_core_codec_destroy(&source->read_codec); - switch_core_codec_destroy(&source->write_codec); - return SWITCH_STATUS_FALSE; - } - } - - source->read_frame.rate = sample_rate; - source->read_frame.codec = &source->read_codec; - - switch_mutex_lock(source->device_lock); - /* LOCKED ************************************************************************************************** */ - inputParameters.device = source->sourcedev; - inputParameters.channelCount = 1; - inputParameters.sampleFormat = SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - outputParameters.device = source->sourcedev; - outputParameters.channelCount = 1; - outputParameters.sampleFormat = SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - - - err = OpenAudioStream(&source->audio_stream, &inputParameters, NULL, sample_rate, paClipOff, source->read_codec.implementation->samples_per_packet, 0); - /* UNLOCKED ************************************************************************************************* */ - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n"); - switch_yield(1000000); - err = OpenAudioStream(&source->audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - source->read_codec.implementation->samples_per_packet, 0); - } - - switch_mutex_unlock(source->device_lock); - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n"); - switch_core_codec_destroy(&source->read_codec); - switch_core_timer_destroy(&source->timer); - return SWITCH_STATUS_FALSE; - } - - - return SWITCH_STATUS_SUCCESS; -} - -static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void *obj) -{ - portaudio_stream_source_t *source = obj; - portaudio_stream_context_t *cp; - int samples; - int bused, bytesToWrite; - - - switch_mutex_lock(globals.mutex); - globals.threads++; - switch_mutex_unlock(globals.mutex); - - if (!source->prebuf) { - source->prebuf = DEFAULT_PREBUFFER_SIZE; - } - - - - switch_mutex_lock(globals.mutex); - switch_core_hash_insert(globals.source_hash, source->sourcename, source); - switch_mutex_unlock(globals.mutex); - - - switch_thread_rwlock_create(&source->rwlock, source->pool); - - if (engage_device(source, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Dev %d cant be engaged !\n", (int) source->sourcedev); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " Dev %d engaged at %d rate!\n", (int) source->sourcedev, (int) source->rate); - if (globals.running && !source->stopped) { - source->ready = 1; - - if (!source->audio_stream) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Audio Stream wops!\n"); - source->stopped = 0; - source->ready = 0; - } else { - while (globals.running && !source->stopped) { - switch_mutex_lock(source->device_lock); - samples = ReadAudioStream(source->audio_stream, source->databuf, - source->read_codec.implementation->samples_per_packet, 0, &source->timer); - switch_mutex_unlock(source->device_lock); - - - if (samples) { - bytesToWrite = source->samples; - if (samples < bytesToWrite) { - bytesToWrite = samples; - } - bytesToWrite *= source->audio_stream->bytesPerFrame; - - if (source->total) { - - switch_mutex_lock(source->mutex); - for (cp = source->context_list; cp; cp = cp->next) { - - switch_mutex_lock(cp->audio_mutex); - - bused = switch_buffer_inuse(cp->audio_buffer); - if (bused > source->samples * 768) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d] %d used %d max\n", - cp->func, cp->file, cp->line, (int) bused, (int) (source->samples * 768)); - switch_buffer_zero(cp->audio_buffer); - } else { - switch_buffer_write(cp->audio_buffer, source->databuf, bytesToWrite); - } - - switch_mutex_unlock(cp->audio_mutex); - } - switch_mutex_unlock(source->mutex); - } - - } - - } - } - - } - } - - - source->ready = 0; - - switch_mutex_lock(globals.mutex); - switch_core_hash_delete(globals.source_hash, source->sourcename); - switch_mutex_unlock(globals.mutex); - - switch_thread_rwlock_wrlock(source->rwlock); - switch_thread_rwlock_unlock(source->rwlock); - - - switch_mutex_lock(source->device_lock); - CloseAudioStream(source->audio_stream); - if (switch_core_codec_ready(&source->read_codec)) { - switch_core_codec_destroy(&source->read_codec); - switch_core_codec_destroy(&source->write_codec); - } - if (switch_core_codec_ready(&source->write_codec)) { - switch_core_codec_destroy(&source->write_codec); - } - switch_mutex_unlock(source->device_lock); - - - switch_core_destroy_memory_pool(&source->pool); - - switch_mutex_lock(globals.mutex); - globals.threads--; - switch_mutex_unlock(globals.mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " thread ending succesfully !\n"); - switch_thread_exit(thread, SWITCH_STATUS_SUCCESS); - - return NULL; -} - - -static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle, const char *path) -{ - portaudio_stream_context_t *context; - portaudio_stream_source_t *source; - switch_memory_pool_t *pool; - switch_status_t status = SWITCH_STATUS_FALSE; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - uint32_t rate = PREFERRED_RATE; - char *npath; - int devNumber; - int tmp; - - handle->pre_buffer_datalen = 0; - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing! (yet)\n"); - return status; - } - - npath = switch_core_strdup(module_pool, path); - - tmp = handle->samplerate; - if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 48000) { - rate = tmp; - } - - if (*path == '#') { - devNumber = get_dev_by_number(npath + 1, 1); - } else { - devNumber = get_dev_by_name(npath, 1); - } - npath = switch_mprintf("device-%d at %d", devNumber, rate); - - switch_mutex_lock(globals.mutex); - source = switch_core_hash_find(globals.source_hash, npath); - - /* dev isnt there, try to start thread */ - if (!source) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " source isnt Created, create and start thread!\n"); - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, " :S no pool\n"); - } else { - source = switch_core_alloc(pool, sizeof(*source)); - if (source != NULL) { - source->pool = pool; - source->sourcedev = devNumber; - source->sourcename = switch_core_strdup(source->pool, npath); - source->rate = rate; - source->interval = 20; - source->channels = 1; - source->timer_name = "soft"; - source->prebuf = DEFAULT_PREBUFFER_SIZE; - source->stopped = 0; - source->ready = 0; - source->samples = switch_samples_per_packet(source->rate, source->interval); - - switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool); - - switch_threadattr_create(&thd_attr, source->pool); - switch_threadattr_detach_set(thd_attr, 1); - - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool); - } - } - } - switch_mutex_unlock(globals.mutex); - switch_yield(1000000); - /* dev already engaged */ - if (source) { - - /*wait for source to be ready */ - while (source->ready == 0) { - switch_yield(100000); - } - - if (switch_thread_rwlock_tryrdlock(source->rwlock) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " error rwlock !\n"); - source = NULL; - } - } - - if (source) { - status = SWITCH_STATUS_SUCCESS; - - if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " error allocating context!\n"); - status = SWITCH_STATUS_MEMERR; - } else { - /* everything goes fine at this point */ - handle->samples = 0; - handle->samplerate = source->rate; - handle->channels = 1; - handle->format = 0; - handle->sections = 0; - handle->seekable = 0; - handle->speed = 0; - handle->private_info = context; - handle->interval = source->interval; - - switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); - if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); - status = SWITCH_STATUS_MEMERR; - } else { - /* context created... then continue */ - context->source = source; - context->file = handle->file; - context->func = handle->func; - context->line = handle->line; - context->handle = handle; - switch_mutex_lock(source->mutex); - context->next = source->context_list; - source->context_list = context; - source->total++; - switch_mutex_unlock(source->mutex); - } - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown source %s\n", path); - status = SWITCH_STATUS_FALSE; - } - - return status; -} - - -static switch_status_t portaudio_stream_file_close(switch_file_handle_t *handle) -{ - portaudio_stream_context_t *cp, *last = NULL, *context = handle->private_info; - - - switch_mutex_lock(context->source->mutex); - for (cp = context->source->context_list; cp; cp = cp->next) { - if (cp == context) { - if (last) { - last->next = cp->next; - } else { - context->source->context_list = cp->next; - } - break; - } - last = cp; - } - context->source->total--; - switch_mutex_unlock(context->source->mutex); - switch_buffer_destroy(&context->audio_buffer); - switch_thread_rwlock_unlock(context->source->rwlock); - - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t portaudio_stream_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - portaudio_stream_context_t *context = handle->private_info; - switch_size_t bytes = 0; - int bytesPerSample = context->source->audio_stream->bytesPerFrame; - size_t need = *len * bytesPerSample; - - if (!context->source->ready) { - *len = 0; - return SWITCH_STATUS_FALSE; - } - - switch_mutex_lock(context->audio_mutex); - if ((bytes = switch_buffer_read(context->audio_buffer, data, need))) { - *len = bytes / bytesPerSample; - } else { - if (need > 2560) { - need = 2560; - } - memset(data, 255, need); - *len = need / bytesPerSample; - } - switch_mutex_unlock(context->audio_mutex); - - - - handle->sample_count += *len; - return SWITCH_STATUS_SUCCESS; - - -} - -/* Registration */ - -static char *supported_formats[SWITCH_MAX_CODECS] = { 0 }; - -static void shutdown_event_handler(switch_event_t *event) -{ - globals.running = 0; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_stream_load) -{ - switch_file_interface_t *file_interface; - supported_formats[0] = "portaudio_stream"; - - module_pool = pool; - - Pa_Initialize(); - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = modname; - file_interface->extens = supported_formats; - file_interface->file_open = portaudio_stream_file_open; - file_interface->file_close = portaudio_stream_file_close; - file_interface->file_read = portaudio_stream_file_read; - - if (switch_event_bind(modname, SWITCH_EVENT_SHUTDOWN, SWITCH_EVENT_SUBCLASS_ANY, shutdown_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind shutdown event handler!\n"); - } - - memset(&globals, 0, sizeof(globals)); - globals.running = 1; - globals.threads = 0; - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); - switch_core_hash_init(&globals.source_hash); - - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_stream_shutdown) -{ - globals.running = 0; - switch_event_unbind_callback(shutdown_event_handler); - - while (globals.threads > 0) { - switch_yield(100000); - } - - Pa_Terminate(); - - switch_core_hash_destroy(&globals.source_hash); - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index 5bd65cfa18..3540628eda 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -529,14 +529,6 @@ Binaries;Content;Satellites INSTALLFOLDER - - mod_PortAudio - {5fd31a25-5d83-4794-8bee-904dad84ce71} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_rtc {3884add2-91d0-4cd6-86d3-d5fb2d4aab9e} diff --git a/w32/Setup/inno_setup/fscomm.iss b/w32/Setup/inno_setup/fscomm.iss index 56c28874eb..6e21f8caa3 100644 --- a/w32/Setup/inno_setup/fscomm.iss +++ b/w32/Setup/inno_setup/fscomm.iss @@ -66,7 +66,6 @@ Source: {#FreeSWITCH_32bit}\mod\mod_event_socket.dll; DestDir: {app}\mod; Flags: Source: {#FreeSWITCH_32bit}\mod\mod_ilbc.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_local_stream.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_loopback.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode -Source: {#FreeSWITCH_32bit}\mod\mod_PortAudio.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_siren.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_sndfile.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_sofia.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode diff --git a/w32/download_portaudio.props b/w32/download_portaudio.props deleted file mode 100644 index 8a9b16049e..0000000000 --- a/w32/download_portaudio.props +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - true - - - - - - - - - From 4235d86aeedd4951ef61e45f5273534afc113fb9 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Aug 2024 21:30:43 +0300 Subject: [PATCH 187/205] [mod_mp4, mod_mp4v, mod_mp4v2] Remove from tree --- build/modules.conf.in | 3 - build/modules.conf.most | 2 - ci.sh | 1 - configure.ac | 3 - debian/bootstrap.sh | 4 - debian/control-modules | 14 - freeswitch.spec | 13 +- src/mod/applications/mod_mp4/Makefile.am | 8 - src/mod/applications/mod_mp4/exception.hpp | 59 -- src/mod/applications/mod_mp4/mod_mp4.cpp | 550 -------------- src/mod/applications/mod_mp4/mp4_helper.cpp | 136 ---- src/mod/applications/mod_mp4/mp4_helper.hpp | 143 ---- src/mod/applications/mod_mp4v2/Makefile.am | 8 - src/mod/applications/mod_mp4v2/mod_mp4v2.c | 772 -------------------- src/mod/codecs/mod_mp4v/Makefile.am | 8 - src/mod/codecs/mod_mp4v/mod_mp4v.c | 102 --- 16 files changed, 1 insertion(+), 1825 deletions(-) delete mode 100644 src/mod/applications/mod_mp4/Makefile.am delete mode 100644 src/mod/applications/mod_mp4/exception.hpp delete mode 100644 src/mod/applications/mod_mp4/mod_mp4.cpp delete mode 100644 src/mod/applications/mod_mp4/mp4_helper.cpp delete mode 100644 src/mod/applications/mod_mp4/mp4_helper.hpp delete mode 100644 src/mod/applications/mod_mp4v2/Makefile.am delete mode 100644 src/mod/applications/mod_mp4v2/mod_mp4v2.c delete mode 100644 src/mod/codecs/mod_mp4v/Makefile.am delete mode 100644 src/mod/codecs/mod_mp4v/mod_mp4v.c diff --git a/build/modules.conf.in b/build/modules.conf.in index 76f192308c..de87399e74 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -29,8 +29,6 @@ applications/mod_httapi #applications/mod_lcr #applications/mod_memcache #applications/mod_mongo -#applications/mod_mp4 -#applications/mod_mp4v2 #applications/mod_nibblebill #applications/mod_oreka #applications/mod_osp @@ -69,7 +67,6 @@ codecs/mod_g729 codecs/mod_h26x #codecs/mod_ilbc #codecs/mod_isac -#codecs/mod_mp4v codecs/mod_opus #codecs/mod_silk #codecs/mod_siren diff --git a/build/modules.conf.most b/build/modules.conf.most index 943ff71336..ad14f0bb7a 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -29,7 +29,6 @@ applications/mod_http_cache applications/mod_lcr applications/mod_memcache applications/mod_mongo -applications/mod_mp4 applications/mod_nibblebill applications/mod_oreka #applications/mod_osp @@ -67,7 +66,6 @@ codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac -codecs/mod_mp4v codecs/mod_opus codecs/mod_silk codecs/mod_siren diff --git a/ci.sh b/ci.sh index d7322c4432..26947f6a70 100755 --- a/ci.sh +++ b/ci.sh @@ -93,7 +93,6 @@ configure_freeswitch() sed -i \ -e '/mod_ilbc/s/^/#/g' \ -e '/mod_isac/s/^/#/g' \ - -e '/mod_mp4/s/^/#/g' \ -e '/mod_mongo/s/^/#/g' \ -e '/mod_pocketsphinx/s/^/#/g' \ -e '/mod_siren/s/^/#/g' \ diff --git a/configure.ac b/configure.ac index e56bc72e9d..4b90871540 100755 --- a/configure.ac +++ b/configure.ac @@ -2119,8 +2119,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_limit/Makefile src/mod/applications/mod_memcache/Makefile src/mod/applications/mod_mongo/Makefile - src/mod/applications/mod_mp4/Makefile - src/mod/applications/mod_mp4v2/Makefile src/mod/applications/mod_nibblebill/Makefile src/mod/applications/mod_oreka/Makefile src/mod/applications/mod_osp/Makefile @@ -2160,7 +2158,6 @@ AC_CONFIG_FILES([Makefile src/mod/codecs/mod_h26x/Makefile src/mod/codecs/mod_ilbc/Makefile src/mod/codecs/mod_isac/Makefile - src/mod/codecs/mod_mp4v/Makefile src/mod/codecs/mod_opus/Makefile src/mod/codecs/mod_openh264/Makefile src/mod/codecs/mod_silk/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index d3a00c7071..d77ca48d3f 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -35,8 +35,6 @@ supported_distros="$supported_debian_distros $supported_ubuntu_distros" avoid_mods=( applications/mod_limit applications/mod_mongo - applications/mod_mp4 - applications/mod_mp4v2 applications/mod_osp applications/mod_rad_auth applications/mod_skel @@ -712,7 +710,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g729 (= \${binary:Version}), freeswitch-mod-h26x (= \${binary:Version}), freeswitch-mod-isac (= \${binary:Version}), - freeswitch-mod-mp4v (= \${binary:Version}), freeswitch-mod-opus (= \${binary:Version}), freeswitch-mod-silk (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), @@ -738,7 +735,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g729-dbg (= \${binary:Version}), freeswitch-mod-h26x-dbg (= \${binary:Version}), freeswitch-mod-isac-dbg (= \${binary:Version}), - freeswitch-mod-mp4v-dbg (= \${binary:Version}), freeswitch-mod-opus-dbg (= \${binary:Version}), freeswitch-mod-silk-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index b11dc10005..2261416c47 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -149,16 +149,6 @@ Description: MongoDB This module provides an interface to MongoDB. Build-Depends: libmongoc-dev -Module: applications/mod_mp4 -Section: contrib/comm -Description: MP4 video support - This module adds support for MP4 video playback. -Build-Depends: libmp4v2-dev - -Module: applications/mod_mp4v2 -Description: Adds mod_mp4v2 - Adds mod_mp4v2. - Module: applications/mod_nibblebill Description: Nibblebill This module allows for real-time accounting of a cash balance and @@ -333,10 +323,6 @@ Module: codecs/mod_isac Description: mod_isac Adds mod_isac. -Module: codecs/mod_mp4v -Description: mod_mp4v - Adds mod_mp4v. - Module: codecs/mod_openh264 Description: Adds mod_openh264 Adds mod_openh264. diff --git a/freeswitch.spec b/freeswitch.spec index 773b8784c7..8761ca2365 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -722,14 +722,6 @@ Requires: %{name} = %{version}-%{release} %description codec-vpx iSAC Codec support for FreeSWITCH open source telephony platform -%package codec-mp4v -Summary: MP4V Video Codec support for FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description codec-mp4v -MP4V Video Codec support for FreeSWITCH open source telephony platform - %package codec-opus Summary: Opus Codec support for FreeSWITCH open source telephony platform Group: System/Libraries @@ -1351,7 +1343,7 @@ ASR_TTS_MODULES="asr_tts/mod_flite asr_tts/mod_pocketsphinx asr_tts/mod_tts_comm # ###################################################################################################################### CODECS_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_bv codecs/mod_codec2 codecs/mod_g723_1 \ - codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_mp4v codecs/mod_opus codecs/mod_silk \ + codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_opus codecs/mod_silk \ codecs/mod_siren codecs/mod_theora" # @@ -2075,9 +2067,6 @@ fi %files codec-isac %{MODINSTDIR}/mod_isac.so* -%files codec-mp4v -%{MODINSTDIR}/mod_mp4v.so* - %files codec-opus %{MODINSTDIR}/mod_opus.so* %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opus.conf.xml diff --git a/src/mod/applications/mod_mp4/Makefile.am b/src/mod/applications/mod_mp4/Makefile.am deleted file mode 100644 index 46d3f78dfa..0000000000 --- a/src/mod/applications/mod_mp4/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4 - -mod_LTLIBRARIES = mod_mp4.la -mod_mp4_la_SOURCES = mod_mp4.cpp mp4_helper.cpp -mod_mp4_la_CFLAGS = $(AM_CFLAGS) -mod_mp4_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lmp4v2 diff --git a/src/mod/applications/mod_mp4/exception.hpp b/src/mod/applications/mod_mp4/exception.hpp deleted file mode 100644 index 75f84989a2..0000000000 --- a/src/mod/applications/mod_mp4/exception.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - -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. - -The Original Code is MP4 Helper Library to Freeswitch MP4 module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -*/ - -#ifndef EXCEPTION_HPP_ -#define EXCEPTION_HPP_ - -#include -#include - -class Exception: public std::exception { - public: - Exception() - { - } - - Exception(const std::string & message): message_(message) - { - } - - Exception(const std::exception & e): message_(e.what()) - { - } - - Exception(const Exception & e): message_(e.message_) - { - } - - virtual ~Exception() throw() - { - } - - const char * what() const throw() - { - return message_.c_str(); - } - - private: - std::string message_; -}; - -#endif \ No newline at end of file diff --git a/src/mod/applications/mod_mp4/mod_mp4.cpp b/src/mod/applications/mod_mp4/mod_mp4.cpp deleted file mode 100644 index 433642d816..0000000000 --- a/src/mod/applications/mod_mp4/mod_mp4.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Paulo Rogério Panhoto - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * mod_mp4 -- MP4 File Format support for video apps. - * - */ - -#include -#include "mp4_helper.hpp" -#include "exception.hpp" - - -#ifndef min -#define min(x, y) ((x) < (y) ? (x) : (y)) -#endif - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4_load); -SWITCH_MODULE_DEFINITION(mod_mp4, mod_mp4_load, NULL, NULL); - -#define VID_BIT (1 << 31) -#define VERSION 4201 - -#ifdef MP4_RECORD -struct file_header { - int32_t version; - char video_codec_name[32]; - char video_fmtp[128]; - uint32_t audio_rate; - uint32_t audio_ptime; - switch_time_t created; -}; - -struct record_helper { - switch_core_session_t *session; - switch_mutex_t *mutex; - int fd; - int up; -}; -#endif - -struct AVParams { - switch_core_session_t * session; - switch_channel_t * channel; - switch_timer_t * timer; - switch_frame_t * frame; - switch_mutex_t * mutex; - bool video; - switch_payload_t pt; - MP4::Context * vc; - bool done; - bool * quit; -}; - -static void *SWITCH_THREAD_FUNC record_video_thread(switch_thread_t *thread, void *obj) -{ -#ifdef MP4_RECORD - record_helper *eh = reinterpret_cast(obj); - switch_core_session_t *session = eh->session; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status; - switch_frame_t *read_frame; - int bytes; - - eh->up = 1; - while (switch_channel_ready(channel)) { - status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; - } - - if (switch_test_flag(read_frame, SFF_CNG)) { - continue; - } - - bytes = read_frame->packetlen | VID_BIT; - - switch_mutex_lock(eh->mutex); - - if (write(eh->fd, &bytes, sizeof(bytes)) != (int) sizeof(bytes)) { - switch_mutex_unlock(eh->mutex); - break; - } - - if (write(eh->fd, read_frame->packet, read_frame->packetlen) != (int) read_frame->packetlen) { - switch_mutex_unlock(eh->mutex); - break; - } - - switch_mutex_unlock(eh->mutex); - - switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); - } - eh->up = 0; -#endif - return NULL; -} - -SWITCH_STANDARD_APP(record_mp4_function) -{ -#ifdef MP4_RECORD - switch_status_t status; - switch_frame_t *read_frame; - switch_channel_t *channel = switch_core_session_get_channel(session); - struct record_helper eh = { 0 }; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - int fd; - switch_mutex_t *mutex = NULL; - switch_codec_t codec, *vid_codec; - switch_codec_implementation_t read_impl = { }; - int count = 0, sanity = 30; - - switch_core_session_get_read_impl(session, &read_impl); - switch_channel_answer(channel); - - - while (switch_channel_up(channel) && !switch_channel_test_flag(channel, CF_VIDEO)) { - switch_yield(10000); - - if (count) count--; - - if (count == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s waiting for video.\n", switch_channel_get_name(channel)); - count = 100; - if (!--sanity) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s timeout waiting for video.\n", - switch_channel_get_name(channel)); - return; - } - } - } - - if (!switch_channel_ready(channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s not ready.\n", switch_channel_get_name(channel)); - return; - } - -/* - if ((fd = open((char *) data, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data); - return; - } -*/ - - MP4::Context ctx(reinterpret_cast(data), true); - - if (switch_core_codec_init(&codec, - "L16", - NULL, - NULL, - read_impl.samples_per_second, - read_impl.microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); - goto end; - } - - switch_core_session_set_read_codec(session, &codec); - - if (switch_channel_test_flag(channel, CF_VIDEO)) { - struct file_header h; - memset(&h, 0, sizeof(h)); - vid_codec = switch_core_session_get_video_read_codec(session); - - h.version = VERSION; - h.created = switch_micro_time_now(); - switch_set_string(h.video_codec_name, vid_codec->implementation->iananame); - if (vid_codec->fmtp_in) { - switch_set_string(h.video_fmtp, vid_codec->fmtp_in); - } - h.audio_rate = read_impl.samples_per_second; - h.audio_ptime = read_impl.microseconds_per_packet / 1000; - - if (write(fd, &h, sizeof(h)) != sizeof(h)) { - goto end; - } - - switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - eh.mutex = mutex; - eh.fd = fd; - eh.session = session; - switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, record_video_thread, &eh, switch_core_session_get_pool(session)); - } - - - while (switch_channel_ready(channel)) { - - status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; - } - - if (switch_test_flag(read_frame, SFF_CNG)) { - continue; - } - - if (mutex) { - switch_mutex_lock(mutex); - } - - if (write(fd, &read_frame->datalen, sizeof(read_frame->datalen)) != sizeof(read_frame->datalen)) { - if (mutex) { - switch_mutex_unlock(mutex); - } - break; - } - - if (write(fd, read_frame->data, read_frame->datalen) != (int) read_frame->datalen) { - if (mutex) { - switch_mutex_unlock(mutex); - } - break; - } - - if (mutex) { - switch_mutex_unlock(mutex); - } - } - - - end: - - if (eh.up) { - while (eh.up) { - switch_cond_next(); - } - } - - switch_core_session_set_read_codec(session, NULL); - switch_core_codec_destroy(&codec); -#endif -} - -static void *SWITCH_THREAD_FUNC play_video_function(switch_thread_t *thread, void *obj) -{ - AVParams * pt = reinterpret_cast(obj); - u_int next = 0, first = 0xffffffff; - uint64_t ts = 0, control = 0; - - bool ok; - bool sent = true; - pt->done = false; - switch_time_t start = switch_time_now(); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Video thread Started\n"); - while (!*pt->quit && switch_channel_ready(pt->channel)) { - if (pt->video) { - if (sent) { - switch_mutex_lock(pt->mutex); - pt->frame->packetlen = pt->frame->buflen; - ok = pt->vc->getVideoPacket(pt->frame->packet, pt->frame->packetlen, next); - switch_mutex_unlock(pt->mutex); - sent = false; - if (ok) { - switch_rtp_hdr_t *hdr = reinterpret_cast(pt->frame->packet); - if(first == 0xffffffff) first = next; - next -= first; - control = next * 90000LL / pt->vc->videoTrack().track.clock; - control -= first; - hdr->ts = htonl(control); - control = control * 1000 / 90; - if (pt->pt) - hdr->pt = pt->pt; - } else break; - } - - ts = switch_time_now() - start; - int64_t wait = control > ts ? (control - ts) : 0; - - if (wait > 0) { - switch_cond_next(); - // wait the time for the next Video frame - switch_sleep(wait); - } - - if (switch_channel_test_flag(pt->channel, CF_VIDEO)) { - switch_byte_t *data = (switch_byte_t *) pt->frame->packet; - - pt->frame->data = data + 12; - pt->frame->datalen = pt->frame->packetlen - 12; - switch_core_session_write_video_frame(pt->session, pt->frame, SWITCH_IO_FLAG_NONE, 0); - sent = true; - } - - } - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Video thread ended\n"); - pt->done = true; - return NULL; -} - -static void *SWITCH_THREAD_FUNC play_audio_function(switch_thread_t *thread, void *obj) -{ - AVParams * pt = reinterpret_cast(obj); - u_int next = 0, first = 0xffffffff; - uint64_t ts = 0, control = 0; - - bool ok; - bool sent = true; - switch_dtmf_t dtmf = {0}; - pt->done = false; - switch_frame_t * read_frame; - - while (!*pt->quit && switch_channel_ready(pt->channel)) { - // event processing. - // -- SEE switch_ivr_play_say.c:1231 && mod_dptools.c:1428 && mod_dptools.c:1919 - switch_core_session_read_frame(pt->session, &read_frame, SWITCH_IO_FLAG_SINGLE_READ, 0); - - if (switch_channel_test_flag(pt->channel, CF_BREAK)) { - switch_channel_clear_flag(pt->channel, CF_BREAK); - break; - } - - switch_ivr_parse_all_events(pt->session); - - if (switch_channel_has_dtmf(pt->channel)) { - switch_channel_dequeue_dtmf(pt->channel, &dtmf); - const char * terminators = switch_channel_get_variable(pt->channel, SWITCH_PLAYBACK_TERMINATORS_VARIABLE); - if (terminators && !strcasecmp(terminators, "none")) terminators = NULL; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Digit %c\n", dtmf.digit); - if (terminators && strchr(terminators, dtmf.digit)) { - std::string digit(&dtmf.digit, 0, 1); - switch_channel_set_variable(pt->channel, SWITCH_PLAYBACK_TERMINATOR_USED, digit.c_str()); - break; - } - } - - switch_mutex_lock(pt->mutex); - pt->frame->datalen = pt->frame->buflen; - ok = pt->vc->getAudioPacket(pt->frame->data, pt->frame->datalen, next); - switch_mutex_unlock(pt->mutex); - - if (ok) { - if (pt->frame->datalen > (int) pt->frame->buflen) - pt->frame->datalen = pt->frame->buflen; - - switch_core_session_write_frame(pt->session, pt->frame, SWITCH_IO_FLAG_NONE, 0); - switch_core_timer_next(pt->timer); - } - else break; - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Audio done\n"); - *pt->quit = pt->done = true; - return NULL; -} - -SWITCH_STANDARD_APP(play_mp4_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_frame_t write_frame = { 0 }, vid_frame = {0}; - switch_codec_t codec = { 0 }, vid_codec = {0}, *read_vid_codec; - unsigned char *aud_buffer; - unsigned char *vid_buffer; - switch_timer_t timer = { 0 }; - switch_codec_implementation_t read_impl = {}; - bool done = false; - - try { - MP4::Context vc((char *) data); - - switch_payload_t pt = 0; - - switch_core_session_get_read_impl(session, &read_impl); - - aud_buffer = (unsigned char *) switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); - vid_buffer = (unsigned char *) switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); - - /* - if (!vc.isOpen()) - { - char msgbuf[1024]; - sprintf(msgbuf, "PLAYBACK ERROR (%s): FILE NOT FOUND.", (char*) data); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, msgbuf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data); - return; - } - - if(!vc.isSupported()) - { - char msgbuf[1024]; - sprintf(msgbuf, "PLAYBACK ERROR (%s): UNSUPPORTED FORMAT OR FILE NOT HINTED.", (char*) data); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, msgbuf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, - "Error reading track info. Maybe this file is not hinted.\n"); - throw 1; - } - */ - - switch_channel_set_variable(channel, "rtp_force_video_fmtp", vc.videoTrack().fmtp.c_str()); - switch_channel_answer(channel); - - if ((read_vid_codec = switch_core_session_get_video_read_codec(session))) { - pt = read_vid_codec->agreed_pt; - } - - write_frame.codec = &codec; - write_frame.data = aud_buffer; - write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; - - vid_frame.codec = &vid_codec; - vid_frame.packet = vid_buffer; - vid_frame.data = vid_buffer + 12; - vid_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE - 12; - switch_set_flag((&vid_frame), SFF_RAW_RTP); - switch_set_flag((&vid_frame), SFF_PROXY_PACKET); - - if (switch_core_timer_init(&timer, "soft", read_impl.microseconds_per_packet / 1000, - read_impl.samples_per_packet, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Timer Activation Fail\n"); - throw 2; - } - - if (switch_core_codec_init(&codec, - vc.audioTrack().codecName, - NULL, - NULL, - vc.audioTrack().clock, - vc.audioTrack().packetLength, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - throw Exception("Audio Codec Activation Fail"); - } - - if (switch_core_codec_init(&vid_codec, - vc.videoTrack().track.codecName, - NULL, - NULL, - 0, - 0, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Activation Success\n"); - } else - { - throw Exception("Video Codec Activation Fail"); - } - switch_core_session_set_read_codec(session, &codec); - - AVParams vpt; - vpt.session = session; - vpt.channel = channel; - vpt.frame = &vid_frame; - vpt.timer = &timer; - vpt.video = true; - vpt.pt = pt; - vpt.vc = &vc; - switch_mutex_init(&vpt.mutex, SWITCH_MUTEX_DEFAULT, switch_core_session_get_pool(session)); - vpt.quit = &done; - - switch_threadattr_t * thd_attr; - switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_t *thread; - switch_thread_create(&thread, thd_attr, play_video_function, (void*)&vpt, switch_core_session_get_pool(session)); - - AVParams apt; - apt.session = session; - apt.channel = channel; - apt.frame = &write_frame; - apt.timer = &timer; - apt.video = false; - apt.vc = &vc; - apt.mutex = vpt.mutex; - apt.quit = &done; - play_audio_function(NULL, &apt); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Waiting for video thread to join.\n"); - while (!vpt.done) { - switch_cond_next(); - } - - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE PLAYED"); - } catch(const std::exception & e) - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s\n", e.what()); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, - (std::string("PLAYBACK_FAILED - ") + e.what()).c_str()); - }catch(...) - { - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK_FAILED - See FS logs for detail."); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Exception caught.\n"); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "All done.\n"); - if (timer.interval) switch_core_timer_destroy(&timer); - - switch_core_session_set_read_codec(session, NULL); - - if (switch_core_codec_ready(&codec)) switch_core_codec_destroy(&codec); - - if (switch_core_codec_ready(&vid_codec)) switch_core_codec_destroy(&vid_codec); -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4_load) -{ - switch_application_interface_t *app_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "play_mp4", "play an MP4 file", "play an MP4 file", play_mp4_function, "", SAF_NONE); - //SWITCH_ADD_APP(app_interface, "record_mp4", "record an MP4 file", "record an MP4 file", record_mp4_function, "", SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/applications/mod_mp4/mp4_helper.cpp b/src/mod/applications/mod_mp4/mp4_helper.cpp deleted file mode 100644 index 0904cafd67..0000000000 --- a/src/mod/applications/mod_mp4/mp4_helper.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - -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. - -The Original Code is MP4 Helper Library to the Freeswitch MP4 Module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -Contributors: - - Seven Du -*/ - -#include -#include "mp4_helper.hpp" - -namespace MP4 -{ - - Context::Context(const char * file, bool newFile) - { - if(newFile) create(file); - else open(file); - } - - Context::~Context() - { - close(); - } - - void Context::open(const char * file) - { - fh = MP4Read(file); - if (fh == MP4_INVALID_FILE_HANDLE) throw Exception(file, "Open failed"); - getTracks(file); - } - - void Context::create(const char * file) - { - fh = MP4Create(file); - if (fh == MP4_INVALID_FILE_HANDLE) throw Exception(file, "Create file failed"); - } - - void Context::close() - { - if (!isOpen()) return; - MP4Close(fh); - } - - void Context::getTracks(const char * file) - { - int i = 0; - bool audioTrack = false, videoTrack = false; - - if (!isOpen()) throw Exception(file, "File is closed."); - - for (;;) - { - TrackProperties track; - if((track.hint = MP4FindTrackId(fh, i++, MP4_HINT_TRACK_TYPE, 0)) == MP4_INVALID_TRACK_ID) break; - - MP4GetHintTrackRtpPayload(fh, track.hint, &track.codecName, &track.payload, NULL, NULL); - - track.track = MP4GetHintTrackReferenceTrackId(fh, track.hint); - if(track.track == MP4_INVALID_TRACK_ID) continue; - track.clock = MP4GetTrackTimeScale(fh, track.hint); - - if (!strcmp(MP4GetTrackType(fh, track.track), MP4_AUDIO_TRACK_TYPE)) { - audioTrack = true; - - if(!strncmp(track.codecName, "PCM", 3)) - track.packetLength = 20; - else - track.packetLength = track.clock = 0; - - audio = track; - } else if (!strcmp(MP4GetTrackType(fh, track.track), MP4_VIDEO_TRACK_TYPE)) { - videoTrack = true; - - const char * sdp = MP4GetHintTrackSdp(fh, track.hint); - const char * fmtp = strstr(sdp, "fmtp"); - - if (fmtp) { - // finds beginning of 'fmtp' value; - for(fmtp += 5; *fmtp != ' '; ++fmtp); - ++fmtp; - - const char * eol = fmtp; - for(;*eol != '\r' && *eol != '\n'; ++eol); - video.fmtp = std::string(fmtp, eol); - } - video.track = track; - } - } - - if (!audioTrack || !videoTrack) throw Exception(file, "Missing audio/video track."); - } - - bool Context::getVideoPacket(void * buffer, u_int & size, u_int & ts) - { - return getPacket(video.track.hint, video.track.runtime, true, buffer, size, ts); - } - - bool Context::getAudioPacket(void * buffer, u_int & size, u_int & ts) - { - return getPacket(audio.hint, audio.runtime, false, buffer, size, ts); - } - - bool Context::getPacket(MP4TrackId hint, RuntimeProperties & rt, - bool header, void * buffer, u_int & size, u_int & ts) - { - if (rt.frame == 0 || rt.packet == rt.packetsPerFrame) { - ++rt.frame; - if(!MP4ReadRtpHint(fh, hint, rt.frame, &rt.packetsPerFrame)) - return false; - rt.packet = 0; - rt.last_frame = MP4GetSampleTime(fh, hint, rt.frame); - } - - ts = rt.last_frame; - if (!MP4ReadRtpPacket(fh, hint, rt.packet, (uint8_t **) &buffer, &size, 0, header, true)) return false; - ++rt.packet; - return true; - } -} diff --git a/src/mod/applications/mod_mp4/mp4_helper.hpp b/src/mod/applications/mod_mp4/mp4_helper.hpp deleted file mode 100644 index 8f61cd6c6b..0000000000 --- a/src/mod/applications/mod_mp4/mp4_helper.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - -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. - -The Original Code is MP4 Helper Library to Freeswitch MP4 module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -Contributor(s): - - Seven Du - -*/ - -#ifndef MP4_HELPER_HPP_ -#define MP4_HELPER_HPP_ - -#include -#include -#include -#include - -typedef unsigned int u_int; - -namespace MP4 -{ - class Exception: public std::exception { - public: - Exception(const std::string & file, const std::string & error) - : description_(file + ':' + error) - { - } - - const char * what() const throw() - { - return description_.c_str(); - } - - ~Exception() throw() - { - } - - private: - std::string description_; - }; - - struct RuntimeProperties { - uint32_t frame; // sampleID - uint16_t packetsPerFrame; - uint16_t packet; // packetID - uint32_t last_frame; // timestamp - - RuntimeProperties(): frame(0), packetsPerFrame(0), packet(0) - { - } - }; - - - struct TrackProperties { - MP4TrackId hint; - MP4TrackId track; - - char * codecName; - uint8_t payload; - uint32_t clock; - uint32_t packetLength; // packet Length in time (ms) - - RuntimeProperties runtime; - - TrackProperties(): hint(MP4_INVALID_TRACK_ID), track(MP4_INVALID_TRACK_ID), - codecName(NULL), payload(0), clock(0), packetLength(0) - { - } - }; - - typedef TrackProperties AudioProperties; - - struct VideoProperties { - TrackProperties track; - std::string fmtp; - - VideoProperties() - { - } - - VideoProperties(const TrackProperties & rhs): track(rhs) - { - } - }; - - class Context { - public: - - Context(const char * file, bool create = false); - ~Context(); - - void open(const char * file); - - void create(const char * file); - - void close(); - - // returns: TRUE = has more data, FALSE = end-of-stream or failure - bool getVideoPacket(void * buffer, u_int & size, u_int & ts); - - // returns: TRUE = has more data, FALSE = end-of-stream or failure - bool getAudioPacket(void * buffer, u_int & size, u_int & ts); - - bool isOpen() const { return fh != MP4_INVALID_FILE_HANDLE; } - - bool isSupported() const { return audio.track != MP4_INVALID_TRACK_ID && video.track.track != MP4_INVALID_TRACK_ID; } - - const AudioProperties & audioTrack() const { return audio; } - - const VideoProperties & videoTrack() const { return video; } - - private: - MP4FileHandle fh; - AudioProperties audio; - - VideoProperties video; - - // Prevent copy construction. - Context(const Context &); - - bool getPacket(MP4TrackId hint, RuntimeProperties & rt, - bool header, void * buffer, u_int & size, u_int & ts); - - void getTracks(const char * file); - }; -} -#endif diff --git a/src/mod/applications/mod_mp4v2/Makefile.am b/src/mod/applications/mod_mp4v2/Makefile.am deleted file mode 100644 index f8b8bec05a..0000000000 --- a/src/mod/applications/mod_mp4v2/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4v2 - -mod_LTLIBRARIES = mod_mp4v2.la -mod_mp4v2_la_SOURCES = mod_mp4v2.c -mod_mp4v2_la_CFLAGS = $(AM_CFLAGS) -mod_mp4v2_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4v2_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lmp4v2 diff --git a/src/mod/applications/mod_mp4v2/mod_mp4v2.c b/src/mod/applications/mod_mp4v2/mod_mp4v2.c deleted file mode 100644 index 8faccc4e02..0000000000 --- a/src/mod/applications/mod_mp4v2/mod_mp4v2.c +++ /dev/null @@ -1,772 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2015, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Seven Du - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * - * mod_mp4v2 -- MP4 File Format for FreeSWITCH - * - * - * status: For write, codec is hard coded to PCMU for audio and H264 for video - * tested with lib mp4v2-2.0.0 - * Read from mp4 is not supported yet. - */ - -#include - -#include - -#define TIMESCALE 1000 -#define SampleLenFieldSize 4 -#define PTIME 20 -// #define HAS_SPS_PARSER - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v2_load); -SWITCH_MODULE_DEFINITION(mod_mp4v2, mod_mp4v2_load, NULL, NULL); - -struct record_helper { - switch_core_session_t *session; - switch_mutex_t *mutex; - MP4FileHandle fd; - MP4TrackId video_track; - MP4TrackId audio_track; - switch_timer_t timer; - int up; - uint64_t last_pts; -}; - -#ifdef HAS_SPS_PARSER -#include "bs.h" -static void parse_sps_video_size(uint8_t *sps_buffer, int len, int *width, int *height) -{ - sps_t sps = { 0 }; - bs_t b = { 0 }; - - bs_init(&b, sps_buffer, len); - read_sps(&sps, &b); - - *width = ((sps.pic_width_in_mbs_minus1 +1)*16) - sps.frame_crop_left_offset*2 - sps.frame_crop_right_offset*2; - *height= ((2 - sps.frame_mbs_only_flag)* (sps.pic_height_in_map_units_minus1 +1) * 16) - (sps.frame_crop_top_offset * 2) - (sps.frame_crop_bottom_offset * 2); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "H264 Profile: %d size: %dx%d\n", sps.profile_idc, *width, *height); -} -#else -// use hardcoded value -static void parse_sps_video_size(uint8_t *sps_buffer, int len, int *width, int *height) -{ - *width = 1280; - *height = 720; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "We have no idea about the video size without decoding the video or actually parse the SPS, using hardcoded %dx%d\n", *width, *height); -} -#endif - -static void init_video_track(MP4FileHandle mp4, MP4TrackId *video, switch_frame_t *frame) -{ - int width = 0; - int height = 0; - uint8_t *sps_buffer = frame->data; - uint32_t sps_bytes = frame->datalen; - - sps_buffer++; - - if (frame->img) { - width = frame->img->d_w; - height = frame->img->d_h; - } else { - parse_sps_video_size(sps_buffer, sps_bytes, &width, &height); - } - - MP4SetTimeScale(mp4, TIMESCALE); - - *video = MP4AddH264VideoTrack(mp4, TIMESCALE, MP4_INVALID_DURATION, width, height, *(sps_buffer), *(sps_buffer+1), *(sps_buffer+2), SampleLenFieldSize - 1); - - if (*video == MP4_INVALID_TRACK_ID) { - return; - } - - MP4AddH264SequenceParameterSet(mp4, *video, --sps_buffer, sps_bytes); - - /* - MP4SetVideoProfileLevel sets the minumum profile/level of MPEG-4 video support necessary to render the contents of the file. - - ISO/IEC 14496-1:2001 MPEG-4 Systems defines the following values: - 0x00 Reserved - 0x01 Simple Profile @ Level 3 - 0x02 Simple Profile @ Level 2 - 0x03 Simple Profile @ Level 1 - 0x04 Simple Scalable Profile @ Level 2 - 0x05 Simple Scalable Profile @ Level 1 - 0x06 Core Profile @ Level 2 - 0x07 Core Profile @ Level 1 - 0x08 Main Profile @ Level 4 - 0x09 Main Profile @ Level 3 - 0x0A Main Profile @ Level 2 - 0x0B N-Bit Profile @ Level 2 - 0x0C Hybrid Profile @ Level 2 - 0x0D Hybrid Profile @ Level 1 - 0x0E Basic Animated Texture @ Level 2 - 0x0F Basic Animated Texture @ Level 1 - 0x10 Scalable Texture @ Level 3 - 0x11 Scalable Texture @ Level 2 - 0x12 Scalable Texture @ Level 1 - 0x13 Simple Face Animation @ Level 2 - 0x14 Simple Face Animation @ Level 1 - 0x15-0x7F Reserved - 0x80-0xFD User private - 0xFE No audio profile specified - 0xFF No audio required - */ - MP4SetVideoProfileLevel(mp4, 0x7F); -} - -static inline char *get_audio_codec_name(uint8_t audio_type) -{ - switch (audio_type) { - case MP4_MP3_AUDIO_TYPE: - return "MP3"; - case MP4_ULAW_AUDIO_TYPE: - return "PCMU"; - case MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE: - return "L16"; - case MP4_MPEG4_AUDIO_TYPE: - return "AAC"; - default: - return "ERROR"; - } -} - -static int get_aac_sample_rate_index(unsigned int sampleRate) -{ - if (92017 <= sampleRate) return 0; - if (75132 <= sampleRate) return 1; - if (55426 <= sampleRate) return 2; - if (46009 <= sampleRate) return 3; - if (37566 <= sampleRate) return 4; - if (27713 <= sampleRate) return 5; - if (23004 <= sampleRate) return 6; - if (18783 <= sampleRate) return 7; - if (13856 <= sampleRate) return 8; - if (11502 <= sampleRate) return 9; - if (9391 <= sampleRate) return 10; - - return 11; -} - -struct mp4_file_context { - switch_file_handle_t *handle; - switch_memory_pool_t *pool; - MP4FileHandle fd; - MP4TrackId audio; - MP4TrackId video; - uint32_t audio_frame_size; - switch_codec_t audio_codec; - switch_codec_t video_codec; - switch_mutex_t *mutex; - switch_buffer_t *buf; - uint32_t last_chunk_size; - int sps_set; - int pps_set; - switch_timer_t timer; - uint64_t last_pts; - int offset; - int audio_start; - uint8_t audio_type; // MP4 Audio Type - MP4Duration audio_duration; - switch_thread_t *video_thread; - switch_queue_t *video_queue; -}; - -typedef struct mp4_file_context mp4_file_context_t; - -static switch_status_t do_write_video(switch_file_handle_t *handle, switch_frame_t *frame); - -static void *SWITCH_THREAD_FUNC video_write_thread_run(switch_thread_t *thread, void *obj) -{ - mp4_file_context_t *context = (mp4_file_context_t *)obj; - void *pop = NULL; - switch_image_t *last_img = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_status_t encode_status = SWITCH_STATUS_SUCCESS; - uint8_t data[SWITCH_DEFAULT_VIDEO_SIZE]; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video_write_thread start\n"); - - while (switch_queue_pop(context->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { - switch_frame_t frame = { 0 }; - - if (!pop) break; - - if (!last_img) { // first img - last_img = (switch_image_t *)pop; - continue; - } - - frame.data = data; - frame.img = last_img; - // switch_set_flag(&frame, SFF_DYNAMIC); - - do { - frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE; - encode_status = switch_core_codec_encode_video(&context->video_codec, &frame); - - if (encode_status == SWITCH_STATUS_SUCCESS || encode_status == SWITCH_STATUS_MORE_DATA) { - switch_assert((encode_status == SWITCH_STATUS_SUCCESS && frame.m) || !frame.m); - - if (frame.datalen == 0) break; - - status = do_write_video(context->handle, &frame); - } - } while(status == SWITCH_STATUS_SUCCESS && encode_status == SWITCH_STATUS_MORE_DATA); - - switch_img_free(&last_img); - last_img = (switch_image_t *)pop; - } - - switch_img_free(&last_img); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video_write_thread done\n"); - - return NULL; -} - -static void launch_video_write_thread(mp4_file_context_t *context, switch_memory_pool_t *pool) -{ - //switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - // switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&context->video_thread, thd_attr, video_write_thread_run, context, pool); -} - - -static int flush_video_queue(switch_queue_t *q, int min) -{ - void *pop; - - if (switch_queue_size(q) > min) { - while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { - switch_image_t *img = (switch_image_t *) pop; - switch_img_free(&img); - if (min && switch_queue_size(q) <= min) { - break; - } - } - } - - return switch_queue_size(q); -} - -static switch_status_t mp4_file_open(switch_file_handle_t *handle, const char *path) -{ - mp4_file_context_t *context; - char *ext; - unsigned int flags = 0; - const char *tmp = NULL; - - if ((ext = strrchr(path, '.')) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); - return SWITCH_STATUS_GENERR; - } - ext++; - - if ((context = switch_core_alloc(handle->memory_pool, sizeof(mp4_file_context_t))) == 0) { - return SWITCH_STATUS_MEMERR; - } - - memset(context, 0, sizeof(mp4_file_context_t)); - - context->handle = handle; - context->offset = 0; - - if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_video_offset"))) { - context->offset = atoi(tmp); - } - - context->audio_type = MP4_ULAW_AUDIO_TYPE; // default - - if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_audio_codec"))) { - if (!strcasecmp(tmp, "PCMU")) { - context->audio_type = MP4_ULAW_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "MP3")) { - context->audio_type = MP4_MP3_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "AAC")) { - context->audio_type = MP4_MPEG4_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "L16")) { - context->audio_type = MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE; - } - } - - switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - flags |= SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE; - if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(handle, SWITCH_FILE_WRITE_OVER)) { - flags |= SWITCH_FOPEN_READ; - } else { - flags |= SWITCH_FOPEN_TRUNCATE; - } - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) { - flags |= SWITCH_FOPEN_READ; - } - - if (handle->mm.samplerate) { - handle->samplerate = handle->mm.samplerate; - } else { - handle->mm.samplerate = handle->samplerate; - } - - if (!handle->mm.ab) { - handle->mm.ab = 128; - } - - if (!handle->mm.vb) { - handle->mm.vb = switch_calc_bitrate(handle->mm.vw, handle->mm.vh, 1, handle->mm.fps); - } - - // MP4_CREATE_64BIT_DATA if file > 4G - - if ((context->fd = MP4CreateEx(path, 0, 1, 1, NULL, 0, NULL, 0)) == MP4_INVALID_FILE_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening file %s\n", path); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sample rate: %d, channels: %d\n", handle->samplerate, handle->channels); - - if (context->audio_type == MP4_ULAW_AUDIO_TYPE) { - context->audio = MP4AddULawAudioTrack(context->fd, handle->samplerate); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.sampleSize", 8); - } else if (context->audio_type == MP4_MP3_AUDIO_TYPE) { - // handle->samplerate = 44100; - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_MP3_AUDIO_TYPE); - MP4SetTrackName(context->fd, context->audio, ".mp3"); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - // MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd..mp3.channels", handle->channels); - } else if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) { - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE); - MP4SetTrackName(context->fd, context->audio, "lpcm"); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.sampleSize", 16); - } else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) { - /* AAC object types */ - #define AAC_MAIN 1 - #define AAC_LOW 2 - #define AAC_SSR 3 - #define AAC_LTP 4 - - uint16_t info = 0; - - info |= AAC_LOW << 11; // aacObjectType (5bit) - info |= get_aac_sample_rate_index(handle->samplerate) << 7; //(4bit) - info |= handle->channels << 3; //(4bit) - info = htons(info); - - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, 1024, MP4_MPEG4_AUDIO_TYPE); - MP4SetTrackESConfiguration(context->fd, context->audio, (uint8_t *)&info, sizeof(info)); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - } - - handle->format = 0; - handle->sections = 0; - handle->seekable = 0; - handle->speed = 0; - handle->pos = 0; - handle->private_info = context; - context->pool = handle->memory_pool; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n", - path, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : ""); - - if (switch_core_codec_init(&context->audio_codec, - get_audio_codec_name(context->audio_type), - NULL, - NULL, - handle->samplerate, - PTIME,//ms - handle->channels, SWITCH_CODEC_FLAG_ENCODE, - NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); - goto end; - } - - if (context->audio_type == MP4_MP3_AUDIO_TYPE) { // fetch frame size - uint32_t size; - uint32_t flag = 0xFFFFFFFF; - - switch_core_codec_encode(&context->audio_codec, NULL, &flag, 0, 0, - (void *)&context->audio_frame_size, &size, NULL, &flag); - } else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) { - context->audio_frame_size = 1024; - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { - switch_codec_settings_t codec_settings = {{ 0 }}; - codec_settings.video.bandwidth = handle->mm.vb; - codec_settings.video.fps = handle->mm.fps; - - if (switch_core_codec_init(&context->video_codec, - "H264", - NULL, - NULL, - 90000, - 0,//ms - 1, SWITCH_CODEC_FLAG_ENCODE, - &codec_settings, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Codec H264 Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video Codec H264 Activation Fail\n"); - goto end; - } - - switch_queue_create(&context->video_queue, 60, handle->memory_pool); - launch_video_write_thread(context, handle->memory_pool); - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - MP4SetAudioProfileLevel(context->fd, 0x7F); - } - - switch_buffer_create_dynamic(&context->buf, 512, 512, 1024000); - - return SWITCH_STATUS_SUCCESS; - -end: - if (context->fd) { - MP4Close(context->fd, 0); - context->fd = NULL; - } - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_truncate(switch_file_handle_t *handle, int64_t offset) -{ - mp4_file_context_t *context = handle->private_info; - switch_status_t status; - - if ((status = switch_file_trunc(context->fd, offset)) == SWITCH_STATUS_SUCCESS) { - handle->pos = 0; - } - - return status; - -} - -static switch_status_t mp4_file_close(switch_file_handle_t *handle) -{ - mp4_file_context_t *context = handle->private_info; - switch_status_t status; - - if (context->fd) { - MP4Close(context->fd, MP4_CLOSE_DO_NOT_COMPUTE_BITRATE); - context->fd = NULL; - } - - if (switch_core_codec_ready(&context->audio_codec)) switch_core_codec_destroy(&context->audio_codec); - if (switch_core_codec_ready(&context->video_codec)) switch_core_codec_destroy(&context->video_codec); - - if (context->timer.interval) { - switch_core_timer_destroy(&context->timer); - } - - if (context->video_queue) { - switch_queue_term(context->video_queue); - flush_video_queue(context->video_queue, 0); - } - - if (context->video_thread) { - switch_thread_join(&status, context->video_thread); - } - - switch_buffer_destroy(&context->buf); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t mp4_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "seek not implemented\n"); - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read not implemented\n"); - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_write(switch_file_handle_t *handle, void *data, size_t *len) -{ - uint32_t datalen = *len * 2 * handle->channels; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - uint32_t encoded_rate; - mp4_file_context_t *context = handle->private_info; - uint32_t size = 0; - uint32_t flag = 0; - - if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) { - size = datalen; - memcpy(buf, data, datalen); - } else { - switch_core_codec_encode(&context->audio_codec, NULL, - data, datalen, - handle->samplerate, - buf, &size, &encoded_rate, &flag); - } - - switch_mutex_lock(context->mutex); - - if (!context->timer.interval) { - switch_core_timer_init(&context->timer, "soft", 1, 1, context->pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); - } - - if (size > 0) { - MP4WriteSample(context->fd, context->audio, buf, size, context->audio_frame_size ? context->audio_frame_size : *len, 0, 1); - } - - context->audio_duration += *len; - - switch_mutex_unlock(context->mutex); - - return status; -} - -static switch_status_t mp4_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t do_write_video(switch_file_handle_t *handle, switch_frame_t *frame) -{ - uint32_t datalen = frame->datalen; - switch_status_t status = SWITCH_STATUS_SUCCESS; - int is_iframe = 0; - uint32_t size; - uint8_t *hdr = NULL; - uint8_t fragment_type; - uint8_t nal_type; - uint8_t start_bit; - uint8_t end_bit; - mp4_file_context_t *context = handle->private_info; - - hdr = (uint8_t *)frame->data; - fragment_type = hdr[0] & 0x1f; - nal_type = hdr[1] & 0x1f; - start_bit = hdr[1] & 0x80; - end_bit = hdr[1] & 0x40; - - is_iframe = fragment_type == 5 || (fragment_type == 28 && nal_type == 5); - - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x | len:%d m:%d st:%d i:%d\n", hdr[0], hdr[1], hdr[2], datalen, frame->m, start_bit, is_iframe); - - if (fragment_type == 7 && !context->sps_set) { //sps - context->sps_set = 1; - - init_video_track(context->fd, &context->video, frame); - if (context->video == MP4_INVALID_TRACK_ID) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error add video track!\n"); - return SWITCH_STATUS_FALSE; - } - } else if (fragment_type == 8 && context->sps_set && !context->pps_set) { //pps - MP4AddH264PictureParameterSet(context->fd, context->video, hdr, datalen); - context->pps_set = 1; - } - - if (fragment_type == 28) { - if (start_bit && end_bit) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF?\n"); - } - - if (start_bit) { - nal_type |= (hdr[0] & 0x60); - - size = htonl(datalen); - switch_buffer_write(context->buf, &size, 4); - switch_buffer_write(context->buf, &nal_type, 1); - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size = datalen - 1; - } else if (end_bit) { - uint32_t used; - const void *data; - uint32_t *chunk_size = NULL; - - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size += datalen - 2; - used = switch_buffer_inuse(context->buf); - switch_buffer_peek_zerocopy(context->buf, &data); - chunk_size = (uint32_t *)((uint8_t *)data + used - context->last_chunk_size - 4); - *chunk_size = htonl(context->last_chunk_size); - } else { - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size += datalen - 2; - } - } else { - size = htonl(datalen); - switch_buffer_write(context->buf, &size, 4); - switch_buffer_write(context->buf, hdr, datalen); - } - - if (!frame->m) { - return SWITCH_STATUS_SUCCESS; - } - - switch_mutex_lock(context->mutex); - - if (context->sps_set && context->pps_set) { - uint32_t used = switch_buffer_inuse(context->buf); - const void *data; - int duration = 0; - int ts = 0; - - if (frame->img && frame->img->user_priv) { - ts = *(int *)frame->img->user_priv; - } else { - switch_core_timer_sync(&context->timer); - ts = context->timer.samplecount; - } - - duration = ts - context->last_pts; - - if (duration <= 0) duration = 1; - - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "samplecount: %u, duration: %u\n", context->timer.samplecount, duration); - switch_buffer_peek_zerocopy(context->buf, &data); - - context->last_pts = ts; - - MP4WriteSample(context->fd, context->video, data, used, duration, 0, is_iframe); - switch_buffer_zero(context->buf); - } - - switch_mutex_unlock(context->mutex); - - { - int delta = context->timer.samplecount * (handle->samplerate / 1000) - context->audio_duration; - - if (delta > (int)handle->samplerate) { - uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; - size_t samples = handle->samplerate / 1000 * PTIME; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missed audio %d samples at %d\n", delta, (int)context->audio_duration / (handle->samplerate / 1000)); - - while ((delta -= samples) > 0) { - mp4_file_write(handle, data, &samples); - samples = handle->samplerate / 1000 * PTIME; - } - } - } - - return status; -} - -static switch_status_t mp4_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) -{ - mp4_file_context_t *context = handle->private_info; - - if (!frame->img) { - return do_write_video(handle, frame); - } else { - switch_image_t *img = NULL; - - if (!context->timer.interval) { - switch_mutex_lock(context->mutex); - switch_core_timer_init(&context->timer, "soft", 1, 1, context->pool); - switch_mutex_unlock(context->mutex); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); - } else { - switch_mutex_lock(context->mutex); - switch_core_timer_sync(&context->timer); - switch_mutex_unlock(context->mutex); - } - - switch_img_copy(frame->img, &img); - switch_assert(img); - img->user_priv = malloc(sizeof(int)); - *(int *)img->user_priv = context->timer.samplecount; - - if (switch_queue_trypush(context->video_queue, img) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "video queue full, discard one frame\n"); - } - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t mp4_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string) -{ - return SWITCH_STATUS_FALSE; -} - -static char *supported_formats[3] = { 0 }; - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v2_load) -{ - switch_file_interface_t *file_interface; - - supported_formats[0] = "mp4v2"; - supported_formats[1] = "mp4"; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = modname; - file_interface->extens = supported_formats; - file_interface->file_open = mp4_file_open; - file_interface->file_close = mp4_file_close; - file_interface->file_truncate = mp4_file_truncate; - file_interface->file_read = mp4_file_read; - file_interface->file_write = mp4_file_write; - file_interface->file_read_video = mp4_file_read_video; - file_interface->file_write_video = mp4_file_write_video; - file_interface->file_seek = mp4_file_seek; - file_interface->file_set_string = mp4_file_set_string; - file_interface->file_get_string = mp4_file_get_string; - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/codecs/mod_mp4v/Makefile.am b/src/mod/codecs/mod_mp4v/Makefile.am deleted file mode 100644 index 59f9fa41ef..0000000000 --- a/src/mod/codecs/mod_mp4v/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4v - -mod_LTLIBRARIES = mod_mp4v.la -mod_mp4v_la_SOURCES = mod_mp4v.c -mod_mp4v_la_CFLAGS = $(AM_CFLAGS) -mod_mp4v_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4v_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/codecs/mod_mp4v/mod_mp4v.c b/src/mod/codecs/mod_mp4v/mod_mp4v.c deleted file mode 100644 index 685e6756c7..0000000000 --- a/src/mod/codecs/mod_mp4v/mod_mp4v.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_mp4v.c -- MP4V Video Codec - * - */ - -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load); -SWITCH_MODULE_DEFINITION(mod_mp4v, mod_mp4v_load, NULL, NULL); - -static switch_status_t switch_mp4v_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - int encoding, decoding; - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - if (!(encoding || decoding)) { - return SWITCH_STATUS_FALSE; - } else { - if (codec->fmtp_in) { - codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); - } - return SWITCH_STATUS_SUCCESS; - } -} - -static switch_status_t switch_mp4v_encode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *decoded_data, - uint32_t decoded_data_len, - uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, - unsigned int *flag) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t switch_mp4v_decode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *encoded_data, - uint32_t encoded_data_len, - uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, - unsigned int *flag) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t switch_mp4v_destroy(switch_codec_t *codec) -{ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load) -{ - switch_codec_interface_t *codec_interface; - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - SWITCH_ADD_CODEC(codec_interface, "MP4V Video (passthru)"); - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_VIDEO, 99, "MP4V-ES", NULL, 90000, 90000, 0, - 0, 0, 0, 0, 1, 1, switch_mp4v_init, switch_mp4v_encode, switch_mp4v_decode, switch_mp4v_destroy); - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ From 6286c51ff6e8d5bd5859e46d7ce4be427b7a63f0 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 29 Aug 2024 17:17:18 +0300 Subject: [PATCH 188/205] [mod_isac] Remove from tree --- Freeswitch.2017.sln | 14 - LICENSE | 8 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - ci.sh | 1 - .../vanilla/autoload_configs/modules.conf.xml | 1 - configure.ac | 1 - debian/bootstrap.sh | 2 - debian/control-modules | 4 - debian/copyright | 8 - freeswitch.spec | 15 +- src/mod/codecs/mod_isac/LICENSE | 29 - src/mod/codecs/mod_isac/Makefile.am | 17 - src/mod/codecs/mod_isac/PATENTS | 24 - src/mod/codecs/mod_isac/arith_routines.c | 60 - src/mod/codecs/mod_isac/arith_routines.h | 63 - src/mod/codecs/mod_isac/arith_routines_hist.c | 291 -- .../codecs/mod_isac/arith_routines_logist.c | 294 -- .../codecs/mod_isac/auto_corr_to_refl_coef.c | 103 - src/mod/codecs/mod_isac/auto_correlation.c | 141 - src/mod/codecs/mod_isac/bandwidth_estimator.c | 1024 ------ src/mod/codecs/mod_isac/bandwidth_estimator.h | 177 -- src/mod/codecs/mod_isac/codec.h | 292 -- src/mod/codecs/mod_isac/complex_bit_reverse.c | 51 - src/mod/codecs/mod_isac/complex_fft.c | 425 --- src/mod/codecs/mod_isac/copy_set_operations.c | 108 - src/mod/codecs/mod_isac/crc.c | 110 - src/mod/codecs/mod_isac/crc.h | 46 - src/mod/codecs/mod_isac/cross_correlation.c | 271 -- src/mod/codecs/mod_isac/decode.c | 330 -- src/mod/codecs/mod_isac/decode_bwe.c | 88 - src/mod/codecs/mod_isac/division_operations.c | 144 - .../codecs/mod_isac/dot_product_with_scale.c | 91 - src/mod/codecs/mod_isac/downsample_fast.c | 59 - src/mod/codecs/mod_isac/encode.c | 1451 --------- src/mod/codecs/mod_isac/encode_lpc_swb.c | 708 ----- src/mod/codecs/mod_isac/encode_lpc_swb.h | 283 -- src/mod/codecs/mod_isac/energy.c | 36 - src/mod/codecs/mod_isac/entropy_coding.c | 2748 ---------------- src/mod/codecs/mod_isac/entropy_coding.h | 412 --- src/mod/codecs/mod_isac/fft.c | 947 ------ src/mod/codecs/mod_isac/fft.h | 45 - src/mod/codecs/mod_isac/filter_ar.c | 89 - src/mod/codecs/mod_isac/filter_ar_fast_q12.c | 49 - src/mod/codecs/mod_isac/filter_functions.c | 271 -- src/mod/codecs/mod_isac/filter_ma_fast_q12.c | 49 - src/mod/codecs/mod_isac/filterbank_tables.c | 37 - src/mod/codecs/mod_isac/filterbank_tables.h | 46 - src/mod/codecs/mod_isac/filterbanks.c | 346 -- src/mod/codecs/mod_isac/get_hanning_window.c | 77 - src/mod/codecs/mod_isac/get_scaling_square.c | 44 - .../codecs/mod_isac/ilbc_specific_functions.c | 120 - src/mod/codecs/mod_isac/intialize.c | 175 -- src/mod/codecs/mod_isac/isac.c | 2797 ----------------- src/mod/codecs/mod_isac/isac.gypi | 91 - src/mod/codecs/mod_isac/isac.h | 729 ----- src/mod/codecs/mod_isac/lattice.c | 217 -- src/mod/codecs/mod_isac/levinson_durbin.c | 259 -- src/mod/codecs/mod_isac/lpc_analysis.c | 535 ---- src/mod/codecs/mod_isac/lpc_analysis.h | 50 - src/mod/codecs/mod_isac/lpc_gain_swb_tables.c | 137 - src/mod/codecs/mod_isac/lpc_gain_swb_tables.h | 49 - .../codecs/mod_isac/lpc_shape_swb12_tables.c | 159 - .../codecs/mod_isac/lpc_shape_swb12_tables.h | 65 - .../codecs/mod_isac/lpc_shape_swb16_tables.c | 248 -- .../codecs/mod_isac/lpc_shape_swb16_tables.h | 79 - src/mod/codecs/mod_isac/lpc_tables.c | 1129 ------- src/mod/codecs/mod_isac/lpc_tables.h | 114 - src/mod/codecs/mod_isac/lpc_to_refl_coef.c | 57 - src/mod/codecs/mod_isac/min_max_operations.c | 265 -- .../codecs/mod_isac/min_max_operations_neon.c | 47 - src/mod/codecs/mod_isac/mod_iSAC.2017.vcxproj | 254 -- src/mod/codecs/mod_isac/mod_isac.c | 283 -- src/mod/codecs/mod_isac/os_specific_inline.h | 42 - src/mod/codecs/mod_isac/pitch_estimator.c | 622 ---- src/mod/codecs/mod_isac/pitch_estimator.h | 71 - src/mod/codecs/mod_isac/pitch_filter.c | 469 --- src/mod/codecs/mod_isac/pitch_gain_tables.c | 105 - src/mod/codecs/mod_isac/pitch_gain_tables.h | 45 - src/mod/codecs/mod_isac/pitch_lag_tables.c | 277 -- src/mod/codecs/mod_isac/pitch_lag_tables.h | 114 - .../codecs/mod_isac/randomization_functions.c | 119 - src/mod/codecs/mod_isac/refl_coef_to_lpc.c | 60 - src/mod/codecs/mod_isac/resample.c | 505 --- src/mod/codecs/mod_isac/resample_48khz.c | 186 -- src/mod/codecs/mod_isac/resample_by_2.c | 181 -- .../codecs/mod_isac/resample_by_2_internal.c | 679 ---- .../codecs/mod_isac/resample_by_2_internal.h | 47 - src/mod/codecs/mod_isac/resample_fractional.c | 242 -- src/mod/codecs/mod_isac/settings.h | 199 -- .../mod_isac/signal_processing_library.h | 1686 ---------- .../mod_isac/spectrum_ar_model_tables.c | 138 - .../mod_isac/spectrum_ar_model_tables.h | 76 - src/mod/codecs/mod_isac/spl_inl.h | 159 - src/mod/codecs/mod_isac/spl_inl_armv7.h | 137 - src/mod/codecs/mod_isac/spl_sqrt.c | 184 -- src/mod/codecs/mod_isac/spl_sqrt_floor.c | 53 - src/mod/codecs/mod_isac/spl_version.c | 25 - src/mod/codecs/mod_isac/splitting_filter.c | 198 -- .../mod_isac/sqrt_of_one_minus_x_squared.c | 35 - src/mod/codecs/mod_isac/structs.h | 478 --- src/mod/codecs/mod_isac/transform.c | 131 - src/mod/codecs/mod_isac/typedefs.h | 149 - .../mod_isac/vector_scaling_operations.c | 151 - src/mod/codecs/mod_isac/webrtc_fft_t_1024_8.c | 704 ----- src/mod/codecs/mod_isac/webrtc_fft_t_rad.c | 27 - w32/Setup/Setup.2017.wixproj | 8 - 107 files changed, 2 insertions(+), 28091 deletions(-) delete mode 100644 src/mod/codecs/mod_isac/LICENSE delete mode 100644 src/mod/codecs/mod_isac/Makefile.am delete mode 100644 src/mod/codecs/mod_isac/PATENTS delete mode 100644 src/mod/codecs/mod_isac/arith_routines.c delete mode 100644 src/mod/codecs/mod_isac/arith_routines.h delete mode 100644 src/mod/codecs/mod_isac/arith_routines_hist.c delete mode 100644 src/mod/codecs/mod_isac/arith_routines_logist.c delete mode 100644 src/mod/codecs/mod_isac/auto_corr_to_refl_coef.c delete mode 100644 src/mod/codecs/mod_isac/auto_correlation.c delete mode 100644 src/mod/codecs/mod_isac/bandwidth_estimator.c delete mode 100644 src/mod/codecs/mod_isac/bandwidth_estimator.h delete mode 100644 src/mod/codecs/mod_isac/codec.h delete mode 100644 src/mod/codecs/mod_isac/complex_bit_reverse.c delete mode 100644 src/mod/codecs/mod_isac/complex_fft.c delete mode 100644 src/mod/codecs/mod_isac/copy_set_operations.c delete mode 100644 src/mod/codecs/mod_isac/crc.c delete mode 100644 src/mod/codecs/mod_isac/crc.h delete mode 100644 src/mod/codecs/mod_isac/cross_correlation.c delete mode 100644 src/mod/codecs/mod_isac/decode.c delete mode 100644 src/mod/codecs/mod_isac/decode_bwe.c delete mode 100644 src/mod/codecs/mod_isac/division_operations.c delete mode 100644 src/mod/codecs/mod_isac/dot_product_with_scale.c delete mode 100644 src/mod/codecs/mod_isac/downsample_fast.c delete mode 100644 src/mod/codecs/mod_isac/encode.c delete mode 100644 src/mod/codecs/mod_isac/encode_lpc_swb.c delete mode 100644 src/mod/codecs/mod_isac/encode_lpc_swb.h delete mode 100644 src/mod/codecs/mod_isac/energy.c delete mode 100644 src/mod/codecs/mod_isac/entropy_coding.c delete mode 100644 src/mod/codecs/mod_isac/entropy_coding.h delete mode 100644 src/mod/codecs/mod_isac/fft.c delete mode 100644 src/mod/codecs/mod_isac/fft.h delete mode 100644 src/mod/codecs/mod_isac/filter_ar.c delete mode 100644 src/mod/codecs/mod_isac/filter_ar_fast_q12.c delete mode 100644 src/mod/codecs/mod_isac/filter_functions.c delete mode 100644 src/mod/codecs/mod_isac/filter_ma_fast_q12.c delete mode 100644 src/mod/codecs/mod_isac/filterbank_tables.c delete mode 100644 src/mod/codecs/mod_isac/filterbank_tables.h delete mode 100644 src/mod/codecs/mod_isac/filterbanks.c delete mode 100644 src/mod/codecs/mod_isac/get_hanning_window.c delete mode 100644 src/mod/codecs/mod_isac/get_scaling_square.c delete mode 100644 src/mod/codecs/mod_isac/ilbc_specific_functions.c delete mode 100644 src/mod/codecs/mod_isac/intialize.c delete mode 100644 src/mod/codecs/mod_isac/isac.c delete mode 100644 src/mod/codecs/mod_isac/isac.gypi delete mode 100644 src/mod/codecs/mod_isac/isac.h delete mode 100644 src/mod/codecs/mod_isac/lattice.c delete mode 100644 src/mod/codecs/mod_isac/levinson_durbin.c delete mode 100644 src/mod/codecs/mod_isac/lpc_analysis.c delete mode 100644 src/mod/codecs/mod_isac/lpc_analysis.h delete mode 100644 src/mod/codecs/mod_isac/lpc_gain_swb_tables.c delete mode 100644 src/mod/codecs/mod_isac/lpc_gain_swb_tables.h delete mode 100644 src/mod/codecs/mod_isac/lpc_shape_swb12_tables.c delete mode 100644 src/mod/codecs/mod_isac/lpc_shape_swb12_tables.h delete mode 100644 src/mod/codecs/mod_isac/lpc_shape_swb16_tables.c delete mode 100644 src/mod/codecs/mod_isac/lpc_shape_swb16_tables.h delete mode 100644 src/mod/codecs/mod_isac/lpc_tables.c delete mode 100644 src/mod/codecs/mod_isac/lpc_tables.h delete mode 100644 src/mod/codecs/mod_isac/lpc_to_refl_coef.c delete mode 100644 src/mod/codecs/mod_isac/min_max_operations.c delete mode 100644 src/mod/codecs/mod_isac/min_max_operations_neon.c delete mode 100644 src/mod/codecs/mod_isac/mod_iSAC.2017.vcxproj delete mode 100644 src/mod/codecs/mod_isac/mod_isac.c delete mode 100644 src/mod/codecs/mod_isac/os_specific_inline.h delete mode 100644 src/mod/codecs/mod_isac/pitch_estimator.c delete mode 100644 src/mod/codecs/mod_isac/pitch_estimator.h delete mode 100644 src/mod/codecs/mod_isac/pitch_filter.c delete mode 100644 src/mod/codecs/mod_isac/pitch_gain_tables.c delete mode 100644 src/mod/codecs/mod_isac/pitch_gain_tables.h delete mode 100644 src/mod/codecs/mod_isac/pitch_lag_tables.c delete mode 100644 src/mod/codecs/mod_isac/pitch_lag_tables.h delete mode 100644 src/mod/codecs/mod_isac/randomization_functions.c delete mode 100644 src/mod/codecs/mod_isac/refl_coef_to_lpc.c delete mode 100644 src/mod/codecs/mod_isac/resample.c delete mode 100644 src/mod/codecs/mod_isac/resample_48khz.c delete mode 100644 src/mod/codecs/mod_isac/resample_by_2.c delete mode 100644 src/mod/codecs/mod_isac/resample_by_2_internal.c delete mode 100644 src/mod/codecs/mod_isac/resample_by_2_internal.h delete mode 100644 src/mod/codecs/mod_isac/resample_fractional.c delete mode 100644 src/mod/codecs/mod_isac/settings.h delete mode 100644 src/mod/codecs/mod_isac/signal_processing_library.h delete mode 100644 src/mod/codecs/mod_isac/spectrum_ar_model_tables.c delete mode 100644 src/mod/codecs/mod_isac/spectrum_ar_model_tables.h delete mode 100644 src/mod/codecs/mod_isac/spl_inl.h delete mode 100644 src/mod/codecs/mod_isac/spl_inl_armv7.h delete mode 100644 src/mod/codecs/mod_isac/spl_sqrt.c delete mode 100644 src/mod/codecs/mod_isac/spl_sqrt_floor.c delete mode 100644 src/mod/codecs/mod_isac/spl_version.c delete mode 100644 src/mod/codecs/mod_isac/splitting_filter.c delete mode 100644 src/mod/codecs/mod_isac/sqrt_of_one_minus_x_squared.c delete mode 100644 src/mod/codecs/mod_isac/structs.h delete mode 100644 src/mod/codecs/mod_isac/transform.c delete mode 100644 src/mod/codecs/mod_isac/typedefs.h delete mode 100644 src/mod/codecs/mod_isac/vector_scaling_operations.c delete mode 100644 src/mod/codecs/mod_isac/webrtc_fft_t_1024_8.c delete mode 100644 src/mod/codecs/mod_isac/webrtc_fft_t_rad.c diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 230732acfb..6fac09141b 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -219,8 +219,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pthread", "libs\win32\pthre EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g723_1", "src\mod\codecs\mod_g723_1\mod_g723_1.2017.vcxproj", "{FEA1EEF7-876F-48DE-88BF-C0E3E606D758}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_iSAC", "src\mod\codecs\mod_isac\mod_iSAC.2017.vcxproj", "{7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_native_file", "src\mod\formats\mod_native_file\mod_native_file.2017.vcxproj", "{9254C4B0-6F60-42B6-BB3A-36D63FC001C7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libudns", "libs\win32\udns\libudns.2017.vcxproj", "{4043FC6A-9A30-4577-8AD5-9B233C9575D8}" @@ -832,17 +830,6 @@ Global {FEA1EEF7-876F-48DE-88BF-C0E3E606D758}.Release|Win32.Build.0 = Release Passthrough|Win32 {FEA1EEF7-876F-48DE-88BF-C0E3E606D758}.Release|x64.ActiveCfg = Release Passthrough|x64 {FEA1EEF7-876F-48DE-88BF-C0E3E606D758}.Release|x64.Build.0 = Release Passthrough|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.All|Win32.ActiveCfg = Release|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.All|x64.ActiveCfg = Release|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.All|x64.Build.0 = Release|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Debug|Win32.ActiveCfg = Debug|Win32 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Debug|Win32.Build.0 = Debug|Win32 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Debug|x64.ActiveCfg = Debug|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Debug|x64.Build.0 = Debug|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Release|Win32.ActiveCfg = Release|Win32 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Release|Win32.Build.0 = Release|Win32 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Release|x64.ActiveCfg = Release|x64 - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD}.Release|x64.Build.0 = Release|x64 {9254C4B0-6F60-42B6-BB3A-36D63FC001C7}.All|Win32.ActiveCfg = Release|x64 {9254C4B0-6F60-42B6-BB3A-36D63FC001C7}.All|x64.ActiveCfg = Release|x64 {9254C4B0-6F60-42B6-BB3A-36D63FC001C7}.All|x64.Build.0 = Release|x64 @@ -2516,7 +2503,6 @@ Global {0DF3ABD0-DDC0-4265-B778-07C66780979B} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {FEA1EEF7-876F-48DE-88BF-C0E3E606D758} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {9254C4B0-6F60-42B6-BB3A-36D63FC001C7} = {A5A27244-AD24-46E5-B01B-840CD296C91D} {4043FC6A-9A30-4577-8AD5-9B233C9575D8} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {71A967D5-0E99-4CEF-A587-98836EE6F2EF} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} diff --git a/LICENSE b/LICENSE index c5d335d312..0e0935c1db 100644 --- a/LICENSE +++ b/LICENSE @@ -1578,14 +1578,6 @@ Files: src/include/switch_profile.h Copyright: 2009,2010, Sangoma Technologies License: BSD-3-clause -Files: src/mod/codecs/mod_isac/* -Copyright: 2011-2012 The WebRTC project authors -License: BSD-3-clause - -Files: src/mod/codecs/mod_isac/mod_isac.c -Copyright: 2005-2014, Anthony Minessale II -License: MPL-1.1 - Files: libs/srtp/* Copyright: 2001-2006, Cisco Systems, Inc. 2005 Ingate Systems AB diff --git a/build/modules.conf.in b/build/modules.conf.in index de87399e74..16c251f3be 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -66,7 +66,6 @@ codecs/mod_g723_1 codecs/mod_g729 codecs/mod_h26x #codecs/mod_ilbc -#codecs/mod_isac codecs/mod_opus #codecs/mod_silk #codecs/mod_siren diff --git a/build/modules.conf.most b/build/modules.conf.most index ad14f0bb7a..20478c359b 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -65,7 +65,6 @@ codecs/mod_g723_1 codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc -codecs/mod_isac codecs/mod_opus codecs/mod_silk codecs/mod_siren diff --git a/ci.sh b/ci.sh index 26947f6a70..f689babd9a 100755 --- a/ci.sh +++ b/ci.sh @@ -92,7 +92,6 @@ configure_freeswitch() # "Disable"/"Comment out" mods sed -i \ -e '/mod_ilbc/s/^/#/g' \ - -e '/mod_isac/s/^/#/g' \ -e '/mod_mongo/s/^/#/g' \ -e '/mod_pocketsphinx/s/^/#/g' \ -e '/mod_siren/s/^/#/g' \ diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 20f7fe1c1f..0b3b8c4515 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -93,7 +93,6 @@ - diff --git a/configure.ac b/configure.ac index 4b90871540..dcd560543c 100755 --- a/configure.ac +++ b/configure.ac @@ -2157,7 +2157,6 @@ AC_CONFIG_FILES([Makefile src/mod/codecs/mod_g729/Makefile src/mod/codecs/mod_h26x/Makefile src/mod/codecs/mod_ilbc/Makefile - src/mod/codecs/mod_isac/Makefile src/mod/codecs/mod_opus/Makefile src/mod/codecs/mod_openh264/Makefile src/mod/codecs/mod_silk/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index d77ca48d3f..e9db3c512c 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -709,7 +709,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g723-1 (= \${binary:Version}), freeswitch-mod-g729 (= \${binary:Version}), freeswitch-mod-h26x (= \${binary:Version}), - freeswitch-mod-isac (= \${binary:Version}), freeswitch-mod-opus (= \${binary:Version}), freeswitch-mod-silk (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), @@ -734,7 +733,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g723-1-dbg (= \${binary:Version}), freeswitch-mod-g729-dbg (= \${binary:Version}), freeswitch-mod-h26x-dbg (= \${binary:Version}), - freeswitch-mod-isac-dbg (= \${binary:Version}), freeswitch-mod-opus-dbg (= \${binary:Version}), freeswitch-mod-silk-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 2261416c47..5e8bd3e56d 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -319,10 +319,6 @@ Description: mod_ilbc Adds mod_ilbc. Build-Depends: libilbc-dev -Module: codecs/mod_isac -Description: mod_isac - Adds mod_isac. - Module: codecs/mod_openh264 Description: Adds mod_openh264 Adds mod_openh264. diff --git a/debian/copyright b/debian/copyright index 0165760810..1deeb1869c 100755 --- a/debian/copyright +++ b/debian/copyright @@ -1573,14 +1573,6 @@ Files: libs/libcodec2/src/pack.c Copyright: 2010 Perens LLC License: GPL-3+ -Files: src/mod/codecs/mod_isac/* -Copyright: 2011-2012 The WebRTC project authors -License: BSD-3-clause - -Files: src/mod/codecs/mod_isac/mod_isac.c -Copyright: 2005-2014, Anthony Minessale II -License: MPL-1.1 - Files: libs/srtp/* Copyright: 2001-2006, Cisco Systems, Inc. 2005 Ingate Systems AB diff --git a/freeswitch.spec b/freeswitch.spec index 8761ca2365..b87b4802e0 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -706,21 +706,13 @@ BuildRequires: ilbc2-devel %description codec-ilbc iLBC Codec support for FreeSWITCH open source telephony platform -%package codec-isac -Summary: iSAC Codec support for FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description codec-isac -iSAC Codec support for FreeSWITCH open source telephony platform - %package codec-vpx Summary: vp8 Codec support for FreeSWITCH open source telephony platform Group: System/Libraries Requires: %{name} = %{version}-%{release} %description codec-vpx -iSAC Codec support for FreeSWITCH open source telephony platform +VP8 Codec support for FreeSWITCH open source telephony platform %package codec-opus Summary: Opus Codec support for FreeSWITCH open source telephony platform @@ -1343,7 +1335,7 @@ ASR_TTS_MODULES="asr_tts/mod_flite asr_tts/mod_pocketsphinx asr_tts/mod_tts_comm # ###################################################################################################################### CODECS_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_bv codecs/mod_codec2 codecs/mod_g723_1 \ - codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_opus codecs/mod_silk \ + codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_opus codecs/mod_silk \ codecs/mod_siren codecs/mod_theora" # @@ -2064,9 +2056,6 @@ fi %files codec-ilbc %{MODINSTDIR}/mod_ilbc.so* -%files codec-isac -%{MODINSTDIR}/mod_isac.so* - %files codec-opus %{MODINSTDIR}/mod_opus.so* %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opus.conf.xml diff --git a/src/mod/codecs/mod_isac/LICENSE b/src/mod/codecs/mod_isac/LICENSE deleted file mode 100644 index 4c41b7b251..0000000000 --- a/src/mod/codecs/mod_isac/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -Copyright (c) 2011, The WebRTC project authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of Google nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/mod/codecs/mod_isac/Makefile.am b/src/mod/codecs/mod_isac/Makefile.am deleted file mode 100644 index fc726f30c1..0000000000 --- a/src/mod/codecs/mod_isac/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_isac - -mod_LTLIBRARIES = mod_isac.la -mod_isac_la_SOURCES = mod_isac.c arith_routines.c arith_routines_hist.c arith_routines_logist.c auto_correlation.c auto_corr_to_refl_coef.c -mod_isac_la_SOURCES += bandwidth_estimator.c complex_bit_reverse.c complex_fft.c copy_set_operations.c crc.c cross_correlation.c decode_bwe.c -mod_isac_la_SOURCES += decode.c division_operations.c dot_product_with_scale.c downsample_fast.c encode.c encode_lpc_swb.c energy.c entropy_coding.c -mod_isac_la_SOURCES += fft.c filter_ar.c filter_ar_fast_q12.c filterbanks.c filterbank_tables.c filter_functions.c filter_ma_fast_q12.c -mod_isac_la_SOURCES += get_hanning_window.c get_scaling_square.c ilbc_specific_functions.c intialize.c isac.c lattice.c levinson_durbin.c -mod_isac_la_SOURCES += lpc_analysis.c lpc_gain_swb_tables.c lpc_shape_swb12_tables.c lpc_shape_swb16_tables.c lpc_tables.c -mod_isac_la_SOURCES += lpc_to_refl_coef.c min_max_operations.c min_max_operations_neon.c pitch_estimator.c pitch_filter.c pitch_gain_tables.c -mod_isac_la_SOURCES += pitch_lag_tables.c randomization_functions.c refl_coef_to_lpc.c resample_48khz.c resample_by_2.c resample_by_2_internal.c -mod_isac_la_SOURCES += resample.c resample_fractional.c spectrum_ar_model_tables.c splitting_filter.c spl_sqrt.c spl_sqrt_floor.c spl_version.c -mod_isac_la_SOURCES += sqrt_of_one_minus_x_squared.c transform.c vector_scaling_operations.c webrtc_fft_t_1024_8.c webrtc_fft_t_rad.c -mod_isac_la_CFLAGS = $(AM_CFLAGS) -w -I. -mod_isac_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_isac_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/codecs/mod_isac/PATENTS b/src/mod/codecs/mod_isac/PATENTS deleted file mode 100644 index 190607ac26..0000000000 --- a/src/mod/codecs/mod_isac/PATENTS +++ /dev/null @@ -1,24 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the WebRTC code package. - -Google hereby grants to you a perpetual, worldwide, non-exclusive, -no-charge, irrevocable (except as stated in this section) patent -license to make, have made, use, offer to sell, sell, import, -transfer, and otherwise run, modify and propagate the contents of this -implementation of the WebRTC code package, where such license applies -only to those patent claims, both currently owned by Google and -acquired in the future, licensable by Google that are necessarily -infringed by this implementation of the WebRTC code package. This -grant does not include claims that would be infringed only as a -consequence of further modification of this implementation. If you or -your agent or exclusive licensee institute or order or agree to the -institution of patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that this -implementation of the WebRTC code package or any code incorporated -within this implementation of the WebRTC code package constitutes -direct or contributory patent infringement, or inducement of patent -infringement, then any patent rights granted to you under this License -for this implementation of the WebRTC code package shall terminate as -of the date such litigation is filed. diff --git a/src/mod/codecs/mod_isac/arith_routines.c b/src/mod/codecs/mod_isac/arith_routines.c deleted file mode 100644 index 31c441a7af..0000000000 --- a/src/mod/codecs/mod_isac/arith_routines.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "arith_routines.h" -#include "settings.h" - - -/* - * terminate and return byte stream; - * returns the number of bytes in the stream - */ -int WebRtcIsac_EncTerminate(Bitstr *streamdata) /* in-/output struct containing bitstream */ -{ - WebRtc_UWord8 *stream_ptr; - - - /* point to the right place in the stream buffer */ - stream_ptr = streamdata->stream + streamdata->stream_index; - - /* find minimum length (determined by current interval width) */ - if ( streamdata->W_upper > 0x01FFFFFF ) - { - streamdata->streamval += 0x01000000; - /* add carry to buffer */ - if (streamdata->streamval < 0x01000000) - { - /* propagate carry */ - while ( !(++(*--stream_ptr)) ); - /* put pointer back to the old value */ - stream_ptr = streamdata->stream + streamdata->stream_index; - } - /* write remaining data to bitstream */ - *stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24); - } - else - { - streamdata->streamval += 0x00010000; - /* add carry to buffer */ - if (streamdata->streamval < 0x00010000) - { - /* propagate carry */ - while ( !(++(*--stream_ptr)) ); - /* put pointer back to the old value */ - stream_ptr = streamdata->stream + streamdata->stream_index; - } - /* write remaining data to bitstream */ - *stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24); - *stream_ptr++ = (WebRtc_UWord8) ((streamdata->streamval >> 16) & 0x00FF); - } - - /* calculate stream length */ - return (int)(stream_ptr - streamdata->stream); -} diff --git a/src/mod/codecs/mod_isac/arith_routines.h b/src/mod/codecs/mod_isac/arith_routines.h deleted file mode 100644 index 8e5f496f98..0000000000 --- a/src/mod/codecs/mod_isac/arith_routines.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * arith_routines.h - * - * Functions for arithmetic coding. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_ - -#include "structs.h" - - -int WebRtcIsac_EncLogisticMulti2( - Bitstr *streamdata, /* in-/output struct containing bitstream */ - WebRtc_Word16 *dataQ7, /* input: data vector */ - const WebRtc_UWord16 *env, /* input: side info vector defining the width of the pdf */ - const int N, /* input: data vector length */ - const WebRtc_Word16 isSWB12kHz); /* if the codec is working in 12kHz bandwidth */ - -/* returns the number of bytes in the stream */ -int WebRtcIsac_EncTerminate(Bitstr *streamdata); /* in-/output struct containing bitstream */ - -/* returns the number of bytes in the stream so far */ -int WebRtcIsac_DecLogisticMulti2( - WebRtc_Word16 *data, /* output: data vector */ - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const WebRtc_UWord16 *env, /* input: side info vector defining the width of the pdf */ - const WebRtc_Word16 *dither, /* input: dither vector */ - const int N, /* input: data vector length */ - const WebRtc_Word16 isSWB12kHz); /* if the codec is working in 12kHz bandwidth */ - -void WebRtcIsac_EncHistMulti( - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const int *data, /* input: data vector */ - const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ - const int N); /* input: data vector length */ - -int WebRtcIsac_DecHistBisectMulti( - int *data, /* output: data vector */ - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ - const WebRtc_UWord16 *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */ - const int N); /* input: data vector length */ - -int WebRtcIsac_DecHistOneStepMulti( - int *data, /* output: data vector */ - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ - const WebRtc_UWord16 *init_index,/* input: vector of initial cdf table search entries */ - const int N); /* input: data vector length */ - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_ */ diff --git a/src/mod/codecs/mod_isac/arith_routines_hist.c b/src/mod/codecs/mod_isac/arith_routines_hist.c deleted file mode 100644 index f4a13d6078..0000000000 --- a/src/mod/codecs/mod_isac/arith_routines_hist.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "settings.h" -#include "arith_routines.h" - - -/* - * code symbols into arithmetic bytestream - */ -void WebRtcIsac_EncHistMulti(Bitstr *streamdata, /* in-/output struct containing bitstream */ - const int *data, /* input: data vector */ - const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ - const int N) /* input: data vector length */ -{ - WebRtc_UWord32 W_lower, W_upper; - WebRtc_UWord32 W_upper_LSB, W_upper_MSB; - WebRtc_UWord8 *stream_ptr; - WebRtc_UWord8 *stream_ptr_carry; - WebRtc_UWord32 cdf_lo, cdf_hi; - int k; - - - /* point to beginning of stream buffer */ - stream_ptr = streamdata->stream + streamdata->stream_index; - W_upper = streamdata->W_upper; - - for (k=N; k>0; k--) - { - /* fetch cdf_lower and cdf_upper from cdf tables */ - cdf_lo = (WebRtc_UWord32) *(*cdf + *data); - cdf_hi = (WebRtc_UWord32) *(*cdf++ + *data++ + 1); - - /* update interval */ - W_upper_LSB = W_upper & 0x0000FFFF; - W_upper_MSB = W_upper >> 16; - W_lower = W_upper_MSB * cdf_lo; - W_lower += (W_upper_LSB * cdf_lo) >> 16; - W_upper = W_upper_MSB * cdf_hi; - W_upper += (W_upper_LSB * cdf_hi) >> 16; - - /* shift interval such that it begins at zero */ - W_upper -= ++W_lower; - - /* add integer to bitstream */ - streamdata->streamval += W_lower; - - /* handle carry */ - if (streamdata->streamval < W_lower) - { - /* propagate carry */ - stream_ptr_carry = stream_ptr; - while (!(++(*--stream_ptr_carry))); - } - - /* renormalize interval, store most significant byte of streamval and update streamval */ - while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ - { - W_upper <<= 8; - *stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24); - streamdata->streamval <<= 8; - } - } - - /* calculate new stream_index */ - streamdata->stream_index = (int)(stream_ptr - streamdata->stream); - streamdata->W_upper = W_upper; - - return; -} - - - -/* - * function to decode more symbols from the arithmetic bytestream, using method of bisection - * cdf tables should be of size 2^k-1 (which corresponds to an alphabet size of 2^k-2) - */ -int WebRtcIsac_DecHistBisectMulti(int *data, /* output: data vector */ - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ - const WebRtc_UWord16 *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */ - const int N) /* input: data vector length */ -{ - WebRtc_UWord32 W_lower, W_upper; - WebRtc_UWord32 W_tmp; - WebRtc_UWord32 W_upper_LSB, W_upper_MSB; - WebRtc_UWord32 streamval; - const WebRtc_UWord8 *stream_ptr; - const WebRtc_UWord16 *cdf_ptr; - int size_tmp; - int k; - - W_lower = 0; //to remove warning -DH - stream_ptr = streamdata->stream + streamdata->stream_index; - W_upper = streamdata->W_upper; - if (W_upper == 0) - /* Should not be possible in normal operation */ - return -2; - - if (streamdata->stream_index == 0) /* first time decoder is called for this stream */ - { - /* read first word from bytestream */ - streamval = *stream_ptr << 24; - streamval |= *++stream_ptr << 16; - streamval |= *++stream_ptr << 8; - streamval |= *++stream_ptr; - } else { - streamval = streamdata->streamval; - } - - for (k=N; k>0; k--) - { - /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ - W_upper_LSB = W_upper & 0x0000FFFF; - W_upper_MSB = W_upper >> 16; - - /* start halfway the cdf range */ - size_tmp = *cdf_size++ >> 1; - cdf_ptr = *cdf + (size_tmp - 1); - - /* method of bisection */ - for ( ;; ) - { - W_tmp = W_upper_MSB * *cdf_ptr; - W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; - size_tmp >>= 1; - if (size_tmp == 0) break; - if (streamval > W_tmp) - { - W_lower = W_tmp; - cdf_ptr += size_tmp; - } else { - W_upper = W_tmp; - cdf_ptr -= size_tmp; - } - } - if (streamval > W_tmp) - { - W_lower = W_tmp; - *data++ = (int)(cdf_ptr - *cdf++); - } else { - W_upper = W_tmp; - *data++ = (int)(cdf_ptr - *cdf++ - 1); - } - - /* shift interval to start at zero */ - W_upper -= ++W_lower; - - /* add integer to bitstream */ - streamval -= W_lower; - - /* renormalize interval and update streamval */ - while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ - { - /* read next byte from stream */ - streamval = (streamval << 8) | *++stream_ptr; - W_upper <<= 8; - } - - if (W_upper == 0) - /* Should not be possible in normal operation */ - return -2; - - - } - - streamdata->stream_index = (int)(stream_ptr - streamdata->stream); - streamdata->W_upper = W_upper; - streamdata->streamval = streamval; - - - /* find number of bytes in original stream (determined by current interval width) */ - if ( W_upper > 0x01FFFFFF ) - return streamdata->stream_index - 2; - else - return streamdata->stream_index - 1; -} - - - -/* - * function to decode more symbols from the arithmetic bytestream, taking single step up or - * down at a time - * cdf tables can be of arbitrary size, but large tables may take a lot of iterations - */ -int WebRtcIsac_DecHistOneStepMulti(int *data, /* output: data vector */ - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ - const WebRtc_UWord16 *init_index, /* input: vector of initial cdf table search entries */ - const int N) /* input: data vector length */ -{ - WebRtc_UWord32 W_lower, W_upper; - WebRtc_UWord32 W_tmp; - WebRtc_UWord32 W_upper_LSB, W_upper_MSB; - WebRtc_UWord32 streamval; - const WebRtc_UWord8 *stream_ptr; - const WebRtc_UWord16 *cdf_ptr; - int k; - - - stream_ptr = streamdata->stream + streamdata->stream_index; - W_upper = streamdata->W_upper; - if (W_upper == 0) - /* Should not be possible in normal operation */ - return -2; - - if (streamdata->stream_index == 0) /* first time decoder is called for this stream */ - { - /* read first word from bytestream */ - streamval = *stream_ptr << 24; - streamval |= *++stream_ptr << 16; - streamval |= *++stream_ptr << 8; - streamval |= *++stream_ptr; - } else { - streamval = streamdata->streamval; - } - - - for (k=N; k>0; k--) - { - /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ - W_upper_LSB = W_upper & 0x0000FFFF; - W_upper_MSB = W_upper >> 16; - - /* start at the specified table entry */ - cdf_ptr = *cdf + (*init_index++); - W_tmp = W_upper_MSB * *cdf_ptr; - W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; - if (streamval > W_tmp) - { - for ( ;; ) - { - W_lower = W_tmp; - if (cdf_ptr[0]==65535) - /* range check */ - return -3; - W_tmp = W_upper_MSB * *++cdf_ptr; - W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; - if (streamval <= W_tmp) break; - } - W_upper = W_tmp; - *data++ = (int)(cdf_ptr - *cdf++ - 1); - } else { - for ( ;; ) - { - W_upper = W_tmp; - --cdf_ptr; - if (cdf_ptr<*cdf) { - /* range check */ - return -3; - } - W_tmp = W_upper_MSB * *cdf_ptr; - W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; - if (streamval > W_tmp) break; - } - W_lower = W_tmp; - *data++ = (int)(cdf_ptr - *cdf++); - } - - /* shift interval to start at zero */ - W_upper -= ++W_lower; - /* add integer to bitstream */ - streamval -= W_lower; - - /* renormalize interval and update streamval */ - while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ - { - /* read next byte from stream */ - streamval = (streamval << 8) | *++stream_ptr; - W_upper <<= 8; - } - } - - streamdata->stream_index = (int)(stream_ptr - streamdata->stream); - streamdata->W_upper = W_upper; - streamdata->streamval = streamval; - - - /* find number of bytes in original stream (determined by current interval width) */ - if ( W_upper > 0x01FFFFFF ) - return streamdata->stream_index - 2; - else - return streamdata->stream_index - 1; -} diff --git a/src/mod/codecs/mod_isac/arith_routines_logist.c b/src/mod/codecs/mod_isac/arith_routines_logist.c deleted file mode 100644 index 422855a4ce..0000000000 --- a/src/mod/codecs/mod_isac/arith_routines_logist.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * arith_routines.h - * - * This file contains functions for arithmatically encoding and - * decoding DFT coefficients. - * - */ - - -#include "arith_routines.h" - - - -static const WebRtc_Word32 kHistEdgesQ15[51] = { - -327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716, - -196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858, -91751, -78644, - -65536, -52429, -39322, -26215, -13108, 0, 13107, 26214, 39321, 52428, - 65536, 78643, 91750, 104857, 117964, 131072, 144179, 157286, 170393, 183500, - 196608, 209715, 222822, 235929, 249036, 262144, 275251, 288358, 301465, 314572, - 327680}; - - -static const int kCdfSlopeQ0[51] = { /* Q0 */ - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 13, 23, 47, 87, 154, 315, 700, 1088, - 2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312, - 1095, 660, 316, 145, 86, 41, 32, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 0}; - - -static const int kCdfQ16[51] = { /* Q16 */ - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, - 20, 22, 24, 29, 38, 57, 92, 153, 279, 559, - 994, 1983, 4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636, - 64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514, - 65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534, - 65535}; - - - -/* function to be converted to fixed point */ -static __inline WebRtc_UWord32 piecewise(WebRtc_Word32 xinQ15) { - - WebRtc_Word32 ind, qtmp1, qtmp2, qtmp3; - WebRtc_UWord32 tmpUW32; - - - qtmp2 = xinQ15; - - if (qtmp2 < kHistEdgesQ15[0]) { - qtmp2 = kHistEdgesQ15[0]; - } - if (qtmp2 > kHistEdgesQ15[50]) { - qtmp2 = kHistEdgesQ15[50]; - } - - qtmp1 = qtmp2 - kHistEdgesQ15[0]; /* Q15 - Q15 = Q15 */ - ind = (qtmp1 * 5) >> 16; /* 2^16 / 5 = 0.4 in Q15 */ - /* Q15 -> Q0 */ - qtmp1 = qtmp2 - kHistEdgesQ15[ind]; /* Q15 - Q15 = Q15 */ - qtmp2 = kCdfSlopeQ0[ind] * qtmp1; /* Q0 * Q15 = Q15 */ - qtmp3 = qtmp2>>15; /* Q15 -> Q0 */ - - tmpUW32 = kCdfQ16[ind] + qtmp3; /* Q0 + Q0 = Q0 */ - return tmpUW32; -} - - - -int WebRtcIsac_EncLogisticMulti2( - Bitstr *streamdata, /* in-/output struct containing bitstream */ - WebRtc_Word16 *dataQ7, /* input: data vector */ - const WebRtc_UWord16 *envQ8, /* input: side info vector defining the width of the pdf */ - const int N, /* input: data vector length / 2 */ - const WebRtc_Word16 isSWB12kHz) -{ - WebRtc_UWord32 W_lower, W_upper; - WebRtc_UWord32 W_upper_LSB, W_upper_MSB; - WebRtc_UWord8 *stream_ptr; - WebRtc_UWord8 *maxStreamPtr; - WebRtc_UWord8 *stream_ptr_carry; - WebRtc_UWord32 cdf_lo, cdf_hi; - int k; - - /* point to beginning of stream buffer */ - stream_ptr = streamdata->stream + streamdata->stream_index; - W_upper = streamdata->W_upper; - - maxStreamPtr = streamdata->stream + STREAM_SIZE_MAX_60 - 1; - for (k = 0; k < N; k++) - { - /* compute cdf_lower and cdf_upper by evaluating the piecewise linear cdf */ - cdf_lo = piecewise((*dataQ7 - 64) * *envQ8); - cdf_hi = piecewise((*dataQ7 + 64) * *envQ8); - - /* test and clip if probability gets too small */ - while (cdf_lo+1 >= cdf_hi) { - /* clip */ - if (*dataQ7 > 0) { - *dataQ7 -= 128; - cdf_hi = cdf_lo; - cdf_lo = piecewise((*dataQ7 - 64) * *envQ8); - } else { - *dataQ7 += 128; - cdf_lo = cdf_hi; - cdf_hi = piecewise((*dataQ7 + 64) * *envQ8); - } - } - - dataQ7++; - // increment only once per 4 iterations for SWB-16kHz or WB - // increment only once per 2 iterations for SWB-12kHz - envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1)); - - - /* update interval */ - W_upper_LSB = W_upper & 0x0000FFFF; - W_upper_MSB = W_upper >> 16; - W_lower = W_upper_MSB * cdf_lo; - W_lower += (W_upper_LSB * cdf_lo) >> 16; - W_upper = W_upper_MSB * cdf_hi; - W_upper += (W_upper_LSB * cdf_hi) >> 16; - - /* shift interval such that it begins at zero */ - W_upper -= ++W_lower; - - /* add integer to bitstream */ - streamdata->streamval += W_lower; - - /* handle carry */ - if (streamdata->streamval < W_lower) - { - /* propagate carry */ - stream_ptr_carry = stream_ptr; - while (!(++(*--stream_ptr_carry))); - } - - /* renormalize interval, store most significant byte of streamval and update streamval */ - while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ - { - W_upper <<= 8; - *stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24); - - if(stream_ptr > maxStreamPtr) - { - return -ISAC_DISALLOWED_BITSTREAM_LENGTH; - } - streamdata->streamval <<= 8; - } - } - - /* calculate new stream_index */ - streamdata->stream_index = (int)(stream_ptr - streamdata->stream); - streamdata->W_upper = W_upper; - - return 0; -} - - - -int WebRtcIsac_DecLogisticMulti2( - WebRtc_Word16 *dataQ7, /* output: data vector */ - Bitstr *streamdata, /* in-/output struct containing bitstream */ - const WebRtc_UWord16 *envQ8, /* input: side info vector defining the width of the pdf */ - const WebRtc_Word16 *ditherQ7,/* input: dither vector */ - const int N, /* input: data vector length */ - const WebRtc_Word16 isSWB12kHz) -{ - WebRtc_UWord32 W_lower, W_upper; - WebRtc_UWord32 W_tmp; - WebRtc_UWord32 W_upper_LSB, W_upper_MSB; - WebRtc_UWord32 streamval; - const WebRtc_UWord8 *stream_ptr; - WebRtc_UWord32 cdf_tmp; - WebRtc_Word16 candQ7; - int k; - - stream_ptr = streamdata->stream + streamdata->stream_index; - W_upper = streamdata->W_upper; - if (streamdata->stream_index == 0) /* first time decoder is called for this stream */ - { - /* read first word from bytestream */ - streamval = *stream_ptr << 24; - streamval |= *++stream_ptr << 16; - streamval |= *++stream_ptr << 8; - streamval |= *++stream_ptr; - } else { - streamval = streamdata->streamval; - } - - - for (k = 0; k < N; k++) - { - /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ - W_upper_LSB = W_upper & 0x0000FFFF; - W_upper_MSB = W_upper >> 16; - - /* find first candidate by inverting the logistic cdf */ - candQ7 = - *ditherQ7 + 64; - cdf_tmp = piecewise(candQ7 * *envQ8); - - W_tmp = W_upper_MSB * cdf_tmp; - W_tmp += (W_upper_LSB * cdf_tmp) >> 16; - if (streamval > W_tmp) - { - W_lower = W_tmp; - candQ7 += 128; - cdf_tmp = piecewise(candQ7 * *envQ8); - - W_tmp = W_upper_MSB * cdf_tmp; - W_tmp += (W_upper_LSB * cdf_tmp) >> 16; - while (streamval > W_tmp) - { - W_lower = W_tmp; - candQ7 += 128; - cdf_tmp = piecewise(candQ7 * *envQ8); - - W_tmp = W_upper_MSB * cdf_tmp; - W_tmp += (W_upper_LSB * cdf_tmp) >> 16; - - /* error check */ - if (W_lower == W_tmp) return -1; - } - W_upper = W_tmp; - - /* another sample decoded */ - *dataQ7 = candQ7 - 64; - } - else - { - W_upper = W_tmp; - candQ7 -= 128; - cdf_tmp = piecewise(candQ7 * *envQ8); - - W_tmp = W_upper_MSB * cdf_tmp; - W_tmp += (W_upper_LSB * cdf_tmp) >> 16; - while ( !(streamval > W_tmp) ) - { - W_upper = W_tmp; - candQ7 -= 128; - cdf_tmp = piecewise(candQ7 * *envQ8); - - W_tmp = W_upper_MSB * cdf_tmp; - W_tmp += (W_upper_LSB * cdf_tmp) >> 16; - - /* error check */ - if (W_upper == W_tmp) return -1; - } - W_lower = W_tmp; - - /* another sample decoded */ - *dataQ7 = candQ7 + 64; - } - ditherQ7++; - dataQ7++; - // increment only once per 4 iterations for SWB-16kHz or WB - // increment only once per 2 iterations for SWB-12kHz - envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1)); - - /* shift interval to start at zero */ - W_upper -= ++W_lower; - - /* add integer to bitstream */ - streamval -= W_lower; - - /* renormalize interval and update streamval */ - while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ - { - /* read next byte from stream */ - streamval = (streamval << 8) | *++stream_ptr; - W_upper <<= 8; - } - } - - streamdata->stream_index = (int)(stream_ptr - streamdata->stream); - streamdata->W_upper = W_upper; - streamdata->streamval = streamval; - - /* find number of bytes in original stream (determined by current interval width) */ - if ( W_upper > 0x01FFFFFF ) - return streamdata->stream_index - 2; - else - return streamdata->stream_index - 1; -} diff --git a/src/mod/codecs/mod_isac/auto_corr_to_refl_coef.c b/src/mod/codecs/mod_isac/auto_corr_to_refl_coef.c deleted file mode 100644 index b0ed4605f4..0000000000 --- a/src/mod/codecs/mod_isac/auto_corr_to_refl_coef.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_AutoCorrToReflCoef(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K) -{ - int i, n; - WebRtc_Word16 tmp; - G_CONST WebRtc_Word32 *rptr; - WebRtc_Word32 L_num, L_den; - WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER], - P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER]; - - // Initialize loop and pointers. - acfptr = ACF; - rptr = R; - pptr = P; - p1ptr = &P[1]; - w1ptr = &W[1]; - wptr = w1ptr; - - // First loop; n=0. Determine shifting. - tmp = WebRtcSpl_NormW32(*R); - *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16); - *pptr++ = *acfptr++; - - // Initialize ACF, P and W. - for (i = 1; i <= use_order; i++) - { - *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16); - *wptr++ = *acfptr; - *pptr++ = *acfptr++; - } - - // Compute reflection coefficients. - for (n = 1; n <= use_order; n++, K++) - { - tmp = WEBRTC_SPL_ABS_W16(*p1ptr); - if (*P < tmp) - { - for (i = n; i <= use_order; i++) - *K++ = 0; - - return; - } - - // Division: WebRtcSpl_div(tmp, *P) - *K = 0; - if (tmp != 0) - { - L_num = tmp; - L_den = *P; - i = 15; - while (i--) - { - (*K) <<= 1; - L_num <<= 1; - if (L_num >= L_den) - { - L_num -= L_den; - (*K)++; - } - } - if (*p1ptr > 0) - *K = -*K; - } - - // Last iteration; don't do Schur recursion. - if (n == use_order) - return; - - // Schur recursion. - pptr = P; - wptr = w1ptr; - tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15); - *pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp ); - pptr++; - for (i = 1; i <= use_order - n; i++) - { - tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15); - *pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp ); - pptr++; - tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15); - *wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp ); - wptr++; - } - } -} diff --git a/src/mod/codecs/mod_isac/auto_correlation.c b/src/mod/codecs/mod_isac/auto_correlation.c deleted file mode 100644 index a00fde4bc3..0000000000 --- a/src/mod/codecs/mod_isac/auto_correlation.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_AutoCorrelation(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector, - int in_vector_length, - int order, - WebRtc_Word32* result, - int* scale) -{ - WebRtc_Word32 sum; - int i, j; - WebRtc_Word16 smax; // Sample max - G_CONST WebRtc_Word16* xptr1; - G_CONST WebRtc_Word16* xptr2; - WebRtc_Word32* resultptr; - int scaling = 0; - -#ifdef _ARM_OPT_ -#pragma message("NOTE: _ARM_OPT_ optimizations are used") - WebRtc_Word16 loops4; -#endif - - if (order < 0) - order = in_vector_length; - - // Find the max. sample - smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length); - - // In order to avoid overflow when computing the sum we should scale the samples so that - // (in_vector_length * smax * smax) will not overflow. - - if (smax == 0) - { - scaling = 0; - } else - { - int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop - int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax - - if (t > nbits) - { - scaling = 0; - } else - { - scaling = nbits - t; - } - - } - - resultptr = result; - - // Perform the actual correlation calculation - for (i = 0; i < order + 1; i++) - { - int loops = (in_vector_length - i); - sum = 0; - xptr1 = in_vector; - xptr2 = &in_vector[i]; -#ifndef _ARM_OPT_ - for (j = loops; j > 0; j--) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling); - } -#else - loops4 = (loops >> 2) << 2; - - if (scaling == 0) - { - for (j = 0; j < loops4; j = j + 4) - { - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - } - - for (j = loops4; j < loops; j++) - { - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - } - } - else - { - for (j = 0; j < loops4; j = j + 4) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - } - - for (j = loops4; j < loops; j++) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - } - } - -#endif - *resultptr++ = sum; - } - - *scale = scaling; - - return order + 1; -} diff --git a/src/mod/codecs/mod_isac/bandwidth_estimator.c b/src/mod/codecs/mod_isac/bandwidth_estimator.c deleted file mode 100644 index c84ace38c5..0000000000 --- a/src/mod/codecs/mod_isac/bandwidth_estimator.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * BwEstimator.c - * - * This file contains the code for the Bandwidth Estimator designed - * for iSAC. - * - */ - -#include "bandwidth_estimator.h" -#include "settings.h" -#include "isac.h" - -#include - -/* array of quantization levels for bottle neck info; Matlab code: */ -/* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */ -static const float kQRateTableWb[12] = -{ - 10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f, - 18859.8f, 20963.3f, 23301.4f, 25900.3f, 28789.0f, 32000.0f}; - - -static const float kQRateTableSwb[24] = -{ - 10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f, - 18859.8f, 20963.3f, 23153.1f, 25342.9f, 27532.7f, 29722.5f, - 31912.3f, 34102.1f, 36291.9f, 38481.7f, 40671.4f, 42861.2f, - 45051.0f, 47240.8f, 49430.6f, 51620.4f, 53810.2f, 56000.0f, -}; - - - - -WebRtc_Word32 WebRtcIsac_InitBandwidthEstimator( - BwEstimatorstr* bwest_str, - enum IsacSamplingRate encoderSampRate, - enum IsacSamplingRate decoderSampRate) -{ - switch(encoderSampRate) - { - case kIsacWideband: - { - bwest_str->send_bw_avg = INIT_BN_EST_WB; - break; - } - case kIsacSuperWideband: - { - bwest_str->send_bw_avg = INIT_BN_EST_SWB; - break; - } - default: - return -1; - } - - switch(decoderSampRate) - { - case kIsacWideband: - { - bwest_str->prev_frame_length = INIT_FRAME_LEN_WB; - bwest_str->rec_bw_inv = 1.0f / - (INIT_BN_EST_WB + INIT_HDR_RATE_WB); - bwest_str->rec_bw = (WebRtc_Word32)INIT_BN_EST_WB; - bwest_str->rec_bw_avg_Q = INIT_BN_EST_WB; - bwest_str->rec_bw_avg = INIT_BN_EST_WB + INIT_HDR_RATE_WB; - bwest_str->rec_header_rate = INIT_HDR_RATE_WB; - break; - } - case kIsacSuperWideband: - { - bwest_str->prev_frame_length = INIT_FRAME_LEN_SWB; - bwest_str->rec_bw_inv = 1.0f / - (INIT_BN_EST_SWB + INIT_HDR_RATE_SWB); - bwest_str->rec_bw = (WebRtc_Word32)INIT_BN_EST_SWB; - bwest_str->rec_bw_avg_Q = INIT_BN_EST_SWB; - bwest_str->rec_bw_avg = INIT_BN_EST_SWB + INIT_HDR_RATE_SWB; - bwest_str->rec_header_rate = INIT_HDR_RATE_SWB; - break; - } - default: - return -1; - } - - bwest_str->prev_rec_rtp_number = 0; - bwest_str->prev_rec_arr_ts = 0; - bwest_str->prev_rec_send_ts = 0; - bwest_str->prev_rec_rtp_rate = 1.0f; - bwest_str->last_update_ts = 0; - bwest_str->last_reduction_ts = 0; - bwest_str->count_tot_updates_rec = -9; - bwest_str->rec_jitter = 10.0f; - bwest_str->rec_jitter_short_term = 0.0f; - bwest_str->rec_jitter_short_term_abs = 5.0f; - bwest_str->rec_max_delay = 10.0f; - bwest_str->rec_max_delay_avg_Q = 10.0f; - bwest_str->num_pkts_rec = 0; - - bwest_str->send_max_delay_avg = 10.0f; - - bwest_str->hsn_detect_rec = 0; - - bwest_str->num_consec_rec_pkts_over_30k = 0; - - bwest_str->hsn_detect_snd = 0; - - bwest_str->num_consec_snt_pkts_over_30k = 0; - - bwest_str->in_wait_period = 0; - - bwest_str->change_to_WB = 0; - - bwest_str->numConsecLatePkts = 0; - bwest_str->consecLatency = 0; - bwest_str->inWaitLatePkts = 0; - bwest_str->senderTimestamp = 0; - bwest_str->receiverTimestamp = 0; - return 0; -} - -/* This function updates both bottle neck rates */ -/* Parameters: */ -/* rtp_number - value from RTP packet, from NetEq */ -/* frame length - length of signal frame in ms, from iSAC decoder */ -/* send_ts - value in RTP header giving send time in samples */ -/* arr_ts - value given by timeGetTime() time of arrival in samples of packet from NetEq */ -/* pksize - size of packet in bytes, from NetEq */ -/* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */ -/* returns 0 if everything went fine, -1 otherwise */ -WebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator( - BwEstimatorstr *bwest_str, - const WebRtc_UWord16 rtp_number, - const WebRtc_Word32 frame_length, - const WebRtc_UWord32 send_ts, - const WebRtc_UWord32 arr_ts, - const WebRtc_Word32 pksize - /*, const WebRtc_UWord16 Index*/) -{ - float weight = 0.0f; - float curr_bw_inv = 0.0f; - float rec_rtp_rate; - float t_diff_proj; - float arr_ts_diff; - float send_ts_diff; - float arr_time_noise; - float arr_time_noise_abs; - - float delay_correction_factor = 1; - float late_diff = 0.0f; - int immediate_set = 0; - int num_pkts_expected; - - - // We have to adjust the header-rate if the first packet has a - // frame-size different than the initialized value. - if ( frame_length != bwest_str->prev_frame_length ) - { - bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f * - 1000.0f / (float)frame_length; /* bits/s */ - } - - /* UPDATE ESTIMATES ON THIS SIDE */ - /* compute far-side transmission rate */ - rec_rtp_rate = ((float)pksize * 8.0f * 1000.0f / (float)frame_length) + - bwest_str->rec_header_rate; - // rec_rtp_rate packet bits/s + header bits/s - - /* check for timer wrap-around */ - if (arr_ts < bwest_str->prev_rec_arr_ts) - { - bwest_str->prev_rec_arr_ts = arr_ts; - bwest_str->last_update_ts = arr_ts; - bwest_str->last_reduction_ts = arr_ts + 3*FS; - bwest_str->num_pkts_rec = 0; - - /* store frame length */ - bwest_str->prev_frame_length = frame_length; - - /* store far-side transmission rate */ - bwest_str->prev_rec_rtp_rate = rec_rtp_rate; - - /* store far-side RTP time stamp */ - bwest_str->prev_rec_rtp_number = rtp_number; - - return 0; - } - - bwest_str->num_pkts_rec++; - - /* check that it's not one of the first 9 packets */ - if ( bwest_str->count_tot_updates_rec > 0 ) - { - if(bwest_str->in_wait_period > 0 ) - { - bwest_str->in_wait_period--; - } - - bwest_str->inWaitLatePkts -= ((bwest_str->inWaitLatePkts > 0)? 1:0); - send_ts_diff = (float)(send_ts - bwest_str->prev_rec_send_ts); - - if (send_ts_diff <= (16 * frame_length)*2) - //doesn't allow for a dropped packet, not sure necessary to be - // that strict -DH - { - /* if not been updated for a long time, reduce the BN estimate */ - if((WebRtc_UWord32)(arr_ts - bwest_str->last_update_ts) * - 1000.0f / FS > 3000) - { - //how many frames should have been received since the last - // update if too many have been dropped or there have been - // big delays won't allow this reduction may no longer need - // the send_ts_diff here - num_pkts_expected = (int)(((float)(arr_ts - - bwest_str->last_update_ts) * 1000.0f /(float) FS) / - (float)frame_length); - - if(((float)bwest_str->num_pkts_rec/(float)num_pkts_expected) > - 0.9) - { - float inv_bitrate = (float) pow( 0.99995, - (double)((WebRtc_UWord32)(arr_ts - - bwest_str->last_reduction_ts)*1000.0f/FS) ); - - if ( inv_bitrate ) - { - bwest_str->rec_bw_inv /= inv_bitrate; - - //precautionary, likely never necessary - if (bwest_str->hsn_detect_snd && - bwest_str->hsn_detect_rec) - { - if (bwest_str->rec_bw_inv > 0.000066f) - { - bwest_str->rec_bw_inv = 0.000066f; - } - } - } - else - { - bwest_str->rec_bw_inv = 1.0f / - (INIT_BN_EST_WB + INIT_HDR_RATE_WB); - } - /* reset time-since-update counter */ - bwest_str->last_reduction_ts = arr_ts; - } - else - //reset here? - { - bwest_str->last_reduction_ts = arr_ts + 3*FS; - bwest_str->last_update_ts = arr_ts; - bwest_str->num_pkts_rec = 0; - } - } - } - else - { - bwest_str->last_reduction_ts = arr_ts + 3*FS; - bwest_str->last_update_ts = arr_ts; - bwest_str->num_pkts_rec = 0; - } - - - /* temporarily speed up adaptation if frame length has changed */ - if ( frame_length != bwest_str->prev_frame_length ) - { - bwest_str->count_tot_updates_rec = 10; - bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f * - 1000.0f / (float)frame_length; /* bits/s */ - - bwest_str->rec_bw_inv = 1.0f /((float)bwest_str->rec_bw + - bwest_str->rec_header_rate); - } - - //////////////////////// - arr_ts_diff = (float)(arr_ts - bwest_str->prev_rec_arr_ts); - - if (send_ts_diff > 0 ) - { - late_diff = arr_ts_diff - send_ts_diff; - } - else - { - late_diff = arr_ts_diff - (float)(16 * frame_length); - } - - if((late_diff > 0) && !bwest_str->inWaitLatePkts) - { - bwest_str->numConsecLatePkts++; - bwest_str->consecLatency += late_diff; - } - else - { - bwest_str->numConsecLatePkts = 0; - bwest_str->consecLatency = 0; - } - if(bwest_str->numConsecLatePkts > 50) - { - float latencyMs = bwest_str->consecLatency/(FS/1000); - float averageLatencyMs = latencyMs / bwest_str->numConsecLatePkts; - delay_correction_factor = frame_length / (frame_length + averageLatencyMs); - immediate_set = 1; - bwest_str->inWaitLatePkts = (WebRtc_Word16)((bwest_str->consecLatency/(FS/1000)) / 30);// + 150; - bwest_str->start_wait_period = arr_ts; - } - /////////////////////////////////////////////// - - - - /* update only if previous packet was not lost */ - if ( rtp_number == bwest_str->prev_rec_rtp_number + 1 ) - { - - - if (!(bwest_str->hsn_detect_snd && bwest_str->hsn_detect_rec)) - { - if ((arr_ts_diff > (float)(16 * frame_length))) - { - //1/2 second - if ((late_diff > 8000.0f) && !bwest_str->in_wait_period) - { - delay_correction_factor = 0.7f; - bwest_str->in_wait_period = 55; - bwest_str->start_wait_period = arr_ts; - immediate_set = 1; - } - //320 ms - else if (late_diff > 5120.0f && !bwest_str->in_wait_period) - { - delay_correction_factor = 0.8f; - immediate_set = 1; - bwest_str->in_wait_period = 44; - bwest_str->start_wait_period = arr_ts; - } - } - } - - - if ((bwest_str->prev_rec_rtp_rate > bwest_str->rec_bw_avg) && - (rec_rtp_rate > bwest_str->rec_bw_avg) && - !bwest_str->in_wait_period) - { - /* test if still in initiation period and increment counter */ - if (bwest_str->count_tot_updates_rec++ > 99) - { - /* constant weight after initiation part */ - weight = 0.01f; - } - else - { - /* weight decreases with number of updates */ - weight = 1.0f / (float) bwest_str->count_tot_updates_rec; - } - /* Bottle Neck Estimation */ - - /* limit outliers */ - /* if more than 25 ms too much */ - if (arr_ts_diff > frame_length * FS/1000 + 400.0f) - { - // in samples, why 25ms?? - arr_ts_diff = frame_length * FS/1000 + 400.0f; - } - if(arr_ts_diff < (frame_length * FS/1000) - 160.0f) - { - /* don't allow it to be less than frame rate - 10 ms */ - arr_ts_diff = (float)frame_length * FS/1000 - 160.0f; - } - - /* compute inverse receiving rate for last packet */ - curr_bw_inv = arr_ts_diff / ((float)(pksize + HEADER_SIZE) * - 8.0f * FS); // (180+35)*8*16000 = 27.5 Mbit.... - - - if(curr_bw_inv < - (1.0f / (MAX_ISAC_BW + bwest_str->rec_header_rate))) - { - // don't allow inv rate to be larger than MAX - curr_bw_inv = (1.0f / - (MAX_ISAC_BW + bwest_str->rec_header_rate)); - } - - /* update bottle neck rate estimate */ - bwest_str->rec_bw_inv = weight * curr_bw_inv + - (1.0f - weight) * bwest_str->rec_bw_inv; - - /* reset time-since-update counter */ - bwest_str->last_update_ts = arr_ts; - bwest_str->last_reduction_ts = arr_ts + 3 * FS; - bwest_str->num_pkts_rec = 0; - - /* Jitter Estimation */ - /* projected difference between arrival times */ - t_diff_proj = ((float)(pksize + HEADER_SIZE) * 8.0f * - 1000.0f) / bwest_str->rec_bw_avg; - - - // difference between projected and actual - // arrival time differences - arr_time_noise = (float)(arr_ts_diff*1000.0f/FS) - - t_diff_proj; - arr_time_noise_abs = (float) fabs( arr_time_noise ); - - /* long term averaged absolute jitter */ - bwest_str->rec_jitter = weight * arr_time_noise_abs + - (1.0f - weight) * bwest_str->rec_jitter; - if (bwest_str->rec_jitter > 10.0f) - { - bwest_str->rec_jitter = 10.0f; - } - /* short term averaged absolute jitter */ - bwest_str->rec_jitter_short_term_abs = 0.05f * - arr_time_noise_abs + 0.95f * - bwest_str->rec_jitter_short_term_abs; - - /* short term averaged jitter */ - bwest_str->rec_jitter_short_term = 0.05f * arr_time_noise + - 0.95f * bwest_str->rec_jitter_short_term; - } - } - } - else - { - // reset time-since-update counter when - // receiving the first 9 packets - bwest_str->last_update_ts = arr_ts; - bwest_str->last_reduction_ts = arr_ts + 3*FS; - bwest_str->num_pkts_rec = 0; - - bwest_str->count_tot_updates_rec++; - } - - /* limit minimum bottle neck rate */ - if (bwest_str->rec_bw_inv > 1.0f / ((float)MIN_ISAC_BW + - bwest_str->rec_header_rate)) - { - bwest_str->rec_bw_inv = 1.0f / ((float)MIN_ISAC_BW + - bwest_str->rec_header_rate); - } - - // limit maximum bitrate - if (bwest_str->rec_bw_inv < 1.0f / ((float)MAX_ISAC_BW + - bwest_str->rec_header_rate)) - { - bwest_str->rec_bw_inv = 1.0f / ((float)MAX_ISAC_BW + - bwest_str->rec_header_rate); - } - - /* store frame length */ - bwest_str->prev_frame_length = frame_length; - - /* store far-side transmission rate */ - bwest_str->prev_rec_rtp_rate = rec_rtp_rate; - - /* store far-side RTP time stamp */ - bwest_str->prev_rec_rtp_number = rtp_number; - - // Replace bwest_str->rec_max_delay by the new - // value (atomic operation) - bwest_str->rec_max_delay = 3.0f * bwest_str->rec_jitter; - - /* store send and arrival time stamp */ - bwest_str->prev_rec_arr_ts = arr_ts ; - bwest_str->prev_rec_send_ts = send_ts; - - /* Replace bwest_str->rec_bw by the new value (atomic operation) */ - bwest_str->rec_bw = (WebRtc_Word32)(1.0f / bwest_str->rec_bw_inv - - bwest_str->rec_header_rate); - - if (immediate_set) - { - bwest_str->rec_bw = (WebRtc_Word32) (delay_correction_factor * - (float) bwest_str->rec_bw); - - if (bwest_str->rec_bw < (WebRtc_Word32) MIN_ISAC_BW) - { - bwest_str->rec_bw = (WebRtc_Word32) MIN_ISAC_BW; - } - - bwest_str->rec_bw_avg = bwest_str->rec_bw + - bwest_str->rec_header_rate; - - bwest_str->rec_bw_avg_Q = (float) bwest_str->rec_bw; - - bwest_str->rec_jitter_short_term = 0.0f; - - bwest_str->rec_bw_inv = 1.0f / (bwest_str->rec_bw + - bwest_str->rec_header_rate); - - bwest_str->count_tot_updates_rec = 1; - - immediate_set = 0; - bwest_str->consecLatency = 0; - bwest_str->numConsecLatePkts = 0; - } - - return 0; -} - - -/* This function updates the send bottle neck rate */ -/* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */ -/* returns 0 if everything went fine, -1 otherwise */ -WebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl( - BwEstimatorstr* bwest_str, - WebRtc_Word16 index, - enum IsacSamplingRate encoderSamplingFreq) -{ - if((index < 0) || (index > 23)) - { - return -ISAC_RANGE_ERROR_BW_ESTIMATOR; - } - - /* UPDATE ESTIMATES FROM OTHER SIDE */ - if(encoderSamplingFreq == kIsacWideband) - { - if(index > 11) - { - index -= 12; - /* compute the jitter estimate as decoded on the other side */ - bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg + - 0.1f * (float)MAX_ISAC_MD; - } - else - { - /* compute the jitter estimate as decoded on the other side */ - bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg + - 0.1f * (float)MIN_ISAC_MD; - } - - /* compute the BN estimate as decoded on the other side */ - bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg + - 0.1f * kQRateTableWb[index]; - } - else - { - /* compute the BN estimate as decoded on the other side */ - bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg + - 0.1f * kQRateTableSwb[index]; - } - - if (bwest_str->send_bw_avg > (float) 28000 && !bwest_str->hsn_detect_snd) - { - bwest_str->num_consec_snt_pkts_over_30k++; - - if (bwest_str->num_consec_snt_pkts_over_30k >= 66) - { - //approx 2 seconds with 30ms frames - bwest_str->hsn_detect_snd = 1; - } - } - else if (!bwest_str->hsn_detect_snd) - { - bwest_str->num_consec_snt_pkts_over_30k = 0; - } - return 0; -} - -// called when there is upper-band bit-stream to update jitter -// statistics. -WebRtc_Word16 WebRtcIsac_UpdateUplinkJitter( - BwEstimatorstr* bwest_str, - WebRtc_Word32 index) -{ - if((index < 0) || (index > 23)) - { - return -ISAC_RANGE_ERROR_BW_ESTIMATOR; - } - - if(index > 0) - { - /* compute the jitter estimate as decoded on the other side */ - bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg + - 0.1f * (float)MAX_ISAC_MD; - } - else - { - /* compute the jitter estimate as decoded on the other side */ - bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg + - 0.1f * (float)MIN_ISAC_MD; - } - - return 0; -} - - - -// Returns the bandwidth/jitter estimation code (integer 0...23) -// to put in the sending iSAC payload -WebRtc_UWord16 -WebRtcIsac_GetDownlinkBwJitIndexImpl( - BwEstimatorstr* bwest_str, - WebRtc_Word16* bottleneckIndex, - WebRtc_Word16* jitterInfo, - enum IsacSamplingRate decoderSamplingFreq) -{ - float MaxDelay; - //WebRtc_UWord16 MaxDelayBit; - - float rate; - float r; - float e1, e2; - const float weight = 0.1f; - const float* ptrQuantizationTable; - WebRtc_Word16 addJitterInfo; - WebRtc_Word16 minInd; - WebRtc_Word16 maxInd; - WebRtc_Word16 midInd; - - /* Get Max Delay Bit */ - /* get unquantized max delay */ - MaxDelay = (float)WebRtcIsac_GetDownlinkMaxDelay(bwest_str); - - if ( ((1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight * - MAX_ISAC_MD - MaxDelay) > (MaxDelay - (1.f-weight) * - bwest_str->rec_max_delay_avg_Q - weight * MIN_ISAC_MD) ) - { - jitterInfo[0] = 0; - /* update quantized average */ - bwest_str->rec_max_delay_avg_Q = - (1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight * - (float)MIN_ISAC_MD; - } - else - { - jitterInfo[0] = 1; - /* update quantized average */ - bwest_str->rec_max_delay_avg_Q = - (1.f-weight) * bwest_str->rec_max_delay_avg_Q + weight * - (float)MAX_ISAC_MD; - } - - // Get unquantized rate. - rate = (float)WebRtcIsac_GetDownlinkBandwidth(bwest_str); - - /* Get Rate Index */ - if(decoderSamplingFreq == kIsacWideband) - { - ptrQuantizationTable = kQRateTableWb; - addJitterInfo = 1; - maxInd = 11; - } - else - { - ptrQuantizationTable = kQRateTableSwb; - addJitterInfo = 0; - maxInd = 23; - } - - minInd = 0; - while(maxInd > minInd + 1) - { - midInd = (maxInd + minInd) >> 1; - if(rate > ptrQuantizationTable[midInd]) - { - minInd = midInd; - } - else - { - maxInd = midInd; - } - } - // Chose the index which gives results an average which is closest - // to rate - r = (1 - weight) * bwest_str->rec_bw_avg_Q - rate; - e1 = weight * ptrQuantizationTable[minInd] + r; - e2 = weight * ptrQuantizationTable[maxInd] + r; - e1 = (e1 > 0)? e1:-e1; - e2 = (e2 > 0)? e2:-e2; - if(e1 < e2) - { - bottleneckIndex[0] = minInd; - } - else - { - bottleneckIndex[0] = maxInd; - } - - bwest_str->rec_bw_avg_Q = (1 - weight) * bwest_str->rec_bw_avg_Q + - weight * ptrQuantizationTable[bottleneckIndex[0]]; - bottleneckIndex[0] += jitterInfo[0] * 12 * addJitterInfo; - - bwest_str->rec_bw_avg = (1 - weight) * bwest_str->rec_bw_avg + weight * - (rate + bwest_str->rec_header_rate); - - return 0; -} - - - -/* get the bottle neck rate from far side to here, as estimated on this side */ -WebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth( const BwEstimatorstr *bwest_str) -{ - WebRtc_Word32 rec_bw; - float jitter_sign; - float bw_adjust; - - /* create a value between -1.0 and 1.0 indicating "average sign" of jitter */ - jitter_sign = bwest_str->rec_jitter_short_term / - bwest_str->rec_jitter_short_term_abs; - - /* adjust bw proportionally to negative average jitter sign */ - bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign); - - /* adjust Rate if jitter sign is mostly constant */ - rec_bw = (WebRtc_Word32)(bwest_str->rec_bw * bw_adjust); - - /* limit range of bottle neck rate */ - if (rec_bw < MIN_ISAC_BW) - { - rec_bw = MIN_ISAC_BW; - } - else if (rec_bw > MAX_ISAC_BW) - { - rec_bw = MAX_ISAC_BW; - } - return rec_bw; -} - -/* Returns the max delay (in ms) */ -WebRtc_Word32 -WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str) -{ - WebRtc_Word32 rec_max_delay; - - rec_max_delay = (WebRtc_Word32)(bwest_str->rec_max_delay); - - /* limit range of jitter estimate */ - if (rec_max_delay < MIN_ISAC_MD) - { - rec_max_delay = MIN_ISAC_MD; - } - else if (rec_max_delay > MAX_ISAC_MD) - { - rec_max_delay = MAX_ISAC_MD; - } - return rec_max_delay; -} - -/* get the bottle neck rate from here to far side, as estimated by far side */ -void -WebRtcIsac_GetUplinkBandwidth( - const BwEstimatorstr* bwest_str, - WebRtc_Word32* bitRate) -{ - /* limit range of bottle neck rate */ - if (bwest_str->send_bw_avg < MIN_ISAC_BW) - { - *bitRate = MIN_ISAC_BW; - } - else if (bwest_str->send_bw_avg > MAX_ISAC_BW) - { - *bitRate = MAX_ISAC_BW; - } - else - { - *bitRate = (WebRtc_Word32)(bwest_str->send_bw_avg); - } - return; -} - -/* Returns the max delay value from the other side in ms */ -WebRtc_Word32 -WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str) -{ - WebRtc_Word32 send_max_delay; - - send_max_delay = (WebRtc_Word32)(bwest_str->send_max_delay_avg); - - /* limit range of jitter estimate */ - if (send_max_delay < MIN_ISAC_MD) - { - send_max_delay = MIN_ISAC_MD; - } - else if (send_max_delay > MAX_ISAC_MD) - { - send_max_delay = MAX_ISAC_MD; - } - return send_max_delay; -} - - -/* - * update long-term average bitrate and amount of data in buffer - * returns minimum payload size (bytes) - */ -int WebRtcIsac_GetMinBytes( - RateModel* State, - int StreamSize, /* bytes in bitstream */ - const int FrameSamples, /* samples per frame */ - const double BottleNeck, /* bottle neck rate; excl headers (bps) */ - const double DelayBuildUp, /* max delay from bottleneck buffering (ms) */ - enum ISACBandwidth bandwidth - /*,WebRtc_Word16 frequentLargePackets*/) -{ - double MinRate = 0.0; - int MinBytes; - double TransmissionTime; - int burstInterval = BURST_INTERVAL; - - // first 10 packets @ low rate, then INIT_BURST_LEN packets @ - // fixed rate of INIT_RATE bps - if (State->InitCounter > 0) - { - if (State->InitCounter-- <= INIT_BURST_LEN) - { - if(bandwidth == isac8kHz) - { - MinRate = INIT_RATE_WB; - } - else - { - MinRate = INIT_RATE_SWB; - } - } - else - { - MinRate = 0; - } - } - else - { - /* handle burst */ - if (State->BurstCounter) - { - if (State->StillBuffered < (1.0 - 1.0/BURST_LEN) * DelayBuildUp) - { - /* max bps derived from BottleNeck and DelayBuildUp values */ - MinRate = (1.0 + (FS/1000) * DelayBuildUp / - (double)(BURST_LEN * FrameSamples)) * BottleNeck; - } - else - { - // max bps derived from StillBuffered and DelayBuildUp - // values - MinRate = (1.0 + (FS/1000) * (DelayBuildUp - - State->StillBuffered) / (double)FrameSamples) * BottleNeck; - if (MinRate < 1.04 * BottleNeck) - { - MinRate = 1.04 * BottleNeck; - } - } - State->BurstCounter--; - } - } - - - /* convert rate from bits/second to bytes/packet */ - MinBytes = (int) (MinRate * FrameSamples / (8.0 * FS)); - - /* StreamSize will be adjusted if less than MinBytes */ - if (StreamSize < MinBytes) - { - StreamSize = MinBytes; - } - - /* keep track of when bottle neck was last exceeded by at least 1% */ - if (StreamSize * 8.0 * FS / FrameSamples > 1.01 * BottleNeck) { - if (State->PrevExceed) { - /* bottle_neck exceded twice in a row, decrease ExceedAgo */ - State->ExceedAgo -= /*BURST_INTERVAL*/ burstInterval / (BURST_LEN - 1); - if (State->ExceedAgo < 0) - State->ExceedAgo = 0; - } - else - { - State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */ - State->PrevExceed = 1; - } - } - else - { - State->PrevExceed = 0; - State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */ - } - - /* set burst flag if bottle neck not exceeded for long time */ - if ((State->ExceedAgo > burstInterval) && - (State->BurstCounter == 0)) - { - if (State->PrevExceed) - { - State->BurstCounter = BURST_LEN - 1; - } - else - { - State->BurstCounter = BURST_LEN; - } - } - - - /* Update buffer delay */ - TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck; /* ms */ - State->StillBuffered += TransmissionTime; - State->StillBuffered -= (FrameSamples * 1000) / FS; /* ms */ - if (State->StillBuffered < 0.0) - { - State->StillBuffered = 0.0; - } - - return MinBytes; -} - - -/* - * update long-term average bitrate and amount of data in buffer - */ -void WebRtcIsac_UpdateRateModel( - RateModel *State, - int StreamSize, /* bytes in bitstream */ - const int FrameSamples, /* samples per frame */ - const double BottleNeck) /* bottle neck rate; excl headers (bps) */ -{ - double TransmissionTime; - - /* avoid the initial "high-rate" burst */ - State->InitCounter = 0; - - /* Update buffer delay */ - TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck; /* ms */ - State->StillBuffered += TransmissionTime; - State->StillBuffered -= (FrameSamples * 1000) / FS; /* ms */ - if (State->StillBuffered < 0.0) - State->StillBuffered = 0.0; - -} - - -void WebRtcIsac_InitRateModel( - RateModel *State) -{ - State->PrevExceed = 0; /* boolean */ - State->ExceedAgo = 0; /* ms */ - State->BurstCounter = 0; /* packets */ - State->InitCounter = INIT_BURST_LEN + 10; /* packets */ - State->StillBuffered = 1.0; /* ms */ -} - -int WebRtcIsac_GetNewFrameLength( - double bottle_neck, - int current_framesamples) -{ - int new_framesamples; - - const int Thld_20_30 = 20000; - - //const int Thld_30_20 = 30000; - const int Thld_30_20 = 1000000; // disable 20 ms frames - - const int Thld_30_60 = 18000; - //const int Thld_30_60 = 0; // disable 60 ms frames - - const int Thld_60_30 = 27000; - - - new_framesamples = current_framesamples; - - /* find new framelength */ - switch(current_framesamples) { - case 320: - if (bottle_neck < Thld_20_30) - new_framesamples = 480; - break; - case 480: - if (bottle_neck < Thld_30_60) - new_framesamples = 960; - else if (bottle_neck > Thld_30_20) - new_framesamples = 320; - break; - case 960: - if (bottle_neck >= Thld_60_30) - new_framesamples = 480; - break; - } - - return new_framesamples; -} - -double WebRtcIsac_GetSnr( - double bottle_neck, - int framesamples) -{ - double s2nr; - - const double a_20 = -30.0; - const double b_20 = 0.8; - const double c_20 = 0.0; - - const double a_30 = -23.0; - const double b_30 = 0.48; - const double c_30 = 0.0; - - const double a_60 = -23.0; - const double b_60 = 0.53; - const double c_60 = 0.0; - - - /* find new SNR value */ - switch(framesamples) { - case 320: - s2nr = a_20 + b_20 * bottle_neck * 0.001 + c_20 * bottle_neck * - bottle_neck * 0.000001; - break; - case 480: - s2nr = a_30 + b_30 * bottle_neck * 0.001 + c_30 * bottle_neck * - bottle_neck * 0.000001; - break; - case 960: - s2nr = a_60 + b_60 * bottle_neck * 0.001 + c_60 * bottle_neck * - bottle_neck * 0.000001; - break; - default: - s2nr = 0; - } - - return s2nr; - -} diff --git a/src/mod/codecs/mod_isac/bandwidth_estimator.h b/src/mod/codecs/mod_isac/bandwidth_estimator.h deleted file mode 100644 index 5604d7bbbd..0000000000 --- a/src/mod/codecs/mod_isac/bandwidth_estimator.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * bandwidth_estimator.h - * - * This header file contains the API for the Bandwidth Estimator - * designed for iSAC. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_ - -#include "structs.h" -#include "settings.h" - - -#define MIN_ISAC_BW 10000 -#define MIN_ISAC_BW_LB 10000 -#define MIN_ISAC_BW_UB 25000 - -#define MAX_ISAC_BW 56000 -#define MAX_ISAC_BW_UB 32000 -#define MAX_ISAC_BW_LB 32000 - -#define MIN_ISAC_MD 5 -#define MAX_ISAC_MD 25 - -// assumed header size, in bytes; we don't know the exact number -// (header compression may be used) -#define HEADER_SIZE 35 - -// Initial Frame-Size, in ms, for Wideband & Super-Wideband Mode -#define INIT_FRAME_LEN_WB 60 -#define INIT_FRAME_LEN_SWB 30 - -// Initial Bottleneck Estimate, in bits/sec, for -// Wideband & Super-wideband mode -#define INIT_BN_EST_WB 20e3f -#define INIT_BN_EST_SWB 56e3f - -// Initial Header rate (header rate depends on frame-size), -// in bits/sec, for Wideband & Super-Wideband mode. -#define INIT_HDR_RATE_WB \ - ((float)HEADER_SIZE * 8.0f * 1000.0f / (float)INIT_FRAME_LEN_WB) -#define INIT_HDR_RATE_SWB \ - ((float)HEADER_SIZE * 8.0f * 1000.0f / (float)INIT_FRAME_LEN_SWB) - -// number of packets in a row for a high rate burst -#define BURST_LEN 3 - -// ms, max time between two full bursts -#define BURST_INTERVAL 500 - -// number of packets in a row for initial high rate burst -#define INIT_BURST_LEN 5 - -// bits/s, rate for the first BURST_LEN packets -#define INIT_RATE_WB INIT_BN_EST_WB -#define INIT_RATE_SWB INIT_BN_EST_SWB - - -#if defined(__cplusplus) -extern "C" { -#endif - - /* This function initializes the struct */ - /* to be called before using the struct for anything else */ - /* returns 0 if everything went fine, -1 otherwise */ - WebRtc_Word32 WebRtcIsac_InitBandwidthEstimator( - BwEstimatorstr* bwest_str, - enum IsacSamplingRate encoderSampRate, - enum IsacSamplingRate decoderSampRate); - - /* This function updates the receiving estimate */ - /* Parameters: */ - /* rtp_number - value from RTP packet, from NetEq */ - /* frame length - length of signal frame in ms, from iSAC decoder */ - /* send_ts - value in RTP header giving send time in samples */ - /* arr_ts - value given by timeGetTime() time of arrival in samples of packet from NetEq */ - /* pksize - size of packet in bytes, from NetEq */ - /* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */ - /* returns 0 if everything went fine, -1 otherwise */ - WebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator( - BwEstimatorstr* bwest_str, - const WebRtc_UWord16 rtp_number, - const WebRtc_Word32 frame_length, - const WebRtc_UWord32 send_ts, - const WebRtc_UWord32 arr_ts, - const WebRtc_Word32 pksize); - - /* Update receiving estimates. Used when we only receive BWE index, no iSAC data packet. */ - WebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl( - BwEstimatorstr* bwest_str, - WebRtc_Word16 Index, - enum IsacSamplingRate encoderSamplingFreq); - - /* Returns the bandwidth/jitter estimation code (integer 0...23) to put in the sending iSAC payload */ - WebRtc_UWord16 WebRtcIsac_GetDownlinkBwJitIndexImpl( - BwEstimatorstr* bwest_str, - WebRtc_Word16* bottleneckIndex, - WebRtc_Word16* jitterInfo, - enum IsacSamplingRate decoderSamplingFreq); - - /* Returns the bandwidth estimation (in bps) */ - WebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth( - const BwEstimatorstr *bwest_str); - - /* Returns the max delay (in ms) */ - WebRtc_Word32 WebRtcIsac_GetDownlinkMaxDelay( - const BwEstimatorstr *bwest_str); - - /* Returns the bandwidth that iSAC should send with in bps */ - void WebRtcIsac_GetUplinkBandwidth( - const BwEstimatorstr* bwest_str, - WebRtc_Word32* bitRate); - - /* Returns the max delay value from the other side in ms */ - WebRtc_Word32 WebRtcIsac_GetUplinkMaxDelay( - const BwEstimatorstr *bwest_str); - - - /* - * update amount of data in bottle neck buffer and burst handling - * returns minimum payload size (bytes) - */ - int WebRtcIsac_GetMinBytes( - RateModel* State, - int StreamSize, /* bytes in bitstream */ - const int FrameLen, /* ms per frame */ - const double BottleNeck, /* bottle neck rate; excl headers (bps) */ - const double DelayBuildUp, /* max delay from bottleneck buffering (ms) */ - enum ISACBandwidth bandwidth - /*,WebRtc_Word16 frequentLargePackets*/); - - /* - * update long-term average bitrate and amount of data in buffer - */ - void WebRtcIsac_UpdateRateModel( - RateModel* State, - int StreamSize, /* bytes in bitstream */ - const int FrameSamples, /* samples per frame */ - const double BottleNeck); /* bottle neck rate; excl headers (bps) */ - - - void WebRtcIsac_InitRateModel( - RateModel *State); - - /* Returns the new framelength value (input argument: bottle_neck) */ - int WebRtcIsac_GetNewFrameLength( - double bottle_neck, - int current_framelength); - - /* Returns the new SNR value (input argument: bottle_neck) */ - double WebRtcIsac_GetSnr( - double bottle_neck, - int new_framelength); - - - WebRtc_Word16 WebRtcIsac_UpdateUplinkJitter( - BwEstimatorstr* bwest_str, - WebRtc_Word32 index); - -#if defined(__cplusplus) -} -#endif - - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_ */ diff --git a/src/mod/codecs/mod_isac/codec.h b/src/mod/codecs/mod_isac/codec.h deleted file mode 100644 index 6af27ea9e0..0000000000 --- a/src/mod/codecs/mod_isac/codec.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * codec.h - * - * This header file contains the calls to the internal encoder - * and decoder functions. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_ - -#include "structs.h" - -int WebRtcIsac_EstimateBandwidth( - BwEstimatorstr* bwest_str, - Bitstr* streamdata, - WebRtc_Word32 packet_size, - WebRtc_UWord16 rtp_seq_number, - WebRtc_UWord32 send_ts, - WebRtc_UWord32 arr_ts, - enum IsacSamplingRate encoderSampRate, - enum IsacSamplingRate decoderSampRate); - -int WebRtcIsac_DecodeLb( - float* signal_out, - ISACLBDecStruct* ISACdec_obj, - WebRtc_Word16* current_framesamples, - WebRtc_Word16 isRCUPayload); - -int WebRtcIsac_DecodeRcuLb( - float* signal_out, - ISACLBDecStruct* ISACdec_obj, - WebRtc_Word16* current_framesamples); - -int WebRtcIsac_EncodeLb( - float* in, - ISACLBEncStruct* ISACencLB_obj, - WebRtc_Word16 codingMode, - WebRtc_Word16 bottleneckIndex); - -int WebRtcIsac_EncodeStoredDataLb( - const ISAC_SaveEncData_t* ISACSavedEnc_obj, - Bitstr* ISACBitStr_obj, - int BWnumber, - float scale); - - -int WebRtcIsac_EncodeStoredDataUb12( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale); - -int WebRtcIsac_EncodeStoredDataUb16( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale); - - -WebRtc_Word16 WebRtcIsac_GetRedPayloadUb( - const ISACUBSaveEncDataStruct* ISACSavedEncObj, - Bitstr* bitStreamObj, - enum ISACBandwidth bandwidth); -/****************************************************************************** - * WebRtcIsac_RateAllocation() - * Internal function to perform a rate-allocation for upper and lower-band, - * given a total rate. - * - * Input: - * - inRateBitPerSec : a total bit-rate in bits/sec. - * - * Output: - * - rateLBBitPerSec : a bit-rate allocated to the lower-band - * in bits/sec. - * - rateUBBitPerSec : a bit-rate allocated to the upper-band - * in bits/sec. - * - * Return value : 0 if rate allocation has been successful. - * -1 if failed to allocate rates. - */ - -WebRtc_Word16 -WebRtcIsac_RateAllocation( - WebRtc_Word32 inRateBitPerSec, - double* rateLBBitPerSec, - double* rateUBBitPerSec, - enum ISACBandwidth* bandwidthKHz); - - -/****************************************************************************** - * WebRtcIsac_DecodeUb16() - * - * Decode the upper-band if the codec is in 0-16 kHz mode. - * - * Input/Output: - * -ISACdec_obj : pointer to the upper-band decoder object. The - * bit-stream is stored inside the decoder object. - * - * Output: - * -signal_out : decoded audio, 480 samples 30 ms. - * - * Return value : >0 number of decoded bytes. - * <0 if an error occurred. - */ -int WebRtcIsac_DecodeUb16( - float* signal_out, - ISACUBDecStruct* ISACdec_obj, - WebRtc_Word16 isRCUPayload); - - -/****************************************************************************** - * WebRtcIsac_DecodeUb12() - * - * Decode the upper-band if the codec is in 0-12 kHz mode. - * - * Input/Output: - * -ISACdec_obj : pointer to the upper-band decoder object. The - * bit-stream is stored inside the decoder object. - * - * Output: - * -signal_out : decoded audio, 480 samples 30 ms. - * - * Return value : >0 number of decoded bytes. - * <0 if an error occurred. - */ -int WebRtcIsac_DecodeUb12( - float* signal_out, - ISACUBDecStruct* ISACdec_obj, - WebRtc_Word16 isRCUPayload); - - -/****************************************************************************** - * WebRtcIsac_EncodeUb16() - * - * Encode the upper-band if the codec is in 0-16 kHz mode. - * - * Input: - * -in : upper-band audio, 160 samples (10 ms). - * - * Input/Output: - * -ISACdec_obj : pointer to the upper-band encoder object. The - * bit-stream is stored inside the encoder object. - * - * Return value : >0 number of encoded bytes. - * <0 if an error occurred. - */ -int WebRtcIsac_EncodeUb16( - float* in, - ISACUBEncStruct* ISACenc_obj, - WebRtc_Word32 jitterInfo); - - -/****************************************************************************** - * WebRtcIsac_EncodeUb12() - * - * Encode the upper-band if the codec is in 0-12 kHz mode. - * - * Input: - * -in : upper-band audio, 160 samples (10 ms). - * - * Input/Output: - * -ISACdec_obj : pointer to the upper-band encoder object. The - * bit-stream is stored inside the encoder object. - * - * Return value : >0 number of encoded bytes. - * <0 if an error occurred. - */ -int WebRtcIsac_EncodeUb12( - float* in, - ISACUBEncStruct* ISACenc_obj, - WebRtc_Word32 jitterInfo); - -/************************** initialization functions *************************/ - -void WebRtcIsac_InitMasking(MaskFiltstr *maskdata); - -void WebRtcIsac_InitPreFilterbank(PreFiltBankstr *prefiltdata); - -void WebRtcIsac_InitPostFilterbank(PostFiltBankstr *postfiltdata); - -void WebRtcIsac_InitPitchFilter(PitchFiltstr *pitchfiltdata); - -void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct *State); - - -/**************************** transform functions ****************************/ - -void WebRtcIsac_InitTransform(); - -void WebRtcIsac_Time2Spec(double *inre1, - double *inre2, - WebRtc_Word16 *outre, - WebRtc_Word16 *outim, - FFTstr *fftstr_obj); - -void WebRtcIsac_Spec2time(double *inre, - double *inim, - double *outre1, - double *outre2, - FFTstr *fftstr_obj); - - -/******************************* filter functions ****************************/ - -void WebRtcIsac_AllPoleFilter(double *InOut, - double *Coef, - int lengthInOut, - int orderCoef); - -void WebRtcIsac_AllZeroFilter(double *In, - double *Coef, - int lengthInOut, - int orderCoef, - double *Out); - -void WebRtcIsac_ZeroPoleFilter(double *In, - double *ZeroCoef, - double *PoleCoef, - int lengthInOut, - int orderCoef, - double *Out); - - -/***************************** filterbank functions **************************/ - -void WebRtcIsac_SplitAndFilter(double *in, - double *LP, - double *HP, - double *LP_la, - double *HP_la, - PreFiltBankstr *prefiltdata); - - -void WebRtcIsac_FilterAndCombine(double *InLP, - double *InHP, - double *Out, - PostFiltBankstr *postfiltdata); - - - -void WebRtcIsac_SplitAndFilterFloat(float *in, - float *LP, - float *HP, - double *LP_la, - double *HP_la, - PreFiltBankstr *prefiltdata); - - -void WebRtcIsac_FilterAndCombineFloat(float *InLP, - float *InHP, - float *Out, - PostFiltBankstr *postfiltdata); - - -/************************* normalized lattice filters ************************/ - -void WebRtcIsac_NormLatticeFilterMa(int orderCoef, - float *stateF, - float *stateG, - float *lat_in, - double *filtcoeflo, - double *lat_out); - -void WebRtcIsac_NormLatticeFilterAr(int orderCoef, - float *stateF, - float *stateG, - double *lat_in, - double *lo_filt_coef, - float *lat_out); - -void WebRtcIsac_Dir2Lat(double *a, - int orderCoef, - float *sth, - float *cth); - -void WebRtcIsac_AutoCorr(double *r, - const double *x, - int N, - int order); - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_ */ diff --git a/src/mod/codecs/mod_isac/complex_bit_reverse.c b/src/mod/codecs/mod_isac/complex_bit_reverse.c deleted file mode 100644 index 85c76f8283..0000000000 --- a/src/mod/codecs/mod_isac/complex_bit_reverse.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_ComplexBitReverse(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 frfi[], int stages) -{ - int mr, nn, n, l, m; - WebRtc_Word16 tr, ti; - - n = 1 << stages; - - mr = 0; - nn = n - 1; - - // decimation in time - re-order data - for (m = 1; m <= nn; ++m) - { - l = n; - do - { - l >>= 1; - } while (mr + l > nn); - mr = (mr & (l - 1)) + l; - - if (mr <= m) - continue; - - tr = frfi[2 * m]; - frfi[2 * m] = frfi[2 * mr]; - frfi[2 * mr] = tr; - - ti = frfi[2 * m + 1]; - frfi[2 * m + 1] = frfi[2 * mr + 1]; - frfi[2 * mr + 1] = ti; - } -} diff --git a/src/mod/codecs/mod_isac/complex_fft.c b/src/mod/codecs/mod_isac/complex_fft.c deleted file mode 100644 index fa09636f7b..0000000000 --- a/src/mod/codecs/mod_isac/complex_fft.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_ComplexFFT(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define CFFTSFT 14 -#define CFFTRND 1 -#define CFFTRND2 16384 - -#define CIFFTSFT 14 -#define CIFFTRND 1 - -static const WebRtc_Word16 kSinTable1024[] = { - 0, 201, 402, 603, 804, 1005, 1206, 1406, - 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, - 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, - 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, - 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, - 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, - 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, - 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, - 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, - 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, - 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, - 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, - 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, - 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, - 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, - 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, - 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, - 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, - 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, - 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, - 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, - 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, - 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, - 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, - 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, - 30851, 30918, 30984, 31049, - 31113, 31175, 31236, 31297, - 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, - 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, - 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, - 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, - 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, - 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766, - 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, - 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, - 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, - 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, - 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, - 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, - 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, - 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, - 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, - 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, - 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, - 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, - 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, - 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, - 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, - 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, - 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, - 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, - 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, - 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, - 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, - 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, - 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, - 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, - 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, - 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, - 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, - 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, - 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, - 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, - 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, - 1607, 1406, 1206, 1005, 804, 603, 402, 201, - 0, -201, -402, -603, -804, -1005, -1206, -1406, - -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, - -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, - -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, - -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, - -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, - -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, - -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, - -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, - -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, - -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, - -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, - -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, - -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, - -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, - -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, - -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, - -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, - -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, - -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, - -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, - -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, - -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, - -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, - -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, - -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, - -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, - -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, - -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, - -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, - -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, - -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, - -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, - -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, - -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, - -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, - -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, - -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, - -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, - -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, - -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, - -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, - -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, - -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, - -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, - -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, - -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, - -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, - -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, - -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, - -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, - -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, - -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, - -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, - -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, - -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, - -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, - -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, - -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, - -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, - -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, - -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, - -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, - -1607, -1406, -1206, -1005, -804, -603, -402, -201 -}; - -int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode) -{ - int i, j, l, k, istep, n, m; - WebRtc_Word16 wr, wi; - WebRtc_Word32 tr32, ti32, qr32, qi32; - - /* The 1024-value is a constant given from the size of kSinTable1024[], - * and should not be changed depending on the input parameter 'stages' - */ - n = 1 << stages; - if (n > 1024) - return -1; - - l = 1; - k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change - depending on the input parameter 'stages' */ - - if (mode == 0) - { - // mode==0: Low-complexity and Low-accuracy mode - while (l < n) - { - istep = l << 1; - - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = kSinTable1024[j + 256]; - wi = -kSinTable1024[j]; - - for (i = m; i < n; i += istep) - { - j = i + l; - - tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) - - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15); - - ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) - + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15); - - qr32 = (WebRtc_Word32)frfi[2 * i]; - qi32 = (WebRtc_Word32)frfi[2 * i + 1]; - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1); - } - } - - --k; - l = istep; - - } - - } else - { - // mode==1: High-complexity and High-accuracy mode - while (l < n) - { - istep = l << 1; - - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = kSinTable1024[j + 256]; - wi = -kSinTable1024[j]; - -#ifdef WEBRTC_ARCH_ARM_V7A - WebRtc_Word32 wri; - WebRtc_Word32 frfi_r; - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) : - "r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi)); -#endif - - for (i = m; i < n; i += istep) - { - j = i + l; - -#ifdef WEBRTC_ARCH_ARM_V7A - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) : - "r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1])); - __asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) : - "r"(wri), "r"(frfi_r), "r"(CFFTRND)); - __asm__("smladx %0, %1, %2, %3" : "=r"(ti32) : - "r"(wri), "r"(frfi_r), "r"(CFFTRND)); - -#else - tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) - - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND; - - ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) - + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND; -#endif - - tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT); - ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT); - - qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT; - qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT; - - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT); - } - } - - --k; - l = istep; - } - } - return 0; -} - -int WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode) -{ - int i, j, l, k, istep, n, m, scale, shift; - WebRtc_Word16 wr, wi; - WebRtc_Word32 tr32, ti32, qr32, qi32; - WebRtc_Word32 tmp32, round2; - - /* The 1024-value is a constant given from the size of kSinTable1024[], - * and should not be changed depending on the input parameter 'stages' - */ - n = 1 << stages; - if (n > 1024) - return -1; - - scale = 0; - - l = 1; - k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change - depending on the input parameter 'stages' */ - - while (l < n) - { - // variable scaling, depending upon data - shift = 0; - round2 = 8192; - - tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n); - if (tmp32 > 13573) - { - shift++; - scale++; - round2 <<= 1; - } - if (tmp32 > 27146) - { - shift++; - scale++; - round2 <<= 1; - } - - istep = l << 1; - - if (mode == 0) - { - // mode==0: Low-complexity and Low-accuracy mode - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = kSinTable1024[j + 256]; - wi = kSinTable1024[j]; - - for (i = m; i < n; i += istep) - { - j = i + l; - - tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0) - - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15); - - ti32 = WEBRTC_SPL_RSHIFT_W32( - (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0) - + WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15); - - qr32 = (WebRtc_Word32)frfi[2 * i]; - qi32 = (WebRtc_Word32)frfi[2 * i + 1]; - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift); - } - } - } else - { - // mode==1: High-complexity and High-accuracy mode - - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = kSinTable1024[j + 256]; - wi = kSinTable1024[j]; - -#ifdef WEBRTC_ARCH_ARM_V7A - WebRtc_Word32 wri; - WebRtc_Word32 frfi_r; - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) : - "r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi)); -#endif - - for (i = m; i < n; i += istep) - { - j = i + l; - -#ifdef WEBRTC_ARCH_ARM_V7A - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) : - "r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1])); - __asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) : - "r"(wri), "r"(frfi_r), "r"(CIFFTRND)); - __asm__("smladx %0, %1, %2, %3" : "=r"(ti32) : - "r"(wri), "r"(frfi_r), "r"(CIFFTRND)); -#else - - tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) - - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CIFFTRND; - - ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) - + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND; -#endif - tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT); - ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT); - - qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT; - qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT; - - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2), - shift+CIFFTSFT); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 - ti32 + round2), shift + CIFFTSFT); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2), - shift + CIFFTSFT); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 + ti32 + round2), shift + CIFFTSFT); - } - } - - } - --k; - l = istep; - } - return scale; -} diff --git a/src/mod/codecs/mod_isac/copy_set_operations.c b/src/mod/codecs/mod_isac/copy_set_operations.c deleted file mode 100644 index 8247337754..0000000000 --- a/src/mod/codecs/mod_isac/copy_set_operations.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the implementation of functions - * WebRtcSpl_MemSetW16() - * WebRtcSpl_MemSetW32() - * WebRtcSpl_MemCpyReversedOrder() - * WebRtcSpl_CopyFromEndW16() - * WebRtcSpl_ZerosArrayW16() - * WebRtcSpl_ZerosArrayW32() - * WebRtcSpl_OnesArrayW16() - * WebRtcSpl_OnesArrayW32() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include -#include "signal_processing_library.h" - - -void WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length) -{ - int j; - WebRtc_Word16 *arrptr = ptr; - - for (j = length; j > 0; j--) - { - *arrptr++ = set_value; - } -} - -void WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length) -{ - int j; - WebRtc_Word32 *arrptr = ptr; - - for (j = length; j > 0; j--) - { - *arrptr++ = set_value; - } -} - -void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length) -{ - int j; - WebRtc_Word16* destPtr = dest; - WebRtc_Word16* sourcePtr = source; - - for (j = 0; j < length; j++) - { - *destPtr-- = *sourcePtr++; - } -} - -WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in, - WebRtc_Word16 length, - WebRtc_Word16 samples, - WebRtc_Word16 *vector_out) -{ - // Copy the last of the input vector to vector_out - WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples); - - return samples; -} - -WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtcSpl_MemSetW16(vector, 0, length); - return length; -} - -WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtcSpl_MemSetW32(vector, 0, length); - return length; -} - -WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 i; - WebRtc_Word16 *tmpvec = vector; - for (i = 0; i < length; i++) - { - *tmpvec++ = 1; - } - return length; -} - -WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 i; - WebRtc_Word32 *tmpvec = vector; - for (i = 0; i < length; i++) - { - *tmpvec++ = 1; - } - return length; -} diff --git a/src/mod/codecs/mod_isac/crc.c b/src/mod/codecs/mod_isac/crc.c deleted file mode 100644 index 098e4b7a69..0000000000 --- a/src/mod/codecs/mod_isac/crc.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "crc.h" -#include -#include "signal_processing_library.h" - -#define POLYNOMIAL 0x04c11db7L - - -static const WebRtc_UWord32 kCrcTable[256] = { - 0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, - 0x808d07d, 0xcc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - - - - -/**************************************************************************** - * WebRtcIsac_GetCrc(...) - * - * This function returns a 32 bit CRC checksum of a bit stream - * - * Input: - * - bitstream : payload bitstream - * - len_bitstream_in_bytes : number of 8-bit words in the bit stream - * - * Output: - * - crc : checksum - * - * Return value : 0 - Ok - * -1 - Error - */ - -WebRtc_Word16 WebRtcIsac_GetCrc(const WebRtc_Word16* bitstream, - WebRtc_Word16 len_bitstream_in_bytes, - WebRtc_UWord32* crc) -{ - WebRtc_UWord8* bitstream_ptr_uw8; - WebRtc_UWord32 crc_state; - int byte_cntr; - int crc_tbl_indx; - - /* Sanity Check. */ - if (bitstream == NULL) { - return -1; - } - /* cast to UWord8 pointer */ - bitstream_ptr_uw8 = (WebRtc_UWord8 *)bitstream; - - /* initialize */ - crc_state = 0xFFFFFFFF; - - for (byte_cntr = 0; byte_cntr < len_bitstream_in_bytes; byte_cntr++) { - crc_tbl_indx = (WEBRTC_SPL_RSHIFT_U32(crc_state, 24) ^ - bitstream_ptr_uw8[byte_cntr]) & 0xFF; - crc_state = WEBRTC_SPL_LSHIFT_U32(crc_state, 8) ^ kCrcTable[crc_tbl_indx]; - } - - *crc = ~crc_state; - return 0; -} diff --git a/src/mod/codecs/mod_isac/crc.h b/src/mod/codecs/mod_isac/crc.h deleted file mode 100644 index 015127894b..0000000000 --- a/src/mod/codecs/mod_isac/crc.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * crc.h - * - * Checksum functions - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_ - -#include "typedefs.h" - -/**************************************************************************** - * WebRtcIsac_GetCrc(...) - * - * This function returns a 32 bit CRC checksum of a bit stream - * - * Input: - * - encoded : payload bit stream - * - no_of_word8s : number of 8-bit words in the bit stream - * - * Output: - * - crc : checksum - * - * Return value : 0 - Ok - * -1 - Error - */ - -WebRtc_Word16 WebRtcIsac_GetCrc( - const WebRtc_Word16* encoded, - WebRtc_Word16 no_of_word8s, - WebRtc_UWord32* crc); - - - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_ */ diff --git a/src/mod/codecs/mod_isac/cross_correlation.c b/src/mod/codecs/mod_isac/cross_correlation.c deleted file mode 100644 index 936ae6877f..0000000000 --- a/src/mod/codecs/mod_isac/cross_correlation.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_CrossCorrelation(). - * The description header can be found in signal_processing_library.h - * - */ - -/* TODO(kma): Clean up the code in this file, and break it up for - * various platforms (Xscale, ARM/Neon etc.). - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1, - WebRtc_Word16* seq2, WebRtc_Word16 dim_seq, - WebRtc_Word16 dim_cross_correlation, - WebRtc_Word16 right_shifts, - WebRtc_Word16 step_seq2) -{ - int i, j; - WebRtc_Word16* seq1Ptr; - WebRtc_Word16* seq2Ptr; - WebRtc_Word32* CrossCorrPtr; - -#ifdef _XSCALE_OPT_ - -#ifdef _WIN32 -#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)") -#endif - - __int64 macc40; - - int iseq1[250]; - int iseq2[250]; - int iseq3[250]; - int * iseq1Ptr; - int * iseq2Ptr; - int * iseq3Ptr; - int len, i_len; - - seq1Ptr = seq1; - iseq1Ptr = iseq1; - for(i = 0; i < ((dim_seq + 1) >> 1); i++) - { - *iseq1Ptr = (unsigned short)*seq1Ptr++; - *iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16; - - } - - if(dim_seq%2) - { - *(iseq1Ptr-1) &= 0x0000ffff; - } - *iseq1Ptr = 0; - iseq1Ptr++; - *iseq1Ptr = 0; - iseq1Ptr++; - *iseq1Ptr = 0; - - if(step_seq2 < 0) - { - seq2Ptr = seq2 - dim_cross_correlation + 1; - CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1]; - } - else - { - seq2Ptr = seq2; - CrossCorrPtr = cross_correlation; - } - - len = dim_seq + dim_cross_correlation - 1; - i_len = (len + 1) >> 1; - iseq2Ptr = iseq2; - - iseq3Ptr = iseq3; - for(i = 0; i < i_len; i++) - { - *iseq2Ptr = (unsigned short)*seq2Ptr++; - *iseq3Ptr = (unsigned short)*seq2Ptr; - *iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16; - *iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16; - } - - if(len % 2) - { - iseq2[i_len - 1] &= 0x0000ffff; - iseq3[i_len - 1] = 0; - } - else - iseq3[i_len - 1] &= 0x0000ffff; - - iseq2[i_len] = 0; - iseq3[i_len] = 0; - iseq2[i_len + 1] = 0; - iseq3[i_len + 1] = 0; - iseq2[i_len + 2] = 0; - iseq3[i_len + 2] = 0; - - // Set pointer to start value - iseq2Ptr = iseq2; - iseq3Ptr = iseq3; - - i_len = (dim_seq + 7) >> 3; - for (i = 0; i < dim_cross_correlation; i++) - { - - iseq1Ptr = iseq1; - - macc40 = 0; - - _WriteCoProcessor(macc40, 0); - - if((i & 1)) - { - iseq3Ptr = iseq3 + (i >> 1); - for (j = i_len; j > 0; j--) - { - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - } - } - else - { - iseq2Ptr = iseq2 + (i >> 1); - for (j = i_len; j > 0; j--) - { - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - } - - } - - macc40 = _ReadCoProcessor(0); - *CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts); - CrossCorrPtr += step_seq2; - } -#else // #ifdef _XSCALE_OPT_ -#ifdef _ARM_OPT_ - WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3; -#endif - - CrossCorrPtr = cross_correlation; - - for (i = 0; i < dim_cross_correlation; i++) - { - // Set the pointer to the static vector, set the pointer to the sliding vector - // and initialize cross_correlation - seq1Ptr = seq1; - seq2Ptr = seq2 + (step_seq2 * i); - (*CrossCorrPtr) = 0; - -#ifndef _ARM_OPT_ -#ifdef _WIN32 -#pragma message("NOTE: default implementation is used") -#endif - // Perform the cross correlation - for (j = 0; j < dim_seq; j++) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts); - seq1Ptr++; - seq2Ptr++; - } -#else -#ifdef _WIN32 -#pragma message("NOTE: _ARM_OPT_ optimizations are used") -#endif - if (right_shifts == 0) - { - // Perform the optimized cross correlation - for (j = 0; j < dim_seq8; j = j + 8) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - } - - for (j = dim_seq8; j < dim_seq; j++) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - } - } - else // right_shifts != 0 - - { - // Perform the optimized cross correlation - for (j = 0; j < dim_seq8; j = j + 8) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - } - - for (j = dim_seq8; j < dim_seq; j++) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - } - } -#endif - CrossCorrPtr++; - } -#endif -} diff --git a/src/mod/codecs/mod_isac/decode.c b/src/mod/codecs/mod_isac/decode.c deleted file mode 100644 index 25634b0a89..0000000000 --- a/src/mod/codecs/mod_isac/decode.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * decode_B.c - * - * This file contains definition of funtions for decoding. - * Decoding of lower-band, including normal-decoding and RCU decoding. - * Decoding of upper-band, including 8-12 kHz, when the bandwidth is - * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz. - * - */ - - -#include "codec.h" -#include "entropy_coding.h" -#include "pitch_estimator.h" -#include "bandwidth_estimator.h" -#include "structs.h" -#include "settings.h" - -#include -#include -#include - - -/* - * function to decode the bitstream - * returns the total number of bytes in the stream - */ -int -WebRtcIsac_DecodeLb( - float* signal_out, - ISACLBDecStruct* ISACdecLB_obj, - WebRtc_Word16* current_framesamples, - WebRtc_Word16 isRCUPayload) -{ - int k, model; - int len, err; - WebRtc_Word16 bandwidthInd; - - float LP_dec_float[FRAMESAMPLES_HALF]; - float HP_dec_float[FRAMESAMPLES_HALF]; - - double LPw[FRAMESAMPLES_HALF]; - double HPw[FRAMESAMPLES_HALF]; - double LPw_pf[FRAMESAMPLES_HALF]; - - double lo_filt_coef[(ORDERLO+1)*SUBFRAMES]; - double hi_filt_coef[(ORDERHI+1)*SUBFRAMES]; - - double real_f[FRAMESAMPLES_HALF]; - double imag_f[FRAMESAMPLES_HALF]; - - double PitchLags[4]; - double PitchGains[4]; - double AvgPitchGain; - WebRtc_Word16 PitchGains_Q12[4]; - WebRtc_Word16 AvgPitchGain_Q12; - - float gain; - - int frame_nb; /* counter */ - int frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */ - int processed_samples; - - (ISACdecLB_obj->bitstr_obj).W_upper = 0xFFFFFFFF; - (ISACdecLB_obj->bitstr_obj).streamval = 0; - (ISACdecLB_obj->bitstr_obj).stream_index = 0; - - len = 0; - - /* decode framelength and BW estimation - not used, - only for stream pointer*/ - err = WebRtcIsac_DecodeFrameLen(&ISACdecLB_obj->bitstr_obj, - current_framesamples); - if (err < 0) { // error check - return err; - } - - /* frame_mode: 0, or 1 */ - frame_mode = *current_framesamples/MAX_FRAMESAMPLES; - /* processed_samples: either 320 (20ms) or 480 (30, 60 ms) */ - processed_samples = *current_framesamples/(frame_mode+1); - - err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd); - if (err < 0) { // error check - return err; - } - - /* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames - bundled together (60ms) */ - for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) { - /* decode & dequantize pitch parameters */ - err = WebRtcIsac_DecodePitchGain(&(ISACdecLB_obj->bitstr_obj), - PitchGains_Q12); - if (err < 0) { // error check - return err; - } - - err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, - PitchGains_Q12, PitchLags); - if (err < 0) { // error check - return err; - } - - AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] + - PitchGains_Q12[2] + PitchGains_Q12[3])>>2; - - /* decode & dequantize FiltCoef */ - err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, - lo_filt_coef,hi_filt_coef, &model); - if (err < 0) { // error check - return err; - } - /* decode & dequantize spectrum */ - len = WebRtcIsac_DecodeSpecLb(&ISACdecLB_obj->bitstr_obj, - real_f, imag_f, AvgPitchGain_Q12); - if (len < 0) { // error check - return len; - } - - /* inverse transform */ - WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, - &ISACdecLB_obj->fftstr_obj); - - /* convert PitchGains back to FLOAT for pitchfilter_post */ - for (k = 0; k < 4; k++) { - PitchGains[k] = ((float)PitchGains_Q12[k])/4096; - } - - if(isRCUPayload) - { - for (k = 0; k < 240; k++) { - LPw[k] *= RCU_TRANSCODING_SCALE_INVERSE; - HPw[k] *= RCU_TRANSCODING_SCALE_INVERSE; - } - } - - /* inverse pitch filter */ - WebRtcIsac_PitchfilterPost(LPw, LPw_pf, - &ISACdecLB_obj->pitchfiltstr_obj, PitchLags, PitchGains); - /* convert AvgPitchGain back to FLOAT for computation of gain */ - AvgPitchGain = ((float)AvgPitchGain_Q12)/4096; - gain = 1.0f - 0.45f * (float)AvgPitchGain; - - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - /* reduce gain to compensate for pitch enhancer */ - LPw_pf[ k ] *= gain; - } - - if(isRCUPayload) - { - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - /* compensation for transcoding gain changes*/ - LPw_pf[k] *= RCU_TRANSCODING_SCALE; - HPw[k] *= RCU_TRANSCODING_SCALE; - } - } - - /* perceptual post-filtering (using normalized lattice filter) */ - WebRtcIsac_NormLatticeFilterAr(ORDERLO, - ISACdecLB_obj->maskfiltstr_obj.PostStateLoF, - (ISACdecLB_obj->maskfiltstr_obj).PostStateLoG, - LPw_pf, lo_filt_coef, LP_dec_float); - WebRtcIsac_NormLatticeFilterAr(ORDERHI, - ISACdecLB_obj->maskfiltstr_obj.PostStateHiF, - (ISACdecLB_obj->maskfiltstr_obj).PostStateHiG, - HPw, hi_filt_coef, HP_dec_float); - - /* recombine the 2 bands */ - WebRtcIsac_FilterAndCombineFloat( LP_dec_float, HP_dec_float, - signal_out + frame_nb * processed_samples, - &ISACdecLB_obj->postfiltbankstr_obj); - } - - return len; -} - - -/* - * This decode function is called when the codec is operating in 16 kHz - * bandwidth to decode the upperband, i.e. 8-16 kHz. - * - * Contrary to lower-band, the upper-band (8-16 kHz) is not split in - * frequency, but split to 12 sub-frames, i.e. twice as lower-band. - */ -int -WebRtcIsac_DecodeUb16( - float* signal_out, - ISACUBDecStruct* ISACdecUB_obj, - WebRtc_Word16 isRCUPayload) -{ - int len, err; - - double halfFrameFirst[FRAMESAMPLES_HALF]; - double halfFrameSecond[FRAMESAMPLES_HALF]; - - double percepFilterParam[(UB_LPC_ORDER+1) * (SUBFRAMES<<1) + - (UB_LPC_ORDER+1)]; - - double real_f[FRAMESAMPLES_HALF]; - double imag_f[FRAMESAMPLES_HALF]; - - len = 0; - - /* decode & dequantize FiltCoef */ - memset(percepFilterParam, 0, sizeof(percepFilterParam)); - err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, - percepFilterParam, isac16kHz); - if (err < 0) { // error check - return err; - } - - /* decode & dequantize spectrum */ - len = WebRtcIsac_DecodeSpecUB16(&ISACdecUB_obj->bitstr_obj, real_f, - imag_f); - if (len < 0) { // error check - return len; - } - if(isRCUPayload) - { - int n; - for(n = 0; n < 240; n++) - { - real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; - imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; - } - } - - /* inverse transform */ - WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond, - &ISACdecUB_obj->fftstr_obj); - - /* perceptual post-filtering (using normalized lattice filter) */ - WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER, - ISACdecUB_obj->maskfiltstr_obj.PostStateLoF, - (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameFirst, - &percepFilterParam[(UB_LPC_ORDER+1)], signal_out); - - WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER, - ISACdecUB_obj->maskfiltstr_obj.PostStateLoF, - (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameSecond, - &percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER+1)], - &signal_out[FRAMESAMPLES_HALF]); - - return len; -} - -/* - * This decode function is called when the codec operates at 0-12 kHz - * bandwidth to decode the upperband, i.e. 8-12 kHz. - * - * At the encoder the upper-band is split into two band, 8-12 kHz & 12-16 - * kHz, and only 8-12 kHz is encoded. At the decoder, 8-12 kHz band is - * reconstructed and 12-16 kHz replaced with zeros. Then two bands - * are combined, to reconstruct the upperband 8-16 kHz. - */ -int -WebRtcIsac_DecodeUb12( - float* signal_out, - ISACUBDecStruct* ISACdecUB_obj, - WebRtc_Word16 isRCUPayload) -{ - int len, err; - - float LP_dec_float[FRAMESAMPLES_HALF]; - float HP_dec_float[FRAMESAMPLES_HALF]; - - double LPw[FRAMESAMPLES_HALF]; - double HPw[FRAMESAMPLES_HALF]; - - double percepFilterParam[(UB_LPC_ORDER+1)*SUBFRAMES]; - - double real_f[FRAMESAMPLES_HALF]; - double imag_f[FRAMESAMPLES_HALF]; - - len = 0; - - /* decode & dequantize FiltCoef */ - err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, - percepFilterParam, isac12kHz); - if(err < 0) { // error check - return err; - } - - /* decode & dequantize spectrum */ - len = WebRtcIsac_DecodeSpecUB12(&ISACdecUB_obj->bitstr_obj, - real_f, imag_f); - if(len < 0) { // error check - return len; - } - - if(isRCUPayload) - { - int n; - for(n = 0; n < 240; n++) - { - real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; - imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; - } - } - - /* inverse transform */ - WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj); - - /* perceptual post-filtering (using normalized lattice filter) */ - WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER, - ISACdecUB_obj->maskfiltstr_obj.PostStateLoF, - (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, LPw, - percepFilterParam, LP_dec_float); - - /* Zerro for upper-band */ - memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF)); - - /* recombine the 2 bands */ - WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out, - &ISACdecUB_obj->postfiltbankstr_obj); - - - - return len; -} diff --git a/src/mod/codecs/mod_isac/decode_bwe.c b/src/mod/codecs/mod_isac/decode_bwe.c deleted file mode 100644 index cdac7fa8bf..0000000000 --- a/src/mod/codecs/mod_isac/decode_bwe.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "structs.h" -#include "bandwidth_estimator.h" -#include "entropy_coding.h" -#include "codec.h" - - -int -WebRtcIsac_EstimateBandwidth( - BwEstimatorstr* bwest_str, - Bitstr* streamdata, - WebRtc_Word32 packet_size, - WebRtc_UWord16 rtp_seq_number, - WebRtc_UWord32 send_ts, - WebRtc_UWord32 arr_ts, - enum IsacSamplingRate encoderSampRate, - enum IsacSamplingRate decoderSampRate) -{ - WebRtc_Word16 index; - WebRtc_Word16 frame_samples; - WebRtc_UWord32 sendTimestampIn16kHz; - WebRtc_UWord32 arrivalTimestampIn16kHz; - WebRtc_UWord32 diffSendTime; - WebRtc_UWord32 diffArrivalTime; - int err; - - /* decode framelength and BW estimation */ - err = WebRtcIsac_DecodeFrameLen(streamdata, &frame_samples); - if(err < 0) // error check - { - return err; - } - err = WebRtcIsac_DecodeSendBW(streamdata, &index); - if(err < 0) // error check - { - return err; - } - - /* UPDATE ESTIMATES FROM OTHER SIDE */ - err = WebRtcIsac_UpdateUplinkBwImpl(bwest_str, index, encoderSampRate); - if(err < 0) - { - return err; - } - - // We like BWE to work at 16 kHz sampling rate, - // therefore, we have to change the timestamps accordingly. - // translate the send timestamp if required - diffSendTime = (WebRtc_UWord32)((WebRtc_UWord32)send_ts - - (WebRtc_UWord32)bwest_str->senderTimestamp); - bwest_str->senderTimestamp = send_ts; - - diffArrivalTime = (WebRtc_UWord32)((WebRtc_UWord32)arr_ts - - (WebRtc_UWord32)bwest_str->receiverTimestamp); - bwest_str->receiverTimestamp = arr_ts; - - if(decoderSampRate == kIsacSuperWideband) - { - diffArrivalTime = (WebRtc_UWord32)diffArrivalTime >> 1; - diffSendTime = (WebRtc_UWord32)diffSendTime >> 1; - } - // arrival timestamp in 16 kHz - arrivalTimestampIn16kHz = (WebRtc_UWord32)((WebRtc_UWord32) - bwest_str->prev_rec_arr_ts + (WebRtc_UWord32)diffArrivalTime); - // send timestamp in 16 kHz - sendTimestampIn16kHz = (WebRtc_UWord32)((WebRtc_UWord32) - bwest_str->prev_rec_send_ts + (WebRtc_UWord32)diffSendTime); - - err = WebRtcIsac_UpdateBandwidthEstimator(bwest_str, rtp_seq_number, - (frame_samples * 1000) / FS, sendTimestampIn16kHz, - arrivalTimestampIn16kHz, packet_size); - // error check - if(err < 0) - { - return err; - } - - return 0; -} diff --git a/src/mod/codecs/mod_isac/division_operations.c b/src/mod/codecs/mod_isac/division_operations.c deleted file mode 100644 index b143373a2f..0000000000 --- a/src/mod/codecs/mod_isac/division_operations.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the divisions - * WebRtcSpl_DivU32U16() - * WebRtcSpl_DivW32W16() - * WebRtcSpl_DivW32W16ResW16() - * WebRtcSpl_DivResultInQ31() - * WebRtcSpl_DivW32HiLow() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den) -{ - // Guard against division with 0 - if (den != 0) - { - return (WebRtc_UWord32)(num / den); - } else - { - return (WebRtc_UWord32)0xFFFFFFFF; - } -} - -WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den) -{ - // Guard against division with 0 - if (den != 0) - { - return (WebRtc_Word32)(num / den); - } else - { - return (WebRtc_Word32)0x7FFFFFFF; - } -} - -WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den) -{ - // Guard against division with 0 - if (den != 0) - { - return (WebRtc_Word16)(num / den); - } else - { - return (WebRtc_Word16)0x7FFF; - } -} - -WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den) -{ - WebRtc_Word32 L_num = num; - WebRtc_Word32 L_den = den; - WebRtc_Word32 div = 0; - int k = 31; - int change_sign = 0; - - if (num == 0) - return 0; - - if (num < 0) - { - change_sign++; - L_num = -num; - } - if (den < 0) - { - change_sign++; - L_den = -den; - } - while (k--) - { - div <<= 1; - L_num <<= 1; - if (L_num >= L_den) - { - L_num -= L_den; - div++; - } - } - if (change_sign == 1) - { - div = -div; - } - return div; -} - -WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, - WebRtc_Word16 den_low) -{ - WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low; - WebRtc_Word32 tmpW32; - - approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi); - // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) - - // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) - tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1) - + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1); - // tmpW32 = den * approx - - tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) - - // Store tmpW32 in hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // tmpW32 = 1/den in Q29 - tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx) - >> 15)) << 1); - - // 1/den in hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // Store num in hi and low format - num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16); - num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1); - - // num * (1/den) by 32 bit multiplication (result in Q28) - - tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low) - >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15)); - - // Put result in Q31 (convert from Q28) - tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); - - return tmpW32; -} diff --git a/src/mod/codecs/mod_isac/dot_product_with_scale.c b/src/mod/codecs/mod_isac/dot_product_with_scale.c deleted file mode 100644 index 6e085fdb60..0000000000 --- a/src/mod/codecs/mod_isac/dot_product_with_scale.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_DotProductWithScale(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2, - int length, int scaling) -{ - WebRtc_Word32 sum; - int i; -#ifdef _ARM_OPT_ -#pragma message("NOTE: _ARM_OPT_ optimizations are used") - WebRtc_Word16 len4 = (length >> 2) << 2; -#endif - - sum = 0; - -#ifndef _ARM_OPT_ - for (i = 0; i < length; i++) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling); - } -#else - if (scaling == 0) - { - for (i = 0; i < len4; i = i + 4) - { - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - } - - for (i = len4; i < length; i++) - { - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - } - } - else - { - for (i = 0; i < len4; i = i + 4) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - } - - for (i = len4; i < length; i++) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - } - } -#endif - - return sum; -} diff --git a/src/mod/codecs/mod_isac/downsample_fast.c b/src/mod/codecs/mod_isac/downsample_fast.c deleted file mode 100644 index cce463c5d3..0000000000 --- a/src/mod/codecs/mod_isac/downsample_fast.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_DownsampleFast(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length, - WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length, - WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor, - WebRtc_Word16 delay) -{ - WebRtc_Word32 o; - int i, j; - - WebRtc_Word16 *downsampled_ptr = out_ptr; - WebRtc_Word16 *b_ptr; - WebRtc_Word16 *x_ptr; - WebRtc_Word16 endpos = delay - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1; - - if (in_length < endpos) - { - return -1; - } - - for (i = delay; i < endpos; i += factor) - { - b_ptr = &B[0]; - x_ptr = &in_ptr[i]; - - o = (WebRtc_Word32)2048; // Round val - - for (j = 0; j < B_length; j++) - { - o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--); - } - - o = WEBRTC_SPL_RSHIFT_W32(o, 12); - - // If output is higher than 32768, saturate it. Same with negative side - - *downsampled_ptr++ = WebRtcSpl_SatW32ToW16(o); - } - - return 0; -} diff --git a/src/mod/codecs/mod_isac/encode.c b/src/mod/codecs/mod_isac/encode.c deleted file mode 100644 index 66b80244a8..0000000000 --- a/src/mod/codecs/mod_isac/encode.c +++ /dev/null @@ -1,1451 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * encode.c - * - * This file contains definition of funtions for encoding. - * Decoding of upper-band, including 8-12 kHz, when the bandwidth is - * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz. - * - */ - -#include -#include - -#include "structs.h" -#include "codec.h" -#include "pitch_estimator.h" -#include "entropy_coding.h" -#include "arith_routines.h" -#include "pitch_gain_tables.h" -#include "pitch_lag_tables.h" -#include "spectrum_ar_model_tables.h" -#include "lpc_tables.h" -#include "lpc_analysis.h" -#include "bandwidth_estimator.h" -#include "lpc_shape_swb12_tables.h" -#include "lpc_shape_swb16_tables.h" -#include "lpc_gain_swb_tables.h" - - -#define UB_LOOKAHEAD 24 - -/* - Rate allocation tables of lower and upper-band bottleneck for - 12kHz & 16kHz bandwidth. - - 12 kHz bandwidth - ----------------- - The overall bottleneck of the coder is between 38 kbps and 45 kbps. We have - considered 7 enteries, uniformly distributed in this interval, i.e. 38, - 39.17, 40.33, 41.5, 42.67, 43.83 and 45. For every entery, the lower-band - and the upper-band bottlenecks are specified in - 'kLowerBandBitRate12' and 'kUpperBandBitRate12' - tables, respectively. E.g. the overall rate of 41.5 kbps corresponts to a - bottleneck of 31 kbps for lower-band and 27 kbps for upper-band. Given an - overall bottleneck of the codec, we use linear interpolation to get - lower-band and upper-band bottlenecks. - - 16 kHz bandwidth - ----------------- - The overall bottleneck of the coder is between 50 kbps and 56 kbps. We have - considered 7 enteries, uniformly distributed in this interval, i.e. 50, 51.2, - 52.4, 53.6, 54.8 and 56. For every entery, the lower-band and the upper-band - bottlenecks are specified in 'kLowerBandBitRate16' and - 'kUpperBandBitRate16' tables, respectively. E.g. the overall rate - of 53.6 kbps corresponts to a bottleneck of 32 kbps for lower-band and 30 - kbps for upper-band. Given an overall bottleneck of the codec, we use linear - interpolation to get lower-band and upper-band bottlenecks. - -*/ - -// 38 39.17 40.33 41.5 42.67 43.83 45 -static const WebRtc_Word16 kLowerBandBitRate12[7] = { - 29000, 30000, 30000, 31000, 31000, 32000, 32000}; -static const WebRtc_Word16 kUpperBandBitRate12[7] = { - 25000, 25000, 27000, 27000, 29000, 29000, 32000}; - -// 50 51.2 52.4 53.6 54.8 56 -static const WebRtc_Word16 kLowerBandBitRate16[6] = { - 31000, 31000, 32000, 32000, 32000, 32000}; -static const WebRtc_Word16 kUpperBandBitRate16[6] = { - 28000, 29000, 29000, 30000, 31000, 32000}; - -/****************************************************************************** - * WebRtcIsac_RateAllocation() - * Internal function to perform a rate-allocation for upper and lower-band, - * given a total rate. - * - * Input: - * - inRateBitPerSec : a total bottleneck in bits/sec. - * - * Output: - * - rateLBBitPerSec : a bottleneck allocated to the lower-band - * in bits/sec. - * - rateUBBitPerSec : a bottleneck allocated to the upper-band - * in bits/sec. - * - * Return value : 0 if rate allocation has been successful. - * -1 if failed to allocate rates. - */ - -WebRtc_Word16 -WebRtcIsac_RateAllocation( - WebRtc_Word32 inRateBitPerSec, - double* rateLBBitPerSec, - double* rateUBBitPerSec, - enum ISACBandwidth* bandwidthKHz) -{ - WebRtc_Word16 idx; - double idxD; - double idxErr; - if(inRateBitPerSec < 38000) - { - // If the given overall bottleneck is less than 38000 then - // then codec has to operate in wideband mode, i.e. 8 kHz - // bandwidth. - *rateLBBitPerSec = (WebRtc_Word16)((inRateBitPerSec > 32000)? - 32000:inRateBitPerSec); - *rateUBBitPerSec = 0; - *bandwidthKHz = isac8kHz; - } - else if((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) - { - // At a bottleneck between 38 and 50 kbps the codec is operating - // at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates - // upper/lower bottleneck - - // find the bottlenecks by linear interpolation - // step is (45000 - 38000)/6.0 we use the inverse of it. - const double stepSizeInv = 8.5714286e-4; - idxD = (inRateBitPerSec - 38000) * stepSizeInv; - idx = (idxD >= 6)? 6:((WebRtc_Word16)idxD); - idxErr = idxD - idx; - *rateLBBitPerSec = kLowerBandBitRate12[idx]; - *rateUBBitPerSec = kUpperBandBitRate12[idx]; - - if(idx < 6) - { - *rateLBBitPerSec += (WebRtc_Word16)(idxErr * - (kLowerBandBitRate12[idx + 1] - - kLowerBandBitRate12[idx])); - *rateUBBitPerSec += (WebRtc_Word16)(idxErr * - (kUpperBandBitRate12[idx + 1] - - kUpperBandBitRate12[idx])); - } - - *bandwidthKHz = isac12kHz; - } - else if((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) - { - // A bottleneck between 50 and 56 kbps corresponds to bandwidth - // of 16 kHz. Using xxxBandBitRate16[] to calculates - // upper/lower bottleneck - - // find the bottlenecks by linear interpolation - // step is (56000 - 50000)/5 we use the inverse of it - const double stepSizeInv = 8.3333333e-4; - idxD = (inRateBitPerSec - 50000) * stepSizeInv; - idx = (idxD >= 5)? 5:((WebRtc_Word16)idxD); - idxErr = idxD - idx; - *rateLBBitPerSec = kLowerBandBitRate16[idx]; - *rateUBBitPerSec = kUpperBandBitRate16[idx]; - - if(idx < 5) - { - *rateLBBitPerSec += (WebRtc_Word16)(idxErr * - (kLowerBandBitRate16[idx + 1] - - kLowerBandBitRate16[idx])); - - *rateUBBitPerSec += (WebRtc_Word16)(idxErr * - (kUpperBandBitRate16[idx + 1] - - kUpperBandBitRate16[idx])); - } - - *bandwidthKHz = isac16kHz; - } - else - { - // Out-of-range botlteneck value. - return -1; - } - - // limit the values. - *rateLBBitPerSec = (*rateLBBitPerSec > 32000)? 32000:*rateLBBitPerSec; - *rateUBBitPerSec = (*rateUBBitPerSec > 32000)? 32000:*rateUBBitPerSec; - - return 0; -} - - - -int -WebRtcIsac_EncodeLb( - float* in, - ISACLBEncStruct* ISACencLB_obj, - WebRtc_Word16 codingMode, - WebRtc_Word16 bottleneckIndex) -{ - int stream_length = 0; - int err; - int k; - int iterCntr; - - double lofilt_coef[(ORDERLO+1)*SUBFRAMES]; - double hifilt_coef[(ORDERHI+1)*SUBFRAMES]; - float LP[FRAMESAMPLES_HALF]; - float HP[FRAMESAMPLES_HALF]; - - double LP_lookahead[FRAMESAMPLES_HALF]; - double HP_lookahead[FRAMESAMPLES_HALF]; - double LP_lookahead_pf[FRAMESAMPLES_HALF + QLOOKAHEAD]; - double LPw[FRAMESAMPLES_HALF]; - - double HPw[FRAMESAMPLES_HALF]; - double LPw_pf[FRAMESAMPLES_HALF]; - WebRtc_Word16 fre[FRAMESAMPLES_HALF]; /* Q7 */ - WebRtc_Word16 fim[FRAMESAMPLES_HALF]; /* Q7 */ - - double PitchLags[4]; - double PitchGains[4]; - WebRtc_Word16 PitchGains_Q12[4]; - WebRtc_Word16 AvgPitchGain_Q12; - - int frame_mode; /* 0 for 30ms, 1 for 60ms */ - int processed_samples, status = 0; - - double bits_gains; - int bmodel; - - transcode_obj transcodingParam; - double bytesLeftSpecCoding; - WebRtc_UWord16 payloadLimitBytes; - - /* copy new frame length and bottle neck rate only for the first - 10 ms data */ - if (ISACencLB_obj->buffer_index == 0) { - /* set the framelength for the next packet */ - ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength; - } - /* frame_mode is 0 (30 ms) or 1 (60 ms) */ - frame_mode = ISACencLB_obj->current_framesamples/MAX_FRAMESAMPLES; - /* processed_samples: 480 (30, 60 ms) */ - processed_samples = ISACencLB_obj->current_framesamples/(frame_mode+1); - - /* buffer speech samples (by 10ms packet) until the framelength */ - /* is reached (30 or 60 ms) */ - /****************************************************************/ - - /* fill the buffer with 10ms input data */ - for (k = 0; k < FRAMESAMPLES_10ms; k++) { - ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = - in[k]; - } - - /* if buffersize is not equal to current framesize then increase index - and return. We do no encoding untill we have enough audio. */ - if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) { - ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms; - return 0; - } - /* if buffer reached the right size, reset index and continue with - encoding the frame */ - ISACencLB_obj->buffer_index = 0; - - /* end of buffer function */ - /**************************/ - - /* encoding */ - /************/ - - if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0 ) { - // This is to avoid Linux warnings until we change 'int' to 'Word32' - // at all places. - int intVar; - /* reset bitstream */ - ISACencLB_obj->bitstr_obj.W_upper = 0xFFFFFFFF; - ISACencLB_obj->bitstr_obj.streamval = 0; - ISACencLB_obj->bitstr_obj.stream_index = 0; - - if((codingMode == 0) && (frame_mode == 0) && - (ISACencLB_obj->enforceFrameSize == 0)) { - ISACencLB_obj->new_framelength = - WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck, - ISACencLB_obj->current_framesamples); - } - - ISACencLB_obj->s2nr = WebRtcIsac_GetSnr( - ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples); - - /* encode frame length */ - status = WebRtcIsac_EncodeFrameLen( - ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj); - if (status < 0) { - /* Wrong frame size */ - return status; - } - /* Save framelength for multiple packets memory */ - ISACencLB_obj->SaveEnc_obj.framelength = - ISACencLB_obj->current_framesamples; - - /* To be used for Redundant Coding */ - ISACencLB_obj->lastBWIdx = bottleneckIndex; - intVar = (int)bottleneckIndex; - WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj); - } - - /* split signal in two bands */ - WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP, - LP_lookahead, HP_lookahead, &ISACencLB_obj->prefiltbankstr_obj ); - - /* estimate pitch parameters and pitch-filter lookahead signal */ - WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf, - &ISACencLB_obj->pitchanalysisstr_obj, PitchLags, PitchGains); - - /* encode in FIX Q12 */ - - /* convert PitchGain to Fixed point */ - for (k=0;kframe_nb == 0) - { - ISACencLB_obj->SaveEnc_obj.startIdx = 0; - } else { - ISACencLB_obj->SaveEnc_obj.startIdx = 1; - } - - /* quantize & encode pitch parameters */ - WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj, - &ISACencLB_obj->SaveEnc_obj); - WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12, - &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); - - AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] + - PitchGains_Q12[2] + PitchGains_Q12[3])>>2; - - /* find coefficients for perceptual pre-filters */ - WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead, - &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr, - PitchGains_Q12, lofilt_coef, hifilt_coef); - - /* code LPC model and shape - gains not quantized yet */ - WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &bmodel, &bits_gains, - &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); - - /* convert PitchGains back to FLOAT for pitchfilter_pre */ - for (k = 0; k < 4; k++) { - PitchGains[k] = ((float)PitchGains_Q12[k])/4096; - } - - /* Store the state of arithmetic coder before coding LPC gains */ - transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper; - transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index; - transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval; - transcodingParam.stream[0] = ISACencLB_obj->bitstr_obj.stream[ - ISACencLB_obj->bitstr_obj.stream_index - 2]; - transcodingParam.stream[1] = ISACencLB_obj->bitstr_obj.stream[ - ISACencLB_obj->bitstr_obj.stream_index - 1]; - transcodingParam.stream[2] = ISACencLB_obj->bitstr_obj.stream[ - ISACencLB_obj->bitstr_obj.stream_index]; - - /* Store LPC Gains before encoding them */ - for(k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER+1)*k]; - transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER+1)*k]; - } - - /* Code gains */ - WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef, bmodel, - &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); - - /* Get the correct value for the payload limit and calculate the - number of bytes left for coding the spectrum.*/ - if((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { - /* It is a 60ms and we are in the first 30ms then the limit at - this point should be half of the assigned value */ - payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1; - } - else if (frame_mode == 0) { - /* It is a 30ms frame */ - /* Subract 3 because termination process may add 3 bytes */ - payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3; - } else { - /* This is the second half of a 60ms frame. */ - /* Subract 3 because termination process may add 3 bytes */ - payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3; - } - bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index; - - /* perceptual pre-filtering (using normalized lattice filter) */ - /* low-band filtering */ - WebRtcIsac_NormLatticeFilterMa(ORDERLO, - ISACencLB_obj->maskfiltstr_obj.PreStateLoF, - ISACencLB_obj->maskfiltstr_obj.PreStateLoG, LP, lofilt_coef, LPw); - /* high-band filtering */ - WebRtcIsac_NormLatticeFilterMa(ORDERHI, - ISACencLB_obj->maskfiltstr_obj.PreStateHiF, - ISACencLB_obj->maskfiltstr_obj.PreStateHiG, HP, hifilt_coef, HPw); - - - /* pitch filter */ - WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj, - PitchLags, PitchGains); - - /* transform */ - WebRtcIsac_Time2Spec(LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj); - - - /* Save data for multiple packets memory */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - ISACencLB_obj->SaveEnc_obj.fre[k + - ISACencLB_obj->SaveEnc_obj.startIdx*FRAMESAMPLES_HALF] = fre[k]; - ISACencLB_obj->SaveEnc_obj.fim[k + - ISACencLB_obj->SaveEnc_obj.startIdx*FRAMESAMPLES_HALF] = fim[k]; - } - ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ - ISACencLB_obj->SaveEnc_obj.startIdx] = AvgPitchGain_Q12; - - /* quantization and lossless coding */ - err = WebRtcIsac_EncodeSpecLb(fre, fim, &ISACencLB_obj->bitstr_obj, - AvgPitchGain_Q12); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large payload - (we can cure too large payload) */ - if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) { - /* If this is the second 30ms of a 60ms frame reset - this such that in the next call encoder starts fresh. */ - ISACencLB_obj->frame_nb = 0; - } - return err; - } - iterCntr = 0; - while((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) || - (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - double bytesSpecCoderUsed; - double transcodeScale; - - if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { - /* We were not able to limit the payload size */ - if((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { - /* This was the first 30ms of a 60ms frame. Although - the payload is larger than it should be but we let - the second 30ms be encoded. Maybe together we - won't exceed the limit. */ - ISACencLB_obj->frame_nb = 1; - return 0; - } else if((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) { - ISACencLB_obj->frame_nb = 0; - } - - if(err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) { - return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; - } else { - return status; - } - } - - if(err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { - bytesSpecCoderUsed = STREAM_SIZE_MAX; - // being coservative - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; - } else { - bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index - - transcodingParam.stream_index; - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; - } - - /* To be safe, we reduce the scale depending on - the number of iterations. */ - transcodeScale *= (1.0 - (0.9 * (double)iterCntr / - (double)MAX_PAYLOAD_LIMIT_ITERATION)); - - /* Scale the LPC Gains */ - for (k = 0; k < SUBFRAMES; k++) { - lofilt_coef[(LPC_LOBAND_ORDER+1) * k] = - transcodingParam.loFiltGain[k] * transcodeScale; - hifilt_coef[(LPC_HIBAND_ORDER+1) * k] = - transcodingParam.hiFiltGain[k] * transcodeScale; - transcodingParam.loFiltGain[k] = - lofilt_coef[(LPC_LOBAND_ORDER+1) * k]; - transcodingParam.hiFiltGain[k] = - hifilt_coef[(LPC_HIBAND_ORDER+1) * k]; - } - - /* Scale DFT coefficients */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale); - fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale); - } - - /* Save data for multiple packets memory */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - ISACencLB_obj->SaveEnc_obj.fre[k + - ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF] = - fre[k]; - ISACencLB_obj->SaveEnc_obj.fim[k + - ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF] = - fim[k]; - } - - /* Re-store the state of arithmetic coder before coding LPC gains */ - ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; - ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; - ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval; - ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] = - transcodingParam.stream[0]; - ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] = - transcodingParam.stream[1]; - ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] = - transcodingParam.stream[2]; - - /* Code gains */ - WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef, bmodel, - &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); - - /* Update the number of bytes left for encoding the spectrum */ - bytesLeftSpecCoding = payloadLimitBytes - - transcodingParam.stream_index; - - /* Encode the spectrum */ - err = WebRtcIsac_EncodeSpecLb(fre, fim, &ISACencLB_obj->bitstr_obj, - AvgPitchGain_Q12); - if((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large - payload (we can cure too large payload) */ - if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) { - /* If this is the second 30ms of a 60ms frame reset - this such that in the next call encoder starts fresh. */ - ISACencLB_obj->frame_nb = 0; - } - return err; - } - iterCntr++; - } - - /* i.e. 60 ms framesize and just processed the first 30ms, */ - /* go back to main function to buffer the other 30ms speech frame */ - if (frame_mode == 1) - { - if(ISACencLB_obj->frame_nb == 0) - { - ISACencLB_obj->frame_nb = 1; - return 0; - } - else if(ISACencLB_obj->frame_nb == 1) - { - ISACencLB_obj->frame_nb = 0; - /* also update the framelength for next packet, - in Adaptive mode only */ - if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) - { - ISACencLB_obj->new_framelength = - WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck, - ISACencLB_obj->current_framesamples); - } - } - } - else - { - ISACencLB_obj->frame_nb = 0; - } - - /* complete arithmetic coding */ - stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj); - - return stream_length; -} - -int -WebRtcIsac_EncodeUb16( - float* in, - ISACUBEncStruct* ISACencUB_obj, - WebRtc_Word32 jitterInfo) -{ - int err; - int k; - - double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES<<1) + - (1 + UB_LPC_ORDER)]; - - double LP_lookahead[FRAMESAMPLES]; - WebRtc_Word16 fre[FRAMESAMPLES_HALF]; /* Q7 */ - WebRtc_Word16 fim[FRAMESAMPLES_HALF]; /* Q7 */ - - int status = 0; - - double varscale[2]; - double corr[SUBFRAMES<<1][UB_LPC_ORDER + 1]; - double lpcGains[SUBFRAMES<<1]; - transcode_obj transcodingParam; - double bytesLeftSpecCoding; - WebRtc_UWord16 payloadLimitBytes; - WebRtc_UWord16 iterCntr; - double s2nr; - - /* buffer speech samples (by 10ms packet) until the framelength is */ - /* reached (30 or 60 ms) */ - /*********************************************************************/ - - /* fill the buffer with 10ms input data */ - for (k = 0; k < FRAMESAMPLES_10ms; k++) { - ISACencUB_obj->data_buffer_float[k + ISACencUB_obj->buffer_index] = - in[k]; - } - - /* if buffersize is not equal to current framesize, and end of file is - not reached yet, we don't do encoding unless we have the whole frame */ - if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) { - ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms; - return 0; - } - - /* end of buffer function */ - /**************************/ - - /* encoding */ - /************/ - - /* reset bitstream */ - ISACencUB_obj->bitstr_obj.W_upper = 0xFFFFFFFF; - ISACencUB_obj->bitstr_obj.streamval = 0; - ISACencUB_obj->bitstr_obj.stream_index = 0; - - /* bandwidth estimation and coding */ - /* To be used for Redundant Coding */ - WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj); - - status = WebRtcIsac_EncodeBandwidth(isac16kHz, - &ISACencUB_obj->bitstr_obj); - if (status < 0) { - return status; - } - - s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, - FRAMESAMPLES); - - memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double)); - - for (k = 0; k < FRAMESAMPLES; k++) { - LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k]; - } - - /* find coefficients for perceptual pre-filters */ - WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj, - &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz); - - memcpy(ISACencUB_obj->lastLPCVec, - &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)], - sizeof(double) * UB_LPC_ORDER); - - /* code LPC model and shape - gains not quantized yet */ - WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj, - percepFilterParams, isac16kHz, &ISACencUB_obj->SaveEnc_obj); - - - // the first set of lpc parameters are from the last sub-frame of - // the previous frame. so we don't care about them - WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1], - (SUBFRAMES<<1), lpcGains, corr, varscale); - - /* Store the state of arithmetic coder before coding LPC gains */ - transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index; - transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper; - transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval; - transcodingParam.stream[0] = ISACencUB_obj->bitstr_obj.stream[ - ISACencUB_obj->bitstr_obj.stream_index - 2]; - transcodingParam.stream[1] = ISACencUB_obj->bitstr_obj.stream[ - ISACencUB_obj->bitstr_obj.stream_index - 1]; - transcodingParam.stream[2] = ISACencUB_obj->bitstr_obj.stream[ - ISACencUB_obj->bitstr_obj.stream_index]; - - /* Store LPC Gains before encoding them */ - for(k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] = lpcGains[k]; - transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k]; - } - - // Store the gains for multiple encoding - memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, (SUBFRAMES << 1) * sizeof(double)); - - WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj, - ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - WebRtcIsac_EncodeLpcGainUb(&lpcGains[SUBFRAMES], &ISACencUB_obj->bitstr_obj, - &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]); - - /* Get the correct value for the payload limit and calculate the number of - bytes left for coding the spectrum. It is a 30ms frame - Subract 3 because termination process may add 3 bytes */ - payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes - - ISACencUB_obj->numBytesUsed - 3; - bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; - - for (k = 0; k < (SUBFRAMES<<1); k++) { - percepFilterParams[k*(UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] = - lpcGains[k]; - } - - /* perceptual pre-filtering (using normalized lattice filter) */ - /* first half-frame filtering */ - WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER, - ISACencUB_obj->maskfiltstr_obj.PreStateLoF, - ISACencUB_obj->maskfiltstr_obj.PreStateLoG, - &ISACencUB_obj->data_buffer_float[0], - &percepFilterParams[UB_LPC_ORDER + 1], - &LP_lookahead[0]); - - /* Second half-frame filtering */ - WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER, - ISACencUB_obj->maskfiltstr_obj.PreStateLoF, - ISACencUB_obj->maskfiltstr_obj.PreStateLoG, - &ISACencUB_obj->data_buffer_float[FRAMESAMPLES_HALF], - &percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * - (UB_LPC_ORDER + 1)], &LP_lookahead[FRAMESAMPLES_HALF]); - - WebRtcIsac_Time2Spec(&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF], - fre, fim, &ISACencUB_obj->fftstr_obj); - - //Store FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - // Prepare the audio buffer for the next packet - // move the last 3 ms to the beginning of the buffer - memcpy(ISACencUB_obj->data_buffer_float, - &ISACencUB_obj->data_buffer_float[FRAMESAMPLES], - LB_TOTAL_DELAY_SAMPLES * sizeof(float)); - // start writing with 3 ms delay to compensate for the delay - // of the lower-band. - ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES; - - // Save the bit-stream object at this point for FEC. - memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, - &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - - /* quantization and lossless coding */ - err = WebRtcIsac_EncodeSpecUB16(fre, fim, &ISACencUB_obj->bitstr_obj); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - return err; - } - - iterCntr = 0; - while((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || - (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - double bytesSpecCoderUsed; - double transcodeScale; - - if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { - /* We were not able to limit the payload size */ - return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; - } - - if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { - bytesSpecCoderUsed = STREAM_SIZE_MAX; - // being conservative - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; - } else { - bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index - - transcodingParam.stream_index; - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; - } - - /* To be safe, we reduce the scale depending on the - number of iterations. */ - transcodeScale *= (1.0 - (0.9 * (double)iterCntr/ - (double)MAX_PAYLOAD_LIMIT_ITERATION)); - - /* Scale the LPC Gains */ - for (k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] *= transcodeScale; - transcodingParam.hiFiltGain[k] *= transcodeScale; - } - - /* Scale DFT coefficients */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5); - fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5); - } - - //Store FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - - /* Store the state of arithmetic coder before coding LPC gains */ - ISACencUB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; - - ISACencUB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; - - ISACencUB_obj->bitstr_obj.streamval = transcodingParam.streamval; - - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] = - transcodingParam.stream[0]; - - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] = - transcodingParam.stream[1]; - - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index] = - transcodingParam.stream[2]; - - // Store the gains for multiple encoding - memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, - (SUBFRAMES << 1) * sizeof(double)); - - WebRtcIsac_EncodeLpcGainUb(transcodingParam.loFiltGain, - &ISACencUB_obj->bitstr_obj, - ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - WebRtcIsac_EncodeLpcGainUb(transcodingParam.hiFiltGain, - &ISACencUB_obj->bitstr_obj, - &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]); - - /* Update the number of bytes left for encoding the spectrum */ - bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; - - // Save the bit-stream object at this point for FEC. - memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, - &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - - /* Encode the spectrum */ - err = WebRtcIsac_EncodeSpecUB16(fre, fim, &ISACencUB_obj->bitstr_obj); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large payload - (we can cure too large payload) */ - return err; - } - iterCntr++; - } - - /* complete arithmetic coding */ - return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj); -} - - -int -WebRtcIsac_EncodeUb12( - float* in, - ISACUBEncStruct* ISACencUB_obj, - WebRtc_Word32 jitterInfo) -{ - int err; - int k; - int iterCntr; - - double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME]; - - double percepFilterParams[(1 + UB_LPC_ORDER) * SUBFRAMES]; - float LP[FRAMESAMPLES_HALF]; - float HP[FRAMESAMPLES_HALF]; - - double LP_lookahead[FRAMESAMPLES_HALF]; - double HP_lookahead[FRAMESAMPLES_HALF]; - double LPw[FRAMESAMPLES_HALF]; - - double HPw[FRAMESAMPLES_HALF]; - WebRtc_Word16 fre[FRAMESAMPLES_HALF]; /* Q7 */ - WebRtc_Word16 fim[FRAMESAMPLES_HALF]; /* Q7 */ - - int status = 0; - - double varscale[1]; - - double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1]; - double lpcGains[SUBFRAMES]; - transcode_obj transcodingParam; - double bytesLeftSpecCoding; - WebRtc_UWord16 payloadLimitBytes; - double s2nr; - - /* buffer speech samples (by 10ms packet) until the framelength is */ - /* reached (30 or 60 ms) */ - /********************************************************************/ - - /* fill the buffer with 10ms input data */ - for (k=0; kdata_buffer_float[k + ISACencUB_obj->buffer_index] = - in[k]; - } - - /* if buffer-size is not equal to current frame-size then increase the - index and return. We do the encoding when we have enough audio. */ - if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) { - ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms; - return 0; - } - /* if buffer reached the right size, reset index and continue - with encoding the frame */ - ISACencUB_obj->buffer_index = 0; - - /* end of buffer function */ - /**************************/ - - /* encoding */ - /************/ - - /* reset bitstream */ - ISACencUB_obj->bitstr_obj.W_upper = 0xFFFFFFFF; - ISACencUB_obj->bitstr_obj.streamval = 0; - ISACencUB_obj->bitstr_obj.stream_index = 0; - - /* bandwidth estimation and coding */ - /* To be used for Redundant Coding */ - WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj); - - status = WebRtcIsac_EncodeBandwidth(isac12kHz, - &ISACencUB_obj->bitstr_obj); - if (status < 0) { - return status; - } - - - s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, - FRAMESAMPLES); - - /* split signal in two bands */ - WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP, - HP_lookahead, LP_lookahead, &ISACencUB_obj->prefiltbankstr_obj); - - /* find coefficients for perceptual pre-filters */ - WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj, - lpcVecs, corr, varscale, isac12kHz); - - /* code LPC model and shape - gains not quantized yet */ - WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj, - percepFilterParams, isac12kHz, &ISACencUB_obj->SaveEnc_obj); - - WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, - corr, varscale); - - /* Store the state of arithmetic coder before coding LPC gains */ - transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper; - - transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index; - - transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval; - - transcodingParam.stream[0] = ISACencUB_obj->bitstr_obj.stream[ - ISACencUB_obj->bitstr_obj.stream_index - 2]; - - transcodingParam.stream[1] = ISACencUB_obj->bitstr_obj.stream[ - ISACencUB_obj->bitstr_obj.stream_index - 1]; - - transcodingParam.stream[2] = ISACencUB_obj->bitstr_obj.stream[ - ISACencUB_obj->bitstr_obj.stream_index]; - - /* Store LPC Gains before encoding them */ - for(k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] = lpcGains[k]; - } - - // Store the gains for multiple encoding - memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES * - sizeof(double)); - - WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj, - ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - - for(k = 0; k < SUBFRAMES; k++) { - percepFilterParams[k*(UB_LPC_ORDER + 1)] = lpcGains[k]; - } - - /* perceptual pre-filtering (using normalized lattice filter) */ - /* low-band filtering */ - WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER, - ISACencUB_obj->maskfiltstr_obj.PreStateLoF, - ISACencUB_obj->maskfiltstr_obj.PreStateLoG, LP, percepFilterParams, - LPw); - - /* Get the correct value for the payload limit and calculate the number - of bytes left for coding the spectrum. It is a 30ms frame Subract 3 - because termination process may add 3 bytes */ - payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes - - ISACencUB_obj->numBytesUsed - 3; - bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; - - memset(HPw, 0, sizeof(double) * FRAMESAMPLES_HALF); - - /* transform */ - WebRtcIsac_Time2Spec(LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj); - - //Store real FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - //Store imaginary FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - // Save the bit-stream object at this point for FEC. - memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, - &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - - /* quantization and lossless coding */ - err = WebRtcIsac_EncodeSpecUB12(fre, fim, &ISACencUB_obj->bitstr_obj); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large - payload (we can cure too large payload) */ - return err; - } - iterCntr = 0; - while((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || - (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - double bytesSpecCoderUsed; - double transcodeScale; - - if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { - /* We were not able to limit the payload size */ - return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; - } - - if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { - bytesSpecCoderUsed = STREAM_SIZE_MAX; - // being coservative - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; - } else { - bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index - - transcodingParam.stream_index; - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; - } - - /* To be safe, we reduce the scale depending on the - number of iterations. */ - transcodeScale *= (1.0 - (0.9 * (double)iterCntr/ - (double)MAX_PAYLOAD_LIMIT_ITERATION)); - - /* Scale the LPC Gains */ - for (k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] *= transcodeScale; - } - - /* Scale DFT coefficients */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5); - fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5); - } - - //Store real FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - //Store imaginary FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, - FRAMESAMPLES_HALF * sizeof(WebRtc_Word16)); - - - /* Re-store the state of arithmetic coder before coding LPC gains */ - ISACencUB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; - - ISACencUB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; - - ISACencUB_obj->bitstr_obj.streamval = transcodingParam.streamval; - - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] = - transcodingParam.stream[0]; - - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] = - transcodingParam.stream[1]; - - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index] = - transcodingParam.stream[2]; - - // Store the gains for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES * - sizeof(double)); - - // encode LPC gain and store quantization indices. HAving quantization - // indices reduces transcoding complexity if 'scale factor' is 1. - WebRtcIsac_EncodeLpcGainUb(transcodingParam.loFiltGain, - &ISACencUB_obj->bitstr_obj, - ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - - // Save the bit-stream object at this point for FEC. - memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, - &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - - /* Update the number of bytes left for encoding the spectrum */ - bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; - - /* Encode the spectrum */ - err = WebRtcIsac_EncodeSpecUB12(fre, fim, - &ISACencUB_obj->bitstr_obj); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large payload - (we can cure too large payload) */ - return err; - } - iterCntr++; - } - - /* complete arithmetic coding */ - return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj); -} - - - - - - -/* This function is used to create a new bitstream with new BWE. - The same data as previously encoded with the function WebRtcIsac_Encoder(). - The data needed is taken from the struct, where it was stored - when calling the encoder. */ - -int WebRtcIsac_EncodeStoredDataLb( - const ISAC_SaveEncData_t* ISACSavedEnc_obj, - Bitstr* ISACBitStr_obj, - int BWnumber, - float scale) -{ - int ii; - int status; - int BWno = BWnumber; - - const WebRtc_UWord16 *WebRtcIsac_kQPitchGainCdf_ptr[1]; - const WebRtc_UWord16 **cdf; - - double tmpLPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*2]; - double tmpLPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*2]; - int tmpLPCindex_g[12*2]; - WebRtc_Word16 tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES]; - - /* Sanity Check - possible values for BWnumber is 0 - 23 */ - if ((BWnumber < 0) || (BWnumber > 23)) { - return -ISAC_RANGE_ERROR_BW_ESTIMATOR; - } - - /* reset bitstream */ - ISACBitStr_obj->W_upper = 0xFFFFFFFF; - ISACBitStr_obj->streamval = 0; - ISACBitStr_obj->stream_index = 0; - - /* encode frame length */ - status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength, - ISACBitStr_obj); - if (status < 0) { - /* Wrong frame size */ - return status; - } - - /* Transcoding */ - if ((scale > 0.0) && (scale < 1.0)) { - /* Compensate LPC gain */ - for (ii = 0; - ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx)); - ii++) { - tmpLPCcoeffs_lo[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_lo[ii]; - } - for (ii = 0; - ii < ((ORDERHI + 1) * SUBFRAMES *(1 + ISACSavedEnc_obj->startIdx)); - ii++) { - tmpLPCcoeffs_hi[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_hi[ii]; - } - /* Scale DFT */ - for (ii = 0; - ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx)); - ii++) { - tmp_fre[ii] = (WebRtc_Word16)((scale) * - (float)ISACSavedEnc_obj->fre[ii]) ; - tmp_fim[ii] = (WebRtc_Word16)((scale) * - (float)ISACSavedEnc_obj->fim[ii]) ; - } - } else { - for (ii = 0; - ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx)); - ii++) { - tmpLPCindex_g[ii] = ISACSavedEnc_obj->LPCindex_g[ii]; - } - for (ii = 0; - ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx)); - ii++) { - tmp_fre[ii] = ISACSavedEnc_obj->fre[ii]; - tmp_fim[ii] = ISACSavedEnc_obj->fim[ii]; - } - } - - /* encode bandwidth estimate */ - WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj); - - /* Loop over number of 30 msec */ - for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) { - /* encode pitch gains */ - *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; - WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &ISACSavedEnc_obj->pitchGain_index[ii], WebRtcIsac_kQPitchGainCdf_ptr, 1); - - /* entropy coding of quantization pitch lags */ - /* voicing classificiation */ - if (ISACSavedEnc_obj->meanGain[ii] < 0.2) { - cdf = WebRtcIsac_kQPitchLagCdfPtrLo; - } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) { - cdf = WebRtcIsac_kQPitchLagCdfPtrMid; - } else { - cdf = WebRtcIsac_kQPitchLagCdfPtrHi; - } - WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES*ii], cdf, - PITCH_SUBFRAMES); - - /* LPC */ - /* entropy coding of model number */ - WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &ISACSavedEnc_obj->LPCmodel[ii], WebRtcIsac_kQKltModelCdfPtr, 1); - - /* entropy coding of quantization indices - LPC shape only */ - WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE*ii], - WebRtcIsac_kQKltCdfPtrShape[ISACSavedEnc_obj->LPCmodel[ii]], - KLT_ORDER_SHAPE); - - /* If transcoding, get new LPC gain indices */ - if (scale < 1.0) { - WebRtcIsac_TranscodeLPCCoef(&tmpLPCcoeffs_lo[(ORDERLO+1) * - SUBFRAMES*ii], &tmpLPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*ii], - ISACSavedEnc_obj->LPCmodel[ii], - &tmpLPCindex_g[KLT_ORDER_GAIN * ii]); - } - - /* entropy coding of quantization indices - LPC gain */ - WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &tmpLPCindex_g[KLT_ORDER_GAIN*ii], WebRtcIsac_kQKltCdfPtrGain[ - ISACSavedEnc_obj->LPCmodel[ii]], KLT_ORDER_GAIN); - - /* quantization and lossless coding */ - status = WebRtcIsac_EncodeSpecLb(&tmp_fre[ii*FRAMESAMPLES_HALF], - &tmp_fim[ii*FRAMESAMPLES_HALF], ISACBitStr_obj, - ISACSavedEnc_obj->AvgPitchGain[ii]); - if (status < 0) { - return status; - } - } - - /* complete arithmetic coding */ - return WebRtcIsac_EncTerminate(ISACBitStr_obj); -} - - - - -int WebRtcIsac_EncodeStoredDataUb12( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale) -{ - int n; - int err; - double lpcGain[SUBFRAMES]; - WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; - WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; - - /* reset bitstream */ - bitStream->W_upper = 0xFFFFFFFF; - bitStream->streamval = 0; - bitStream->stream_index = 0; - - // Encode jitter index - WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream); - - err = WebRtcIsac_EncodeBandwidth(isac12kHz, bitStream); - if(err < 0) - { - return err; - } - - // Encode LPC-shape - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape, - WebRtcIsac_kLpcShapeCdfMatUb12, UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); - - - // we only consider scales between zero and one. - if((scale <= 0.0) || (scale > 1.0)) - { - scale = 1.0f; - } - - if(scale == 1.0f) - { - //memcpy(lpcGain, ISACSavedEnc_obj->lpcGain, SUBFRAMES * sizeof(double)); - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex, - WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB12(ISACSavedEnc_obj->realFFT, - ISACSavedEnc_obj->imagFFT, bitStream); - } - else - { - /* scale lpc gain and FFT coefficients */ - for(n = 0; n < SUBFRAMES; n++) - { - lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n]; - } - // store lpc gain - WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); - for(n = 0; n < FRAMESAMPLES_HALF; n++) - { - realFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->realFFT[n] + 0.5f); - imagFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->imagFFT[n] + 0.5f); - } - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB12(realFFT, imagFFT, bitStream); - } - if(err < 0) - { - // error happened while encoding FFT coefficients. - return err; - } - - /* complete arithmetic coding */ - return WebRtcIsac_EncTerminate(bitStream); -} - - -int -WebRtcIsac_EncodeStoredDataUb16( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale) -{ - int n; - int err; - double lpcGain[SUBFRAMES << 1]; - WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; - WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; - - /* reset bitstream */ - bitStream->W_upper = 0xFFFFFFFF; - bitStream->streamval = 0; - bitStream->stream_index = 0; - - // Encode jitter index - WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream); - - err = WebRtcIsac_EncodeBandwidth(isac16kHz, bitStream); - if(err < 0) - { - return err; - } - - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape, - WebRtcIsac_kLpcShapeCdfMatUb16, UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); - - // we only consider scales between zero and one. - if((scale <= 0.0) || (scale > 1.0)) - { - scale = 1.0f; - } - - if(scale == 1.0f) - { - // store gains - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex, - WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); - WebRtcIsac_EncHistMulti(bitStream, &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES], - WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB16(ISACSavedEnc_obj->realFFT, - ISACSavedEnc_obj->imagFFT, bitStream); - - } - else - { - /* Scale Gain */ - for(n = 0; n < SUBFRAMES; n++) - { - lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n]; - lpcGain[n + SUBFRAMES] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES]; - } - // store lpc gain - WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); - WebRtcIsac_StoreLpcGainUb(&lpcGain[SUBFRAMES], bitStream); - /* scale FFT coefficients */ - for(n = 0; n < FRAMESAMPLES_HALF; n++) - { - realFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->realFFT[n] + 0.5f); - imagFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->imagFFT[n] + 0.5f); - } - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB16(realFFT, imagFFT, bitStream); - } - - if(err < 0) - { - // error happened while encoding FFT coefficients. - return err; - } - - /* complete arithmetic coding */ - return WebRtcIsac_EncTerminate(bitStream); -} - - -WebRtc_Word16 -WebRtcIsac_GetRedPayloadUb( - const ISACUBSaveEncDataStruct* ISACSavedEncObj, - Bitstr* bitStreamObj, - enum ISACBandwidth bandwidth) -{ - int n; - WebRtc_Word16 status; - WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; - WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; - - // store bit-stream object. - memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr)); - - // Scale FFT coefficients. - for(n = 0; n < FRAMESAMPLES_HALF; n++) - { - realFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->realFFT[n] * - RCU_TRANSCODING_SCALE_UB + 0.5); - imagFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->imagFFT[n] * - RCU_TRANSCODING_SCALE_UB + 0.5); - } - - switch(bandwidth) - { - case isac12kHz: - { - status = WebRtcIsac_EncodeSpecUB12(realFFT, imagFFT, bitStreamObj); - break; - } - case isac16kHz: - { - status = WebRtcIsac_EncodeSpecUB16(realFFT, imagFFT, bitStreamObj); - break; - } - default: - return -1; - } - - if(status < 0) - { - // error happened - return status; - } - else - { - // terminate entropy coding - return WebRtcIsac_EncTerminate(bitStreamObj); - } -} diff --git a/src/mod/codecs/mod_isac/encode_lpc_swb.c b/src/mod/codecs/mod_isac/encode_lpc_swb.c deleted file mode 100644 index 2bf4c36460..0000000000 --- a/src/mod/codecs/mod_isac/encode_lpc_swb.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * code_LPC_UB.c - * - * This file contains definition of functions used to - * encode LPC parameters (Shape & gain) of the upper band. - * - */ - -#include "encode_lpc_swb.h" -#include "typedefs.h" -#include "settings.h" - -#include "lpc_shape_swb12_tables.h" -#include "lpc_shape_swb16_tables.h" -#include "lpc_gain_swb_tables.h" - -#include -#include -#include - -/****************************************************************************** - * WebRtcIsac_RemoveLarMean() - * - * Remove the means from LAR coefficients. - * - * Input: - * -lar : pointer to lar vectors. LAR vectors are - * concatenated. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -lar : pointer to mean-removed LAR:s. - * - * - */ -WebRtc_Word16 -WebRtcIsac_RemoveLarMean( - double* lar, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 coeffCntr; - WebRtc_Word16 vecCntr; - WebRtc_Word16 numVec; - const double* meanLAR; - switch(bandwidth) - { - case isac12kHz: - { - numVec = UB_LPC_VEC_PER_FRAME; - meanLAR = WebRtcIsac_kMeanLarUb12; - break; - } - case isac16kHz: - { - numVec = UB16_LPC_VEC_PER_FRAME; - meanLAR = WebRtcIsac_kMeanLarUb16; - break; - } - default: - return -1; - } - - for(vecCntr = 0; vecCntr < numVec; vecCntr++) - { - for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) - { - // REMOVE MEAN - *lar++ -= meanLAR[coeffCntr]; - } - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_DecorrelateIntraVec() - * - * Remove the correlation amonge the components of LAR vectors. If LAR vectors - * of one frame are put in a matrix where each column is a LAR vector of a - * sub-frame, then this is equivalent to multiplying the LAR matrix with - * a decorrelting mtrix from left. - * - * Input: - * -inLar : pointer to mean-removed LAR vecrtors. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : decorrelated LAR vectors. - */ -WebRtc_Word16 -WebRtcIsac_DecorrelateIntraVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth) -{ - const double* ptrData; - const double* ptrRow; - WebRtc_Word16 rowCntr; - WebRtc_Word16 colCntr; - WebRtc_Word16 larVecCntr; - WebRtc_Word16 numVec; - const double* decorrMat; - switch(bandwidth) - { - case isac12kHz: - { - decorrMat = &WebRtcIsac_kIntraVecDecorrMatUb12[0][0]; - numVec = UB_LPC_VEC_PER_FRAME; - break; - } - case isac16kHz: - { - decorrMat = &WebRtcIsac_kIintraVecDecorrMatUb16[0][0]; - numVec = UB16_LPC_VEC_PER_FRAME; - break; - } - default: - return -1; - } - - // - // decorrMat * data - // - // data is assumed to contain 'numVec' of LAR - // vectors (mean removed) each of dimension 'UB_LPC_ORDER' - // concatenated one after the other. - // - - ptrData = data; - for(larVecCntr = 0; larVecCntr < numVec; larVecCntr++) - { - for(rowCntr = 0; rowCntr < UB_LPC_ORDER; rowCntr++) - { - ptrRow = &decorrMat[rowCntr * UB_LPC_ORDER]; - *out = 0; - for(colCntr = 0; colCntr < UB_LPC_ORDER; colCntr++) - { - *out += ptrData[colCntr] * ptrRow[colCntr]; - } - out++; - } - ptrData += UB_LPC_ORDER; - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_DecorrelateInterVec() - * - * Remover the correlation among mean-removed LAR vectors. If LAR vectors - * of one frame are put in a matrix where each column is a LAR vector of a - * sub-frame, then this is equivalent to multiplying the LAR matrix with - * a decorrelting mtrix from right. - * - * Input: - * -data : pointer to matrix of LAR vectors. The matrix - * is stored column-wise. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : decorrelated LAR vectors. - */ -WebRtc_Word16 -WebRtcIsac_DecorrelateInterVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 coeffCntr; - WebRtc_Word16 rowCntr; - WebRtc_Word16 colCntr; - const double* decorrMat; - WebRtc_Word16 interVecDim; - - switch(bandwidth) - { - case isac12kHz: - { - decorrMat = &WebRtcIsac_kInterVecDecorrMatUb12[0][0]; - interVecDim = UB_LPC_VEC_PER_FRAME; - break; - } - case isac16kHz: - { - decorrMat = &WebRtcIsac_kInterVecDecorrMatUb16[0][0]; - interVecDim = UB16_LPC_VEC_PER_FRAME; - break; - } - default: - return -1; - } - - // - // data * decorrMat - // - // data is of size 'interVecDim' * 'UB_LPC_ORDER' - // That is 'interVecDim' of LAR vectors (mean removed) - // in columns each of dimension 'UB_LPC_ORDER'. - // matrix is stored column-wise. - // - - for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) - { - for(colCntr = 0; colCntr < interVecDim; colCntr++) - { - out[coeffCntr + colCntr * UB_LPC_ORDER] = 0; - for(rowCntr = 0; rowCntr < interVecDim; rowCntr++) - { - out[coeffCntr + colCntr * UB_LPC_ORDER] += - data[coeffCntr + rowCntr * UB_LPC_ORDER] * - decorrMat[rowCntr * interVecDim + colCntr]; - } - } - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_QuantizeUncorrLar() - * - * Quantize the uncorrelated parameters. - * - * Input: - * -data : uncorrelated LAR vectors. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -data : quantized version of the input. - * -idx : pointer to quantization indices. - */ -double -WebRtcIsac_QuantizeUncorrLar( - double* data, - int* recIdx, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 cntr; - WebRtc_Word32 idx; - WebRtc_Word16 interVecDim; - const double* leftRecPoint; - double quantizationStepSize; - const WebRtc_Word16* numQuantCell; - switch(bandwidth) - { - case isac12kHz: - { - leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb12; - quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb12; - numQuantCell = WebRtcIsac_kLpcShapeNumRecPointUb12; - interVecDim = UB_LPC_VEC_PER_FRAME; - break; - } - case isac16kHz: - { - leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb16; - quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb16; - numQuantCell = WebRtcIsac_kLpcShapeNumRecPointUb16; - interVecDim = UB16_LPC_VEC_PER_FRAME; - break; - } - default: - return -1; - } - - // - // Quantize the parametrs. - // - for(cntr = 0; cntr < UB_LPC_ORDER * interVecDim; cntr++) - { - idx = (WebRtc_Word32)floor((*data - leftRecPoint[cntr]) / - quantizationStepSize + 0.5); - if(idx < 0) - { - idx = 0; - } - else if(idx >= numQuantCell[cntr]) - { - idx = numQuantCell[cntr] - 1; - } - - *data++ = leftRecPoint[cntr] + idx * quantizationStepSize; - *recIdx++ = idx; - } - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_DequantizeLpcParam() - * - * Get the quantized value of uncorrelated LARs given the quantization indices. - * - * Input: - * -idx : pointer to quantiztion indices. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : pointer to quantized values. - */ -WebRtc_Word16 -WebRtcIsac_DequantizeLpcParam( - const int* idx, - double* out, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 cntr; - WebRtc_Word16 interVecDim; - const double* leftRecPoint; - double quantizationStepSize; - - switch(bandwidth) - { - case isac12kHz: - { - leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb12; - quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb12; - interVecDim = UB_LPC_VEC_PER_FRAME; - break; - } - case isac16kHz: - { - leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb16; - quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb16; - interVecDim = UB16_LPC_VEC_PER_FRAME; - break; - } - default: - return -1; - } - - // - // Dequantize given the quantization indices - // - - for(cntr = 0; cntr < UB_LPC_ORDER * interVecDim; cntr++) - { - *out++ = leftRecPoint[cntr] + *idx++ * quantizationStepSize; - } - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_CorrelateIntraVec() - * - * This is the inverse of WebRtcIsac_DecorrelateIntraVec(). - * - * Input: - * -data : uncorrelated parameters. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : correlated parametrs. - */ -WebRtc_Word16 -WebRtcIsac_CorrelateIntraVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 vecCntr; - WebRtc_Word16 rowCntr; - WebRtc_Word16 colCntr; - WebRtc_Word16 numVec; - const double* ptrData; - const double* intraVecDecorrMat; - - switch(bandwidth) - { - case isac12kHz: - { - numVec = UB_LPC_VEC_PER_FRAME; - intraVecDecorrMat = &WebRtcIsac_kIntraVecDecorrMatUb12[0][0]; - break; - } - case isac16kHz: - { - numVec = UB16_LPC_VEC_PER_FRAME; - intraVecDecorrMat = &WebRtcIsac_kIintraVecDecorrMatUb16[0][0]; - break; - } - default: - return -1; - } - - - ptrData = data; - for(vecCntr = 0; vecCntr < numVec; vecCntr++) - { - for(colCntr = 0; colCntr < UB_LPC_ORDER; colCntr++) - { - *out = 0; - for(rowCntr = 0; rowCntr < UB_LPC_ORDER; rowCntr++) - { - *out += ptrData[rowCntr] * - intraVecDecorrMat[rowCntr * UB_LPC_ORDER + colCntr]; - } - out++; - } - ptrData += UB_LPC_ORDER; - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_CorrelateInterVec() - * - * This is the inverse of WebRtcIsac_DecorrelateInterVec(). - * - * Input: - * -data - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : correlated parametrs. - */ -WebRtc_Word16 -WebRtcIsac_CorrelateInterVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 coeffCntr; - WebRtc_Word16 rowCntr; - WebRtc_Word16 colCntr; - WebRtc_Word16 interVecDim; - double myVec[UB16_LPC_VEC_PER_FRAME]; - const double* interVecDecorrMat; - - switch(bandwidth) - { - case isac12kHz: - { - interVecDim = UB_LPC_VEC_PER_FRAME; - interVecDecorrMat = &WebRtcIsac_kInterVecDecorrMatUb12[0][0]; - break; - } - case isac16kHz: - { - interVecDim = UB16_LPC_VEC_PER_FRAME; - interVecDecorrMat = &WebRtcIsac_kInterVecDecorrMatUb16[0][0]; - break; - } - default: - return -1; - } - - for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) - { - for(rowCntr = 0; rowCntr < interVecDim; rowCntr++) - { - myVec[rowCntr] = 0; - for(colCntr = 0; colCntr < interVecDim; colCntr++) - { - myVec[rowCntr] += data[coeffCntr + colCntr * UB_LPC_ORDER] * //*ptrData * - interVecDecorrMat[rowCntr * interVecDim + colCntr]; - //ptrData += UB_LPC_ORDER; - } - } - - for(rowCntr = 0; rowCntr < interVecDim; rowCntr++) - { - out[coeffCntr + rowCntr * UB_LPC_ORDER] = myVec[rowCntr]; - } - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_AddLarMean() - * - * This is the inverse of WebRtcIsac_RemoveLarMean() - * - * Input: - * -data : pointer to mean-removed LAR:s. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -data : pointer to LARs. - */ -WebRtc_Word16 -WebRtcIsac_AddLarMean( - double* data, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 coeffCntr; - WebRtc_Word16 vecCntr; - WebRtc_Word16 numVec; - const double* meanLAR; - - switch(bandwidth) - { - case isac12kHz: - { - numVec = UB_LPC_VEC_PER_FRAME; - meanLAR = WebRtcIsac_kMeanLarUb12; - break; - } - case isac16kHz: - { - numVec = UB16_LPC_VEC_PER_FRAME; - meanLAR = WebRtcIsac_kMeanLarUb16; - break; - } - default: - return -1; - } - - for(vecCntr = 0; vecCntr < numVec; vecCntr++) - { - for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) - { - *data++ += meanLAR[coeffCntr]; - } - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_ToLogDomainRemoveMean() - * - * Transform the LPC gain to log domain then remove the mean value. - * - * Input: - * -lpcGain : pointer to LPC Gain, expecting 6 LPC gains - * - * Output: - * -lpcGain : mean-removed in log domain. - */ -WebRtc_Word16 -WebRtcIsac_ToLogDomainRemoveMean( - double* data) -{ - WebRtc_Word16 coeffCntr; - for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++) - { - data[coeffCntr] = log(data[coeffCntr]) - WebRtcIsac_kMeanLpcGain; - } - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_DecorrelateLPGain() - * - * Decorrelate LPC gains. There are 6 LPC Gains per frame. This is like - * multiplying gain vector with decorrelating matrix. - * - * Input: - * -data : LPC gain in log-domain with mean removed. - * - * Output: - * -out : decorrelated parameters. - */ -WebRtc_Word16 WebRtcIsac_DecorrelateLPGain( - const double* data, - double* out) -{ - WebRtc_Word16 rowCntr; - WebRtc_Word16 colCntr; - - for(colCntr = 0; colCntr < UB_LPC_GAIN_DIM; colCntr++) - { - *out = 0; - for(rowCntr = 0; rowCntr < UB_LPC_GAIN_DIM; rowCntr++) - { - *out += data[rowCntr] * WebRtcIsac_kLpcGainDecorrMat[rowCntr][colCntr]; - } - out++; - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_QuantizeLpcGain() - * - * Quantize the decorrelated log-domain gains. - * - * Input: - * -lpcGain : uncorrelated LPC gains. - * - * Output: - * -idx : quantization indices - * -lpcGain : quantized value of the inpt. - */ -double WebRtcIsac_QuantizeLpcGain( - double* data, - int* idx) -{ - WebRtc_Word16 coeffCntr; - for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++) - { - *idx = (int)floor((*data - WebRtcIsac_kLeftRecPointLpcGain[coeffCntr]) / - WebRtcIsac_kQSizeLpcGain + 0.5); - - if(*idx < 0) - { - *idx = 0; - } - else if(*idx >= WebRtcIsac_kNumQCellLpcGain[coeffCntr]) - { - *idx = WebRtcIsac_kNumQCellLpcGain[coeffCntr] - 1; - } - *data = WebRtcIsac_kLeftRecPointLpcGain[coeffCntr] + *idx * - WebRtcIsac_kQSizeLpcGain; - - data++; - idx++; - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_DequantizeLpcGain() - * - * Get the quantized values given the quantization indices. - * - * Input: - * -idx : pointer to quantization indices. - * - * Output: - * -lpcGains : quantized values of the given parametes. - */ -WebRtc_Word16 WebRtcIsac_DequantizeLpcGain( - const int* idx, - double* out) -{ - WebRtc_Word16 coeffCntr; - for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++) - { - *out = WebRtcIsac_kLeftRecPointLpcGain[coeffCntr] + *idx * - WebRtcIsac_kQSizeLpcGain; - out++; - idx++; - } - return 0; -} - -/****************************************************************************** - * WebRtcIsac_CorrelateLpcGain() - * - * This is the inverse of WebRtcIsac_DecorrelateLPGain(). - * - * Input: - * -data : decorrelated parameters. - * - * Output: - * -out : correlated parameters. - */ -WebRtc_Word16 WebRtcIsac_CorrelateLpcGain( - const double* data, - double* out) -{ - WebRtc_Word16 rowCntr; - WebRtc_Word16 colCntr; - - for(rowCntr = 0; rowCntr < UB_LPC_GAIN_DIM; rowCntr++) - { - *out = 0; - for(colCntr = 0; colCntr < UB_LPC_GAIN_DIM; colCntr++) - { - *out += WebRtcIsac_kLpcGainDecorrMat[rowCntr][colCntr] * data[colCntr]; - } - out++; - } - - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_AddMeanToLinearDomain() - * - * This is the inverse of WebRtcIsac_ToLogDomainRemoveMean(). - * - * Input: - * -lpcGain : LPC gain in log-domain & mean removed - * - * Output: - * -lpcGain : LPC gain in normal domain. - */ -WebRtc_Word16 WebRtcIsac_AddMeanToLinearDomain( - double* lpcGains) -{ - WebRtc_Word16 coeffCntr; - for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++) - { - lpcGains[coeffCntr] = exp(lpcGains[coeffCntr] + WebRtcIsac_kMeanLpcGain); - } - return 0; -} diff --git a/src/mod/codecs/mod_isac/encode_lpc_swb.h b/src/mod/codecs/mod_isac/encode_lpc_swb.h deleted file mode 100644 index 84c7ec0d26..0000000000 --- a/src/mod/codecs/mod_isac/encode_lpc_swb.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * encode_lpc_swb.h - * - * This file contains declaration of functions used to - * encode LPC parameters (Shape & gain) of the upper band. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_ - -#include "typedefs.h" -#include "settings.h" -#include "structs.h" - - -/****************************************************************************** - * WebRtcIsac_RemoveLarMean() - * - * Remove the means from LAR coefficients. - * - * Input: - * -lar : pointer to lar vectors. LAR vectors are - * concatenated. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -lar : pointer to mean-removed LAR:s. - * - * - */ -WebRtc_Word16 WebRtcIsac_RemoveLarMean( - double* lar, - WebRtc_Word16 bandwidth); - -/****************************************************************************** - * WebRtcIsac_DecorrelateIntraVec() - * - * Remove the correlation amonge the components of LAR vectors. If LAR vectors - * of one frame are put in a matrix where each column is a LAR vector of a - * sub-frame, then this is equivalent to multiplying the LAR matrix with - * a decorrelting mtrix from left. - * - * Input: - * -inLar : pointer to mean-removed LAR vecrtors. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : decorrelated LAR vectors. - */ -WebRtc_Word16 WebRtcIsac_DecorrelateIntraVec( - const double* inLAR, - double* out, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_DecorrelateInterVec() - * - * Remover the correlation among mean-removed LAR vectors. If LAR vectors - * of one frame are put in a matrix where each column is a LAR vector of a - * sub-frame, then this is equivalent to multiplying the LAR matrix with - * a decorrelting mtrix from right. - * - * Input: - * -data : pointer to matrix of LAR vectors. The matrix - * is stored column-wise. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : decorrelated LAR vectors. - */ -WebRtc_Word16 WebRtcIsac_DecorrelateInterVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_QuantizeUncorrLar() - * - * Quantize the uncorrelated parameters. - * - * Input: - * -data : uncorrelated LAR vectors. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -data : quantized version of the input. - * -idx : pointer to quantization indices. - */ -double WebRtcIsac_QuantizeUncorrLar( - double* data, - int* idx, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_CorrelateIntraVec() - * - * This is the inverse of WebRtcIsac_DecorrelateIntraVec(). - * - * Input: - * -data : uncorrelated parameters. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : correlated parametrs. - */ -WebRtc_Word16 WebRtcIsac_CorrelateIntraVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_CorrelateInterVec() - * - * This is the inverse of WebRtcIsac_DecorrelateInterVec(). - * - * Input: - * -data - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : correlated parametrs. - */ -WebRtc_Word16 WebRtcIsac_CorrelateInterVec( - const double* data, - double* out, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_AddLarMean() - * - * This is the inverse of WebRtcIsac_RemoveLarMean() - * - * Input: - * -data : pointer to mean-removed LAR:s. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -data : pointer to LARs. - */ -WebRtc_Word16 WebRtcIsac_AddLarMean( - double* data, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_DequantizeLpcParam() - * - * Get the quantized value of uncorrelated LARs given the quantization indices. - * - * Input: - * -idx : pointer to quantiztion indices. - * -bandwidth : indicates if the given LAR vectors belong - * to SWB-12kHz or SWB-16kHz. - * - * Output: - * -out : pointer to quantized values. - */ -WebRtc_Word16 WebRtcIsac_DequantizeLpcParam( - const int* idx, - double* out, - WebRtc_Word16 bandwidth); - - -/****************************************************************************** - * WebRtcIsac_ToLogDomainRemoveMean() - * - * Transform the LPC gain to log domain then remove the mean value. - * - * Input: - * -lpcGain : pointer to LPC Gain, expecting 6 LPC gains - * - * Output: - * -lpcGain : mean-removed in log domain. - */ -WebRtc_Word16 WebRtcIsac_ToLogDomainRemoveMean( - double* lpGains); - - -/****************************************************************************** - * WebRtcIsac_DecorrelateLPGain() - * - * Decorrelate LPC gains. There are 6 LPC Gains per frame. This is like - * multiplying gain vector with decorrelating matrix. - * - * Input: - * -data : LPC gain in log-domain with mean removed. - * - * Output: - * -out : decorrelated parameters. - */ -WebRtc_Word16 WebRtcIsac_DecorrelateLPGain( - const double* data, - double* out); - - -/****************************************************************************** - * WebRtcIsac_QuantizeLpcGain() - * - * Quantize the decorrelated log-domain gains. - * - * Input: - * -lpcGain : uncorrelated LPC gains. - * - * Output: - * -idx : quantization indices - * -lpcGain : quantized value of the inpt. - */ -double WebRtcIsac_QuantizeLpcGain( - double* lpGains, - int* idx); - - -/****************************************************************************** - * WebRtcIsac_DequantizeLpcGain() - * - * Get the quantized values given the quantization indices. - * - * Input: - * -idx : pointer to quantization indices. - * - * Output: - * -lpcGains : quantized values of the given parametes. - */ -WebRtc_Word16 WebRtcIsac_DequantizeLpcGain( - const int* idx, - double* lpGains); - - -/****************************************************************************** - * WebRtcIsac_CorrelateLpcGain() - * - * This is the inverse of WebRtcIsac_DecorrelateLPGain(). - * - * Input: - * -data : decorrelated parameters. - * - * Output: - * -out : correlated parameters. - */ -WebRtc_Word16 WebRtcIsac_CorrelateLpcGain( - const double* data, - double* out); - - -/****************************************************************************** - * WebRtcIsac_AddMeanToLinearDomain() - * - * This is the inverse of WebRtcIsac_ToLogDomainRemoveMean(). - * - * Input: - * -lpcGain : LPC gain in log-domain & mean removed - * - * Output: - * -lpcGain : LPC gain in normal domain. - */ -WebRtc_Word16 WebRtcIsac_AddMeanToLinearDomain( - double* lpcGains); - - -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_ diff --git a/src/mod/codecs/mod_isac/energy.c b/src/mod/codecs/mod_isac/energy.c deleted file mode 100644 index e8fdf94e03..0000000000 --- a/src/mod/codecs/mod_isac/energy.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_Energy(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, int vector_length, int* scale_factor) -{ - WebRtc_Word32 en = 0; - int i; - int scaling = WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length); - int looptimes = vector_length; - WebRtc_Word16 *vectorptr = vector; - - for (i = 0; i < looptimes; i++) - { - en += WEBRTC_SPL_MUL_16_16_RSFT(*vectorptr, *vectorptr, scaling); - vectorptr++; - } - *scale_factor = scaling; - - return en; -} diff --git a/src/mod/codecs/mod_isac/entropy_coding.c b/src/mod/codecs/mod_isac/entropy_coding.c deleted file mode 100644 index 13b6cf7e86..0000000000 --- a/src/mod/codecs/mod_isac/entropy_coding.c +++ /dev/null @@ -1,2748 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * entropy_coding.c - * - * This header file defines all of the functions used to arithmetically - * encode the iSAC bistream - * - */ - - -#include "entropy_coding.h" -#include "settings.h" -#include "arith_routines.h" -#include "signal_processing_library.h" -#include "spectrum_ar_model_tables.h" -#include "lpc_tables.h" -#include "pitch_gain_tables.h" -#include "pitch_lag_tables.h" -#include "encode_lpc_swb.h" -#include "lpc_shape_swb12_tables.h" -#include "lpc_shape_swb16_tables.h" -#include "lpc_gain_swb_tables.h" -#include "os_specific_inline.h" - -#include -#include - -static const WebRtc_UWord16 kLpcVecPerSegmentUb12 = 5; -static const WebRtc_UWord16 kLpcVecPerSegmentUb16 = 4; - -/* coefficients for the stepwise rate estimation */ -static const WebRtc_Word32 kRPointsQ10[100] = { - 14495, 14295, 14112, 13944, 13788, 13643, 13459, 13276, 13195, 13239, - 13243, 13191, 13133, 13216, 13263, 13330, 13316, 13242, 13191, 13106, - 12942, 12669, 12291, 11840, 11361, 10795, 10192, 9561, 8934, 8335, - 7750, 7161, 6589, 6062, 5570, 5048, 4548, 4069, 3587, 3143, - 2717, 2305, 1915, 1557, 1235, 963, 720, 541, 423, 366, - 369, 435, 561, 750, 1001, 1304, 1626, 1989, 2381, 2793, - 3219, 3656, 4134, 4612, 5106, 5629, 6122, 6644, 7216, 7801, - 8386, 8987, 9630, 10255, 10897, 11490, 11950, 12397, 12752, 12999, - 13175, 13258, 13323, 13290, 13296, 13335, 13113, 13255, 13347, 13355, - 13298, 13247, 13313, 13155, 13267, 13313, 13374, 13446, 13525, 13609}; - - -/* cdf array for encoder bandwidth (12 vs 16 kHz) indicator */ -static const WebRtc_UWord16 kOneBitEqualProbCdf[3] = { - 0, 32768, 65535 }; - -/* pointer to cdf array for encoder bandwidth (12 vs 16 kHz) indicator */ -static const WebRtc_UWord16 *kOneBitEqualProbCdf_ptr[1] = { - kOneBitEqualProbCdf }; - -/* initial cdf index for decoder of encoded bandwidth (12 vs 16 kHz) indicator */ -static const WebRtc_UWord16 kOneBitEqualProbInitIndex[1] = {1}; - - -/* coefficients for the stepwise rate estimation */ - - -static const WebRtc_Word32 acnQ10 = 426; -static const WebRtc_Word32 bcnQ10 = -581224; -static const WebRtc_Word32 ccnQ10 = 722631; -static const WebRtc_Word32 lbcnQ10 = -402874; -#define DPMIN_Q10 -10240 // -10.00 in Q10 -#define DPMAX_Q10 10240 // 10.00 in Q10 -#define MINBITS_Q10 10240 /* 10.0 in Q10 */ -#define IS_SWB_12KHZ 1 - -__inline WebRtc_UWord32 stepwise(WebRtc_Word32 dinQ10) { - - WebRtc_Word32 ind, diQ10, dtQ10; - - diQ10 = dinQ10; - if (diQ10 < DPMIN_Q10) - diQ10 = DPMIN_Q10; - if (diQ10 >= DPMAX_Q10) - diQ10 = DPMAX_Q10 - 1; - - dtQ10 = diQ10 - DPMIN_Q10; /* Q10 + Q10 = Q10 */ - ind = (dtQ10 * 5) >> 10; /* 2^10 / 5 = 0.2 in Q10 */ - /* Q10 -> Q0 */ - - return kRPointsQ10[ind]; -} - - -__inline short log2_Q10_B( int x ) -{ - int zeros; - short frac; - - zeros = WebRtcSpl_NormU32( x ); - frac = ((unsigned int)(x << zeros) & 0x7FFFFFFF) >> 21; - return (short) (((31 - zeros) << 10) + frac); -} - - - -/* compute correlation from power spectrum */ -static void WebRtcIsac_FindCorrelation(WebRtc_Word32 *PSpecQ12, WebRtc_Word32 *CorrQ7) -{ - WebRtc_Word32 summ[FRAMESAMPLES/8]; - WebRtc_Word32 diff[FRAMESAMPLES/8]; - const WebRtc_Word16 *CS_ptrQ9; - WebRtc_Word32 sum; - int k, n; - - for (k = 0; k < FRAMESAMPLES/8; k++) { - summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES_QUARTER-1 - k] + 16) >> 5; - diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES_QUARTER-1 - k] + 16) >> 5; - } - - sum = 2; - for (n = 0; n < FRAMESAMPLES/8; n++) - sum += summ[n]; - CorrQ7[0] = sum; - - for (k = 0; k < AR_ORDER; k += 2) { - sum = 0; - CS_ptrQ9 = WebRtcIsac_kCos[k]; - for (n = 0; n < FRAMESAMPLES/8; n++) - sum += (CS_ptrQ9[n] * diff[n] + 256) >> 9; - CorrQ7[k+1] = sum; - } - - for (k=1; k> 9; - CorrQ7[k+1] = sum; - } -} - -/* compute inverse AR power spectrum */ -/* Changed to the function used in iSAC FIX for compatibility reasons */ -static void WebRtcIsac_FindInvArSpec(const WebRtc_Word16 *ARCoefQ12, - const WebRtc_Word32 gainQ10, - WebRtc_Word32 *CurveQ16) -{ - WebRtc_Word32 CorrQ11[AR_ORDER+1]; - WebRtc_Word32 sum, tmpGain; - WebRtc_Word32 diffQ16[FRAMESAMPLES/8]; - const WebRtc_Word16 *CS_ptrQ9; - int k, n; - WebRtc_Word16 round, shftVal = 0, sh; - - sum = 0; - for (n = 0; n < AR_ORDER+1; n++) - sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ - sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ - CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); - - /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ - if(gainQ10>400000){ - tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); - round = 32; - shftVal = 6; - } else { - tmpGain = gainQ10; - round = 256; - shftVal = 9; - } - - for (k = 1; k < AR_ORDER+1; k++) { - sum = 16384; - for (n = k; n < AR_ORDER+1; n++) - sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ - sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); - CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); - } - sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); - for (n = 0; n < FRAMESAMPLES/8; n++) - CurveQ16[n] = sum; - - for (k = 1; k < AR_ORDER; k += 2) { - //CS_ptrQ9 = WebRtcIsac_kCos[k]; - for (n = 0; n < FRAMESAMPLES/8; n++) - CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32( - WEBRTC_SPL_MUL(WebRtcIsac_kCos[k][n], CorrQ11[k+1]) + 2, 2); - } - - CS_ptrQ9 = WebRtcIsac_kCos[0]; - - /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ - sh=WebRtcSpl_NormW32(CorrQ11[1]); - if (CorrQ11[1]==0) /* Use next correlation */ - sh=WebRtcSpl_NormW32(CorrQ11[2]); - - if (sh<9) - shftVal = 9 - sh; - else - shftVal = 0; - - for (n = 0; n < FRAMESAMPLES/8; n++) - diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); - for (k = 2; k < AR_ORDER; k += 2) { - CS_ptrQ9 = WebRtcIsac_kCos[k]; - for (n = 0; n < FRAMESAMPLES/8; n++) - diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); - } - - for (k=0; k>25); // * 128/4294967295 - - /* new random unsigned int */ - seed = (seed * 196314165) + 907633515; - - /* fixed-point dither sample between -64 and 64 */ - dither2_Q7 = (WebRtc_Word16)(((int)seed + 16777216)>>25); - - shft = (seed >> 25) & 15; - if (shft < 5) - { - bufQ7[k] = dither1_Q7; - bufQ7[k+1] = dither2_Q7; - bufQ7[k+2] = 0; - } - else if (shft < 10) - { - bufQ7[k] = dither1_Q7; - bufQ7[k+1] = 0; - bufQ7[k+2] = dither2_Q7; - } - else - { - bufQ7[k] = 0; - bufQ7[k+1] = dither1_Q7; - bufQ7[k+2] = dither2_Q7; - } - } - } - else - { - dither_gain_Q14 = (WebRtc_Word16)(22528 - 10 * AvgPitchGain_Q12); - - /* dither on half of the coefficients */ - for (k = 0; k < length-1; k += 2) - { - /* new random unsigned int */ - seed = (seed * 196314165) + 907633515; - - /* fixed-point dither sample between -64 and 64 */ - dither1_Q7 = (WebRtc_Word16)(((int)seed + 16777216)>>25); - - /* dither sample is placed in either even or odd index */ - shft = (seed >> 25) & 1; /* either 0 or 1 */ - - bufQ7[k + shft] = (((dither_gain_Q14 * dither1_Q7) + 8192)>>14); - bufQ7[k + 1 - shft] = 0; - } - } -} - - - -/****************************************************************************** - * GenerateDitherQ7LbUB() - * - * generate array of dither samples in Q7 There are less zeros in dither - * vector compared to GenerateDitherQ7Lb. - * - * A uniform random number generator with the range of [-64 64] is employed - * but the generated dithers are scaled by 0.35, a heuristic scaling. - * - * Input: - * -seed : the initial seed for the random number generator. - * -length : the number of dither values to be generated. - * - * Output: - * -bufQ7 : pointer to a buffer where dithers are written to. - */ -static void GenerateDitherQ7LbUB( - WebRtc_Word16 *bufQ7, - WebRtc_UWord32 seed, - int length) -{ - int k; - for (k = 0; k < length; k++) { - /* new random unsigned int */ - seed = (seed * 196314165) + 907633515; - - /* fixed-point dither sample between -64 and 64 (Q7) */ - // * 128/4294967295 - bufQ7[k] = (WebRtc_Word16)(((int)seed + 16777216)>>25); - - // scale by 0.35 - bufQ7[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(bufQ7[k], - 2048, 13); - } -} - - - -/* - * function to decode the complex spectrum from the bit stream - * returns the total number of bytes in the stream - */ -int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, - double *fr, - double *fi, - WebRtc_Word16 AvgPitchGain_Q12) -{ - WebRtc_Word16 DitherQ7[FRAMESAMPLES]; - WebRtc_Word16 data[FRAMESAMPLES]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 gainQ10; - WebRtc_Word32 gain2_Q10, res; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - int k, len, i; - - /* create dither signal */ - GenerateDitherQ7Lb(DitherQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); - - /* decode model parameters */ - if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic decoding of spectrum */ - if ((len = WebRtcIsac_DecLogisticMulti2(data, streamdata, invARSpecQ8, DitherQ7, - FRAMESAMPLES, !IS_SWB_12KHZ)) <1) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - /* subtract dither and scale down spectral samples with low SNR */ - if (AvgPitchGain_Q12 <= 614) - { - for (k = 0; k < FRAMESAMPLES; k += 4) - { - gainQ10 = WebRtcSpl_DivW32W16ResW16(30 << 10, - (WebRtc_Word16)((invARSpec2_Q16[k>>2] + (32768 + (33 << 16))) >> 16)); - *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+1] * gainQ10 + 512) >> 10) / 128.0; - *fr++ = (double)((data[k+2] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+3] * gainQ10 + 512) >> 10) / 128.0; - } - } - else - { - for (k = 0; k < FRAMESAMPLES; k += 4) - { - gainQ10 = WebRtcSpl_DivW32W16ResW16(36 << 10, - (WebRtc_Word16)((invARSpec2_Q16[k>>2] + (32768 + (40 << 16))) >> 16)); - *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+1] * gainQ10 + 512) >> 10) / 128.0; - *fr++ = (double)((data[k+2] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+3] * gainQ10 + 512) >> 10) / 128.0; - } - } - - return len; -} - -/****************************************************************************** - * WebRtcIsac_DecodeSpecUB16() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). - * - * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB16( - Bitstr* streamdata, - double* fr, - double* fi) -{ - WebRtc_Word16 DitherQ7[FRAMESAMPLES]; - WebRtc_Word16 data[FRAMESAMPLES]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word32 gain2_Q10, res; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - int k, len, i, j; - - /* create dither signal */ - GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* decode model parameters */ - if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic decoding of spectrum */ - if ((len = WebRtcIsac_DecLogisticMulti2(data, streamdata, invARSpecQ8, - DitherQ7, FRAMESAMPLES, !IS_SWB_12KHZ)) <1) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - /* re-arrange DFT coefficients and scale down */ - for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) - { - fr[j] = (double)data[ k ] / 128.0; - fi[j] = (double)data[k+1] / 128.0; - fr[(FRAMESAMPLES_HALF) - 1 - j] = (double)data[k+2] / 128.0; - fi[(FRAMESAMPLES_HALF) - 1 - j] = (double)data[k+3] / 128.0; - - } - return len; -} - - - - -/****************************************************************************** - * WebRtcIsac_DecodeSpecUB12() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-12 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). - * - * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB12( - Bitstr *streamdata, - double *fr, - double *fi) -{ - WebRtc_Word16 DitherQ7[FRAMESAMPLES]; - WebRtc_Word16 data[FRAMESAMPLES]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word32 res; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - int k, len, i; - - /* create dither signal */ - GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* decode model parameters */ - if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic decoding of spectrum */ - if ((len = WebRtcIsac_DecLogisticMulti2(data, streamdata, - invARSpecQ8, DitherQ7, (FRAMESAMPLES_HALF), IS_SWB_12KHZ)) < 1) - { - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - } - - for (k = 0, i = 0; k < FRAMESAMPLES_HALF; k += 4) - { - fr[i] = (double)data[ k ] / 128.0; - fi[i] = (double)data[k+1] / 128.0; - i++; - fr[i] = (double)data[k+2] / 128.0; - fi[i] = (double)data[k+3] / 128.0; - i++; - } - - // The second half of real and imaginary coefficients is zero. This is - // due to using the old FFT module which requires two signals as input - // while in 0-12 kHz mode we only have 8-12 kHz band, and the second signal - // is set to zero - memset(&fr[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * sizeof(double)); - memset(&fi[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * sizeof(double)); - - return len; -} - - - - - -int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16 *fr, - const WebRtc_Word16 *fi, - Bitstr *streamdata, - WebRtc_Word16 AvgPitchGain_Q12) -{ - WebRtc_Word16 ditherQ7[FRAMESAMPLES]; - WebRtc_Word16 dataQ7[FRAMESAMPLES]; - WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 CorrQ7[AR_ORDER+1]; - WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word16 val; - WebRtc_Word32 nrg, res; - WebRtc_UWord32 sum; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - WebRtc_Word16 err; - WebRtc_UWord32 nrg_u32; - int shift_var; - int k, n, j, i; - - - /* create dither_float signal */ - GenerateDitherQ7Lb(ditherQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); - - /* add dither and quantize, and compute power spectrum */ - for (k = 0; k < FRAMESAMPLES; k += 4) - { - val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; - dataQ7[k] = val; - sum = val * val; - - val = ((*fi++ + ditherQ7[k+1] + 64) & 0xFF80) - ditherQ7[k+1]; - dataQ7[k+1] = val; - sum += val * val; - - val = ((*fr++ + ditherQ7[k+2] + 64) & 0xFF80) - ditherQ7[k+2]; - dataQ7[k+2] = val; - sum += val * val; - - val = ((*fi++ + ditherQ7[k+3] + 64) & 0xFF80) - ditherQ7[k+3]; - dataQ7[k+3] = val; - sum += val * val; - - PSpec[k>>2] = sum >> 2; - } - - /* compute correlation from power spectrum */ - WebRtcIsac_FindCorrelation(PSpec, CorrQ7); - - - /* find AR coefficients */ - /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */ - shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; - - if (shift_var > 0) { - for (k=0; k> (-shift_var); - } - } - - /* find RC coefficients */ - WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); - - /* quantize & code RC Coefficient */ - WebRtcIsac_EncodeRc(RCQ15, streamdata); - - /* RC -> AR coefficients */ - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - /* compute ARCoef' * Corr * ARCoef in Q19 */ - nrg = 0; - for (j = 0; j <= AR_ORDER; j++) { - for (n = 0; n <= j; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[j-n] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3; - } - for (n = j+1; n <= AR_ORDER; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3; - } - } - - nrg_u32 = (WebRtc_UWord32)nrg; - if (shift_var > 0) { - nrg_u32 = nrg_u32 >> shift_var; - } else { - nrg_u32 = nrg_u32 << (-shift_var); - } - - if (nrg_u32 > 0x7FFFFFFF) - nrg = 0x7FFFFFFF; - else - nrg = (WebRtc_Word32)nrg_u32; - - gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); /* also shifts 31 bits to the left! */ - - /* quantize & code gain2_Q10 */ - if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { - return -1; - } - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic coding of spectrum */ - err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, - FRAMESAMPLES, !IS_SWB_12KHZ); - if (err < 0) - { - return (err); - } - - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_EncodeSpecUB16() - * Quantize and encode real and imaginary part of the DFT coefficients. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The real and imaginary part are computed by calling WebRtcIsac_Time2Spec(). - * - * - * Input: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are stored. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are stored. - * - * Output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_EncodeSpecUB16( - const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata) -{ - WebRtc_Word16 ditherQ7[FRAMESAMPLES]; - WebRtc_Word16 dataQ7[FRAMESAMPLES]; - WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 CorrQ7[AR_ORDER+1]; - WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word16 val; - WebRtc_Word32 nrg, res; - WebRtc_UWord32 sum; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - WebRtc_Word16 err; - WebRtc_UWord32 nrg_u32; - int shift_var; - int k, n, j, i; - - /* create dither_float signal */ - GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* add dither and quantize, and compute power spectrum */ - for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) - { - val = ((fr[j] + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; - dataQ7[k] = val; - sum = val * val; - - val = ((fi[j] + ditherQ7[k+1] + 64) & 0xFF80) - ditherQ7[k+1]; - dataQ7[k+1] = val; - sum += val * val; - - val = ((fr[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k+2] + 64) & - 0xFF80) - ditherQ7[k+2]; - dataQ7[k+2] = val; - sum += val * val; - - val = ((fi[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k+3] + 64) & - 0xFF80) - ditherQ7[k+3]; - dataQ7[k+3] = val; - sum += val * val; - - PSpec[k>>2] = sum >> 2; - } - - /* compute correlation from power spectrum */ - WebRtcIsac_FindCorrelation(PSpec, CorrQ7); - - - /* find AR coefficients - number of bit shifts to 14-bit normalize CorrQ7[0] - (leaving room for sign) */ - shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; - - if (shift_var > 0) { - for (k=0; k> (-shift_var); - } - } - - /* find RC coefficients */ - WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); - - /* quantize & code RC Coef */ - WebRtcIsac_EncodeRc(RCQ15, streamdata); - - /* RC -> AR coefficients */ - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - /* compute ARCoef' * Corr * ARCoef in Q19 */ - nrg = 0; - for (j = 0; j <= AR_ORDER; j++) { - for (n = 0; n <= j; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[j-n] * ARCoefQ12[n] + - 256) >> 9) + 4 ) >> 3; - } - for (n = j+1; n <= AR_ORDER; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + - 256) >> 9) + 4 ) >> 3; - } - } - nrg_u32 = (WebRtc_UWord32)nrg; - if (shift_var > 0) { - nrg_u32 = nrg_u32 >> shift_var; - } else { - nrg_u32 = nrg_u32 << (-shift_var); - } - - if (nrg_u32 > 0x7FFFFFFF) - nrg = 0x7FFFFFFF; - else - nrg = (WebRtc_Word32)nrg_u32; - - gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); /* also shifts 31 bits to the left! */ - - /* quantize & code gain2_Q10 */ - if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { - return -1; - } - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic coding of spectrum */ - err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, - FRAMESAMPLES, !IS_SWB_12KHZ); - if (err < 0) - { - return (err); - } - - return 0; -} - - - - -int WebRtcIsac_EncodeSpecUB12(const WebRtc_Word16 *fr, - const WebRtc_Word16 *fi, - Bitstr *streamdata) -{ - WebRtc_Word16 ditherQ7[FRAMESAMPLES]; - WebRtc_Word16 dataQ7[FRAMESAMPLES]; - WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 CorrQ7[AR_ORDER+1]; - WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word16 val; - WebRtc_Word32 nrg, res; - WebRtc_UWord32 sum; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - WebRtc_Word16 err; - int shift_var; - int k, n, j, i; - WebRtc_UWord32 nrg_u32; - - /* create dither_float signal */ - GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* add dither and quantize, and compute power spectrum */ - for (k = 0, j = 0; k < (FRAMESAMPLES_HALF); k += 4) - { - val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; - dataQ7[k] = val; - sum = (val) * (val); - - val = ((*fi++ + ditherQ7[k+1] + 64) & 0xFF80) - ditherQ7[k+1]; - dataQ7[k+1] = val; - sum += (val) * (val); - - if(j < FRAMESAMPLES_QUARTER) - { - PSpec[j] = sum >> 1; - j++; - } - - val = ((*fr++ + ditherQ7[k+2] + 64) & 0xFF80) - ditherQ7[k+2]; - dataQ7[k+2] = val; - sum = (val) * (val); - - val = ((*fi++ + ditherQ7[k+3] + 64) & 0xFF80) - ditherQ7[k+3]; - dataQ7[k+3] = val; - sum += (val) * (val); - - if(j < FRAMESAMPLES_QUARTER) - { - PSpec[j] = sum >> 1; - j++; - } - } - /* compute correlation from power spectrum */ - WebRtcIsac_FindCorrelation(PSpec, CorrQ7); - - - /* find AR coefficients */ - /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */ - shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; - - if (shift_var > 0) { - for (k=0; k> (-shift_var); - } - } - - /* find RC coefficients */ - WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); - - /* quantize & code RC Coef */ - WebRtcIsac_EncodeRc(RCQ15, streamdata); - - - /* RC -> AR coefficients */ - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - - /* compute ARCoef' * Corr * ARCoef in Q19 */ - nrg = 0; - for (j = 0; j <= AR_ORDER; j++) { - for (n = 0; n <= j; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[j-n] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3; - } - for (n = j+1; n <= AR_ORDER; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3; - } - } - - nrg_u32 = (WebRtc_UWord32)nrg; - if (shift_var > 0) { - nrg_u32 = nrg_u32 >> shift_var; - } else { - nrg_u32 = nrg_u32 << (-shift_var); - } - - if (nrg_u32 > 0x7FFFFFFF) { - nrg = 0x7FFFFFFF; - } else { - nrg = (WebRtc_Word32)nrg_u32; - } - - gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); /* also shifts 31 bits to the left! */ - - /* quantize & code gain2_Q10 */ - if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { - return -1; - } - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic coding of spectrum */ - err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, - (FRAMESAMPLES_HALF), IS_SWB_12KHZ); - if (err < 0) - { - return (err); - } - - return 0; -} - - - -/* step-up */ -void WebRtcIsac_Rc2Poly(double *RC, int N, double *a) -{ - int m, k; - double tmp[MAX_AR_MODEL_ORDER]; - - a[0] = 1.0; - tmp[0] = 1.0; - for (m=1; m<=N; m++) { - /* copy */ - for (k=1; k0; m--) { - tmp_inv = 1.0 / (1.0 - RC[m]*RC[m]); - for (k=1; k<=m; k++) - tmp[k] = (a[k] - RC[m] * a[m-k+1]) * tmp_inv; - - for (k=1; k WebRtcIsac_kQKltMaxIndGain[k]) - index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; - index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[bmodel][k]+index_g[k]; - pos = WebRtcIsac_kQKltOfLevelsGain[bmodel] + index_ovr_g[k]; - - /* determine number of bits */ - sum = WebRtcIsac_kQKltCodeLenGain[pos]; - Bits += sum; - } - - for (k=0; k WebRtcIsac_kQKltMaxIndShape[k]) - index_s[k] = WebRtcIsac_kQKltMaxIndShape[k]; - index_ovr_s[k] = WebRtcIsac_kQKltOffsetShape[bmodel][k]+index_s[k]; - pos = WebRtcIsac_kQKltOfLevelsShape[bmodel] + index_ovr_s[k]; - sum = WebRtcIsac_kQKltCodeLenShape[pos]; - Bits += sum; - } - - - /* Only one model remains in this version of the code, model = 0 */ - *model=bmodel; - *size=Bits; - - /* entropy coding of model number */ - WebRtcIsac_EncHistMulti(streamdata, model, WebRtcIsac_kQKltModelCdfPtr, 1); - - /* entropy coding of quantization indices - shape only */ - WebRtcIsac_EncHistMulti(streamdata, index_s, WebRtcIsac_kQKltCdfPtrShape[bmodel], KLT_ORDER_SHAPE); - - /* Save data for creation of multiple bit streams */ - encData->LPCmodel[encData->startIdx] = 0; - for (k=0; kLPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_s[k]; - } - - /* find quantization levels for shape coefficients */ - for (k=0; kLPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*encData->startIdx + k] = LPCCoef_lo[k]; - } - for (k=0; k<(ORDERHI+1)*SUBFRAMES; k++) { - encData->LPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*encData->startIdx + k] = LPCCoef_hi[k]; - } -} - - -WebRtc_Word16 -WebRtcIsac_EncodeLpcUB( - double* lpcVecs, - Bitstr* streamdata, - double* interpolLPCCoeff, - WebRtc_Word16 bandwidth, - ISACUBSaveEncDataStruct* encData) -{ - - double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - int idx[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - int interpolCntr; - - WebRtcIsac_Poly2LarUB(lpcVecs, bandwidth); - WebRtcIsac_RemoveLarMean(lpcVecs, bandwidth); - WebRtcIsac_DecorrelateIntraVec(lpcVecs, U, bandwidth); - WebRtcIsac_DecorrelateInterVec(U, lpcVecs, bandwidth); - WebRtcIsac_QuantizeUncorrLar(lpcVecs, idx, bandwidth); - - WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth); - WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth); - WebRtcIsac_AddLarMean(lpcVecs, bandwidth); - - switch(bandwidth) - { - case isac12kHz: - { - // Stor the indices to be used for multiple encoding. - memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME * - sizeof(int)); - WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb12, - UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); - for(interpolCntr = 0; interpolCntr < UB_INTERPOL_SEGMENTS; interpolCntr++) - { - WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, - interpolLPCCoeff, kLpcVecPerSegmentUb12 + 1); - lpcVecs += UB_LPC_ORDER; - interpolLPCCoeff += (kLpcVecPerSegmentUb12 * (UB_LPC_ORDER + 1)); - } - break; - } - case isac16kHz: - { - // Stor the indices to be used for multiple encoding. - memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME * - sizeof(int)); - WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb16, - UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); - for(interpolCntr = 0; interpolCntr < UB16_INTERPOL_SEGMENTS; interpolCntr++) - { - WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, - interpolLPCCoeff, kLpcVecPerSegmentUb16 + 1); - lpcVecs += UB_LPC_ORDER; - interpolLPCCoeff += (kLpcVecPerSegmentUb16 * (UB_LPC_ORDER + 1)); - } - break; - } - default: - return -1; - } - return 0; -} - -void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, int model, Bitstr *streamdata, ISAC_SaveEncData_t* encData) { - - int j, k, n, pos, pos2, posg, offsg, offs2; - int index_g[KLT_ORDER_GAIN]; - int index_ovr_g[KLT_ORDER_GAIN]; - double tmpcoeffs_g[KLT_ORDER_GAIN]; - double tmpcoeffs2_g[KLT_ORDER_GAIN]; - double sum; - - /* log gains, mean removal and scaling */ - posg = 0; - for (k=0; k WebRtcIsac_kQKltMaxIndGain[k]) { - index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; - } - index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[model][k]+index_g[k]; - - /* find quantization levels for coefficients */ - tmpcoeffs_g[WebRtcIsac_kQKltSelIndGain[k]] = WebRtcIsac_kQKltLevelsGain[WebRtcIsac_kQKltOfLevelsGain[model]+index_ovr_g[k]]; - - /* Save data for creation of multiple bit streams */ - encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_g[k]; - } - - - /* entropy coding of quantization indices - gain */ - WebRtcIsac_EncHistMulti(streamdata, index_g, WebRtcIsac_kQKltCdfPtrGain[model], KLT_ORDER_GAIN); - - /* find quantization levels for coefficients */ - - /* left transform */ - offsg = 0; - posg = 0; - for (j=0; j WebRtcIsac_kQArBoundaryLevels[index[k]]) - { - while (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k] + 1]) - index[k]++; - } - else - { - while (RCQ15[k] < WebRtcIsac_kQArBoundaryLevels[--index[k]]) ; - } - - RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]); - } - - - /* entropy coding of quantization indices */ - WebRtcIsac_EncHistMulti(streamdata, index, WebRtcIsac_kQArRcCdfPtr, AR_ORDER); -} - - -/* decode & dequantize squared Gain */ -int WebRtcIsac_DecodeGain2(Bitstr *streamdata, WebRtc_Word32 *gainQ10) -{ - int index, err; - - /* entropy decoding of quantization index */ - err = WebRtcIsac_DecHistOneStepMulti(&index, streamdata, WebRtcIsac_kQGainCdf_ptr, - WebRtcIsac_kQGainInitIndex, 1); - if (err<0) // error check - return err; - - /* find quantization level */ - *gainQ10 = WebRtcIsac_kQGain2Levels[index]; - - return 0; -} - - - -/* quantize & code squared Gain */ -int WebRtcIsac_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr *streamdata) -{ - int index; - - - /* find quantization index */ - index = WebRtcIsac_kQGainInitIndex[0]; - if (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index]) - { - while (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index + 1]) - index++; - } - else - { - while (*gainQ10 < WebRtcIsac_kQGain2BoundaryLevels[--index]) ; - } - - /* dequantize */ - *gainQ10 = WebRtcIsac_kQGain2Levels[index]; - - - /* entropy coding of quantization index */ - WebRtcIsac_EncHistMulti(streamdata, &index, WebRtcIsac_kQGainCdf_ptr, 1); - - return 0; -} - - -/* code and decode Pitch Gains and Lags functions */ - -/* decode & dequantize Pitch Gains */ -int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, WebRtc_Word16 *PitchGains_Q12) -{ - int index_comb, err; - const WebRtc_UWord16 *WebRtcIsac_kQPitchGainCdf_ptr[1]; - - /* entropy decoding of quantization indices */ - *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; - err = WebRtcIsac_DecHistBisectMulti(&index_comb, streamdata, WebRtcIsac_kQPitchGainCdf_ptr, WebRtcIsac_kQCdfTableSizeGain, 1); - /* error check, Q_mean_Gain.. tables are of size 144 */ - if ((err<0) || (index_comb<0) || (index_comb>143)) - return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; - - /* unquantize back to pitch gains by table look-up */ - PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb]; - PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb]; - PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb]; - PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb]; - - return 0; -} - - -/* quantize & code Pitch Gains */ -void WebRtcIsac_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, Bitstr *streamdata, ISAC_SaveEncData_t* encData) -{ - int k,j; - double C; - double S[PITCH_SUBFRAMES]; - int index[3]; - int index_comb; - const WebRtc_UWord16 *WebRtcIsac_kQPitchGainCdf_ptr[1]; - double PitchGains[PITCH_SUBFRAMES] = {0,0,0,0}; - - /* take the asin */ - for (k=0; k WebRtcIsac_kIndexUpperLimitGain[k]) index[k] = WebRtcIsac_kIndexUpperLimitGain[k]; - index[k] -= WebRtcIsac_kIndexLowerLimitGain[k]; - } - - /* calculate unique overall index */ - index_comb = WebRtcIsac_kIndexMultsGain[0] * index[0] + WebRtcIsac_kIndexMultsGain[1] * index[1] + index[2]; - - /* unquantize back to pitch gains by table look-up */ - PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb]; - PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb]; - PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb]; - PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb]; - - /* entropy coding of quantization pitch gains */ - *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; - WebRtcIsac_EncHistMulti(streamdata, &index_comb, WebRtcIsac_kQPitchGainCdf_ptr, 1); - encData->pitchGain_index[encData->startIdx] = index_comb; - -} - - - -/* Pitch LAG */ - - -/* decode & dequantize Pitch Lags */ -int WebRtcIsac_DecodePitchLag(Bitstr *streamdata, WebRtc_Word16 *PitchGain_Q12, double *PitchLags) -{ - int k, err; - double StepSize; - double C; - int index[PITCH_SUBFRAMES]; - double mean_gain; - const double *mean_val2, *mean_val3, *mean_val4; - const WebRtc_Word16 *lower_limit; - const WebRtc_UWord16 *init_index; - const WebRtc_UWord16 *cdf_size; - const WebRtc_UWord16 **cdf; - - //(Y) - double PitchGain[4]={0,0,0,0}; - // - - /* compute mean pitch gain */ - mean_gain = 0.0; - for (k = 0; k < 4; k++) - { - //(Y) - PitchGain[k] = ((float)PitchGain_Q12[k])/4096; - //(Y) - mean_gain += PitchGain[k]; - } - mean_gain /= 4.0; - - /* voicing classificiation */ - if (mean_gain < 0.2) { - StepSize = WebRtcIsac_kQPitchLagStepsizeLo; - cdf = WebRtcIsac_kQPitchLagCdfPtrLo; - cdf_size = WebRtcIsac_kQPitchLagCdfSizeLo; - mean_val2 = WebRtcIsac_kQMeanLag2Lo; - mean_val3 = WebRtcIsac_kQMeanLag3Lo; - mean_val4 = WebRtcIsac_kQMeanLag4Lo; - lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo; - init_index = WebRtcIsac_kQInitIndexLagLo; - } else if (mean_gain < 0.4) { - StepSize = WebRtcIsac_kQPitchLagStepsizeMid; - cdf = WebRtcIsac_kQPitchLagCdfPtrMid; - cdf_size = WebRtcIsac_kQPitchLagCdfSizeMid; - mean_val2 = WebRtcIsac_kQMeanLag2Mid; - mean_val3 = WebRtcIsac_kQMeanLag3Mid; - mean_val4 = WebRtcIsac_kQMeanLag4Mid; - lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid; - init_index = WebRtcIsac_kQInitIndexLagMid; - } else { - StepSize = WebRtcIsac_kQPitchLagStepsizeHi; - cdf = WebRtcIsac_kQPitchLagCdfPtrHi; - cdf_size = WebRtcIsac_kQPitchLagCdfSizeHi; - mean_val2 = WebRtcIsac_kQMeanLag2Hi; - mean_val3 = WebRtcIsac_kQMeanLag3Hi; - mean_val4 = WebRtcIsac_kQMeanLag4Hi; - lower_limit = WebRtcIsac_kQindexLowerLimitLagHi; - init_index = WebRtcIsac_kQInitIndexLagHi; - } - - /* entropy decoding of quantization indices */ - err = WebRtcIsac_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1); - if ((err<0) || (index[0]<0)) // error check - return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; - - err = WebRtcIsac_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3); - if (err<0) // error check - return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; - - - /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ - C = (index[0] + lower_limit[0]) * StepSize; - for (k=0; kmeanGain[encData->startIdx] = mean_gain; - - /* voicing classification */ - if (mean_gain < 0.2) { - StepSize = WebRtcIsac_kQPitchLagStepsizeLo; - cdf = WebRtcIsac_kQPitchLagCdfPtrLo; - mean_val2 = WebRtcIsac_kQMeanLag2Lo; - mean_val3 = WebRtcIsac_kQMeanLag3Lo; - mean_val4 = WebRtcIsac_kQMeanLag4Lo; - lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo; - upper_limit = WebRtcIsac_kQIndexUpperLimitLagLo; - } else if (mean_gain < 0.4) { - StepSize = WebRtcIsac_kQPitchLagStepsizeMid; - cdf = WebRtcIsac_kQPitchLagCdfPtrMid; - mean_val2 = WebRtcIsac_kQMeanLag2Mid; - mean_val3 = WebRtcIsac_kQMeanLag3Mid; - mean_val4 = WebRtcIsac_kQMeanLag4Mid; - lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid; - upper_limit = WebRtcIsac_kQIndexUpperLimitLagMid; - } else { - StepSize = WebRtcIsac_kQPitchLagStepsizeHi; - cdf = WebRtcIsac_kQPitchLagCdfPtrHi; - mean_val2 = WebRtcIsac_kQMeanLag2Hi; - mean_val3 = WebRtcIsac_kQMeanLag3Hi; - mean_val4 = WebRtcIsac_kQMeanLag4Hi; - lower_limit = WebRtcIsac_kQindexLowerLimitLagHi; - upper_limit = WebRtcIsac_kQindexUpperLimitLagHi; - } - - - /* find quantization index */ - for (k=0; k<4; k++) - { - /* transform */ - C = 0.0; - for (j=0; j upper_limit[k]) index[k] = upper_limit[k]; - index[k] -= lower_limit[k]; - - /* Save data for creation of multiple bit streams */ - encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; - } - - /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ - C = (index[0] + lower_limit[0]) * StepSize; - for (k=0; k WebRtcIsac_kQKltMaxIndGain[k]) { - index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; - } - index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[model][k]+index_g[k]; - - /* find quantization levels for coefficients */ - tmpcoeffs_g[WebRtcIsac_kQKltSelIndGain[k]] = WebRtcIsac_kQKltLevelsGain[WebRtcIsac_kQKltOfLevelsGain[model]+index_ovr_g[k]]; - } -} - - -/* decode & dequantize LPC Coef */ -int -WebRtcIsac_DecodeLpcCoefUB( - Bitstr* streamdata, - double* lpcVecs, - double* percepFilterGains, - WebRtc_Word16 bandwidth) -{ - int index_s[KLT_ORDER_SHAPE]; - - double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - int err; - - /* entropy decoding of quantization indices */ - switch(bandwidth) - { - case isac12kHz: - { - err = WebRtcIsac_DecHistOneStepMulti(index_s, streamdata, - WebRtcIsac_kLpcShapeCdfMatUb12, WebRtcIsac_kLpcShapeEntropySearchUb12, - UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); - break; - } - case isac16kHz: - { - err = WebRtcIsac_DecHistOneStepMulti(index_s, streamdata, - WebRtcIsac_kLpcShapeCdfMatUb16, WebRtcIsac_kLpcShapeEntropySearchUb16, - UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); - break; - } - default: - return -1; - } - - if (err<0) // error check - { - return err; - } - - WebRtcIsac_DequantizeLpcParam(index_s, lpcVecs, bandwidth); - WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth); - WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth); - WebRtcIsac_AddLarMean(lpcVecs, bandwidth); - - - WebRtcIsac_DecodeLpcGainUb(percepFilterGains, streamdata); - - if(bandwidth == isac16kHz) - { - // decode another set of Gains - WebRtcIsac_DecodeLpcGainUb(&percepFilterGains[SUBFRAMES], streamdata); - } - - return 0; -} - -WebRtc_Word16 -WebRtcIsac_EncodeBandwidth( - enum ISACBandwidth bandwidth, - Bitstr* streamData) -{ - int bandwidthMode; - switch(bandwidth) - { - case isac12kHz: - { - bandwidthMode = 0; - break; - } - case isac16kHz: - { - bandwidthMode = 1; - break; - } - default: - return -ISAC_DISALLOWED_ENCODER_BANDWIDTH; - } - - WebRtcIsac_EncHistMulti(streamData, &bandwidthMode, - kOneBitEqualProbCdf_ptr, 1); - return 0; -} - -WebRtc_Word16 -WebRtcIsac_DecodeBandwidth( - Bitstr* streamData, - enum ISACBandwidth* bandwidth) -{ - int bandwidthMode; - - if(WebRtcIsac_DecHistOneStepMulti(&bandwidthMode, streamData, - kOneBitEqualProbCdf_ptr, - kOneBitEqualProbInitIndex, 1) < 0) - { - // error check - return -ISAC_RANGE_ERROR_DECODE_BANDWITH; - } - - switch(bandwidthMode) - { - case 0: - { - *bandwidth = isac12kHz; - break; - } - case 1: - { - *bandwidth = isac16kHz; - break; - } - default: - return -ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER; - } - return 0; -} - -WebRtc_Word16 -WebRtcIsac_EncodeJitterInfo( - WebRtc_Word32 jitterIndex, - Bitstr* streamData) -{ - // This is to avoid LINUX warning until we change 'int' to - // 'Word32' - int intVar; - - if((jitterIndex < 0) || (jitterIndex > 1)) - { - return -1; - } - intVar = (int)(jitterIndex); - // Use the same CDF table as for bandwidth - // both take two values with equal probability - WebRtcIsac_EncHistMulti(streamData, &intVar, - kOneBitEqualProbCdf_ptr, 1); - return 0; - -} - -WebRtc_Word16 -WebRtcIsac_DecodeJitterInfo( - Bitstr* streamData, - WebRtc_Word32* jitterInfo) -{ - int intVar; - - // Use the same CDF table as for bandwidth - // both take two values with equal probability - if(WebRtcIsac_DecHistOneStepMulti(&intVar, streamData, - kOneBitEqualProbCdf_ptr, - kOneBitEqualProbInitIndex, 1) < 0) - { - // error check - return -ISAC_RANGE_ERROR_DECODE_BANDWITH; - } - *jitterInfo = (WebRtc_Word16)(intVar); - return 0; -} diff --git a/src/mod/codecs/mod_isac/entropy_coding.h b/src/mod/codecs/mod_isac/entropy_coding.h deleted file mode 100644 index 8446bcf3e5..0000000000 --- a/src/mod/codecs/mod_isac/entropy_coding.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * entropy_coding.h - * - * This header file declares all of the functions used to arithmetically - * encode the iSAC bistream - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ - -#include "structs.h" - -/* decode complex spectrum (return number of bytes in stream) */ -int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, - double *fr, - double *fi, - WebRtc_Word16 AvgPitchGain_Q12); - -/****************************************************************************** - * WebRtcIsac_DecodeSpecUB16() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). - * - * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB16( - Bitstr* streamdata, - double* fr, - double* fi); - - -/****************************************************************************** - * WebRtcIsac_DecodeSpecUB12() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-12 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). - * - * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB12( - Bitstr* streamdata, - double* fr, - double* fi); - - -/* encode complex spectrum */ -int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata, - WebRtc_Word16 AvgPitchGain_Q12); - - -/****************************************************************************** - * WebRtcIsac_EncodeSpecUB16() - * Quantize and encode real and imaginary part of the DFT coefficients. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The real and imaginary part are computed by calling WebRtcIsac_Time2Spec(). - * - * - * Input: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are stored. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are stored. - * - * Output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_EncodeSpecUB16( - const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata); - - -/****************************************************************************** - * WebRtcIsac_EncodeSpecUB12() - * Quantize and encode real and imaginary part of the DFT coefficients. - * This function is called when the codec is in 0-12 kHz bandwidth. - * The real and imaginary part are computed by calling WebRtcIsac_Time2Spec(). - * - * - * Input: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are stored. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are stored. - * - * Output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_EncodeSpecUB12( - const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata); - - -/* decode & dequantize LPC Coef */ -int WebRtcIsac_DecodeLpcCoef(Bitstr *streamdata, double *LPCCoef, int *outmodel); -int WebRtcIsac_DecodeLpcCoefUB( - Bitstr* streamdata, - double* lpcVecs, - double* percepFilterGains, - WebRtc_Word16 bandwidth); - -int WebRtcIsac_DecodeLpc(Bitstr *streamdata, double *LPCCoef_lo, double *LPCCoef_hi, int *outmodel); - -/* quantize & code LPC Coef */ -void WebRtcIsac_EncodeLpcLb(double *LPCCoef_lo, double *LPCCoef_hi, int *model, double *size, Bitstr *streamdata, ISAC_SaveEncData_t* encData); -void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, int model, Bitstr *streamdata, ISAC_SaveEncData_t* encData); - -/****************************************************************************** - * WebRtcIsac_EncodeLpcUB() - * Encode LPC parameters, given as A-polynomial, of upper-band. The encoding - * is performed in LAR domain. - * For the upper-band, we compute and encode LPC of some sub-frames, LPC of - * other sub-frames are computed by linear interpolation, in LAR domain. This - * function performs the interpolation and returns the LPC of all sub-frames. - * - * Inputs: - * - lpcCoef : a buffer containing A-polynomials of sub-frames - * (excluding first coefficient that is 1). - * - bandwidth : specifies if the codec is operating at 0-12 kHz - * or 0-16 kHz mode. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * - interpolLPCCoeff : Decoded and interpolated LPC (A-polynomial) - * of all sub-frames. - * If LP analysis is of order K, and there are N - * sub-frames then this is a buffer of size - * (k + 1) * N, each vector starts with the LPC gain - * of the corresponding sub-frame. The LPC gains - * are encoded and inserted after this function is - * called. The first A-coefficient which is 1 is not - * included. - * - * Return value : 0 if encoding is successful, - * <0 if failed to encode. - */ -WebRtc_Word16 WebRtcIsac_EncodeLpcUB( - double* lpcCoeff, - Bitstr* streamdata, - double* interpolLPCCoeff, - WebRtc_Word16 bandwidth, - ISACUBSaveEncDataStruct* encData); - -/****************************************************************************** - * WebRtcIsac_DecodeInterpolLpcUb() - * Decode LPC coefficients and interpolate to get the coefficients fo all - * sub-frmaes. - * - * Inputs: - * - bandwidth : spepecifies if the codec is in 0-12 kHz or - * 0-16 kHz mode. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * - percepFilterParam : Decoded and interpolated LPC (A-polynomial) of - * all sub-frames. - * If LP analysis is of order K, and there are N - * sub-frames then this is a buffer of size - * (k + 1) * N, each vector starts with the LPC gain - * of the corresponding sub-frame. The LPC gains - * are encoded and inserted after this function is - * called. The first A-coefficient which is 1 is not - * included. - * - * Return value : 0 if encoding is successful, - * <0 if failed to encode. - */ -WebRtc_Word16 WebRtcIsac_DecodeInterpolLpcUb( - Bitstr* streamdata, - double* percepFilterParam, - WebRtc_Word16 bandwidth); - -/* decode & dequantize RC */ -int WebRtcIsac_DecodeRc(Bitstr *streamdata, WebRtc_Word16 *RCQ15); - -/* quantize & code RC */ -void WebRtcIsac_EncodeRc(WebRtc_Word16 *RCQ15, Bitstr *streamdata); - -/* decode & dequantize squared Gain */ -int WebRtcIsac_DecodeGain2(Bitstr *streamdata, WebRtc_Word32 *Gain2); - -/* quantize & code squared Gain (input is squared gain) */ -int WebRtcIsac_EncodeGain2(WebRtc_Word32 *gain2, Bitstr *streamdata); - -void WebRtcIsac_EncodePitchGain(WebRtc_Word16* PitchGains_Q12, Bitstr* streamdata, ISAC_SaveEncData_t* encData); - -void WebRtcIsac_EncodePitchLag(double* PitchLags, WebRtc_Word16* PitchGain_Q12, Bitstr* streamdata, ISAC_SaveEncData_t* encData); - -int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, WebRtc_Word16 *PitchGain_Q12); -int WebRtcIsac_DecodePitchLag(Bitstr *streamdata, WebRtc_Word16 *PitchGain_Q12, double *PitchLag); - -int WebRtcIsac_DecodeFrameLen(Bitstr *streamdata, WebRtc_Word16 *framelength); -int WebRtcIsac_EncodeFrameLen(WebRtc_Word16 framelength, Bitstr *streamdata); -int WebRtcIsac_DecodeSendBW(Bitstr *streamdata, WebRtc_Word16 *BWno); -void WebRtcIsac_EncodeReceiveBw(int *BWno, Bitstr *streamdata); - -/* step-down */ -void WebRtcIsac_Poly2Rc(double *a, int N, double *RC); - -/* step-up */ -void WebRtcIsac_Rc2Poly(double *RC, int N, double *a); - -void WebRtcIsac_TranscodeLPCCoef(double *LPCCoef_lo, double *LPCCoef_hi, int model, - int *index_g); - - -/****************************************************************************** - * WebRtcIsac_EncodeLpcGainUb() - * Encode LPC gains of sub-Frames. - * - * Input/outputs: - * - lpGains : a buffer which contains 'SUBFRAME' number of - * LP gains to be encoded. The input values are - * overwritten by the quantized values. - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * - lpcGainIndex : quantization indices for lpc gains, these will - * be stored to be used for FEC. - */ -void WebRtcIsac_EncodeLpcGainUb( - double* lpGains, - Bitstr* streamdata, - int* lpcGainIndex); - - -/****************************************************************************** - * WebRtcIsac_EncodeLpcGainUb() - * Store LPC gains of sub-Frames in 'streamdata'. - * - * Input: - * - lpGains : a buffer which contains 'SUBFRAME' number of - * LP gains to be encoded. - * Input/outputs: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - */ -void WebRtcIsac_StoreLpcGainUb( - double* lpGains, - Bitstr* streamdata); - - -/****************************************************************************** - * WebRtcIsac_DecodeLpcGainUb() - * Decode the LPC gain of sub-frames. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * - lpGains : a buffer where decoded LPC gians will be stored. - * - * Return value : 0 if succeeded. - * <0 if failed. - */ -WebRtc_Word16 WebRtcIsac_DecodeLpcGainUb( - double* lpGains, - Bitstr* streamdata); - - -/****************************************************************************** - * WebRtcIsac_EncodeBandwidth() - * Encode if the bandwidth of encoded audio is 0-12 kHz or 0-16 kHz. - * - * Input: - * - bandwidth : an enumerator specifying if the codec in is - * 0-12 kHz or 0-16 kHz mode. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Return value : 0 if succeeded. - * <0 if failed. - */ -WebRtc_Word16 WebRtcIsac_EncodeBandwidth( - enum ISACBandwidth bandwidth, - Bitstr* streamData); - - -/****************************************************************************** - * WebRtcIsac_DecodeBandwidth() - * Decode the bandwidth of the encoded audio, i.e. if the bandwidth is 0-12 kHz - * or 0-16 kHz. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * - bandwidth : an enumerator specifying if the codec is in - * 0-12 kHz or 0-16 kHz mode. - * - * Return value : 0 if succeeded. - * <0 if failed. - */ -WebRtc_Word16 WebRtcIsac_DecodeBandwidth( - Bitstr* streamData, - enum ISACBandwidth* bandwidth); - - -/****************************************************************************** - * WebRtcIsac_EncodeJitterInfo() - * Decode the jitter information. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Input: - * - jitterInfo : one bit of info specifying if the channel is - * in high/low jitter. Zero indicates low jitter - * and one indicates high jitter. - * - * Return value : 0 if succeeded. - * <0 if failed. - */ -WebRtc_Word16 WebRtcIsac_EncodeJitterInfo( - WebRtc_Word32 jitterIndex, - Bitstr* streamData); - - -/****************************************************************************** - * WebRtcIsac_DecodeJitterInfo() - * Decode the jitter information. - * - * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * - jitterInfo : one bit of info specifying if the channel is - * in high/low jitter. Zero indicates low jitter - * and one indicates high jitter. - * - * Return value : 0 if succeeded. - * <0 if failed. - */ -WebRtc_Word16 WebRtcIsac_DecodeJitterInfo( - Bitstr* streamData, - WebRtc_Word32* jitterInfo); - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ */ diff --git a/src/mod/codecs/mod_isac/fft.c b/src/mod/codecs/mod_isac/fft.c deleted file mode 100644 index 4164d3b59b..0000000000 --- a/src/mod/codecs/mod_isac/fft.c +++ /dev/null @@ -1,947 +0,0 @@ -/* - * Copyright(c)1995,97 Mark Olesen - * Queen's Univ at Kingston (Canada) - * - * Permission to use, copy, modify, and distribute this software for - * any purpose without fee is hereby granted, provided that this - * entire notice is included in all copies of any software which is - * or includes a copy or modification of this software and in all - * copies of the supporting documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR QUEEN'S - * UNIVERSITY AT KINGSTON MAKES ANY REPRESENTATION OR WARRANTY OF ANY - * KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS - * FITNESS FOR ANY PARTICULAR PURPOSE. - * - * All of which is to say that you can do what you like with this - * source code provided you don't try to sell it as your own and you - * include an unaltered copy of this message (including the - * copyright). - * - * It is also implicitly understood that bug fixes and improvements - * should make their way back to the general Internet community so - * that everyone benefits. - * - * Changes: - * Trivial type modifications by the WebRTC authors. - */ - - -/* - * File: - * WebRtcIsac_Fftn.c - * - * Public: - * WebRtcIsac_Fftn / fftnf (); - * - * Private: - * WebRtcIsac_Fftradix / fftradixf (); - * - * Descript: - * multivariate complex Fourier transform, computed in place - * using mixed-radix Fast Fourier Transform algorithm. - * - * Fortran code by: - * RC Singleton, Stanford Research Institute, Sept. 1968 - * - * translated by f2c (version 19950721). - * - * int WebRtcIsac_Fftn (int ndim, const int dims[], REAL Re[], REAL Im[], - * int iSign, double scaling); - * - * NDIM = the total number dimensions - * DIMS = a vector of array sizes - * if NDIM is zero then DIMS must be zero-terminated - * - * RE and IM hold the real and imaginary components of the data, and return - * the resulting real and imaginary Fourier coefficients. Multidimensional - * data *must* be allocated contiguously. There is no limit on the number - * of dimensions. - * - * ISIGN = the sign of the complex exponential (ie, forward or inverse FFT) - * the magnitude of ISIGN (normally 1) is used to determine the - * correct indexing increment (see below). - * - * SCALING = normalizing constant by which the final result is *divided* - * if SCALING == -1, normalize by total dimension of the transform - * if SCALING < -1, normalize by the square-root of the total dimension - * - * example: - * tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3] - * - * int dims[3] = {n1,n2,n3} - * WebRtcIsac_Fftn (3, dims, Re, Im, 1, scaling); - * - *-----------------------------------------------------------------------* - * int WebRtcIsac_Fftradix (REAL Re[], REAL Im[], size_t nTotal, size_t nPass, - * size_t nSpan, int iSign, size_t max_factors, - * size_t max_perm); - * - * RE, IM - see above documentation - * - * Although there is no limit on the number of dimensions, WebRtcIsac_Fftradix() must - * be called once for each dimension, but the calls may be in any order. - * - * NTOTAL = the total number of complex data values - * NPASS = the dimension of the current variable - * NSPAN/NPASS = the spacing of consecutive data values while indexing the - * current variable - * ISIGN - see above documentation - * - * example: - * tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3] - * - * WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n1, n1, 1, maxf, maxp); - * WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n2, n1*n2, 1, maxf, maxp); - * WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n3, n1*n2*n3, 1, maxf, maxp); - * - * single-variate transform, - * NTOTAL = N = NSPAN = (number of complex data values), - * - * WebRtcIsac_Fftradix (Re, Im, n, n, n, 1, maxf, maxp); - * - * The data can also be stored in a single array with alternating real and - * imaginary parts, the magnitude of ISIGN is changed to 2 to give correct - * indexing increment, and data [0] and data [1] used to pass the initial - * addresses for the sequences of real and imaginary values, - * - * example: - * REAL data [2*NTOTAL]; - * WebRtcIsac_Fftradix ( &data[0], &data[1], NTOTAL, nPass, nSpan, 2, maxf, maxp); - * - * for temporary allocation: - * - * MAX_FACTORS >= the maximum prime factor of NPASS - * MAX_PERM >= the number of prime factors of NPASS. In addition, - * if the square-free portion K of NPASS has two or more prime - * factors, then MAX_PERM >= (K-1) - * - * storage in FACTOR for a maximum of 15 prime factors of NPASS. if NPASS - * has more than one square-free factor, the product of the square-free - * factors must be <= 210 array storage for maximum prime factor of 23 the - * following two constants should agree with the array dimensions. - * - *----------------------------------------------------------------------*/ -#include "fft.h" - -#include -#include - - - -/* double precision routine */ -static int -WebRtcIsac_Fftradix (double Re[], double Im[], - size_t nTotal, size_t nPass, size_t nSpan, int isign, - int max_factors, unsigned int max_perm, - FFTstr *fftstate); - - - -#ifndef M_PI -# define M_PI 3.14159265358979323846264338327950288 -#endif - -#ifndef SIN60 -# define SIN60 0.86602540378443865 /* sin(60 deg) */ -# define COS72 0.30901699437494742 /* cos(72 deg) */ -# define SIN72 0.95105651629515357 /* sin(72 deg) */ -#endif - -# define REAL double -# define FFTN WebRtcIsac_Fftn -# define FFTNS "fftn" -# define FFTRADIX WebRtcIsac_Fftradix -# define FFTRADIXS "fftradix" - - -int WebRtcIsac_Fftns(unsigned int ndim, const int dims[], - double Re[], - double Im[], - int iSign, - double scaling, - FFTstr *fftstate) -{ - - size_t nSpan, nPass, nTotal; - unsigned int i; - int ret, max_factors, max_perm; - - /* - * tally the number of elements in the data array - * and determine the number of dimensions - */ - nTotal = 1; - if (ndim && dims [0]) - { - for (i = 0; i < ndim; i++) - { - if (dims [i] <= 0) - { - return -1; - } - nTotal *= dims [i]; - } - } - else - { - ndim = 0; - for (i = 0; dims [i]; i++) - { - if (dims [i] <= 0) - { - return -1; - } - nTotal *= dims [i]; - ndim++; - } - } - - /* determine maximum number of factors and permuations */ -#if 1 - /* - * follow John Beale's example, just use the largest dimension and don't - * worry about excess allocation. May be someone else will do it? - */ - max_factors = max_perm = 1; - for (i = 0; i < ndim; i++) - { - nSpan = dims [i]; - if ((int)nSpan > max_factors) - { - max_factors = (int)nSpan; - } - if ((int)nSpan > max_perm) - { - max_perm = (int)nSpan; - } - } -#else - /* use the constants used in the original Fortran code */ - max_factors = 23; - max_perm = 209; -#endif - /* loop over the dimensions: */ - nPass = 1; - for (i = 0; i < ndim; i++) - { - nSpan = dims [i]; - nPass *= nSpan; - ret = FFTRADIX (Re, Im, nTotal, nSpan, nPass, iSign, - max_factors, max_perm, fftstate); - /* exit, clean-up already done */ - if (ret) - return ret; - } - - /* Divide through by the normalizing constant: */ - if (scaling && scaling != 1.0) - { - if (iSign < 0) iSign = -iSign; - if (scaling < 0.0) - { - scaling = (double)nTotal; - if (scaling < -1.0) - scaling = sqrt (scaling); - } - scaling = 1.0 / scaling; /* multiply is often faster */ - for (i = 0; i < nTotal; i += iSign) - { - Re [i] *= scaling; - Im [i] *= scaling; - } - } - return 0; -} - -/* - * singleton's mixed radix routine - * - * could move allocation out to WebRtcIsac_Fftn(), but leave it here so that it's - * possible to make this a standalone function - */ - -static int FFTRADIX (REAL Re[], - REAL Im[], - size_t nTotal, - size_t nPass, - size_t nSpan, - int iSign, - int max_factors, - unsigned int max_perm, - FFTstr *fftstate) -{ - int ii, mfactor, kspan, ispan, inc; - int j, jc, jf, jj, k, k1, k2, k3, k4, kk, kt, nn, ns, nt; - - - REAL radf; - REAL c1, c2, c3, cd, aa, aj, ak, ajm, ajp, akm, akp; - REAL s1, s2, s3, sd, bb, bj, bk, bjm, bjp, bkm, bkp; - - REAL *Rtmp = NULL; /* temp space for real part*/ - REAL *Itmp = NULL; /* temp space for imaginary part */ - REAL *Cos = NULL; /* Cosine values */ - REAL *Sin = NULL; /* Sine values */ - - REAL s60 = SIN60; /* sin(60 deg) */ - REAL c72 = COS72; /* cos(72 deg) */ - REAL s72 = SIN72; /* sin(72 deg) */ - REAL pi2 = M_PI; /* use PI first, 2 PI later */ - - - fftstate->SpaceAlloced = 0; - fftstate->MaxPermAlloced = 0; - - - // initialize to avoid warnings - k3 = c2 = c3 = s2 = s3 = 0.0; - - if (nPass < 2) - return 0; - - /* allocate storage */ - if (fftstate->SpaceAlloced < max_factors * sizeof (REAL)) - { -#ifdef SUN_BROKEN_REALLOC - if (!fftstate->SpaceAlloced) /* first time */ - { - fftstate->SpaceAlloced = max_factors * sizeof (REAL); - } - else - { -#endif - fftstate->SpaceAlloced = max_factors * sizeof (REAL); -#ifdef SUN_BROKEN_REALLOC - } -#endif - } - else - { - /* allow full use of alloc'd space */ - max_factors = fftstate->SpaceAlloced / sizeof (REAL); - } - if (fftstate->MaxPermAlloced < max_perm) - { -#ifdef SUN_BROKEN_REALLOC - if (!fftstate->MaxPermAlloced) /* first time */ - else -#endif - fftstate->MaxPermAlloced = max_perm; - } - else - { - /* allow full use of alloc'd space */ - max_perm = fftstate->MaxPermAlloced; - } - if (fftstate->Tmp0 == NULL || fftstate->Tmp1 == NULL || fftstate->Tmp2 == NULL || fftstate->Tmp3 == NULL - || fftstate->Perm == NULL) { - return -1; - } - - /* assign pointers */ - Rtmp = (REAL *) fftstate->Tmp0; - Itmp = (REAL *) fftstate->Tmp1; - Cos = (REAL *) fftstate->Tmp2; - Sin = (REAL *) fftstate->Tmp3; - - /* - * Function Body - */ - inc = iSign; - if (iSign < 0) { - s72 = -s72; - s60 = -s60; - pi2 = -pi2; - inc = -inc; /* absolute value */ - } - - /* adjust for strange increments */ - nt = inc * (int)nTotal; - ns = inc * (int)nSpan; - kspan = ns; - - nn = nt - inc; - jc = ns / (int)nPass; - radf = pi2 * (double) jc; - pi2 *= 2.0; /* use 2 PI from here on */ - - ii = 0; - jf = 0; - /* determine the factors of n */ - mfactor = 0; - k = (int)nPass; - while (k % 16 == 0) { - mfactor++; - fftstate->factor [mfactor - 1] = 4; - k /= 16; - } - j = 3; - jj = 9; - do { - while (k % jj == 0) { - mfactor++; - fftstate->factor [mfactor - 1] = j; - k /= jj; - } - j += 2; - jj = j * j; - } while (jj <= k); - if (k <= 4) { - kt = mfactor; - fftstate->factor [mfactor] = k; - if (k != 1) - mfactor++; - } else { - if (k - (k / 4 << 2) == 0) { - mfactor++; - fftstate->factor [mfactor - 1] = 2; - k /= 4; - } - kt = mfactor; - j = 2; - do { - if (k % j == 0) { - mfactor++; - fftstate->factor [mfactor - 1] = j; - k /= j; - } - j = ((j + 1) / 2 << 1) + 1; - } while (j <= k); - } - if (kt) { - j = kt; - do { - mfactor++; - fftstate->factor [mfactor - 1] = fftstate->factor [j - 1]; - j--; - } while (j); - } - - /* test that mfactors is in range */ - if (mfactor > NFACTOR) - { - return -1; - } - - /* compute fourier transform */ - for (;;) { - sd = radf / (double) kspan; - cd = sin(sd); - cd = 2.0 * cd * cd; - sd = sin(sd + sd); - kk = 0; - ii++; - - switch (fftstate->factor [ii - 1]) { - case 2: - /* transform for factor of 2 (including rotation factor) */ - kspan /= 2; - k1 = kspan + 2; - do { - do { - k2 = kk + kspan; - ak = Re [k2]; - bk = Im [k2]; - Re [k2] = Re [kk] - ak; - Im [k2] = Im [kk] - bk; - Re [kk] += ak; - Im [kk] += bk; - kk = k2 + kspan; - } while (kk < nn); - kk -= nn; - } while (kk < jc); - if (kk >= kspan) - goto Permute_Results_Label; /* exit infinite loop */ - do { - c1 = 1.0 - cd; - s1 = sd; - do { - do { - do { - k2 = kk + kspan; - ak = Re [kk] - Re [k2]; - bk = Im [kk] - Im [k2]; - Re [kk] += Re [k2]; - Im [kk] += Im [k2]; - Re [k2] = c1 * ak - s1 * bk; - Im [k2] = s1 * ak + c1 * bk; - kk = k2 + kspan; - } while (kk < (nt-1)); - k2 = kk - nt; - c1 = -c1; - kk = k1 - k2; - } while (kk > k2); - ak = c1 - (cd * c1 + sd * s1); - s1 = sd * c1 - cd * s1 + s1; - c1 = 2.0 - (ak * ak + s1 * s1); - s1 *= c1; - c1 *= ak; - kk += jc; - } while (kk < k2); - k1 += inc + inc; - kk = (k1 - kspan + 1) / 2 + jc - 1; - } while (kk < (jc + jc)); - break; - - case 4: /* transform for factor of 4 */ - ispan = kspan; - kspan /= 4; - - do { - c1 = 1.0; - s1 = 0.0; - do { - do { - k1 = kk + kspan; - k2 = k1 + kspan; - k3 = k2 + kspan; - akp = Re [kk] + Re [k2]; - akm = Re [kk] - Re [k2]; - ajp = Re [k1] + Re [k3]; - ajm = Re [k1] - Re [k3]; - bkp = Im [kk] + Im [k2]; - bkm = Im [kk] - Im [k2]; - bjp = Im [k1] + Im [k3]; - bjm = Im [k1] - Im [k3]; - Re [kk] = akp + ajp; - Im [kk] = bkp + bjp; - ajp = akp - ajp; - bjp = bkp - bjp; - if (iSign < 0) { - akp = akm + bjm; - bkp = bkm - ajm; - akm -= bjm; - bkm += ajm; - } else { - akp = akm - bjm; - bkp = bkm + ajm; - akm += bjm; - bkm -= ajm; - } - /* avoid useless multiplies */ - if (s1 == 0.0) { - Re [k1] = akp; - Re [k2] = ajp; - Re [k3] = akm; - Im [k1] = bkp; - Im [k2] = bjp; - Im [k3] = bkm; - } else { - Re [k1] = akp * c1 - bkp * s1; - Re [k2] = ajp * c2 - bjp * s2; - Re [k3] = akm * c3 - bkm * s3; - Im [k1] = akp * s1 + bkp * c1; - Im [k2] = ajp * s2 + bjp * c2; - Im [k3] = akm * s3 + bkm * c3; - } - kk = k3 + kspan; - } while (kk < nt); - - c2 = c1 - (cd * c1 + sd * s1); - s1 = sd * c1 - cd * s1 + s1; - c1 = 2.0 - (c2 * c2 + s1 * s1); - s1 *= c1; - c1 *= c2; - /* values of c2, c3, s2, s3 that will get used next time */ - c2 = c1 * c1 - s1 * s1; - s2 = 2.0 * c1 * s1; - c3 = c2 * c1 - s2 * s1; - s3 = c2 * s1 + s2 * c1; - kk = kk - nt + jc; - } while (kk < kspan); - kk = kk - kspan + inc; - } while (kk < jc); - if (kspan == jc) - goto Permute_Results_Label; /* exit infinite loop */ - break; - - default: - /* transform for odd factors */ -#ifdef FFT_RADIX4 - return -1; - break; -#else /* FFT_RADIX4 */ - k = fftstate->factor [ii - 1]; - ispan = kspan; - kspan /= k; - - switch (k) { - case 3: /* transform for factor of 3 (optional code) */ - do { - do { - k1 = kk + kspan; - k2 = k1 + kspan; - ak = Re [kk]; - bk = Im [kk]; - aj = Re [k1] + Re [k2]; - bj = Im [k1] + Im [k2]; - Re [kk] = ak + aj; - Im [kk] = bk + bj; - ak -= 0.5 * aj; - bk -= 0.5 * bj; - aj = (Re [k1] - Re [k2]) * s60; - bj = (Im [k1] - Im [k2]) * s60; - Re [k1] = ak - bj; - Re [k2] = ak + bj; - Im [k1] = bk + aj; - Im [k2] = bk - aj; - kk = k2 + kspan; - } while (kk < (nn - 1)); - kk -= nn; - } while (kk < kspan); - break; - - case 5: /* transform for factor of 5 (optional code) */ - c2 = c72 * c72 - s72 * s72; - s2 = 2.0 * c72 * s72; - do { - do { - k1 = kk + kspan; - k2 = k1 + kspan; - k3 = k2 + kspan; - k4 = k3 + kspan; - akp = Re [k1] + Re [k4]; - akm = Re [k1] - Re [k4]; - bkp = Im [k1] + Im [k4]; - bkm = Im [k1] - Im [k4]; - ajp = Re [k2] + Re [k3]; - ajm = Re [k2] - Re [k3]; - bjp = Im [k2] + Im [k3]; - bjm = Im [k2] - Im [k3]; - aa = Re [kk]; - bb = Im [kk]; - Re [kk] = aa + akp + ajp; - Im [kk] = bb + bkp + bjp; - ak = akp * c72 + ajp * c2 + aa; - bk = bkp * c72 + bjp * c2 + bb; - aj = akm * s72 + ajm * s2; - bj = bkm * s72 + bjm * s2; - Re [k1] = ak - bj; - Re [k4] = ak + bj; - Im [k1] = bk + aj; - Im [k4] = bk - aj; - ak = akp * c2 + ajp * c72 + aa; - bk = bkp * c2 + bjp * c72 + bb; - aj = akm * s2 - ajm * s72; - bj = bkm * s2 - bjm * s72; - Re [k2] = ak - bj; - Re [k3] = ak + bj; - Im [k2] = bk + aj; - Im [k3] = bk - aj; - kk = k4 + kspan; - } while (kk < (nn-1)); - kk -= nn; - } while (kk < kspan); - break; - - default: - if (k != jf) { - jf = k; - s1 = pi2 / (double) k; - c1 = cos(s1); - s1 = sin(s1); - if (jf > max_factors){ - return -1; - } - Cos [jf - 1] = 1.0; - Sin [jf - 1] = 0.0; - j = 1; - do { - Cos [j - 1] = Cos [k - 1] * c1 + Sin [k - 1] * s1; - Sin [j - 1] = Cos [k - 1] * s1 - Sin [k - 1] * c1; - k--; - Cos [k - 1] = Cos [j - 1]; - Sin [k - 1] = -Sin [j - 1]; - j++; - } while (j < k); - } - do { - do { - k1 = kk; - k2 = kk + ispan; - ak = aa = Re [kk]; - bk = bb = Im [kk]; - j = 1; - k1 += kspan; - do { - k2 -= kspan; - j++; - Rtmp [j - 1] = Re [k1] + Re [k2]; - ak += Rtmp [j - 1]; - Itmp [j - 1] = Im [k1] + Im [k2]; - bk += Itmp [j - 1]; - j++; - Rtmp [j - 1] = Re [k1] - Re [k2]; - Itmp [j - 1] = Im [k1] - Im [k2]; - k1 += kspan; - } while (k1 < k2); - Re [kk] = ak; - Im [kk] = bk; - k1 = kk; - k2 = kk + ispan; - j = 1; - do { - k1 += kspan; - k2 -= kspan; - jj = j; - ak = aa; - bk = bb; - aj = 0.0; - bj = 0.0; - k = 1; - do { - k++; - ak += Rtmp [k - 1] * Cos [jj - 1]; - bk += Itmp [k - 1] * Cos [jj - 1]; - k++; - aj += Rtmp [k - 1] * Sin [jj - 1]; - bj += Itmp [k - 1] * Sin [jj - 1]; - jj += j; - if (jj > jf) { - jj -= jf; - } - } while (k < jf); - k = jf - j; - Re [k1] = ak - bj; - Im [k1] = bk + aj; - Re [k2] = ak + bj; - Im [k2] = bk - aj; - j++; - } while (j < k); - kk += ispan; - } while (kk < nn); - kk -= nn; - } while (kk < kspan); - break; - } - - /* multiply by rotation factor (except for factors of 2 and 4) */ - if (ii == mfactor) - goto Permute_Results_Label; /* exit infinite loop */ - kk = jc; - do { - c2 = 1.0 - cd; - s1 = sd; - do { - c1 = c2; - s2 = s1; - kk += kspan; - do { - do { - ak = Re [kk]; - Re [kk] = c2 * ak - s2 * Im [kk]; - Im [kk] = s2 * ak + c2 * Im [kk]; - kk += ispan; - } while (kk < nt); - ak = s1 * s2; - s2 = s1 * c2 + c1 * s2; - c2 = c1 * c2 - ak; - kk = kk - nt + kspan; - } while (kk < ispan); - c2 = c1 - (cd * c1 + sd * s1); - s1 += sd * c1 - cd * s1; - c1 = 2.0 - (c2 * c2 + s1 * s1); - s1 *= c1; - c2 *= c1; - kk = kk - ispan + jc; - } while (kk < kspan); - kk = kk - kspan + jc + inc; - } while (kk < (jc + jc)); - break; -#endif /* FFT_RADIX4 */ - } - } - - /* permute the results to normal order---done in two stages */ - /* permutation for square factors of n */ -Permute_Results_Label: - fftstate->Perm [0] = ns; - if (kt) { - k = kt + kt + 1; - if (mfactor < k) - k--; - j = 1; - fftstate->Perm [k] = jc; - do { - fftstate->Perm [j] = fftstate->Perm [j - 1] / fftstate->factor [j - 1]; - fftstate->Perm [k - 1] = fftstate->Perm [k] * fftstate->factor [j - 1]; - j++; - k--; - } while (j < k); - k3 = fftstate->Perm [k]; - kspan = fftstate->Perm [1]; - kk = jc; - k2 = kspan; - j = 1; - if (nPass != nTotal) { - /* permutation for multivariate transform */ - Permute_Multi_Label: - do { - do { - k = kk + jc; - do { - /* swap Re [kk] <> Re [k2], Im [kk] <> Im [k2] */ - ak = Re [kk]; Re [kk] = Re [k2]; Re [k2] = ak; - bk = Im [kk]; Im [kk] = Im [k2]; Im [k2] = bk; - kk += inc; - k2 += inc; - } while (kk < (k-1)); - kk += ns - jc; - k2 += ns - jc; - } while (kk < (nt-1)); - k2 = k2 - nt + kspan; - kk = kk - nt + jc; - } while (k2 < (ns-1)); - do { - do { - k2 -= fftstate->Perm [j - 1]; - j++; - k2 = fftstate->Perm [j] + k2; - } while (k2 > fftstate->Perm [j - 1]); - j = 1; - do { - if (kk < (k2-1)) - goto Permute_Multi_Label; - kk += jc; - k2 += kspan; - } while (k2 < (ns-1)); - } while (kk < (ns-1)); - } else { - /* permutation for single-variate transform (optional code) */ - Permute_Single_Label: - do { - /* swap Re [kk] <> Re [k2], Im [kk] <> Im [k2] */ - ak = Re [kk]; Re [kk] = Re [k2]; Re [k2] = ak; - bk = Im [kk]; Im [kk] = Im [k2]; Im [k2] = bk; - kk += inc; - k2 += kspan; - } while (k2 < (ns-1)); - do { - do { - k2 -= fftstate->Perm [j - 1]; - j++; - k2 = fftstate->Perm [j] + k2; - } while (k2 >= fftstate->Perm [j - 1]); - j = 1; - do { - if (kk < k2) - goto Permute_Single_Label; - kk += inc; - k2 += kspan; - } while (k2 < (ns-1)); - } while (kk < (ns-1)); - } - jc = k3; - } - - if ((kt << 1) + 1 >= mfactor) - return 0; - ispan = fftstate->Perm [kt]; - /* permutation for square-free factors of n */ - j = mfactor - kt; - fftstate->factor [j] = 1; - do { - fftstate->factor [j - 1] *= fftstate->factor [j]; - j--; - } while (j != kt); - kt++; - nn = fftstate->factor [kt - 1] - 1; - if (nn > (int) max_perm) { - return -1; - } - j = jj = 0; - for (;;) { - k = kt + 1; - k2 = fftstate->factor [kt - 1]; - kk = fftstate->factor [k - 1]; - j++; - if (j > nn) - break; /* exit infinite loop */ - jj += kk; - while (jj >= k2) { - jj -= k2; - k2 = kk; - k++; - kk = fftstate->factor [k - 1]; - jj += kk; - } - fftstate->Perm [j - 1] = jj; - } - /* determine the permutation cycles of length greater than 1 */ - j = 0; - for (;;) { - do { - j++; - kk = fftstate->Perm [j - 1]; - } while (kk < 0); - if (kk != j) { - do { - k = kk; - kk = fftstate->Perm [k - 1]; - fftstate->Perm [k - 1] = -kk; - } while (kk != j); - k3 = kk; - } else { - fftstate->Perm [j - 1] = -j; - if (j == nn) - break; /* exit infinite loop */ - } - } - max_factors *= inc; - /* reorder a and b, following the permutation cycles */ - for (;;) { - j = k3 + 1; - nt -= ispan; - ii = nt - inc + 1; - if (nt < 0) - break; /* exit infinite loop */ - do { - do { - j--; - } while (fftstate->Perm [j - 1] < 0); - jj = jc; - do { - kspan = jj; - if (jj > max_factors) { - kspan = max_factors; - } - jj -= kspan; - k = fftstate->Perm [j - 1]; - kk = jc * k + ii + jj; - k1 = kk + kspan - 1; - k2 = 0; - do { - k2++; - Rtmp [k2 - 1] = Re [k1]; - Itmp [k2 - 1] = Im [k1]; - k1 -= inc; - } while (k1 != (kk-1)); - do { - k1 = kk + kspan - 1; - k2 = k1 - jc * (k + fftstate->Perm [k - 1]); - k = -fftstate->Perm [k - 1]; - do { - Re [k1] = Re [k2]; - Im [k1] = Im [k2]; - k1 -= inc; - k2 -= inc; - } while (k1 != (kk-1)); - kk = k2 + 1; - } while (k != j); - k1 = kk + kspan - 1; - k2 = 0; - do { - k2++; - Re [k1] = Rtmp [k2 - 1]; - Im [k1] = Itmp [k2 - 1]; - k1 -= inc; - } while (k1 != (kk-1)); - } while (jj); - } while (j != 1); - } - return 0; /* exit point here */ -} -/* ---------------------- end-of-file (c source) ---------------------- */ - diff --git a/src/mod/codecs/mod_isac/fft.h b/src/mod/codecs/mod_isac/fft.h deleted file mode 100644 index a42f57bcb5..0000000000 --- a/src/mod/codecs/mod_isac/fft.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*--------------------------------*-C-*---------------------------------* - * File: - * fftn.h - * ---------------------------------------------------------------------* - * Re[]: real value array - * Im[]: imaginary value array - * nTotal: total number of complex values - * nPass: number of elements involved in this pass of transform - * nSpan: nspan/nPass = number of bytes to increment pointer - * in Re[] and Im[] - * isign: exponent: +1 = forward -1 = reverse - * scaling: normalizing constant by which the final result is *divided* - * scaling == -1, normalize by total dimension of the transform - * scaling < -1, normalize by the square-root of the total dimension - * - * ---------------------------------------------------------------------- - * See the comments in the code for correct usage! - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_ - - -#include "structs.h" - - -/* double precision routine */ - - -int WebRtcIsac_Fftns (unsigned int ndim, const int dims[], double Re[], double Im[], - int isign, double scaling, FFTstr *fftstate); - - - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_ */ diff --git a/src/mod/codecs/mod_isac/filter_ar.c b/src/mod/codecs/mod_isac/filter_ar.c deleted file mode 100644 index 24e83a6b91..0000000000 --- a/src/mod/codecs/mod_isac/filter_ar.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_FilterAR(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* a, - int a_length, - G_CONST WebRtc_Word16* x, - int x_length, - WebRtc_Word16* state, - int state_length, - WebRtc_Word16* state_low, - int state_low_length, - WebRtc_Word16* filtered, - WebRtc_Word16* filtered_low, - int filtered_low_length) -{ - WebRtc_Word32 o; - WebRtc_Word32 oLOW; - int i, j, stop; - G_CONST WebRtc_Word16* x_ptr = &x[0]; - WebRtc_Word16* filteredFINAL_ptr = filtered; - WebRtc_Word16* filteredFINAL_LOW_ptr = filtered_low; - - for (i = 0; i < x_length; i++) - { - // Calculate filtered[i] and filtered_low[i] - G_CONST WebRtc_Word16* a_ptr = &a[1]; - WebRtc_Word16* filtered_ptr = &filtered[i - 1]; - WebRtc_Word16* filtered_low_ptr = &filtered_low[i - 1]; - WebRtc_Word16* state_ptr = &state[state_length - 1]; - WebRtc_Word16* state_low_ptr = &state_low[state_length - 1]; - - o = (WebRtc_Word32)(*x_ptr++) << 12; - oLOW = (WebRtc_Word32)0; - - stop = (i < a_length) ? i + 1 : a_length; - for (j = 1; j < stop; j++) - { - o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--); - oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--); - } - for (j = i + 1; j < a_length; j++) - { - o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *state_ptr--); - oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *state_low_ptr--); - } - - o += (oLOW >> 12); - *filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); - *filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++) - << 12)); - } - - // Save the filter state - if (x_length >= state_length) - { - WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state); - WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low); - } else - { - for (i = 0; i < state_length - x_length; i++) - { - state[i] = state[i + x_length]; - state_low[i] = state_low[i + x_length]; - } - for (i = 0; i < x_length; i++) - { - state[state_length - x_length + i] = filtered[i]; - state[state_length - x_length + i] = filtered_low[i]; - } - } - - return x_length; -} diff --git a/src/mod/codecs/mod_isac/filter_ar_fast_q12.c b/src/mod/codecs/mod_isac/filter_ar_fast_q12.c deleted file mode 100644 index 6184da3f4c..0000000000 --- a/src/mod/codecs/mod_isac/filter_ar_fast_q12.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_FilterARFastQ12(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_FilterARFastQ12(WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 *A, - WebRtc_Word16 A_length, WebRtc_Word16 length) -{ - WebRtc_Word32 o; - int i, j; - - WebRtc_Word16 *x_ptr = &in[0]; - WebRtc_Word16 *filtered_ptr = &out[0]; - - for (i = 0; i < length; i++) - { - // Calculate filtered[i] - G_CONST WebRtc_Word16 *a_ptr = &A[0]; - WebRtc_Word16 *state_ptr = &out[i - 1]; - - o = WEBRTC_SPL_MUL_16_16(*x_ptr++, *a_ptr++); - - for (j = 1; j < A_length; j++) - { - o -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_ptr--); - } - - // Saturate the output - o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728); - - *filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); - } - - return; -} diff --git a/src/mod/codecs/mod_isac/filter_functions.c b/src/mod/codecs/mod_isac/filter_functions.c deleted file mode 100644 index 33024a3dee..0000000000 --- a/src/mod/codecs/mod_isac/filter_functions.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#ifdef WEBRTC_ANDROID -#include -#endif -#include "pitch_estimator.h" -#include "lpc_analysis.h" -#include "codec.h" - - - -void WebRtcIsac_AllPoleFilter(double *InOut, double *Coef, int lengthInOut, int orderCoef){ - - /* the state of filter is assumed to be in InOut[-1] to InOut[-orderCoef] */ - double scal; - double sum; - int n,k; - - //if (fabs(Coef[0]-1.0)<0.001) { - if ( (Coef[0] > 0.9999) && (Coef[0] < 1.0001) ) - { - for(n = 0; n < lengthInOut; n++) - { - sum = Coef[1] * InOut[-1]; - for(k = 2; k <= orderCoef; k++){ - sum += Coef[k] * InOut[-k]; - } - *InOut++ -= sum; - } - } - else - { - scal = 1.0 / Coef[0]; - for(n=0;nbuffer, sizeof(double) * PITCH_WLPCBUFLEN); - memcpy(tmpbuffer+PITCH_WLPCBUFLEN, in, sizeof(double) * PITCH_FRAME_LEN); - memcpy(wfdata->buffer, tmpbuffer+PITCH_FRAME_LEN, sizeof(double) * PITCH_WLPCBUFLEN); - - dp=weoutbuf; - dp2=whoutbuf; - for (k=0;kweostate[k]; - *dp2++ = wfdata->whostate[k]; - opol[k]=0.0; - } - opol[0]=1.0; - opol[PITCH_WLPCORDER]=0.0; - weo=dp; - who=dp2; - - endpos=PITCH_WLPCBUFLEN + PITCH_SUBFRAME_LEN; - inp=tmpbuffer + PITCH_WLPCBUFLEN; - - for (n=0; nwindow[k]*tmpbuffer[start+k]; - } - - /* Get LPC polynomial */ - WebRtcIsac_AutoCorr(corr, ext, PITCH_WLPCWINLEN, PITCH_WLPCORDER); - corr[0]=1.01*corr[0]+1.0; /* White noise correction */ - WebRtcIsac_LevDurb(apol, rc, corr, PITCH_WLPCORDER); - WebRtcIsac_BwExpand(apolr, apol, rho, PITCH_WLPCORDER+1); - - /* Filtering */ - WebRtcIsac_ZeroPoleFilter(inp, apol, apolr, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, weo); - WebRtcIsac_ZeroPoleFilter(inp, apolr, opol, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, who); - - inp+=PITCH_SUBFRAME_LEN; - endpos+=PITCH_SUBFRAME_LEN; - weo+=PITCH_SUBFRAME_LEN; - who+=PITCH_SUBFRAME_LEN; - } - - /* Export filter states */ - for (k=0;kweostate[k]=weoutbuf[PITCH_FRAME_LEN+k]; - wfdata->whostate[k]=whoutbuf[PITCH_FRAME_LEN+k]; - } - - /* Export output data */ - memcpy(weiout, weoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN); - memcpy(whiout, whoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN); -} - - -static const double APupper[ALLPASSSECTIONS] = {0.0347, 0.3826}; -static const double APlower[ALLPASSSECTIONS] = {0.1544, 0.744}; - - - -void WebRtcIsac_AllpassFilterForDec(double *InOut, - const double *APSectionFactors, - int lengthInOut, - double *FilterState) -{ - //This performs all-pass filtering--a series of first order all-pass sections are used - //to filter the input in a cascade manner. - int n,j; - double temp; - for (j=0; j> 12); - } - return; -} diff --git a/src/mod/codecs/mod_isac/filterbank_tables.c b/src/mod/codecs/mod_isac/filterbank_tables.c deleted file mode 100644 index 0f844af9d2..0000000000 --- a/src/mod/codecs/mod_isac/filterbank_tables.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* filterbank_tables.c*/ -/* This file contains variables that are used in filterbanks.c*/ - -#include "filterbank_tables.h" -#include "settings.h" - -/* The composite all-pass filter factors */ -const float WebRtcIsac_kCompositeApFactorsFloat[4] = { - 0.03470000000000f, 0.15440000000000f, 0.38260000000000f, 0.74400000000000f}; - -/* The upper channel all-pass filter factors */ -const float WebRtcIsac_kUpperApFactorsFloat[2] = { - 0.03470000000000f, 0.38260000000000f}; - -/* The lower channel all-pass filter factors */ -const float WebRtcIsac_kLowerApFactorsFloat[2] = { - 0.15440000000000f, 0.74400000000000f}; - -/* The matrix for transforming the backward composite state to upper channel state */ -const float WebRtcIsac_kTransform1Float[8] = { - -0.00158678506084f, 0.00127157815343f, -0.00104805672709f, 0.00084837248079f, - 0.00134467983258f, -0.00107756549387f, 0.00088814793277f, -0.00071893072525f}; - -/* The matrix for transforming the backward composite state to lower channel state */ -const float WebRtcIsac_kTransform2Float[8] = { - -0.00170686041697f, 0.00136780109829f, -0.00112736532350f, 0.00091257055385f, - 0.00103094281812f, -0.00082615076557f, 0.00068092756088f, -0.00055119165484f}; diff --git a/src/mod/codecs/mod_isac/filterbank_tables.h b/src/mod/codecs/mod_isac/filterbank_tables.h deleted file mode 100644 index e8fda5e545..0000000000 --- a/src/mod/codecs/mod_isac/filterbank_tables.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * filterbank_tables.h - * - * Header file for variables that are defined in - * filterbank_tables.c. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_ - -#include "structs.h" - -/********************* Coefficient Tables ************************/ -/* The number of composite all-pass filter factors */ -#define NUMBEROFCOMPOSITEAPSECTIONS 4 - -/* The number of all-pass filter factors in an upper or lower channel*/ -#define NUMBEROFCHANNELAPSECTIONS 2 - -/* The composite all-pass filter factors */ -extern const float WebRtcIsac_kCompositeApFactorsFloat[4]; - -/* The upper channel all-pass filter factors */ -extern const float WebRtcIsac_kUpperApFactorsFloat[2]; - -/* The lower channel all-pass filter factors */ -extern const float WebRtcIsac_kLowerApFactorsFloat[2]; - -/* The matrix for transforming the backward composite state to upper channel state */ -extern const float WebRtcIsac_kTransform1Float[8]; - -/* The matrix for transforming the backward composite state to lower channel state */ -extern const float WebRtcIsac_kTransform2Float[8]; - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_ */ diff --git a/src/mod/codecs/mod_isac/filterbanks.c b/src/mod/codecs/mod_isac/filterbanks.c deleted file mode 100644 index 671fd321ce..0000000000 --- a/src/mod/codecs/mod_isac/filterbanks.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * filterbanks.c - * - * This file contains function WebRtcIsac_AllPassFilter2Float, - * WebRtcIsac_SplitAndFilter, and WebRtcIsac_FilterAndCombine - * which implement filterbanks that produce decimated lowpass and - * highpass versions of a signal, and performs reconstruction. - * - */ - -#include "settings.h" -#include "filterbank_tables.h" -#include "codec.h" - -/* This function performs all-pass filtering--a series of first order all-pass - * sections are used to filter the input in a cascade manner. - * The input is overwritten!! - */ -static void WebRtcIsac_AllPassFilter2Float(float *InOut, const float *APSectionFactors, - int lengthInOut, int NumberOfSections, - float *FilterState) -{ - int n, j; - float temp; - for (j=0; jINLABUFx arrays - each of length QLOOKAHEAD. - The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based - on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input - array in[]. - HP: a FRAMESAMPLES_HALF array of high-pass filtered samples that - have been phase equalized. The first QLOOKAHEAD samples are - based on the samples in the two prefiltdata->INLABUFx arrays - each of length QLOOKAHEAD. - The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based - on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input - array in[]. - - LP_la: a FRAMESAMPLES_HALF array of low-pass filtered samples. - These samples are not phase equalized. They are computed - from the samples in the in[] array. - HP_la: a FRAMESAMPLES_HALF array of high-pass filtered samples - that are not phase equalized. They are computed from - the in[] vector. - prefiltdata: this input data structure's filterbank state and - lookahead sample buffers are updated for the next - encoding iteration. -*/ -void WebRtcIsac_SplitAndFilterFloat(float *pin, float *LP, float *HP, - double *LP_la, double *HP_la, - PreFiltBankstr *prefiltdata) -{ - int k,n; - float CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS]; - float ForTransform_CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS]; - float ForTransform_CompositeAPFilterState2[NUMBEROFCOMPOSITEAPSECTIONS]; - float tempinoutvec[FRAMESAMPLES+MAX_AR_MODEL_ORDER]; - float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER]; - float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER]; - float in[FRAMESAMPLES]; - float ftmp; - - - /* High pass filter */ - - for (k=0;kHPstates_float[0] + - kHpStCoefInFloat[3] * prefiltdata->HPstates_float[1]; - ftmp = pin[k] - kHpStCoefInFloat[0] * prefiltdata->HPstates_float[0] - - kHpStCoefInFloat[1] * prefiltdata->HPstates_float[1]; - prefiltdata->HPstates_float[1] = prefiltdata->HPstates_float[0]; - prefiltdata->HPstates_float[0] = ftmp; - } - - /* - % backwards all-pass filtering to obtain zero-phase - [tmp1(N2+LA:-1:LA+1, 1), state1] = filter(Q.coef, Q.coef(end:-1:1), in(N:-2:2)); - tmp1(LA:-1:1) = filter(Q.coef, Q.coef(end:-1:1), Q.LookAheadBuf1, state1); - Q.LookAheadBuf1 = in(N:-2:N-2*LA+2); - */ - /*Backwards all-pass filter the odd samples of the input (upper channel) - to eventually obtain zero phase. The composite all-pass filter (comprised of both - the upper and lower channel all-pass filsters in series) is used for the - filtering. */ - - /* First Channel */ - - /*initial state of composite filter is zero */ - for (k=0;kINLABUF1_float, - WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD, - NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState); - - /* save the output, but write it in forward order */ - /* write the lookahead samples for the next encoding iteration. Every other - sample at the end of the input frame is written in reverse order for the - lookahead length. Exported in the prefiltdata structure. */ - for (k=0;kINLABUF1_float[k]; - prefiltdata->INLABUF1_float[k]=in[FRAMESAMPLES-1-2*k]; - } - - /* Second Channel. This is exactly like the first channel, except that the - even samples are now filtered instead (lower channel). */ - for (k=0;kINLABUF2_float, - WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,NUMBEROFCOMPOSITEAPSECTIONS, - CompositeAPFilterState); - - for (k=0;kINLABUF2_float[k]; - prefiltdata->INLABUF2_float[k]=in[FRAMESAMPLES-2-2*k]; - } - - /* Transform filter states from backward to forward */ - /*At this point, each of the states of the backwards composite filters for the - two channels are transformed into forward filtering states for the corresponding - forward channel filters. Each channel's forward filtering state from the previous - encoding iteration is added to the transformed state to get a proper forward state */ - - /* So the existing NUMBEROFCOMPOSITEAPSECTIONS x 1 (4x1) state vector is multiplied by a - NUMBEROFCHANNELAPSECTIONSxNUMBEROFCOMPOSITEAPSECTIONS (2x4) transform matrix to get the - new state that is added to the previous 2x1 input state */ - - for (k=0;kINSTAT1_float[k] += ForTransform_CompositeAPFilterState[n]* - WebRtcIsac_kTransform1Float[k*NUMBEROFCHANNELAPSECTIONS+n]; - prefiltdata->INSTAT2_float[k] += ForTransform_CompositeAPFilterState2[n]* - WebRtcIsac_kTransform2Float[k*NUMBEROFCHANNELAPSECTIONS+n]; - } - } - - /*obtain polyphase components by forward all-pass filtering through each channel */ - /* the backward filtered samples are now forward filtered with the corresponding channel filters */ - /* The all pass filtering automatically updates the filter states which are exported in the - prefiltdata structure */ - WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat, - FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_float); - WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat, - FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_float); - - /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ - for (k=0; kINSTATLA1_float); - WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat, - FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA2_float); - - for (k=0; kSTATE_0_UPPER_float); - - /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors - at the decoder are swapped from the ones at the encoder, the 'upper' channel - all-pass filter factors (WebRtcIsac_kUpperApFactorsFloat) are used to filter this new - lower channel signal */ - WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kUpperApFactorsFloat, - FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_float); - - - /* Merge outputs to form the full length output signal.*/ - for (k=0;kHPstates1_float[0] + - kHpStCoefOut1Float[3] * postfiltdata->HPstates1_float[1]; - ftmp = Out[k] - kHpStCoefOut1Float[0] * postfiltdata->HPstates1_float[0] - - kHpStCoefOut1Float[1] * postfiltdata->HPstates1_float[1]; - postfiltdata->HPstates1_float[1] = postfiltdata->HPstates1_float[0]; - postfiltdata->HPstates1_float[0] = ftmp; - Out[k] = ftmp2; - } - - for (k=0;kHPstates2_float[0] + - kHpStCoefOut2Float[3] * postfiltdata->HPstates2_float[1]; - ftmp = Out[k] - kHpStCoefOut2Float[0] * postfiltdata->HPstates2_float[0] - - kHpStCoefOut2Float[1] * postfiltdata->HPstates2_float[1]; - postfiltdata->HPstates2_float[1] = postfiltdata->HPstates2_float[0]; - postfiltdata->HPstates2_float[0] = ftmp; - Out[k] = ftmp2; - } -} diff --git a/src/mod/codecs/mod_isac/get_hanning_window.c b/src/mod/codecs/mod_isac/get_hanning_window.c deleted file mode 100644 index 6d67e60f7a..0000000000 --- a/src/mod/codecs/mod_isac/get_hanning_window.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_GetHanningWindow(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -// Hanning table with 256 entries -static const WebRtc_Word16 kHanningTable[] = { - 1, 2, 6, 10, 15, 22, 30, 39, - 50, 62, 75, 89, 104, 121, 138, 157, - 178, 199, 222, 246, 271, 297, 324, 353, - 383, 413, 446, 479, 513, 549, 586, 624, - 663, 703, 744, 787, 830, 875, 920, 967, - 1015, 1064, 1114, 1165, 1218, 1271, 1325, 1381, - 1437, 1494, 1553, 1612, 1673, 1734, 1796, 1859, - 1924, 1989, 2055, 2122, 2190, 2259, 2329, 2399, - 2471, 2543, 2617, 2691, 2765, 2841, 2918, 2995, - 3073, 3152, 3232, 3312, 3393, 3475, 3558, 3641, - 3725, 3809, 3895, 3980, 4067, 4154, 4242, 4330, - 4419, 4509, 4599, 4689, 4781, 4872, 4964, 5057, - 5150, 5244, 5338, 5432, 5527, 5622, 5718, 5814, - 5910, 6007, 6104, 6202, 6299, 6397, 6495, 6594, - 6693, 6791, 6891, 6990, 7090, 7189, 7289, 7389, - 7489, 7589, 7690, 7790, 7890, 7991, 8091, 8192, - 8293, 8393, 8494, 8594, 8694, 8795, 8895, 8995, - 9095, 9195, 9294, 9394, 9493, 9593, 9691, 9790, - 9889, 9987, 10085, 10182, 10280, 10377, 10474, 10570, -10666, 10762, 10857, 10952, 11046, 11140, 11234, 11327, -11420, 11512, 11603, 11695, 11785, 11875, 11965, 12054, -12142, 12230, 12317, 12404, 12489, 12575, 12659, 12743, -12826, 12909, 12991, 13072, 13152, 13232, 13311, 13389, -13466, 13543, 13619, 13693, 13767, 13841, 13913, 13985, -14055, 14125, 14194, 14262, 14329, 14395, 14460, 14525, -14588, 14650, 14711, 14772, 14831, 14890, 14947, 15003, -15059, 15113, 15166, 15219, 15270, 15320, 15369, 15417, -15464, 15509, 15554, 15597, 15640, 15681, 15721, 15760, -15798, 15835, 15871, 15905, 15938, 15971, 16001, 16031, -16060, 16087, 16113, 16138, 16162, 16185, 16206, 16227, -16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345, -16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384 -}; - -void WebRtcSpl_GetHanningWindow(WebRtc_Word16 *v, WebRtc_Word16 size) -{ - int jj; - WebRtc_Word16 *vptr1; - - WebRtc_Word32 index; - WebRtc_Word32 factor = ((WebRtc_Word32)0x40000000); - - factor = WebRtcSpl_DivW32W16(factor, size); - if (size < 513) - index = (WebRtc_Word32)-0x200000; - else - index = (WebRtc_Word32)-0x100000; - vptr1 = v; - - for (jj = 0; jj < size; jj++) - { - index += factor; - (*vptr1++) = kHanningTable[index >> 22]; - } - -} diff --git a/src/mod/codecs/mod_isac/get_scaling_square.c b/src/mod/codecs/mod_isac/get_scaling_square.c deleted file mode 100644 index dccbf334fd..0000000000 --- a/src/mod/codecs/mod_isac/get_scaling_square.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_GetScalingSquare(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int times) -{ - int nbits = WebRtcSpl_GetSizeInBits(times); - int i; - WebRtc_Word16 smax = -1; - WebRtc_Word16 sabs; - WebRtc_Word16 *sptr = in_vector; - int t; - int looptimes = in_vector_length; - - for (i = looptimes; i > 0; i--) - { - sabs = (*sptr > 0 ? *sptr++ : -*sptr++); - smax = (sabs > smax ? sabs : smax); - } - t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); - - if (smax == 0) - { - return 0; // Since norm(0) returns 0 - } else - { - return (t > nbits) ? 0 : nbits - t; - } -} diff --git a/src/mod/codecs/mod_isac/ilbc_specific_functions.c b/src/mod/codecs/mod_isac/ilbc_specific_functions.c deleted file mode 100644 index 5a9e5773b3..0000000000 --- a/src/mod/codecs/mod_isac/ilbc_specific_functions.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the iLBC specific functions - * WebRtcSpl_ScaleAndAddVectorsWithRound() - * WebRtcSpl_ReverseOrderMultArrayElements() - * WebRtcSpl_ElementwiseVectorMult() - * WebRtcSpl_AddVectorsAndShift() - * WebRtcSpl_AddAffineVectorToVector() - * WebRtcSpl_AffineTransformVector() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16 *vector1, WebRtc_Word16 scale1, - WebRtc_Word16 *vector2, WebRtc_Word16 scale2, - WebRtc_Word16 right_shifts, WebRtc_Word16 *out, - WebRtc_Word16 vector_length) -{ - int i; - WebRtc_Word16 roundVal; - roundVal = 1 << right_shifts; - roundVal = roundVal >> 1; - for (i = 0; i < vector_length; i++) - { - out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(vector1[i], scale1) - + WEBRTC_SPL_MUL_16_16(vector2[i], scale2) + roundVal) >> right_shifts); - } -} - -void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in, - G_CONST WebRtc_Word16 *win, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts) -{ - int i; - WebRtc_Word16 *outptr = out; - G_CONST WebRtc_Word16 *inptr = in; - G_CONST WebRtc_Word16 *winptr = win; - for (i = 0; i < vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, - *winptr--, right_shifts); - } -} - -void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in, - G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts) -{ - int i; - WebRtc_Word16 *outptr = out; - G_CONST WebRtc_Word16 *inptr = in; - G_CONST WebRtc_Word16 *winptr = win; - for (i = 0; i < vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, - *winptr++, right_shifts); - } -} - -void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1, - G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts) -{ - int i; - WebRtc_Word16 *outptr = out; - G_CONST WebRtc_Word16 *in1ptr = in1; - G_CONST WebRtc_Word16 *in2ptr = in2; - for (i = vector_length; i > 0; i--) - { - (*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts); - } -} - -void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in, - WebRtc_Word16 gain, WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, int vector_length) -{ - WebRtc_Word16 *inPtr; - WebRtc_Word16 *outPtr; - int i; - - inPtr = in; - outPtr = out; - for (i = 0; i < vector_length; i++) - { - (*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain) - + (WebRtc_Word32)add_constant) >> right_shifts); - } -} - -void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in, - WebRtc_Word16 gain, WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, int vector_length) -{ - WebRtc_Word16 *inPtr; - WebRtc_Word16 *outPtr; - int i; - - inPtr = in; - outPtr = out; - for (i = 0; i < vector_length; i++) - { - (*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain) - + (WebRtc_Word32)add_constant) >> right_shifts); - } -} diff --git a/src/mod/codecs/mod_isac/intialize.c b/src/mod/codecs/mod_isac/intialize.c deleted file mode 100644 index 6df034d1c7..0000000000 --- a/src/mod/codecs/mod_isac/intialize.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* encode.c - Encoding function for the iSAC coder */ - -#include "structs.h" -#include "codec.h" -#include "pitch_estimator.h" - -#include - -void WebRtcIsac_InitMasking(MaskFiltstr *maskdata) { - - int k; - - for (k = 0; k < WINLEN; k++) { - maskdata->DataBufferLo[k] = 0.0; - maskdata->DataBufferHi[k] = 0.0; - } - for (k = 0; k < ORDERLO+1; k++) { - maskdata->CorrBufLo[k] = 0.0; - maskdata->PreStateLoF[k] = 0.0; - maskdata->PreStateLoG[k] = 0.0; - maskdata->PostStateLoF[k] = 0.0; - maskdata->PostStateLoG[k] = 0.0; - } - for (k = 0; k < ORDERHI+1; k++) { - maskdata->CorrBufHi[k] = 0.0; - maskdata->PreStateHiF[k] = 0.0; - maskdata->PreStateHiG[k] = 0.0; - maskdata->PostStateHiF[k] = 0.0; - maskdata->PostStateHiG[k] = 0.0; - } - - maskdata->OldEnergy = 10.0; - - /* fill tables for transforms */ - WebRtcIsac_InitTransform(); - - return; -} - -void WebRtcIsac_InitPreFilterbank(PreFiltBankstr *prefiltdata) -{ - int k; - - for (k = 0; k < QLOOKAHEAD; k++) { - prefiltdata->INLABUF1[k] = 0; - prefiltdata->INLABUF2[k] = 0; - - prefiltdata->INLABUF1_float[k] = 0; - prefiltdata->INLABUF2_float[k] = 0; - } - for (k = 0; k < 2*(QORDER-1); k++) { - prefiltdata->INSTAT1[k] = 0; - prefiltdata->INSTAT2[k] = 0; - prefiltdata->INSTATLA1[k] = 0; - prefiltdata->INSTATLA2[k] = 0; - - prefiltdata->INSTAT1_float[k] = 0; - prefiltdata->INSTAT2_float[k] = 0; - prefiltdata->INSTATLA1_float[k] = 0; - prefiltdata->INSTATLA2_float[k] = 0; - } - - /* High pass filter states */ - prefiltdata->HPstates[0] = 0.0; - prefiltdata->HPstates[1] = 0.0; - - prefiltdata->HPstates_float[0] = 0.0f; - prefiltdata->HPstates_float[1] = 0.0f; - - return; -} - -void WebRtcIsac_InitPostFilterbank(PostFiltBankstr *postfiltdata) -{ - int k; - - for (k = 0; k < 2*POSTQORDER; k++) { - postfiltdata->STATE_0_LOWER[k] = 0; - postfiltdata->STATE_0_UPPER[k] = 0; - - postfiltdata->STATE_0_LOWER_float[k] = 0; - postfiltdata->STATE_0_UPPER_float[k] = 0; - } - - /* High pass filter states */ - postfiltdata->HPstates1[0] = 0.0; - postfiltdata->HPstates1[1] = 0.0; - - postfiltdata->HPstates2[0] = 0.0; - postfiltdata->HPstates2[1] = 0.0; - - postfiltdata->HPstates1_float[0] = 0.0f; - postfiltdata->HPstates1_float[1] = 0.0f; - - postfiltdata->HPstates2_float[0] = 0.0f; - postfiltdata->HPstates2_float[1] = 0.0f; - - return; -} - - -void WebRtcIsac_InitPitchFilter(PitchFiltstr *pitchfiltdata) -{ - int k; - - for (k = 0; k < PITCH_BUFFSIZE; k++) { - pitchfiltdata->ubuf[k] = 0.0; - } - pitchfiltdata->ystate[0] = 0.0; - for (k = 1; k < (PITCH_DAMPORDER); k++) { - pitchfiltdata->ystate[k] = 0.0; - } - pitchfiltdata->oldlagp[0] = 50.0; - pitchfiltdata->oldgainp[0] = 0.0; -} - -void WebRtcIsac_InitWeightingFilter(WeightFiltstr *wfdata) -{ - int k; - double t, dtmp, dtmp2, denum, denum2; - - for (k=0;kbuffer[k]=0.0; - - for (k=0;kistate[k]=0.0; - wfdata->weostate[k]=0.0; - wfdata->whostate[k]=0.0; - } - - /* next part should be in Matlab, writing to a global table */ - t = 0.5; - denum = 1.0 / ((double) PITCH_WLPCWINLEN); - denum2 = denum * denum; - for (k=0;kwindow[k] = dtmp2 * dtmp2; - t++; - } -} - -/* clear all buffers */ -void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct *State) -{ - int k; - - for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++) - State->dec_buffer[k] = 0.0; - for (k = 0; k < 2*ALLPASSSECTIONS+1; k++) - State->decimator_state[k] = 0.0; - for (k = 0; k < 2; k++) - State->hp_state[k] = 0.0; - for (k = 0; k < QLOOKAHEAD; k++) - State->whitened_buf[k] = 0.0; - for (k = 0; k < QLOOKAHEAD; k++) - State->inbuf[k] = 0.0; - - WebRtcIsac_InitPitchFilter(&(State->PFstr_wght)); - - WebRtcIsac_InitPitchFilter(&(State->PFstr)); - - WebRtcIsac_InitWeightingFilter(&(State->Wghtstr)); -} diff --git a/src/mod/codecs/mod_isac/isac.c b/src/mod/codecs/mod_isac/isac.c deleted file mode 100644 index 6c03726fca..0000000000 --- a/src/mod/codecs/mod_isac/isac.c +++ /dev/null @@ -1,2797 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * isac.c - * - * This C file contains the functions for the ISAC API - * - */ - -#include "isac.h" -#include "bandwidth_estimator.h" -#include "crc.h" -#include "entropy_coding.h" -#include "codec.h" -#include "structs.h" -#include "signal_processing_library.h" -#include "lpc_shape_swb16_tables.h" -#include "os_specific_inline.h" - -#include -#include -#include -#include - -#define BIT_MASK_DEC_INIT 0x0001 -#define BIT_MASK_ENC_INIT 0x0002 - -#define LEN_CHECK_SUM_WORD8 4 -#define MAX_NUM_LAYERS 10 - - -/**************************************************************************** - * UpdatePayloadSizeLimit() - * - * Call this function to update the limit on the payload size. The limit on - * payload size might change i) if a user ''directly changes the limit by - * calling xxx_setMaxPayloadSize() or xxx_setMaxRate(), or ii) indirectly - * when bandwidth is changing. The latter might be the result of bandwidth - * adaptation, or direct change of the bottleneck in instantaneous mode. - * - * This function takes the current overall limit on payload, and translate it - * to the limits on lower and upper-band. If the codec is in wideband mode - * then the overall limit and the limit on the lower-band is the same. - * Otherwise, a fraction of the limit should be allocated to lower-band - * leaving some room for the upper-band bit-stream. That is why an update - * of limit is required every time that the bandwidth is changing. - * - */ -static void UpdatePayloadSizeLimit( - ISACMainStruct *instISAC) -{ - WebRtc_Word16 lim30MsPayloadBytes; - WebRtc_Word16 lim60MsPayloadBytes; - - lim30MsPayloadBytes = WEBRTC_SPL_MIN( - (instISAC->maxPayloadSizeBytes), - (instISAC->maxRateBytesPer30Ms)); - - lim60MsPayloadBytes = WEBRTC_SPL_MIN( - (instISAC->maxPayloadSizeBytes), - (instISAC->maxRateBytesPer30Ms << 1)); - - // The only time that iSAC will have 60 ms - // frame-size is when operating in wideband so - // there is no upper-band bit-stream - - if(instISAC->bandwidthKHz == isac8kHz) - { - // at 8 kHz there is no upper-band bit-stream - // therefore the lower-band limit is as the overall - // limit. - instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 = - lim60MsPayloadBytes; - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - lim30MsPayloadBytes; - } - else - { - // when in super-wideband, we only have 30 ms frames - // Do a rate allocation for the given limit. - if(lim30MsPayloadBytes > 250) - { - // 4/5 to lower-band the rest for upper-band - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - (lim30MsPayloadBytes << 2) / 5; - } - else if(lim30MsPayloadBytes > 200) - { - // for the interval of 200 to 250 the share of - // upper-band linearly grows from 20 to 50; - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - (lim30MsPayloadBytes << 1) / 5 + 100; - } - else - { - // allocate only 20 for upper-band - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - lim30MsPayloadBytes - 20; - } - instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes = - lim30MsPayloadBytes; - } -} - - -/**************************************************************************** - * UpdateBottleneck() - * - * This function updates the bottleneck only if the codec is operating in - * channel-adaptive mode. Furthermore, as the update of bottleneck might - * result in an update of bandwidth, therefore, the bottlenech should be - * updated just right before the first 10ms of a frame is pushed into encoder. - * - */ -static void UpdateBottleneck( - ISACMainStruct *instISAC) -{ - // read the bottleneck from bandwidth estimator for the - // first 10 ms audio. This way, if there is a change - // in bandwidth upper and lower-band will be in sync. - if((instISAC->codingMode == 0) && - (instISAC->instLB.ISACencLB_obj.buffer_index == 0) && - (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) - { - WebRtc_Word32 bottleneck; - WebRtcIsac_GetUplinkBandwidth(&(instISAC->bwestimator_obj), - &bottleneck); - - // Adding hysteresis when increasing signal bandwidth - if((instISAC->bandwidthKHz == isac8kHz) - && (bottleneck > 37000) - && (bottleneck < 41000)) - { - bottleneck = 37000; - } - - // switching from 12 kHz to 16 kHz is not allowed at this revision - // If we let this happen, we have to take care of buffer_index and - // the last LPC vector. - if((instISAC->bandwidthKHz != isac16kHz) && - (bottleneck > 46000)) - { - bottleneck = 46000; - } - - // we might need a rate allocation. - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - // wideband is the only choise we have here. - instISAC->instLB.ISACencLB_obj.bottleneck = - (bottleneck > 32000)? 32000:bottleneck; - instISAC->bandwidthKHz = isac8kHz; - } - else - { - // do the rate-allosation and get the new bandwidth. - enum ISACBandwidth bandwidth; - WebRtcIsac_RateAllocation(bottleneck, - &(instISAC->instLB.ISACencLB_obj.bottleneck), - &(instISAC->instUB.ISACencUB_obj.bottleneck), - &bandwidth); - if(bandwidth != isac8kHz) - { - instISAC->instLB.ISACencLB_obj.new_framelength = 480; - } - if(bandwidth != instISAC->bandwidthKHz) - { - // bandwidth is changing. - instISAC->bandwidthKHz = bandwidth; - UpdatePayloadSizeLimit(instISAC); - if(bandwidth == isac12kHz) - { - instISAC->instLB.ISACencLB_obj.buffer_index = 0; - } - // currently we don't let the bandwidth to switch to 16 kHz - // if in adaptive mode. If we let this happen, we have to take - // car of buffer_index and the last LPC vector. - } - } - } -} - - -/**************************************************************************** - * GetSendBandwidthInfo() - * - * This is called to get the bandwidth info. This info is the bandwidth and - * and the jitter of 'there-to-here' channel, estimated 'here.' These info - * is signaled in an in-band fashion to the otherside. - * - * The call to the bandwidth estimator trigers a recursive averaging which - * has to be synchronized between encoder & decoder, therefore. The call to - * BWE should be once per packet. As the BWE info is inserted into bit-stream - * we need a valid info right before the encodeLB function is going to - * generating a bit-stream. That is when lower-band buffer has already 20ms - * of audio, and the 3rd block of 10ms is going to be injected into encoder. - * - * Inputs: - * - instISAC : iSAC instance. - * - * Outputs: - * - bandwidthIndex : an index which has to be encoded in - * lower-band bit-stream, indicating the - * bandwidth of there-to-here channel. - * - jitterInfo : this indicates if the jitter is high - * or low and it is encoded in upper-band - * bit-stream. - * - */ -static void GetSendBandwidthInfo( - ISACMainStruct* instISAC, - WebRtc_Word16* bandwidthIndex, - WebRtc_Word16* jitterInfo) -{ - if((instISAC->instLB.ISACencLB_obj.buffer_index == - (FRAMESAMPLES_10ms << 1)) && - (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) - { - /* bandwidth estimation and coding */ - WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), - bandwidthIndex, jitterInfo, instISAC->decoderSamplingRateKHz); - } -} - - -/**************************************************************************** - * WebRtcIsac_AssignSize(...) - * - * This function returns the size of the ISAC instance, so that the instance - * can be created out side iSAC. - * - * Output: - * - sizeinbytes : number of bytes needed to allocate for the - * instance. - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_AssignSize( - int *sizeInBytes) -{ - *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(WebRtc_Word16); - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_Assign(...) - * - * This function assignes the memory already created to the ISAC instance. - * - * Input: - * - ISAC_main_inst : address of the pointer to the coder instance. - * - instISAC_Addr : the already allocaded memeory, where we put the - * iSAC struct - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_Assign( - ISACStruct** ISAC_main_inst, - void* instISAC_Addr) -{ - if(instISAC_Addr != NULL) - { - ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr; - instISAC->errorCode = 0; - instISAC->initFlag = 0; - - // Assign the address - *ISAC_main_inst = (ISACStruct*)instISAC_Addr; - - // Default is wideband. - instISAC->encoderSamplingRateKHz = kIsacWideband; - instISAC->decoderSamplingRateKHz = kIsacWideband; - instISAC->bandwidthKHz = isac8kHz; - return 0; - } - else - { - return -1; - } -} - - -/**************************************************************************** - * WebRtcIsac_Create(...) - * - * This function creates an ISAC instance, which will contain the state - * information for one coding/decoding channel. - * - * Input: - * - ISAC_main_inst : address of the pointer to the coder instance. - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_Create( - ISACStruct** ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)WEBRTC_SPL_VNEW(ISACMainStruct, 1); - *ISAC_main_inst = (ISACStruct*)instISAC; - if(*ISAC_main_inst != NULL) - { - instISAC->errorCode = 0; - instISAC->initFlag = 0; - // Default is wideband - instISAC->bandwidthKHz = isac8kHz; - instISAC->encoderSamplingRateKHz = kIsacWideband; - instISAC->decoderSamplingRateKHz = kIsacWideband; - return 0; - } - else - { - return -1; - } -} - - -/**************************************************************************** - * WebRtcIsac_Free(...) - * - * This function frees the ISAC instance created at the beginning. - * - * Input: - * - ISAC_main_inst : a ISAC instance. - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_Free( - ISACStruct* ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - WEBRTC_SPL_FREE(instISAC); - return 0; -} - - -/**************************************************************************** - * EncoderInitLb(...) - internal function for initialization of - * Lower Band - * EncoderInitUb(...) - internal function for initialization of - * Upper Band - * WebRtcIsac_EncoderInit(...) - API function - * - * This function initializes a ISAC instance prior to the encoder calls. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - CodingMode : 0 -> Bit rate and frame length are automatically - * adjusted to available bandwidth on - * transmission channel, applicable just to - * wideband mode. - * 1 -> User sets a frame length and a target bit - * rate which is taken as the maximum - * short-term average bit rate. - * - * Return value : 0 - Ok - * -1 - Error - */ -static WebRtc_Word16 EncoderInitLb( - ISACLBStruct* instLB, - WebRtc_Word16 codingMode, - enum IsacSamplingRate sampRate) -{ - WebRtc_Word16 statusInit = 0; - int k; - - /* Init stream vector to zero */ - for(k=0; k < STREAM_SIZE_MAX_60; k++) - { - instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0; - } - - if((codingMode == 1) || (sampRate == kIsacSuperWideband)) - { - // 30 ms frame-size if either in super-wideband or - // instanteneous mode (I-mode) - instLB->ISACencLB_obj.new_framelength = 480; - } - else - { - instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES; - } - - WebRtcIsac_InitMasking(&instLB->ISACencLB_obj.maskfiltstr_obj); - WebRtcIsac_InitPreFilterbank(&instLB->ISACencLB_obj.prefiltbankstr_obj); - WebRtcIsac_InitPitchFilter(&instLB->ISACencLB_obj.pitchfiltstr_obj); - WebRtcIsac_InitPitchAnalysis( - &instLB->ISACencLB_obj.pitchanalysisstr_obj); - - - instLB->ISACencLB_obj.buffer_index = 0; - instLB->ISACencLB_obj.frame_nb = 0; - /* default for I-mode */ - instLB->ISACencLB_obj.bottleneck = 32000; - instLB->ISACencLB_obj.current_framesamples = 0; - instLB->ISACencLB_obj.s2nr = 0; - instLB->ISACencLB_obj.payloadLimitBytes30 = STREAM_SIZE_MAX_30; - instLB->ISACencLB_obj.payloadLimitBytes60 = STREAM_SIZE_MAX_60; - instLB->ISACencLB_obj.maxPayloadBytes = STREAM_SIZE_MAX_60; - instLB->ISACencLB_obj.maxRateInBytes = STREAM_SIZE_MAX_30; - instLB->ISACencLB_obj.enforceFrameSize = 0; - /* invalid value prevents getRedPayload to - run before encoder is called */ - instLB->ISACencLB_obj.lastBWIdx = -1; - return statusInit; -} - -static WebRtc_Word16 EncoderInitUb( - ISACUBStruct* instUB, - WebRtc_Word16 bandwidth) -{ - WebRtc_Word16 statusInit = 0; - int k; - - /* Init stream vector to zero */ - for(k = 0; k < STREAM_SIZE_MAX_60; k++) - { - instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0; - } - - WebRtcIsac_InitMasking(&instUB->ISACencUB_obj.maskfiltstr_obj); - WebRtcIsac_InitPreFilterbank(&instUB->ISACencUB_obj.prefiltbankstr_obj); - - if(bandwidth == isac16kHz) - { - instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES; - } - else - { - instUB->ISACencUB_obj.buffer_index = 0; - } - /* default for I-mode */ - instUB->ISACencUB_obj.bottleneck = 32000; - // These store the limits for the wideband + super-wideband bit-stream. - instUB->ISACencUB_obj.maxPayloadSizeBytes = STREAM_SIZE_MAX_30 << 1; - // This has to be updated after each lower-band encoding to guarantee - // a correct payload-limitation. - instUB->ISACencUB_obj.numBytesUsed = 0; - memset(instUB->ISACencUB_obj.data_buffer_float, 0, - (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES) * sizeof(float)); - - memcpy(&(instUB->ISACencUB_obj.lastLPCVec), - WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); - - return statusInit; -} - - -WebRtc_Word16 WebRtcIsac_EncoderInit( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 codingMode) -{ - ISACMainStruct *instISAC; - WebRtc_Word16 status; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if((codingMode != 0) && (codingMode != 1)) - { - instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE; - return -1; - } - // default bottleneck - instISAC->bottleneck = MAX_ISAC_BW; - - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - instISAC->bandwidthKHz = isac8kHz; - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; - } - else - { - instISAC->bandwidthKHz = isac16kHz; - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; - } - - // Channel-adaptive = 0; Instantaneous (Channel-independent) = 1; - instISAC->codingMode = codingMode; - - WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, - instISAC->encoderSamplingRateKHz, - instISAC->decoderSamplingRateKHz); - - WebRtcIsac_InitRateModel(&instISAC->rate_data_obj); - /* default for I-mode */ - instISAC->MaxDelay = 10.0; - - status = EncoderInitLb(&instISAC->instLB, codingMode, - instISAC->encoderSamplingRateKHz); - if(status < 0) - { - instISAC->errorCode = -status; - return -1; - } - - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - // Initialize encoder filter-bank. - memset(instISAC->analysisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->analysisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - status = EncoderInitUb(&(instISAC->instUB), - instISAC->bandwidthKHz); - if(status < 0) - { - instISAC->errorCode = -status; - return -1; - } - } - // Initializtion is successful, set the flag - instISAC->initFlag |= BIT_MASK_ENC_INIT; - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_Encode(...) - * - * This function encodes 10ms frame(s) and inserts it into a package. - * Input speech length has to be 160 samples (10ms). The encoder buffers those - * 10ms frames until it reaches the chosen Framesize (480 or 960 samples - * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - speechIn : input speech vector. - * - * Output: - * - encoded : the encoded data vector - * - * Return value: - * : >0 - Length (in bytes) of coded data - * : 0 - The buffer didn't reach the chosen - * frameSize so it keeps buffering speech - * samples. - * : -1 - Error - */ -WebRtc_Word16 WebRtcIsac_Encode( - ISACStruct* ISAC_main_inst, - const WebRtc_Word16* speechIn, - WebRtc_Word16* encoded) -{ - ISACMainStruct* instISAC; - ISACLBStruct* instLB; - ISACUBStruct* instUB; - - float inFrame[FRAMESAMPLES_10ms]; - WebRtc_Word16 speechInLB[FRAMESAMPLES_10ms]; - WebRtc_Word16 speechInUB[FRAMESAMPLES_10ms]; - WebRtc_Word16 streamLenLB; - WebRtc_Word16 streamLenUB; - WebRtc_Word16 streamLen; - WebRtc_Word16 k; - WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; - int garbageLen; - WebRtc_Word32 bottleneck; - WebRtc_Word16 bottleneckIdx = 0; - WebRtc_Word16 jitterInfo = 0; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - instLB = &(instISAC->instLB); - instUB = &(instISAC->instUB); - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - WebRtcSpl_AnalysisQMF(speechIn, speechInLB, speechInUB, - instISAC->analysisFBState1, instISAC->analysisFBState2); - - /* convert from fixed to floating point */ - for(k = 0; k < FRAMESAMPLES_10ms; k++) - { - inFrame[k] = (float)speechInLB[k]; - } - } - else - { - for(k = 0; k < FRAMESAMPLES_10ms; k++) - { - inFrame[k] = (float) speechIn[k]; - } - } - - /* add some noise to avoid denormal numbers */ - inFrame[0] += (float)1.23455334e-3; - inFrame[1] -= (float)2.04324239e-3; - inFrame[2] += (float)1.90854954e-3; - inFrame[9] += (float)1.84854878e-3; - - - // This function will update the bottleneck if required - UpdateBottleneck(instISAC); - - // Get the bandwith information which has to be sent to the other side - GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo); - - // - // ENCODE LOWER-BAND - // - streamLenLB = WebRtcIsac_EncodeLb(inFrame, &instLB->ISACencLB_obj, - instISAC->codingMode, bottleneckIdx); - - if(streamLenLB < 0) - { - return -1; - } - - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - instUB = &(instISAC->instUB); - - // convert to float - for(k = 0; k < FRAMESAMPLES_10ms; k++) - { - inFrame[k] = (float) speechInUB[k]; - } - - /* add some noise to avoid denormal numbers */ - inFrame[0] += (float)1.23455334e-3; - inFrame[1] -= (float)2.04324239e-3; - inFrame[2] += (float)1.90854954e-3; - inFrame[9] += (float)1.84854878e-3; - - // Tell to upper-band the number of bytes used so far. - // This is for payload limitation. - instUB->ISACencUB_obj.numBytesUsed = streamLenLB + 1 + - LEN_CHECK_SUM_WORD8; - - // - // ENCODE UPPER-BAND - // - switch(instISAC->bandwidthKHz) - { - case isac12kHz: - { - streamLenUB = WebRtcIsac_EncodeUb12(inFrame, - &instUB->ISACencUB_obj, - jitterInfo); - break; - } - case isac16kHz: - { - streamLenUB = WebRtcIsac_EncodeUb16(inFrame, - &instUB->ISACencUB_obj, - jitterInfo); - break; - } - case isac8kHz: - { - streamLenUB = 0; - break; - } - default: - return -1; - } - - if((streamLenUB < 0) && - (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) - { - // an error has happened but this is not the error due to a - // bit-stream larger than the limit - return -1; - } - - if(streamLenLB == 0) - { - return 0; - } - - // One bite is allocated for the length. According to older decoders - // so the length bit-stream plus one byte for size and - // LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal - // to 255. - if((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) || - (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) - { - // we have got a too long bit-stream we skip the upper-band - // bit-stream for this frame. - streamLenUB = 0; - } - - memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, - streamLenLB); - streamLen = streamLenLB; - if(streamLenUB > 0) - { - ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)(streamLenUB + 1 + - LEN_CHECK_SUM_WORD8); - memcpy(&ptrEncodedUW8[streamLenLB + 1], - instUB->ISACencUB_obj.bitstr_obj.stream, streamLenUB); - streamLen += ptrEncodedUW8[streamLenLB]; - } - else - { - ptrEncodedUW8[streamLenLB] = 0; - } - } - else - { - if(streamLenLB == 0) - { - return 0; - } - memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, - streamLenLB); - streamLenUB = 0; - streamLen = streamLenLB; - } - - // Add Garbage if required. - WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj, &bottleneck); - if(instISAC->codingMode == 0) - { - int minBytes; - int limit; - WebRtc_UWord8* ptrGarbage; - - instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay( - &instISAC->bwestimator_obj); - - /* update rate model and get minimum number of bytes in this packet */ - minBytes = WebRtcIsac_GetMinBytes(&(instISAC->rate_data_obj), - streamLen, instISAC->instLB.ISACencLB_obj.current_framesamples, - bottleneck, instISAC->MaxDelay, instISAC->bandwidthKHz); - - /* Make sure MinBytes does not exceed packet size limit */ - if(instISAC->bandwidthKHz == isac8kHz) - { - if(instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES) - { - limit = instLB->ISACencLB_obj.payloadLimitBytes30; - } - else - { - limit = instLB->ISACencLB_obj.payloadLimitBytes60; - } - } - else - { - limit = instUB->ISACencUB_obj.maxPayloadSizeBytes; - } - minBytes = (minBytes > limit)? limit:minBytes; - - /* Make sure we don't allow more than 255 bytes of garbage data. - We store the length of the garbage data in 8 bits in the bitstream, - 255 is the max garbage length we can signal using 8 bits. */ - if((instISAC->bandwidthKHz == isac8kHz) || - (streamLenUB == 0)) - { - ptrGarbage = &ptrEncodedUW8[streamLenLB]; - limit = streamLen + 255; - } - else - { - ptrGarbage = &ptrEncodedUW8[streamLenLB + 1 + streamLenUB]; - limit = streamLen + (255 - ptrEncodedUW8[streamLenLB]); - } - minBytes = (minBytes > limit)? limit:minBytes; - - garbageLen = (minBytes > streamLen)? (minBytes - streamLen):0; - - /* Save data for creation of multiple bitstreams */ - //ISACencLB_obj->SaveEnc_obj.minBytes = MinBytes; - - /* if bitstream is too short, add garbage at the end */ - if(garbageLen > 0) - { - for(k = 0; k < garbageLen; k++) - { - ptrGarbage[k] = (WebRtc_UWord8)(rand() & 0xFF); - } - - // for a correct length of the upper-band bit-stream together - // with the garbage. Garbage is embeded in upper-band bit-stream. - // That is the only way to preserve backward compatibility. - if((instISAC->bandwidthKHz == isac8kHz) || - (streamLenUB == 0)) - { - ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)garbageLen; - } - else - { - ptrEncodedUW8[streamLenLB] += (WebRtc_UWord8)garbageLen; - // write the length of the garbage at the end of the upper-band - // bit-stream, if exists. This helps for sanity check. - ptrEncodedUW8[streamLenLB + 1 + streamLenUB] = (WebRtc_UWord8)garbageLen; - - } - - streamLen += garbageLen; - } - } - else - { - /* update rate model */ - WebRtcIsac_UpdateRateModel(&instISAC->rate_data_obj, streamLen, - instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck); - garbageLen = 0; - } - - // Generate CRC if required. - if((instISAC->bandwidthKHz != isac8kHz) && - (streamLenUB > 0)) - { - WebRtc_UWord32 crc; - - WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), - streamLenUB + garbageLen, &crc); -#ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = - (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); - } -#else - memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, - LEN_CHECK_SUM_WORD8); -#endif - } - - return streamLen; -} - - -/****************************************************************************** - * WebRtcIsac_GetNewBitStream(...) - * - * This function returns encoded data, with the recieved bwe-index in the - * stream. If the rate is set to a value less than bottleneck of codec - * the new bistream will be re-encoded with the given target rate. - * It should always return a complete packet, i.e. only called once - * even for 60 msec frames. - * - * NOTE 1! This function does not write in the ISACStruct, it is not allowed. - * NOTE 3! Rates larger than the bottleneck of the codec will be limited - * to the current bottleneck. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - bweIndex : Index of bandwidth estimate to put in new - * bitstream - * - rate : target rate of the transcoder is bits/sec. - * Valid values are the accepted rate in iSAC, - * i.e. 10000 to 56000. - * - * Output: - * - encoded : The encoded data vector - * - * Return value : >0 - Length (in bytes) of coded data - * -1 - Error or called in SWB mode - * NOTE! No error code is written to - * the struct since it is only allowed to read - * the struct. - */ -WebRtc_Word16 WebRtcIsac_GetNewBitStream( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 bweIndex, - WebRtc_Word16 jitterInfo, - WebRtc_Word32 rate, - WebRtc_Word16* encoded, - WebRtc_Word16 isRCU) -{ - Bitstr iSACBitStreamInst; /* Local struct for bitstream handling */ - WebRtc_Word16 streamLenLB; - WebRtc_Word16 streamLenUB; - WebRtc_Word16 totalStreamLen; - double gain2; - double gain1; - float scale; - enum ISACBandwidth bandwidthKHz; - double rateLB; - double rateUB; - WebRtc_Word32 currentBN; - ISACMainStruct* instISAC; - WebRtc_UWord8* encodedPtrUW8 = (WebRtc_UWord8*)encoded; - WebRtc_UWord32 crc; -#ifndef WEBRTC_BIG_ENDIAN - WebRtc_Word16 k; -#endif - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - return -1; - } - - // Get the bottleneck of this iSAC and limit the - // given rate to the current bottleneck. - WebRtcIsac_GetUplinkBw(ISAC_main_inst, ¤tBN); - if(rate > currentBN) - { - rate = currentBN; - } - - if(WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0) - { - return -1; - } - - // Cannot transcode from 16 kHz to 12 kHz - if((bandwidthKHz == isac12kHz) && - (instISAC->bandwidthKHz == isac16kHz)) - { - return -1; - } - - // These gains are in dB - // gain for the given rate. - gain1 = WebRtcIsac_GetSnr(rateLB, - instISAC->instLB.ISACencLB_obj.current_framesamples); - // gain of this iSAC - gain2 = WebRtcIsac_GetSnr( - instISAC->instLB.ISACencLB_obj.bottleneck, - instISAC->instLB.ISACencLB_obj.current_framesamples); - - // scale is the ratio of two gains in normal domain. - scale = (float)pow(10, (gain1 - gain2) / 20.0); - // change the scale if this is a RCU bit-stream. - scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE):scale; - - streamLenLB = WebRtcIsac_EncodeStoredDataLb( - &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, &iSACBitStreamInst, - bweIndex, scale); - - if(streamLenLB < 0) - { - return -1; - } - - /* convert from bytes to WebRtc_Word16 */ - memcpy(encoded, iSACBitStreamInst.stream, streamLenLB); - - if(bandwidthKHz == isac8kHz) - { - return streamLenLB; - } - - totalStreamLen = streamLenLB; - // super-wideband is always at 30ms. - // These gains are in dB - // gain for the given rate. - gain1 = WebRtcIsac_GetSnr(rateUB, FRAMESAMPLES); - // gain of this iSAC - gain2 = WebRtcIsac_GetSnr( - instISAC->instUB.ISACencUB_obj.bottleneck, FRAMESAMPLES); - - // scale is the ratio of two gains in normal domain. - scale = (float)pow(10, (gain1 - gain2) / 20.0); - - // change the scale if this is a RCU bit-stream. - scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB):scale; - - switch(instISAC->bandwidthKHz) - { - case isac12kHz: - { - streamLenUB = WebRtcIsac_EncodeStoredDataUb12( - &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), - &iSACBitStreamInst, jitterInfo, scale); - break; - } - case isac16kHz: - { - streamLenUB = WebRtcIsac_EncodeStoredDataUb16( - &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), - &iSACBitStreamInst, jitterInfo, scale); - break; - } - default: - return -1; - } - - if(streamLenUB < 0) - { - return -1; - } - - if(streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255) - { - return streamLenLB; - } - - totalStreamLen = streamLenLB + streamLenUB + 1 + LEN_CHECK_SUM_WORD8; - encodedPtrUW8[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; - - memcpy(&encodedPtrUW8[streamLenLB+1], iSACBitStreamInst.stream, - streamLenUB); - - WebRtcIsac_GetCrc((WebRtc_Word16*)(&(encodedPtrUW8[streamLenLB + 1])), - streamLenUB, &crc); -#ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - encodedPtrUW8[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] = - (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); - } -#else - memcpy(&encodedPtrUW8[streamLenLB + streamLenUB + 1], &crc, - LEN_CHECK_SUM_WORD8); -#endif - - - return totalStreamLen; -} - - -/**************************************************************************** - * DecoderInitLb(...) - internal function for initialization of - * Lower Band - * DecoderInitUb(...) - internal function for initialization of - * Upper Band - * WebRtcIsac_DecoderInit(...) - API function - * - * This function initializes a ISAC instance prior to the decoder calls. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - * Return value - * : 0 - Ok - * -1 - Error - */ -static WebRtc_Word16 DecoderInitLb( - ISACLBStruct* instISAC) -{ - int i; - /* Init stream vector to zero */ - for (i=0; iISACdecLB_obj.bitstr_obj.stream[i] = 0; - } - - WebRtcIsac_InitMasking(&instISAC->ISACdecLB_obj.maskfiltstr_obj); - WebRtcIsac_InitPostFilterbank( - &instISAC->ISACdecLB_obj.postfiltbankstr_obj); - WebRtcIsac_InitPitchFilter(&instISAC->ISACdecLB_obj.pitchfiltstr_obj); - - return (0); -} - -static WebRtc_Word16 DecoderInitUb( - ISACUBStruct* instISAC) -{ - int i; - /* Init stream vector to zero */ - for (i = 0; i < STREAM_SIZE_MAX_60; i++) - { - instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0; - } - - WebRtcIsac_InitMasking(&instISAC->ISACdecUB_obj.maskfiltstr_obj); - WebRtcIsac_InitPostFilterbank( - &instISAC->ISACdecUB_obj.postfiltbankstr_obj); - return (0); -} - -WebRtc_Word16 WebRtcIsac_DecoderInit( - ISACStruct *ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if(DecoderInitLb(&instISAC->instLB) < 0) - { - return -1; - } - - if(instISAC->decoderSamplingRateKHz == kIsacSuperWideband) - { - memset(instISAC->synthesisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->synthesisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - if(DecoderInitUb(&(instISAC->instUB)) < 0) - { - return -1; - } - } - - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, - instISAC->encoderSamplingRateKHz, - instISAC->decoderSamplingRateKHz); - } - - instISAC->initFlag |= BIT_MASK_DEC_INIT; - - instISAC->resetFlag_8kHz = 0; - - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_UpdateBwEstimate(...) - * - * This function updates the estimate of the bandwidth. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - encoded : encoded ISAC frame(s). - * - packet_size : size of the packet. - * - rtp_seq_number : the RTP number of the packet. - * - arr_ts : the arrival time of the packet (from NetEq) - * in samples. - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_UpdateBwEstimate( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word32 packet_size, - WebRtc_UWord16 rtp_seq_number, - WebRtc_UWord32 send_ts, - WebRtc_UWord32 arr_ts) -{ - ISACMainStruct *instISAC; - Bitstr streamdata; -#ifndef WEBRTC_BIG_ENDIAN - int k; -#endif - WebRtc_Word16 err; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* check if decoder initiated */ - if((instISAC->initFlag & BIT_MASK_DEC_INIT) != - BIT_MASK_DEC_INIT) - { - instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; - return -1; - } - - if(packet_size <= 0) - { - /* return error code if the packet length is null */ - instISAC->errorCode = ISAC_EMPTY_PACKET; - return -1; - } - - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - -#ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < 10; k++) - { - streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >> - ((k&1) << 3)) & 0xFF); - } -#else - memcpy(streamdata.stream, encoded, 10); -#endif - - err = WebRtcIsac_EstimateBandwidth(&instISAC->bwestimator_obj, &streamdata, - packet_size, rtp_seq_number, send_ts, arr_ts, - instISAC->encoderSamplingRateKHz, - instISAC->decoderSamplingRateKHz); - - if(err < 0) - { - /* return error code if something went wrong */ - instISAC->errorCode = -err; - return -1; - } - - return 0; -} - -static WebRtc_Word16 Decode( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 lenEncodedBytes, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType, - WebRtc_Word16 isRCUPayload) -{ - /* number of samples (480 or 960), output from decoder - that were actually used in the encoder/decoder - (determined on the fly) */ - ISACMainStruct* instISAC; - ISACUBDecStruct* decInstUB; - ISACLBDecStruct* decInstLB; - - WebRtc_Word16 numSamplesLB; - WebRtc_Word16 numSamplesUB; - WebRtc_Word16 speechIdx; - float outFrame[MAX_FRAMESAMPLES]; - WebRtc_Word16 outFrameLB[MAX_FRAMESAMPLES]; - WebRtc_Word16 outFrameUB[MAX_FRAMESAMPLES]; - WebRtc_Word16 numDecodedBytesLB; - WebRtc_Word16 numDecodedBytesUB; - WebRtc_Word16 lenEncodedLBBytes; - WebRtc_Word16 validChecksum = 1; - WebRtc_Word16 k; - WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; - WebRtc_UWord16 numLayer; - WebRtc_Word16 totSizeBytes; - WebRtc_Word16 err; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - decInstUB = &(instISAC->instUB.ISACdecUB_obj); - decInstLB = &(instISAC->instLB.ISACdecLB_obj); - - /* check if decoder initiated */ - if((instISAC->initFlag & BIT_MASK_DEC_INIT) != - BIT_MASK_DEC_INIT) - { - instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; - return -1; - } - - if(lenEncodedBytes <= 0) - { - /* return error code if the packet length is null */ - instISAC->errorCode = ISAC_EMPTY_PACKET; - return -1; - } - - // the size of the rncoded lower-band is bounded by - // STREAM_SIZE_MAX, - // If a payload with the size larger than STREAM_SIZE_MAX - // is received, it is not considered erroneous. - lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX) - ? STREAM_SIZE_MAX:lenEncodedBytes; - - // Copy to lower-band bit-stream structure - memcpy(instISAC->instLB.ISACdecLB_obj.bitstr_obj.stream, ptrEncodedUW8, - lenEncodedLBBytes); - - // Regardless of that the current codec is setup to work in - // wideband or super-wideband, the decoding of the lower-band - // has to be performed. - numDecodedBytesLB = WebRtcIsac_DecodeLb(outFrame, decInstLB, - &numSamplesLB, isRCUPayload); - - // Check for error - if((numDecodedBytesLB < 0) || - (numDecodedBytesLB > lenEncodedLBBytes) || - (numSamplesLB > MAX_FRAMESAMPLES)) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - - // Error Check, we accept multi-layer bit-stream - // This will limit number of iterations of the - // while loop. Even withouut this the number of iterations - // is limited. - numLayer = 1; - totSizeBytes = numDecodedBytesLB; - while(totSizeBytes != lenEncodedBytes) - { - if((totSizeBytes > lenEncodedBytes) || - (ptrEncodedUW8[totSizeBytes] == 0) || - (numLayer > MAX_NUM_LAYERS)) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - totSizeBytes += ptrEncodedUW8[totSizeBytes]; - numLayer++; - } - - if(instISAC->decoderSamplingRateKHz == kIsacWideband) - { - for(k = 0; k < numSamplesLB; k++) - { - if(outFrame[k] > 32767) - { - decoded[k] = 32767; - } - else if(outFrame[k] < -32768) - { - decoded[k] = -32768; - } - else - { - decoded[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); - } - } - numSamplesUB = 0; - } - else - { - WebRtc_UWord32 crc; - // We don't accept larger than 30ms (480 samples at lower-band) - // frame-size. - for(k = 0; k < numSamplesLB; k++) - { - if(outFrame[k] > 32767) - { - outFrameLB[k] = 32767; - } - else if(outFrame[k] < -32768) - { - outFrameLB[k] = -32768; - } - else - { - outFrameLB[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); - } - } - - //numSamplesUB = numSamplesLB; - - // Check for possible error, and if upper-band stream exist. - if(numDecodedBytesLB == lenEncodedBytes) - { - // Decoding was successful. No super-wideband bitstream - // exists. - numSamplesUB = numSamplesLB; - memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); - - // Prepare for the potential increase of signal bandwidth - instISAC->resetFlag_8kHz = 2; - } - else - { - // this includes the check sum and the bytes that stores the - // length - WebRtc_Word16 lenNextStream = ptrEncodedUW8[numDecodedBytesLB]; - - // Is this garbage or valid super-wideband bit-stream? - // Check if checksum is valid - if(lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1)) - { - // such a small second layer cannot be super-wideband layer. - // It must be a short garbage. - validChecksum = 0; - } - else - { - // Run CRC to see if the checksum match. - WebRtcIsac_GetCrc((WebRtc_Word16*)( - &ptrEncodedUW8[numDecodedBytesLB + 1]), - lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc); - - validChecksum = 1; - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) == - ptrEncodedUW8[numDecodedBytesLB + lenNextStream - - LEN_CHECK_SUM_WORD8 + k]); - } - } - - if(!validChecksum) - { - // this is a garbage, we have received a wideband - // bit-stream with garbage - numSamplesUB = numSamplesLB; - memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); - } - else - { - // A valid super-wideband biststream exists. - enum ISACBandwidth bandwidthKHz; - WebRtc_Word32 maxDelayBit; - - //instISAC->bwestimator_obj.incomingStreamSampFreq = - // kIsacSuperWideband; - // If we have super-wideband bit-stream, we cannot - // have 60 ms frame-size. - if(numSamplesLB > FRAMESAMPLES) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - - // the rest of the bit-stream contains the upper-band - // bit-stream curently this is the only thing there, - // however, we might add more layers. - - // Have to exclude one byte where the length is stored - // and last 'LEN_CHECK_SUM_WORD8' bytes where the - // checksum is stored. - lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1); - - memcpy(decInstUB->bitstr_obj.stream, - &ptrEncodedUW8[numDecodedBytesLB + 1], lenNextStream); - - // THIS IS THE FIRST DECODING - decInstUB->bitstr_obj.W_upper = 0xFFFFFFFF; - decInstUB->bitstr_obj.streamval = 0; - decInstUB->bitstr_obj.stream_index = 0; - - // Decode jitter infotmation - err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, - &maxDelayBit); - // error check - if(err < 0) - { - instISAC->errorCode = -err; - return -1; - } - - // Update jitter info which is in the upper-band bit-stream - // only if the encoder is in super-wideband. Otherwise, - // the jitter info is already embeded in bandwidth index - // and has been updated. - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - err = WebRtcIsac_UpdateUplinkJitter( - &(instISAC->bwestimator_obj), maxDelayBit); - if(err < 0) - { - instISAC->errorCode = -err; - return -1; - } - } - - // decode bandwidth information - err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj, - &bandwidthKHz); - if(err < 0) - { - instISAC->errorCode = -err; - return -1; - } - - switch(bandwidthKHz) - { - case isac12kHz: - { - numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame, - decInstUB, isRCUPayload); - - // Hang-over for transient alleviation - - // wait two frames to add the upper band going up from 8 kHz - if (instISAC->resetFlag_8kHz > 0) - { - if (instISAC->resetFlag_8kHz == 2) - { - // Silence first and a half frame - memset(outFrame, 0, MAX_FRAMESAMPLES * - sizeof(float)); - } - else - { - const float rampStep = 2.0f / MAX_FRAMESAMPLES; - float rampVal = 0; - memset(outFrame, 0, (MAX_FRAMESAMPLES>>1) * - sizeof(float)); - - // Ramp up second half of second frame - for(k = MAX_FRAMESAMPLES/2; k < MAX_FRAMESAMPLES; k++) - { - outFrame[k] *= rampVal; - rampVal += rampStep; - } - } - instISAC->resetFlag_8kHz -= 1; - } - - break; - } - case isac16kHz: - { - numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame, - decInstUB, isRCUPayload); - break; - } - default: - return -1; - } - - // it might be less due to garbage. - if((numDecodedBytesUB != lenNextStream) && - (numDecodedBytesUB != (lenNextStream - ptrEncodedUW8[ - numDecodedBytesLB + 1 + numDecodedBytesUB]))) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - - // If there is no error Upper-band always decodes - // 30 ms (480 samples) - numSamplesUB = FRAMESAMPLES; - - // Convert to W16 - for(k = 0; k < numSamplesUB; k++) - { - if(outFrame[k] > 32767) - { - outFrameUB[k] = 32767; - } - else if(outFrame[k] < -32768) - { - outFrameUB[k] = -32768; - } - else - { - outFrameUB[k] = (WebRtc_Word16)WebRtcIsac_lrint( - outFrame[k]); - } - } - } - } - - speechIdx = 0; - while(speechIdx < numSamplesLB) - { - WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], - &outFrameUB[speechIdx], &decoded[(speechIdx<<1)], - instISAC->synthesisFBState1, instISAC->synthesisFBState2); - - speechIdx += FRAMESAMPLES_10ms; - } - } - *speechType = 0; - return (numSamplesLB + numSamplesUB); -} - - - - - - - -/**************************************************************************** - * WebRtcIsac_Decode(...) - * - * This function decodes a ISAC frame. Output speech length - * will be a multiple of 480 samples: 480 or 960 samples, - * depending on the frameSize (30 or 60 ms). - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - encoded : encoded ISAC frame(s) - * - len : bytes in encoded vector - * - * Output: - * - decoded : The decoded vector - * - * Return value : >0 - number of samples in decoded vector - * -1 - Error - */ - -WebRtc_Word16 WebRtcIsac_Decode( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 lenEncodedBytes, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType) -{ - WebRtc_Word16 isRCUPayload = 0; - return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, - speechType, isRCUPayload); -} - -/**************************************************************************** - * WebRtcIsac_DecodeRcu(...) - * - * This function decodes a redundant (RCU) iSAC frame. Function is called in - * NetEq with a stored RCU payload i case of packet loss. Output speech length - * will be a multiple of 480 samples: 480 or 960 samples, - * depending on the framesize (30 or 60 ms). - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - encoded : encoded ISAC RCU frame(s) - * - len : bytes in encoded vector - * - * Output: - * - decoded : The decoded vector - * - * Return value : >0 - number of samples in decoded vector - * -1 - Error - */ - - - -WebRtc_Word16 WebRtcIsac_DecodeRcu( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 lenEncodedBytes, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType) -{ - WebRtc_Word16 isRCUPayload = 1; - return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, - speechType, isRCUPayload); -} - - -/**************************************************************************** - * WebRtcIsac_DecodePlc(...) - * - * This function conducts PLC for ISAC frame(s). Output speech length - * will be a multiple of 480 samples: 480 or 960 samples, - * depending on the frameSize (30 or 60 ms). - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - noOfLostFrames : Number of PLC frames to produce - * - * Output: - * - decoded : The decoded vector - * - * Return value : >0 - number of samples in decoded PLC vector - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_DecodePlc( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* decoded, - WebRtc_Word16 noOfLostFrames) -{ - WebRtc_Word16 numSamples; - ISACMainStruct* instISAC; - - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; - - /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */ - if(noOfLostFrames > 2) - { - noOfLostFrames = 2; - } - - /* Get the number of samples per frame */ - switch(instISAC->decoderSamplingRateKHz) - { - case kIsacWideband: - { - numSamples = 480 * noOfLostFrames; - break; - } - case kIsacSuperWideband: - { - numSamples = 960 * noOfLostFrames; - break; - } - default: - return -1; - } - - /* Set output samples to zero */ - memset(decoded, 0, numSamples * sizeof(WebRtc_Word16)); - return numSamples; -} - - -/**************************************************************************** - * ControlLb(...) - Internal function for controling Lower Band - * ControlUb(...) - Internal function for controling Upper Band - * WebRtcIsac_Control(...) - API function - * - * This function sets the limit on the short-term average bit rate and the - * frame length. Should be used only in Instantaneous mode. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - rate : limit on the short-term average bit rate, - * in bits/second (between 10000 and 32000) - * - frameSize : number of milliseconds per frame (30 or 60) - * - * Return value : 0 - ok - * -1 - Error - */ -static WebRtc_Word16 ControlLb( - ISACLBStruct* instISAC, - double rate, - WebRtc_Word16 frameSize) -{ - if((rate >= 10000) && (rate <= 32000)) - { - instISAC->ISACencLB_obj.bottleneck = rate; - } - else - { - return -ISAC_DISALLOWED_BOTTLENECK; - } - - if((frameSize == 30) || (frameSize == 60)) - { - instISAC->ISACencLB_obj.new_framelength = (FS/1000) * frameSize; - } - else - { - return -ISAC_DISALLOWED_FRAME_LENGTH; - } - - return 0; -} - -static WebRtc_Word16 ControlUb( - ISACUBStruct* instISAC, - double rate) -{ - if((rate >= 10000) && (rate <= 32000)) - { - instISAC->ISACencUB_obj.bottleneck = rate; - } - else - { - return -ISAC_DISALLOWED_BOTTLENECK; - } - return 0; -} - -WebRtc_Word16 WebRtcIsac_Control( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 bottleneckBPS, - WebRtc_Word16 frameSize) -{ - ISACMainStruct *instISAC; - WebRtc_Word16 status; - double rateLB; - double rateUB; - enum ISACBandwidth bandwidthKHz; - - - /* Typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if(instISAC->codingMode == 0) - { - /* in adaptive mode */ - instISAC->errorCode = ISAC_MODE_MISMATCH; - return -1; - } - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - // if the sampling rate is 16kHz then bandwith should be 8kHz, - // regardless of bottleneck. - bandwidthKHz = isac8kHz; - rateLB = (bottleneckBPS > 32000)? 32000:bottleneckBPS; - rateUB = 0; - } - else - { - if(WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, - &bandwidthKHz) < 0) - { - return -1; - } - } - - if((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) && - (frameSize != 30) && - (bandwidthKHz != isac8kHz)) - { - // Cannot have 60 ms in super-wideband - instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; - return -1; - } - - status = ControlLb(&instISAC->instLB, rateLB, frameSize); - if(status < 0) - { - instISAC->errorCode = -status; - return -1; - } - if(bandwidthKHz != isac8kHz) - { - status = ControlUb(&(instISAC->instUB), rateUB); - if(status < 0) - { - instISAC->errorCode = -status; - return -1; - } - } - - // - // Check if bandwidth is changing from wideband to super-wideband - // then we have to synch data buffer of lower & upper-band. also - // clean up the upper-band data buffer. - // - if((instISAC->bandwidthKHz == isac8kHz) && - (bandwidthKHz != isac8kHz)) - { - memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0, - sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES)); - - if(bandwidthKHz == isac12kHz) - { - instISAC->instUB.ISACencUB_obj.buffer_index = - instISAC->instLB.ISACencLB_obj.buffer_index; - } - else - { - instISAC->instUB.ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES + - instISAC->instLB.ISACencLB_obj.buffer_index; - - memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec), - WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); - } - } - - // update the payload limit it the bandwidth is changing. - if(instISAC->bandwidthKHz != bandwidthKHz) - { - instISAC->bandwidthKHz = bandwidthKHz; - UpdatePayloadSizeLimit(instISAC); - } - instISAC->bottleneck = bottleneckBPS; - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_ControlBwe(...) - * - * This function sets the initial values of bottleneck and frame-size if - * iSAC is used in channel-adaptive mode. Through this API, users can - * enforce a frame-size for all values of bottleneck. Then iSAC will not - * automatically change the frame-size. - * - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - rateBPS : initial value of bottleneck in bits/second - * 10000 <= rateBPS <= 32000 is accepted - * For default bottleneck set rateBPS = 0 - * - frameSizeMs : number of milliseconds per frame (30 or 60) - * - enforceFrameSize : 1 to enforce the given frame-size through out - * the adaptation process, 0 to let iSAC change - * the frame-size if required. - * - * Return value : 0 - ok - * -1 - Error - */ -WebRtc_Word16 WebRtcIsac_ControlBwe( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 bottleneckBPS, - WebRtc_Word16 frameSizeMs, - WebRtc_Word16 enforceFrameSize) -{ - ISACMainStruct *instISAC; - enum ISACBandwidth bandwidth; - - /* Typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - /* Check that we are in channel-adaptive mode, otherwise, return (-1) */ - if(instISAC->codingMode != 0) - { - instISAC->errorCode = ISAC_MODE_MISMATCH; - return -1; - } - if((frameSizeMs != 30) && - (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) - { - return -1; - } - - /* Set struct variable if enforceFrameSize is set. ISAC will then */ - /* keep the chosen frame size. */ - if((enforceFrameSize != 0) /*|| - (instISAC->samplingRateKHz == kIsacSuperWideband)*/) - { - instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1; - } - else - { - instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0; - } - - /* Set initial rate, if value between 10000 and 32000, */ - /* if rateBPS is 0, keep the default initial bottleneck value (15000) */ - if(bottleneckBPS != 0) - { - double rateLB; - double rateUB; - if(WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, &bandwidth) < 0) - { - return -1; - } - instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS; - instISAC->bandwidthKHz = bandwidth; - } - - /* Set initial frameSize. If enforceFrameSize is set the frame size will - not change */ - if(frameSizeMs != 0) - { - if((frameSizeMs == 30) || (frameSizeMs == 60)) - { - instISAC->instLB.ISACencLB_obj.new_framelength = (FS/1000) * - frameSizeMs; - //instISAC->bwestimator_obj.rec_header_rate = ((float)HEADER_SIZE * - // 8.0f * 1000.0f / (float)frameSizeMs); - } - else - { - instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; - return -1; - } - } - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_GetDownLinkBwIndex(...) - * - * This function returns index representing the Bandwidth estimate from - * other side to this side. - * - * Input: - * - ISAC_main_inst : iSAC struct - * - * Output: - * - bweIndex : Bandwidth estimate to transmit to other side. - * - */ -WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* bweIndex, - WebRtc_Word16* jitterInfo) -{ - ISACMainStruct *instISAC; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_DEC_INIT) != - BIT_MASK_DEC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - /* Call function to get Bandwidth Estimate */ - WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), - bweIndex, jitterInfo, instISAC->decoderSamplingRateKHz); - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_UpdateUplinkBw(...) - * - * This function takes an index representing the Bandwidth estimate from - * this side to other side and updates BWE. - * - * Input: - * - ISAC_main_inst : iSAC struct - * - rateIndex : Bandwidth estimate from other side. - * - * Return value : 0 - ok - * -1 - index out of range - */ -WebRtc_Word16 WebRtcIsac_UpdateUplinkBw( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 bweIndex) -{ - ISACMainStruct *instISAC; - WebRtc_Word16 returnVal; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - /* Call function to get Bandwidth Estimate */ - returnVal = WebRtcIsac_UpdateUplinkBwImpl( - &(instISAC->bwestimator_obj), bweIndex, - instISAC->encoderSamplingRateKHz); - - if(returnVal < 0) - { - instISAC->errorCode = -returnVal; - return -1; - } - else - { - return 0; - } -} - - -/**************************************************************************** - * WebRtcIsac_ReadBwIndex(...) - * - * This function returns the index of the Bandwidth estimate from the - * bitstream. - * - * Input: - * - encoded : Encoded bitstream - * - * Output: - * - frameLength : Length of frame in packet (in samples) - * - bweIndex : Bandwidth estimate in bitstream - * - */ -WebRtc_Word16 WebRtcIsac_ReadBwIndex( - const WebRtc_Word16* encoded, - WebRtc_Word16* bweIndex) -{ - Bitstr streamdata; -#ifndef WEBRTC_BIG_ENDIAN - int k; -#endif - WebRtc_Word16 err; - - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - -#ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < 10; k++) - { - streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >> - ((k&1) << 3)) & 0xFF); - } -#else - memcpy(streamdata.stream, encoded, 10); -#endif - - /* decode frame length */ - err = WebRtcIsac_DecodeFrameLen(&streamdata, bweIndex); - if(err < 0) - { - return err; - } - - /* decode BW estimation */ - err = WebRtcIsac_DecodeSendBW(&streamdata, bweIndex); - if(err < 0) - { - return err; - } - - return 0; -} - - -/**************************************************************************** - * WebRtcIsac_ReadFrameLen(...) - * - * This function returns the length of the frame represented in the packet. - * - * Input: - * - encoded : Encoded bitstream - * - * Output: - * - frameLength : Length of frame in packet (in samples) - * - */ -WebRtc_Word16 WebRtcIsac_ReadFrameLen( - ISACStruct* ISAC_main_inst, - const WebRtc_Word16* encoded, - WebRtc_Word16* frameLength) -{ - Bitstr streamdata; -#ifndef WEBRTC_BIG_ENDIAN - int k; -#endif - WebRtc_Word16 err; - ISACMainStruct* instISAC; - - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - -#ifndef WEBRTC_BIG_ENDIAN - for (k=0; k<10; k++) { - streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >> - ((k&1) << 3)) & 0xFF); - } -#else - memcpy(streamdata.stream, encoded, 10); -#endif - - /* decode frame length */ - err = WebRtcIsac_DecodeFrameLen(&streamdata, frameLength); - if(err < 0) { - return -1; - } - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if(instISAC->decoderSamplingRateKHz == kIsacSuperWideband) - { - // the decoded frame length indicates the number of samples in - // lower-band in this case, multiply by 2 to get the total number - // of samples. - *frameLength <<= 1; - } - - return 0; -} - - -/******************************************************************************* - * WebRtcIsac_GetNewFrameLen(...) - * - * returns the frame lenght (in samples) of the next packet. In the case of - * channel-adaptive mode, iSAC decides on its frame lenght based on the - * estimated bottleneck this allows a user to prepare for the next packet - * (at the encoder). - * - * The primary usage is in CE to make the iSAC works in channel-adaptive mode - * - * Input: - * - ISAC_main_inst : iSAC struct - * - * Return Value : frame lenght in samples - * - */ -WebRtc_Word16 WebRtcIsac_GetNewFrameLen( - ISACStruct *ISAC_main_inst) -{ - ISACMainStruct *instISAC; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* Return new frame length */ - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - return (instISAC->instLB.ISACencLB_obj.new_framelength); - } - else - { - return ((instISAC->instLB.ISACencLB_obj.new_framelength) << 1); - } -} - - -/**************************************************************************** - * WebRtcIsac_GetErrorCode(...) - * - * This function can be used to check the error code of an iSAC instance. - * When a function returns -1 a error code will be set for that instance. - * The function below extract the code of the last error that occured in - * the specified instance. - * - * Input: - * - ISAC_main_inst : ISAC instance - * - * Return value : Error code - */ -WebRtc_Word16 WebRtcIsac_GetErrorCode( - ISACStruct *ISAC_main_inst) -{ - ISACMainStruct *instISAC; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - return (instISAC->errorCode); -} - - -/**************************************************************************** - * WebRtcIsac_GetUplinkBw(...) - * - * This function outputs the target bottleneck of the codec. In - * channel-adaptive mode, the target bottleneck is specified through in-band - * signalling retreived by bandwidth estimator. - * In channel-independent, also called instantaneous mode, the target - * bottleneck is provided to the encoder by calling xxx_control(...) (if - * xxx_control is never called the default values is). - * Note that the output is the iSAC internal operating bottleneck whch might - * differ slightly from the one provided through xxx_control(). - * - * Input: - * - ISAC_main_inst : iSAC instance - * - * Output: - * - *bottleneck : bottleneck in bits/sec - * - * Return value : -1 if error happens - * 0 bit-rates computed correctly. - */ -WebRtc_Word16 WebRtcIsac_GetUplinkBw( - ISACStruct* ISAC_main_inst, - WebRtc_Word32* bottleneck) -{ - ISACMainStruct* instISAC = (ISACMainStruct *)ISAC_main_inst; - - if(instISAC->codingMode == 0) - { - // we are in adaptive mode then get the bottleneck from BWE - *bottleneck = (WebRtc_Word32)instISAC->bwestimator_obj.send_bw_avg; - } - else - { - *bottleneck = instISAC->bottleneck; - } - - if((*bottleneck > 32000) && (*bottleneck < 38000)) - { - *bottleneck = 32000; - } - else if((*bottleneck > 45000) && (*bottleneck < 50000)) - { - *bottleneck = 45000; - } - else if(*bottleneck > 56000) - { - *bottleneck = 56000; - } - - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_SetMaxPayloadSize(...) - * - * This function sets a limit for the maximum payload size of iSAC. The same - * value is used both for 30 and 60 ms packets. If the encoder sampling rate - * is 16 kHz the maximum payload size is between 120 and 400 bytes. If the - * encoder sampling rate is 32 kHz the maximum payload size is between 120 - * and 600 bytes. - * - * --------------- - * IMPORTANT NOTES - * --------------- - * The size of a packet is limited to the minimum of 'max-payload-size' and - * 'max-rate.' For instance, let's assume the max-payload-size is set to - * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps - * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms - * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, - * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to - * 170 bytes, i.e. min(170, 300). - * - * Input: - * - ISAC_main_inst : iSAC instance - * - maxPayloadBytes : maximum size of the payload in bytes - * valid values are between 100 and 400 bytes - * if encoder sampling rate is 16 kHz. For - * 32 kHz encoder sampling rate valid values - * are between 100 and 600 bytes. - * - * Return value : 0 if successful - * -1 if error happens - */ -WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 maxPayloadBytes) -{ - ISACMainStruct *instISAC; - WebRtc_Word16 status = 0; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - // sanity check - if(maxPayloadBytes < 120) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = 120; - status = -1; - } - - /* sanity check */ - if(maxPayloadBytes > STREAM_SIZE_MAX) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = STREAM_SIZE_MAX; - status = -1; - } - } - else - { - if(maxPayloadBytes < 120) - { - // max payload-size is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = 120; - status = -1; - } - if(maxPayloadBytes > STREAM_SIZE_MAX_60) - { - // max payload-size is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = STREAM_SIZE_MAX_60; - status = -1; - } - } - instISAC->maxPayloadSizeBytes = maxPayloadBytes; - UpdatePayloadSizeLimit(instISAC); - return status; -} - - -/****************************************************************************** - * WebRtcIsac_SetMaxRate(...) - * - * This function sets the maximum rate which the codec may not exceed for - * any signal packet. The maximum rate is defined and payload-size per - * frame-size in bits per second. - * - * The codec has a maximum rate of 53400 bits per second (200 bytes per 30 - * ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms) - * if the encoder sampling rate is 32 kHz. - * - * It is possible to set a maximum rate between 32000 and 53400 bits/sec - * in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode. - * - * --------------- - * IMPORTANT NOTES - * --------------- - * The size of a packet is limited to the minimum of 'max-payload-size' and - * 'max-rate.' For instance, let's assume the max-payload-size is set to - * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps - * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms - * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, - * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to - * 170 bytes, min(170, 300). - * - * Input: - * - ISAC_main_inst : iSAC instance - * - maxRate : maximum rate in bits per second, - * valid values are 32000 to 53400 bits/sec in - * wideband mode, and 32000 to 160000 bits/sec in - * super-wideband mode. - * - * Return value : 0 if successful - * -1 if error happens - */ -WebRtc_Word16 WebRtcIsac_SetMaxRate( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 maxRate) -{ - ISACMainStruct *instISAC; - WebRtc_Word16 maxRateInBytesPer30Ms; - WebRtc_Word16 status = 0; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - /* - Calculate maximum number of bytes per 30 msec packets for the - given maximum rate. Multiply with 30/1000 to get number of - bits per 30 ms, divide by 8 to get number of bytes per 30 ms: - maxRateInBytes = floor((maxRate * 30/1000) / 8); - */ - maxRateInBytesPer30Ms = (WebRtc_Word16)(maxRate*3/800); - - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - if(maxRate < 32000) - { - // max rate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = 120; - status = -1; - } - - if(maxRate > 53400) - { - // max rate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = 200; - status = -1; - } - } - else - { - if(maxRateInBytesPer30Ms < 120) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = 120; - status = -1; - } - - if(maxRateInBytesPer30Ms > STREAM_SIZE_MAX) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = STREAM_SIZE_MAX; - status = -1; - } - } - instISAC->maxRateBytesPer30Ms = maxRateInBytesPer30Ms; - UpdatePayloadSizeLimit(instISAC); - return status; -} - - -/**************************************************************************** - * WebRtcIsac_GetRedPayload(...) - * - * Populates "encoded" with the redundant payload of the recently encoded - * frame. This function has to be called once that WebRtcIsac_Encode(...) - * returns a positive value. Regardless of the frame-size this function will - * be called only once after encoding is completed. The bit-stream is - * targeted for 16000 bit/sec. - * - * Input: - * - ISAC_main_inst : iSAC struct - * - * Output: - * - encoded : the encoded data vector - * - * - * Return value : >0 - Length (in bytes) of coded data - * : -1 - Error - * - * - */ -WebRtc_Word16 WebRtcIsac_GetRedPayload( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* encoded) -{ - ISACMainStruct* instISAC; - Bitstr iSACBitStreamInst; - WebRtc_Word16 streamLenLB; - WebRtc_Word16 streamLenUB; - WebRtc_Word16 streamLen; - WebRtc_Word16 totalLenUB; - WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; -#ifndef WEBRTC_BIG_ENDIAN - int k; -#endif - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; - - - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - } - - - iSACBitStreamInst.W_upper = 0xFFFFFFFF; - iSACBitStreamInst.streamval = 0; - iSACBitStreamInst.stream_index = 0; - - - streamLenLB = WebRtcIsac_EncodeStoredDataLb( - &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, - &iSACBitStreamInst, - instISAC->instLB.ISACencLB_obj.lastBWIdx, - RCU_TRANSCODING_SCALE); - - if(streamLenLB < 0) - { - return -1; - } - - /* convert from bytes to WebRtc_Word16 */ - memcpy(ptrEncodedUW8, iSACBitStreamInst.stream, streamLenLB); - - streamLen = streamLenLB; - - if(instISAC->bandwidthKHz == isac8kHz) - { - return streamLenLB; - } - - streamLenUB = WebRtcIsac_GetRedPayloadUb( - &instISAC->instUB.ISACencUB_obj.SaveEnc_obj, - &iSACBitStreamInst, instISAC->bandwidthKHz); - - if(streamLenUB < 0) - { - // an error has happened but this is not the error due to a - // bit-stream larger than the limit - return -1; - } - - // We have one byte to write the total length of the upper band - // the length include the bitstream length, check-sum and the - // single byte where the length is written to. This is according to - // iSAC wideband and how the "garbage" is dealt. - totalLenUB = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; - if(totalLenUB > 255) - { - streamLenUB = 0; - } - - // Generate CRC if required. - if((instISAC->bandwidthKHz != isac8kHz) && - (streamLenUB > 0)) - { - WebRtc_UWord32 crc; - streamLen += totalLenUB; - ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)totalLenUB; - memcpy(&ptrEncodedUW8[streamLenLB+1], iSACBitStreamInst.stream, streamLenUB); - - WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), - streamLenUB, &crc); -#ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = - (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); - } -#else - memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, - LEN_CHECK_SUM_WORD8); -#endif - } - - - return streamLen; -} - - -/**************************************************************************** - * WebRtcIsac_version(...) - * - * This function returns the version number. - * - * Output: - * - version : Pointer to character string - * - */ -void WebRtcIsac_version(char *version) -{ - strcpy(version, "4.3.0"); -} - - -/****************************************************************************** - * WebRtcIsac_SetEncSampRate() - * Set the sampling rate of the encoder. Initialization of the encoder WILL - * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz - * which is set when the instance is created. The encoding-mode and the - * bottleneck remain unchanged by this call, however, the maximum rate and - * maximum payload-size will reset to their default value. - * - * Input: - * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. - * - * Return value : 0 if successful - * -1 if failed. - */ -WebRtc_Word16 WebRtcIsac_SetEncSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if((sampRate != kIsacWideband) && - (sampRate != kIsacSuperWideband)) - { - // Sampling Frequency is not supported - instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; - return -1; - } - else if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - if(sampRate == kIsacWideband) - { - instISAC->bandwidthKHz = isac8kHz; - } - else - { - instISAC->bandwidthKHz = isac16kHz; - } - instISAC->encoderSamplingRateKHz = sampRate; - return 0; - } - else - { - ISACUBStruct* instUB = &(instISAC->instUB); - ISACLBStruct* instLB = &(instISAC->instLB); - double bottleneckLB = 0; - double bottleneckUB = 0; - WebRtc_Word32 bottleneck = instISAC->bottleneck; - WebRtc_Word16 codingMode = instISAC->codingMode; - WebRtc_Word16 frameSizeMs = instLB->ISACencLB_obj.new_framelength / (FS / 1000); - - if((sampRate == kIsacWideband) && - (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) - { - // changing from super-wideband to wideband. - // we don't need to re-initialize the encoder of the - // lower-band. - instISAC->bandwidthKHz = isac8kHz; - if(codingMode == 1) - { - ControlLb(instLB, - (bottleneck > 32000)? 32000:bottleneck, FRAMESIZE); - } - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; - } - else if((sampRate == kIsacSuperWideband) && - (instISAC->encoderSamplingRateKHz == kIsacWideband)) - { - if(codingMode == 1) - { - WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB, - &(instISAC->bandwidthKHz)); - } - - instISAC->bandwidthKHz = isac16kHz; - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; - - EncoderInitLb(instLB, codingMode, sampRate); - EncoderInitUb(instUB, instISAC->bandwidthKHz); - - memset(instISAC->analysisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->analysisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - if(codingMode == 1) - { - instISAC->bottleneck = bottleneck; - ControlLb(instLB, bottleneckLB, - (instISAC->bandwidthKHz == isac8kHz)? frameSizeMs:FRAMESIZE); - if(instISAC->bandwidthKHz > isac8kHz) - { - ControlUb(instUB, bottleneckUB); - } - } - else - { - instLB->ISACencLB_obj.enforceFrameSize = 0; - instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES; - } - } - instISAC->encoderSamplingRateKHz = sampRate; - return 0; - } -} - - -/****************************************************************************** - * WebRtcIsac_SetDecSampRate() - * Set the sampling rate of the decoder. Initialization of the decoder WILL - * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz - * which is set when the instance is created. - * - * Input: - * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. - * - * Return value : 0 if successful - * -1 if failed. - */ -WebRtc_Word16 WebRtcIsac_SetDecSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if((sampRate != kIsacWideband) && - (sampRate != kIsacSuperWideband)) - { - // Sampling Frequency is not supported - instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; - return -1; - } - else - { - if((instISAC->decoderSamplingRateKHz == kIsacWideband) && - (sampRate == kIsacSuperWideband)) - { - // switching from wideband to super-wideband at the decoder - // we need to reset the filter-bank and initialize - // upper-band decoder. - memset(instISAC->synthesisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->synthesisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - if(DecoderInitUb(&(instISAC->instUB)) < 0) - { - return -1; - } - } - instISAC->decoderSamplingRateKHz = sampRate; - return 0; - } -} - - -/****************************************************************************** - * WebRtcIsac_EncSampRate() - * - * Input: - * - ISAC_main_inst : iSAC instance - * - * Return value : enumerator representing sampling frequency - * associated with the encoder, the input audio - * is expected to be sampled at this rate. - * - */ -enum IsacSamplingRate WebRtcIsac_EncSampRate( - ISACStruct* ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - return instISAC->encoderSamplingRateKHz; -} - - -/****************************************************************************** - * WebRtcIsac_DecSampRate() - * Return the sampling rate of the decoded audio. - * - * Input: - * - ISAC_main_inst : iSAC instance - * - * Return value : enumerator representing sampling frequency - * associated with the decoder, i.e. the - * sampling rate of the decoded audio. - * - */ -enum IsacSamplingRate WebRtcIsac_DecSampRate( - ISACStruct* ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - - return instISAC->decoderSamplingRateKHz; -} diff --git a/src/mod/codecs/mod_isac/isac.gypi b/src/mod/codecs/mod_isac/isac.gypi deleted file mode 100644 index d30be551bd..0000000000 --- a/src/mod/codecs/mod_isac/isac.gypi +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'targets': [ - { - 'target_name': 'iSAC', - 'type': '<(library)', - 'dependencies': [ - '<(webrtc_root)/common_audio/common_audio.gyp:signal_processing', - ], - 'include_dirs': [ - '../interface', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../interface', - ], - }, - 'sources': [ - '../interface/isac.h', - 'arith_routines.c', - 'arith_routines_hist.c', - 'arith_routines_logist.c', - 'bandwidth_estimator.c', - 'crc.c', - 'decode.c', - 'decode_bwe.c', - 'encode.c', - 'encode_lpc_swb.c', - 'entropy_coding.c', - 'fft.c', - 'filter_functions.c', - 'filterbank_tables.c', - 'intialize.c', - 'isac.c', - 'filterbanks.c', - 'pitch_lag_tables.c', - 'lattice.c', - 'lpc_gain_swb_tables.c', - 'lpc_analysis.c', - 'lpc_shape_swb12_tables.c', - 'lpc_shape_swb16_tables.c', - 'lpc_tables.c', - 'pitch_estimator.c', - 'pitch_filter.c', - 'pitch_gain_tables.c', - 'spectrum_ar_model_tables.c', - 'transform.c', - 'arith_routines.h', - 'bandwidth_estimator.h', - 'codec.h', - 'crc.h', - 'encode_lpc_swb.h', - 'entropy_coding.h', - 'fft.h', - 'filterbank_tables.h', - 'lpc_gain_swb_tables.h', - 'lpc_analysis.h', - 'lpc_shape_swb12_tables.h', - 'lpc_shape_swb16_tables.h', - 'lpc_tables.h', - 'pitch_estimator.h', - 'pitch_gain_tables.h', - 'pitch_lag_tables.h', - 'settings.h', - 'spectrum_ar_model_tables.h', - 'structs.h', - 'os_specific_inline.h', - ], - 'conditions': [ - ['OS!="win"', { - 'defines': [ - 'WEBRTC_LINUX', - ], - }], - ], - }, - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/mod/codecs/mod_isac/isac.h b/src/mod/codecs/mod_isac/isac.h deleted file mode 100644 index 03c260bb8a..0000000000 --- a/src/mod/codecs/mod_isac/isac.h +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_ISAC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_ISAC_H_ - -/* - * Define the fixed-point numeric formats - */ -#include "typedefs.h" - -typedef struct WebRtcISACStruct ISACStruct; - -enum IsacSamplingRate {kIsacWideband = 16, kIsacSuperWideband = 32}; - - -#if defined(__cplusplus) -extern "C" { -#endif - - /****************************************************************************** - * WebRtcIsac_AssignSize(...) - * - * This function returns the size of the ISAC instance, so that the instance - * can be created outside iSAC. - * - * Input: - * - samplingRate : sampling rate of the input/output audio. - * - * Output: - * - sizeinbytes : number of bytes needed to allocate for the - * instance. - * - * Return value : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_AssignSize( - int* sizeinbytes); - - - /****************************************************************************** - * WebRtcIsac_Assign(...) - * - * This function assignes the memory already created to the ISAC instance. - * - * Input: - * - *ISAC_main_inst : a pointer to the coder instance. - * - samplingRate : sampling rate of the input/output audio. - * - ISAC_inst_Addr : the already allocated memory, where we put the - * iSAC structure. - * - * Return value : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_Assign( - ISACStruct** ISAC_main_inst, - void* ISAC_inst_Addr); - - - /****************************************************************************** - * WebRtcIsac_Create(...) - * - * This function creates an ISAC instance, which will contain the state - * information for one coding/decoding channel. - * - * Input: - * - *ISAC_main_inst : a pointer to the coder instance. - * - * Return value : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_Create( - ISACStruct** ISAC_main_inst); - - - /****************************************************************************** - * WebRtcIsac_Free(...) - * - * This function frees the ISAC instance created at the beginning. - * - * Input: - * - ISAC_main_inst : an ISAC instance. - * - * Return value : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_Free( - ISACStruct* ISAC_main_inst); - - - /****************************************************************************** - * WebRtcIsac_EncoderInit(...) - * - * This function initializes an ISAC instance prior to the encoder calls. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - CodingMode : 0 -> Bit rate and frame length are - * automatically adjusted to available bandwidth - * on transmission channel, just valid if codec - * is created to work in wideband mode. - * 1 -> User sets a frame length and a target bit - * rate which is taken as the maximum - * short-term average bit rate. - * - * Return value : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_EncoderInit( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 CodingMode); - - - /****************************************************************************** - * WebRtcIsac_Encode(...) - * - * This function encodes 10ms audio blocks and inserts it into a package. - * Input speech length has 160 samples if operating at 16 kHz sampling - * rate, or 320 if operating at 32 kHz sampling rate. The encoder buffers the - * input audio until the whole frame is buffered then proceeds with encoding. - * - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - speechIn : input speech vector. - * - * Output: - * - encoded : the encoded data vector - * - * Return value: - * : >0 - Length (in bytes) of coded data - * : 0 - The buffer didn't reach the chosen - * frame-size so it keeps buffering speech - * samples. - * : -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_Encode( - ISACStruct* ISAC_main_inst, - const WebRtc_Word16* speechIn, - WebRtc_Word16* encoded); - - - /****************************************************************************** - * WebRtcIsac_DecoderInit(...) - * - * This function initializes an ISAC instance prior to the decoder calls. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - * Return value - * : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_DecoderInit( - ISACStruct* ISAC_main_inst); - - - /****************************************************************************** - * WebRtcIsac_UpdateBwEstimate(...) - * - * This function updates the estimate of the bandwidth. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - encoded : encoded ISAC frame(s). - * - packet_size : size of the packet. - * - rtp_seq_number : the RTP number of the packet. - * - send_ts : the RTP send timestamp, given in samples - * - arr_ts : the arrival time of the packet (from NetEq) - * in samples. - * - * Return value : 0 - Ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_UpdateBwEstimate( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word32 packet_size, - WebRtc_UWord16 rtp_seq_number, - WebRtc_UWord32 send_ts, - WebRtc_UWord32 arr_ts); - - - /****************************************************************************** - * WebRtcIsac_Decode(...) - * - * This function decodes an ISAC frame. At 16 kHz sampling rate, the length - * of the output audio could be either 480 or 960 samples, equivalent to - * 30 or 60 ms respectively. At 32 kHz sampling rate, the length of the - * output audio is 960 samples, which is 30 ms. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - encoded : encoded ISAC frame(s). - * - len : bytes in encoded vector. - * - * Output: - * - decoded : The decoded vector. - * - * Return value : >0 - number of samples in decoded vector. - * -1 - Error. - */ - - WebRtc_Word16 WebRtcIsac_Decode( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 len, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType); - - - /****************************************************************************** - * WebRtcIsac_DecodePlc(...) - * - * This function conducts PLC for ISAC frame(s). Output speech length - * will be a multiple of frames, i.e. multiples of 30 ms audio. Therefore, - * the output is multiple of 480 samples if operating at 16 kHz and multiple - * of 960 if operating at 32 kHz. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - noOfLostFrames : Number of PLC frames to produce. - * - * Output: - * - decoded : The decoded vector. - * - * Return value : >0 - number of samples in decoded PLC vector - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_DecodePlc( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* decoded, - WebRtc_Word16 noOfLostFrames); - - - /****************************************************************************** - * WebRtcIsac_Control(...) - * - * This function sets the limit on the short-term average bit-rate and the - * frame length. Should be used only in Instantaneous mode. At 16 kHz sampling - * rate, an average bit-rate between 10000 to 32000 bps is valid and a - * frame-size of 30 or 60 ms is acceptable. At 32 kHz, an average bit-rate - * between 10000 to 56000 is acceptable, and the valid frame-size is 30 ms. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - rate : limit on the short-term average bit rate, - * in bits/second. - * - framesize : frame-size in millisecond. - * - * Return value : 0 - ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_Control( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 rate, - WebRtc_Word16 framesize); - - - /****************************************************************************** - * WebRtcIsac_ControlBwe(...) - * - * This function sets the initial values of bottleneck and frame-size if - * iSAC is used in channel-adaptive mode. Therefore, this API is not - * applicable if the codec is created to operate in super-wideband mode. - * - * Through this API, users can enforce a frame-size for all values of - * bottleneck. Then iSAC will not automatically change the frame-size. - * - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - rateBPS : initial value of bottleneck in bits/second - * 10000 <= rateBPS <= 56000 is accepted - * For default bottleneck set rateBPS = 0 - * - frameSizeMs : number of milliseconds per frame (30 or 60) - * - enforceFrameSize : 1 to enforce the given frame-size through - * out the adaptation process, 0 to let iSAC - * change the frame-size if required. - * - * Return value : 0 - ok - * -1 - Error - */ - - WebRtc_Word16 WebRtcIsac_ControlBwe( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 rateBPS, - WebRtc_Word16 frameSizeMs, - WebRtc_Word16 enforceFrameSize); - - - /****************************************************************************** - * WebRtcIsac_ReadFrameLen(...) - * - * This function returns the length of the frame represented in the packet. - * - * Input: - * - encoded : Encoded bit-stream - * - * Output: - * - frameLength : Length of frame in packet (in samples) - * - */ - - WebRtc_Word16 WebRtcIsac_ReadFrameLen( - ISACStruct* ISAC_main_inst, - const WebRtc_Word16* encoded, - WebRtc_Word16* frameLength); - - - /****************************************************************************** - * WebRtcIsac_version(...) - * - * This function returns the version number. - * - * Output: - * - version : Pointer to character string - * - */ - - void WebRtcIsac_version( - char *version); - - - /****************************************************************************** - * WebRtcIsac_GetErrorCode(...) - * - * This function can be used to check the error code of an iSAC instance. When - * a function returns -1 a error code will be set for that instance. The - * function below extract the code of the last error that occurred in the - * specified instance. - * - * Input: - * - ISAC_main_inst : ISAC instance - * - * Return value : Error code - */ - - WebRtc_Word16 WebRtcIsac_GetErrorCode( - ISACStruct* ISAC_main_inst); - - - /**************************************************************************** - * WebRtcIsac_GetUplinkBw(...) - * - * This function outputs the target bottleneck of the codec. In - * channel-adaptive mode, the target bottleneck is specified through in-band - * signalling retreived by bandwidth estimator. - * In channel-independent, also called instantaneous mode, the target - * bottleneck is provided to the encoder by calling xxx_control(...). If - * xxx_control is never called the default values is returned. The default - * value for bottleneck at 16 kHz encoder sampling rate is 32000 bits/sec, - * and it is 56000 bits/sec for 32 kHz sampling rate. - * Note that the output is the iSAC internal operating bottleneck which might - * differ slightly from the one provided through xxx_control(). - * - * Input: - * - ISAC_main_inst : iSAC instance - * - * Output: - * - *bottleneck : bottleneck in bits/sec - * - * Return value : -1 if error happens - * 0 bit-rates computed correctly. - */ - - WebRtc_Word16 WebRtcIsac_GetUplinkBw( - ISACStruct* ISAC_main_inst, - WebRtc_Word32* bottleneck); - - - /****************************************************************************** - * WebRtcIsac_SetMaxPayloadSize(...) - * - * This function sets a limit for the maximum payload size of iSAC. The same - * value is used both for 30 and 60 ms packets. If the encoder sampling rate - * is 16 kHz the maximum payload size is between 120 and 400 bytes. If the - * encoder sampling rate is 32 kHz the maximum payload size is between 120 - * and 600 bytes. - * - * If an out of range limit is used, the function returns -1, but the closest - * valid value will be applied. - * - * --------------- - * IMPORTANT NOTES - * --------------- - * The size of a packet is limited to the minimum of 'max-payload-size' and - * 'max-rate.' For instance, let's assume the max-payload-size is set to - * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps - * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms - * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, - * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to - * 170 bytes, i.e. min(170, 300). - * - * Input: - * - ISAC_main_inst : iSAC instance - * - maxPayloadBytes : maximum size of the payload in bytes - * valid values are between 120 and 400 bytes - * if encoder sampling rate is 16 kHz. For - * 32 kHz encoder sampling rate valid values - * are between 120 and 600 bytes. - * - * Return value : 0 if successful - * -1 if error happens - */ - - WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 maxPayloadBytes); - - - /****************************************************************************** - * WebRtcIsac_SetMaxRate(...) - * - * This function sets the maximum rate which the codec may not exceed for - * any signal packet. The maximum rate is defined and payload-size per - * frame-size in bits per second. - * - * The codec has a maximum rate of 53400 bits per second (200 bytes per 30 - * ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms) - * if the encoder sampling rate is 32 kHz. - * - * It is possible to set a maximum rate between 32000 and 53400 bits/sec - * in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode. - * - * If an out of range limit is used, the function returns -1, but the closest - * valid value will be applied. - * - * --------------- - * IMPORTANT NOTES - * --------------- - * The size of a packet is limited to the minimum of 'max-payload-size' and - * 'max-rate.' For instance, let's assume the max-payload-size is set to - * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps - * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms - * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, - * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to - * 170 bytes, min(170, 300). - * - * Input: - * - ISAC_main_inst : iSAC instance - * - maxRate : maximum rate in bits per second, - * valid values are 32000 to 53400 bits/sec in - * wideband mode, and 32000 to 160000 bits/sec in - * super-wideband mode. - * - * Return value : 0 if successful - * -1 if error happens - */ - - WebRtc_Word16 WebRtcIsac_SetMaxRate( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 maxRate); - - - /****************************************************************************** - * WebRtcIsac_DecSampRate() - * Return the sampling rate of the decoded audio. - * - * Input: - * - ISAC_main_inst : iSAC instance - * - * Return value : enumerator representing sampling frequency - * associated with the decoder, i.e. the - * sampling rate of the decoded audio. - * - */ - - enum IsacSamplingRate WebRtcIsac_DecSampRate( - ISACStruct* ISAC_main_inst); - - - /****************************************************************************** - * WebRtcIsac_EncSampRate() - * - * Input: - * - ISAC_main_inst : iSAC instance - * - * Return value : enumerator representing sampling frequency - * associated with the encoder, the input audio - * is expected to be sampled at this rate. - * - */ - - enum IsacSamplingRate WebRtcIsac_EncSampRate( - ISACStruct* ISAC_main_inst); - - - /****************************************************************************** - * WebRtcIsac_SetDecSampRate() - * Set the sampling rate of the decoder. Initialization of the decoder WILL - * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz - * which is set when the instance is created. - * - * Input: - * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. - * - * Return value : 0 if successful - * -1 if failed. - */ - - WebRtc_Word16 WebRtcIsac_SetDecSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate); - - - /****************************************************************************** - * WebRtcIsac_SetEncSampRate() - * Set the sampling rate of the encoder. Initialization of the encoder WILL - * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz - * which is set when the instance is created. The encoding-mode and the - * bottleneck remain unchanged by this call, however, the maximum rate and - * maximum payload-size will reset to their default value. - * - * Input: - * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. - * - * Return value : 0 if successful - * -1 if failed. - */ - - WebRtc_Word16 WebRtcIsac_SetEncSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate); - - - - /****************************************************************************** - * WebRtcIsac_GetNewBitStream(...) - * - * This function returns encoded data, with the recieved bwe-index in the - * stream. If the rate is set to a value less than bottleneck of codec - * the new bistream will be re-encoded with the given target rate. - * It should always return a complete packet, i.e. only called once - * even for 60 msec frames. - * - * NOTE 1! This function does not write in the ISACStruct, it is not allowed. - * NOTE 2! Currently not implemented for SWB mode. - * NOTE 3! Rates larger than the bottleneck of the codec will be limited - * to the current bottleneck. - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - bweIndex : Index of bandwidth estimate to put in new - * bitstream - * - rate : target rate of the transcoder is bits/sec. - * Valid values are the accepted rate in iSAC, - * i.e. 10000 to 56000. - * - isRCU : if the new bit-stream is an RCU stream. - * Note that the rate parameter always indicates - * the target rate of the main paylaod, regardless - * of 'isRCU' value. - * - * Output: - * - encoded : The encoded data vector - * - * Return value : >0 - Length (in bytes) of coded data - * -1 - Error or called in SWB mode - * NOTE! No error code is written to - * the struct since it is only allowed to read - * the struct. - */ - WebRtc_Word16 WebRtcIsac_GetNewBitStream( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 bweIndex, - WebRtc_Word16 jitterInfo, - WebRtc_Word32 rate, - WebRtc_Word16* encoded, - WebRtc_Word16 isRCU); - - - - /**************************************************************************** - * WebRtcIsac_GetDownLinkBwIndex(...) - * - * This function returns index representing the Bandwidth estimate from - * other side to this side. - * - * Input: - * - ISAC_main_inst : iSAC struct - * - * Output: - * - bweIndex : Bandwidth estimate to transmit to other side. - * - */ - - WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* bweIndex, - WebRtc_Word16* jitterInfo); - - - /**************************************************************************** - * WebRtcIsac_UpdateUplinkBw(...) - * - * This function takes an index representing the Bandwidth estimate from - * this side to other side and updates BWE. - * - * Input: - * - ISAC_main_inst : iSAC struct - * - bweIndex : Bandwidth estimate from other side. - * - */ - - WebRtc_Word16 WebRtcIsac_UpdateUplinkBw( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 bweIndex); - - - /**************************************************************************** - * WebRtcIsac_ReadBwIndex(...) - * - * This function returns the index of the Bandwidth estimate from the bitstream. - * - * Input: - * - encoded : Encoded bitstream - * - * Output: - * - frameLength : Length of frame in packet (in samples) - * - bweIndex : Bandwidth estimate in bitstream - * - */ - - WebRtc_Word16 WebRtcIsac_ReadBwIndex( - const WebRtc_Word16* encoded, - WebRtc_Word16* bweIndex); - - - - /******************************************************************************* - * WebRtcIsac_GetNewFrameLen(...) - * - * returns the frame lenght (in samples) of the next packet. In the case of channel-adaptive - * mode, iSAC decides on its frame lenght based on the estimated bottleneck - * this allows a user to prepare for the next packet (at the encoder) - * - * The primary usage is in CE to make the iSAC works in channel-adaptive mode - * - * Input: - * - ISAC_main_inst : iSAC struct - * - * Return Value : frame lenght in samples - * - */ - - WebRtc_Word16 WebRtcIsac_GetNewFrameLen( - ISACStruct* ISAC_main_inst); - - - /**************************************************************************** - * WebRtcIsac_GetRedPayload(...) - * - * Populates "encoded" with the redundant payload of the recently encoded - * frame. This function has to be called once that WebRtcIsac_Encode(...) - * returns a positive value. Regardless of the frame-size this function will - * be called only once after encoding is completed. - * - * Input: - * - ISAC_main_inst : iSAC struct - * - * Output: - * - encoded : the encoded data vector - * - * - * Return value: - * : >0 - Length (in bytes) of coded data - * : -1 - Error - * - * - */ - WebRtc_Word16 WebRtcIsac_GetRedPayload( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* encoded); - - - /**************************************************************************** - * WebRtcIsac_DecodeRcu(...) - * - * This function decodes a redundant (RCU) iSAC frame. Function is called in - * NetEq with a stored RCU payload i case of packet loss. Output speech length - * will be a multiple of 480 samples: 480 or 960 samples, - * depending on the framesize (30 or 60 ms). - * - * Input: - * - ISAC_main_inst : ISAC instance. - * - encoded : encoded ISAC RCU frame(s) - * - len : bytes in encoded vector - * - * Output: - * - decoded : The decoded vector - * - * Return value : >0 - number of samples in decoded vector - * -1 - Error - */ - WebRtc_Word16 WebRtcIsac_DecodeRcu( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 len, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType); - - -#if defined(__cplusplus) -} -#endif - - - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_ISAC_H_ */ diff --git a/src/mod/codecs/mod_isac/lattice.c b/src/mod/codecs/mod_isac/lattice.c deleted file mode 100644 index a46135a3f7..0000000000 --- a/src/mod/codecs/mod_isac/lattice.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * lattice.c - * - * contains the normalized lattice filter routines (MA and AR) for iSAC codec - * - */ -#include "settings.h" -#include "codec.h" - -#include -#include -#ifdef WEBRTC_ANDROID -#include -#endif - -/* filter the signal using normalized lattice filter */ -/* MA filter */ -void WebRtcIsac_NormLatticeFilterMa(int orderCoef, - float *stateF, - float *stateG, - float *lat_in, - double *filtcoeflo, - double *lat_out) -{ - int n,k,i,u,temp1; - int ord_1 = orderCoef+1; - float sth[MAX_AR_MODEL_ORDER]; - float cth[MAX_AR_MODEL_ORDER]; - float inv_cth[MAX_AR_MODEL_ORDER]; - double a[MAX_AR_MODEL_ORDER+1]; - float f[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], g[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN]; - float gain1; - - for (u=0;u=0;i--) //get the state of f&g for the first input, for all orders - { - ARf[i][0] = cth[i]*ARf[i+1][0] - sth[i]*stateG[i]; - ARg[i+1][0] = sth[i]*ARf[i+1][0] + cth[i]* stateG[i]; - } - ARg[0][0] = ARf[0][0]; - - for(n=0;n<(HALF_SUBFRAMELEN-1);n++) - { - for(k=orderCoef-1;k>=0;k--) - { - ARf[k][n+1] = cth[k]*ARf[k+1][n+1] - sth[k]*ARg[k][n]; - ARg[k+1][n+1] = sth[k]*ARf[k+1][n+1] + cth[k]* ARg[k][n]; - } - ARg[0][n+1] = ARf[0][n+1]; - } - - memcpy(lat_out+u * HALF_SUBFRAMELEN, &(ARf[0][0]), sizeof(float) * HALF_SUBFRAMELEN); - - /* cannot use memcpy in the following */ - for (i=0;i0; m--) - { - tmp_inv = 1.0f / cth2; - for (k=1; k<=m; k++) - { - tmp[k] = ((float)a[k] - sth[m] * (float)a[m-k+1]) * tmp_inv; - } - - for (k=1; k= 0; i--) - { - temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm); - // Put R in hi and low format - R_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1); - } - - // K = A[1] = -R[1] / R[0] - - temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); // R[1] in Q31 - temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1] - temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31 - // Put back the sign on R[1] - if (temp2W32 > 0) - { - temp1W32 = -temp1W32; - } - - // Put K in hi and low format - K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); - - // Store first reflection coefficient - K[0] = K_hi; - - temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27 - - // Put A[1] in hi and low format - A_hi[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1); - - // Alpha = R[0] * (1-K^2) - - temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) - << 1); // temp1W32 = k^2 in Q31 - - temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 - temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31 - - // Store temp1W32 = 1 - K[0]*K[0] on hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // Calculate Alpha in Q31 - temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi) - + (WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low) >> 15) - + (WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi) >> 15)) << 1); - - // Normalize Alpha and put it in hi and low format - - Alpha_exp = WebRtcSpl_NormW32(temp1W32); - temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp); - Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); - - // Perform the iterative calculations in the Levinson-Durbin algorithm - - for (i = 2; i <= order; i++) - { - /* ---- - temp1W32 = R[i] + > R[j]*A[i-j] - / - ---- - j=1..i-1 - */ - - temp1W32 = 0; - - for (j = 1; j < i; j++) - { - // temp1W32 is in Q31 - temp1W32 += ((WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]) << 1) - + (((WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]) >> 15) - + (WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]) >> 15)) << 1)); - } - - temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4); - temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1)); - - // K = -temp1W32 / Alpha - temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32) - temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha - - // Put the sign of temp1W32 back again - if (temp1W32 > 0) - { - temp3W32 = -temp3W32; - } - - // Use the Alpha shifts from earlier to de-normalize - norm = WebRtcSpl_NormW32(temp3W32); - if ((Alpha_exp <= norm) || (temp3W32 == 0)) - { - temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp); - } else - { - if (temp3W32 > 0) - { - temp3W32 = (WebRtc_Word32)0x7fffffffL; - } else - { - temp3W32 = (WebRtc_Word32)0x80000000L; - } - } - - // Put K on hi and low format - K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); - K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); - - // Store Reflection coefficient in Q15 - K[i - 1] = K_hi; - - // Test for unstable filter. - // If unstable return 0 and let the user decide what to do in that case - - if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32750) - { - return 0; // Unstable filter - } - - /* - Compute updated LPC coefficient: Anew[i] - Anew[j]= A[j] + K*A[i-j] for j=1..i-1 - Anew[i]= K - */ - - for (j = 1; j < i; j++) - { - // temp1W32 = A[j] in Q27 - temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1); - - // temp1W32 += K*A[i-j] in Q27 - temp1W32 += ((WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j]) - + (WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]) >> 15) - + (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1); - - // Put Anew in hi and low format - A_upd_hi[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1); - } - - // temp3W32 = K in Q27 (Convert from Q31 to Q27) - temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4); - - // Store Anew in hi and low format - A_upd_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); - A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1); - - // Alpha = Alpha * (1-K^2) - - temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) - + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) << 1); // K*K in Q31 - - temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 - temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // 1 - K*K in Q31 - - // Convert 1- K^2 in hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // Calculate Alpha = Alpha * (1-K^2) in Q31 - temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi) - + (WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low) >> 15) - + (WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi) >> 15)) << 1); - - // Normalize Alpha and store it on hi and low format - - norm = WebRtcSpl_NormW32(temp1W32); - temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm); - - Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); - - // Update the total normalization of Alpha - Alpha_exp = Alpha_exp + norm; - - // Update A[] - - for (j = 1; j <= i; j++) - { - A_hi[j] = A_upd_hi[j]; - A_low[j] = A_upd_low[j]; - } - } - - /* - Set A[0] to 1.0 and store the A[i] i=1...order in Q12 - (Convert from Q27 and use rounding) - */ - - A[0] = 4096; - - for (i = 1; i <= order; i++) - { - // temp1W32 in Q27 - temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1); - // Round and store upper word - A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(WebRtc_Word32)32768, 16); - } - return 1; // Stable filters -} diff --git a/src/mod/codecs/mod_isac/lpc_analysis.c b/src/mod/codecs/mod_isac/lpc_analysis.c deleted file mode 100644 index 854b2d733c..0000000000 --- a/src/mod/codecs/mod_isac/lpc_analysis.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "lpc_analysis.h" -#include "settings.h" -#include "codec.h" -#include "entropy_coding.h" - -#include -#include - -#define LEVINSON_EPS 1.0e-10 - - -/* window */ -/* Matlab generation code: - * t = (1:256)/257; r = 1-(1-t).^.45; w = sin(r*pi).^3; w = w/sum(w); plot((1:256)/8, w); grid; - * for k=1:16, fprintf(1, '%.8f, ', w(k*16 + (-15:0))); fprintf(1, '\n'); end - */ -static const double kLpcCorrWindow[WINLEN] = { - 0.00000000, 0.00000001, 0.00000004, 0.00000010, 0.00000020, - 0.00000035, 0.00000055, 0.00000083, 0.00000118, 0.00000163, - 0.00000218, 0.00000283, 0.00000361, 0.00000453, 0.00000558, 0.00000679, - 0.00000817, 0.00000973, 0.00001147, 0.00001342, 0.00001558, - 0.00001796, 0.00002058, 0.00002344, 0.00002657, 0.00002997, - 0.00003365, 0.00003762, 0.00004190, 0.00004651, 0.00005144, 0.00005673, - 0.00006236, 0.00006837, 0.00007476, 0.00008155, 0.00008875, - 0.00009636, 0.00010441, 0.00011290, 0.00012186, 0.00013128, - 0.00014119, 0.00015160, 0.00016252, 0.00017396, 0.00018594, 0.00019846, - 0.00021155, 0.00022521, 0.00023946, 0.00025432, 0.00026978, - 0.00028587, 0.00030260, 0.00031998, 0.00033802, 0.00035674, - 0.00037615, 0.00039626, 0.00041708, 0.00043863, 0.00046092, 0.00048396, - 0.00050775, 0.00053233, 0.00055768, 0.00058384, 0.00061080, - 0.00063858, 0.00066720, 0.00069665, 0.00072696, 0.00075813, - 0.00079017, 0.00082310, 0.00085692, 0.00089164, 0.00092728, 0.00096384, - 0.00100133, 0.00103976, 0.00107914, 0.00111947, 0.00116077, - 0.00120304, 0.00124630, 0.00129053, 0.00133577, 0.00138200, - 0.00142924, 0.00147749, 0.00152676, 0.00157705, 0.00162836, 0.00168070, - 0.00173408, 0.00178850, 0.00184395, 0.00190045, 0.00195799, - 0.00201658, 0.00207621, 0.00213688, 0.00219860, 0.00226137, - 0.00232518, 0.00239003, 0.00245591, 0.00252284, 0.00259079, 0.00265977, - 0.00272977, 0.00280078, 0.00287280, 0.00294582, 0.00301984, - 0.00309484, 0.00317081, 0.00324774, 0.00332563, 0.00340446, - 0.00348421, 0.00356488, 0.00364644, 0.00372889, 0.00381220, 0.00389636, - 0.00398135, 0.00406715, 0.00415374, 0.00424109, 0.00432920, - 0.00441802, 0.00450754, 0.00459773, 0.00468857, 0.00478001, - 0.00487205, 0.00496464, 0.00505775, 0.00515136, 0.00524542, 0.00533990, - 0.00543476, 0.00552997, 0.00562548, 0.00572125, 0.00581725, - 0.00591342, 0.00600973, 0.00610612, 0.00620254, 0.00629895, - 0.00639530, 0.00649153, 0.00658758, 0.00668341, 0.00677894, 0.00687413, - 0.00696891, 0.00706322, 0.00715699, 0.00725016, 0.00734266, - 0.00743441, 0.00752535, 0.00761540, 0.00770449, 0.00779254, - 0.00787947, 0.00796519, 0.00804963, 0.00813270, 0.00821431, 0.00829437, - 0.00837280, 0.00844949, 0.00852436, 0.00859730, 0.00866822, - 0.00873701, 0.00880358, 0.00886781, 0.00892960, 0.00898884, - 0.00904542, 0.00909923, 0.00915014, 0.00919805, 0.00924283, 0.00928436, - 0.00932252, 0.00935718, 0.00938821, 0.00941550, 0.00943890, - 0.00945828, 0.00947351, 0.00948446, 0.00949098, 0.00949294, - 0.00949020, 0.00948262, 0.00947005, 0.00945235, 0.00942938, 0.00940099, - 0.00936704, 0.00932738, 0.00928186, 0.00923034, 0.00917268, - 0.00910872, 0.00903832, 0.00896134, 0.00887763, 0.00878706, - 0.00868949, 0.00858478, 0.00847280, 0.00835343, 0.00822653, 0.00809199, - 0.00794970, 0.00779956, 0.00764145, 0.00747530, 0.00730103, - 0.00711857, 0.00692787, 0.00672888, 0.00652158, 0.00630597, - 0.00608208, 0.00584994, 0.00560962, 0.00536124, 0.00510493, 0.00484089, - 0.00456935, 0.00429062, 0.00400505, 0.00371310, 0.00341532, - 0.00311238, 0.00280511, 0.00249452, 0.00218184, 0.00186864, - 0.00155690, 0.00124918, 0.00094895, 0.00066112, 0.00039320, 0.00015881 -}; - -double WebRtcIsac_LevDurb(double *a, double *k, double *r, int order) -{ - - double sum, alpha; - int m, m_h, i; - alpha = 0; //warning -DH - a[0] = 1.0; - if (r[0] < LEVINSON_EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ - for (i = 0; i < order; i++) { - k[i] = 0; - a[i+1] = 0; - } - } else { - a[1] = k[0] = -r[1]/r[0]; - alpha = r[0] + r[1] * k[0]; - for (m = 1; m < order; m++){ - sum = r[m + 1]; - for (i = 0; i < m; i++){ - sum += a[i+1] * r[m - i]; - } - k[m] = -sum / alpha; - alpha += k[m] * sum; - m_h = (m + 1) >> 1; - for (i = 0; i < m_h; i++){ - sum = a[i+1] + k[m] * a[m - i]; - a[m - i] += k[m] * a[i+1]; - a[i+1] = sum; - } - a[m+1] = k[m]; - } - } - return alpha; -} - - -//was static before, but didn't work with MEX file -void WebRtcIsac_GetVars(const double *input, const WebRtc_Word16 *pitchGains_Q12, - double *oldEnergy, double *varscale) -{ - double nrg[4], chng, pg; - int k; - - double pitchGains[4]={0,0,0,0};; - - /* Calculate energies of first and second frame halfs */ - nrg[0] = 0.0001; - for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES_QUARTER + QLOOKAHEAD) / 2; k++) { - nrg[0] += input[k]*input[k]; - } - nrg[1] = 0.0001; - for ( ; k < (FRAMESAMPLES_HALF + QLOOKAHEAD) / 2; k++) { - nrg[1] += input[k]*input[k]; - } - nrg[2] = 0.0001; - for ( ; k < (FRAMESAMPLES*3/4 + QLOOKAHEAD) / 2; k++) { - nrg[2] += input[k]*input[k]; - } - nrg[3] = 0.0001; - for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) { - nrg[3] += input[k]*input[k]; - } - - /* Calculate average level change */ - chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) + - fabs(10.0 * log10(nrg[2] / nrg[1])) + - fabs(10.0 * log10(nrg[1] / nrg[0])) + - fabs(10.0 * log10(nrg[0] / *oldEnergy))); - - - /* Find average pitch gain */ - pg = 0.0; - for (k=0; k<4; k++) - { - pitchGains[k] = ((float)pitchGains_Q12[k])/4096; - pg += pitchGains[k]; - } - pg *= 0.25; - - /* If pitch gain is low and energy constant - increase noise level*/ - /* Matlab code: - pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) )) - */ - *varscale = 0.0 + 1.0 * exp( -1.4 * exp(-200.0 * pg*pg*pg) / (1.0 + 0.4 * chng) ); - - *oldEnergy = nrg[3]; -} - -void -WebRtcIsac_GetVarsUB( - const double* input, - double* oldEnergy, - double* varscale) -{ - double nrg[4], chng; - int k; - - /* Calculate energies of first and second frame halfs */ - nrg[0] = 0.0001; - for (k = 0; k < (FRAMESAMPLES_QUARTER) / 2; k++) { - nrg[0] += input[k]*input[k]; - } - nrg[1] = 0.0001; - for ( ; k < (FRAMESAMPLES_HALF) / 2; k++) { - nrg[1] += input[k]*input[k]; - } - nrg[2] = 0.0001; - for ( ; k < (FRAMESAMPLES*3/4) / 2; k++) { - nrg[2] += input[k]*input[k]; - } - nrg[3] = 0.0001; - for ( ; k < (FRAMESAMPLES) / 2; k++) { - nrg[3] += input[k]*input[k]; - } - - /* Calculate average level change */ - chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) + - fabs(10.0 * log10(nrg[2] / nrg[1])) + - fabs(10.0 * log10(nrg[1] / nrg[0])) + - fabs(10.0 * log10(nrg[0] / *oldEnergy))); - - - /* If pitch gain is low and energy constant - increase noise level*/ - /* Matlab code: - pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) )) - */ - *varscale = exp( -1.4 / (1.0 + 0.4 * chng) ); - - *oldEnergy = nrg[3]; -} - -void WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata, - double signal_noise_ratio, const WebRtc_Word16 *pitchGains_Q12, - double *lo_coeff, double *hi_coeff) -{ - int k, n, j, pos1, pos2; - double varscale; - - double DataLo[WINLEN], DataHi[WINLEN]; - double corrlo[ORDERLO+2], corrlo2[ORDERLO+1]; - double corrhi[ORDERHI+1]; - double k_veclo[ORDERLO], k_vechi[ORDERHI]; - - double a_LO[ORDERLO+1], a_HI[ORDERHI+1]; - double tmp, res_nrg; - - double FwdA, FwdB; - - /* hearing threshold level in dB; higher value gives more noise */ - const double HearThresOffset = -28.0; - - /* bandwdith expansion factors for low- and high band */ - const double gammaLo = 0.9; - const double gammaHi = 0.8; - - /* less-noise-at-low-frequencies factor */ - double aa; - - - /* convert from dB to signal level */ - const double H_T_H = pow(10.0, 0.05 * HearThresOffset); - double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46; /* divide by sqrt(12) */ - - /* change quallevel depending on pitch gains and level fluctuations */ - WebRtcIsac_GetVars(inLo, pitchGains_Q12, &(maskdata->OldEnergy), &varscale); - - /* less-noise-at-low-frequencies factor */ - aa = 0.35 * (0.5 + 0.5 * varscale); - - /* replace data in buffer by new look-ahead data */ - for (pos1 = 0; pos1 < QLOOKAHEAD; pos1++) - maskdata->DataBufferLo[pos1 + WINLEN - QLOOKAHEAD] = inLo[pos1]; - - for (k = 0; k < SUBFRAMES; k++) { - - /* Update input buffer and multiply signal with window */ - for (pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) { - maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 + UPDATE/2]; - maskdata->DataBufferHi[pos1] = maskdata->DataBufferHi[pos1 + UPDATE/2]; - DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; - DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1]; - } - pos2 = k * UPDATE/2; - for (n = 0; n < UPDATE/2; n++, pos1++) { - maskdata->DataBufferLo[pos1] = inLo[QLOOKAHEAD + pos2]; - maskdata->DataBufferHi[pos1] = inHi[pos2++]; - DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; - DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1]; - } - - /* Get correlation coefficients */ - WebRtcIsac_AutoCorr(corrlo, DataLo, WINLEN, ORDERLO+1); /* computing autocorrelation */ - WebRtcIsac_AutoCorr(corrhi, DataHi, WINLEN, ORDERHI); - - - /* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */ - corrlo2[0] = (1.0+aa*aa) * corrlo[0] - 2.0*aa * corrlo[1]; - tmp = (1.0 + aa*aa); - for (n = 1; n <= ORDERLO; n++) { - corrlo2[n] = tmp * corrlo[n] - aa * (corrlo[n-1] + corrlo[n+1]); - } - tmp = (1.0+aa) * (1.0+aa); - for (n = 0; n <= ORDERHI; n++) { - corrhi[n] = tmp * corrhi[n]; - } - - /* add white noise floor */ - corrlo2[0] += 1e-6; - corrhi[0] += 1e-6; - - - FwdA = 0.01; - FwdB = 0.01; - - /* recursive filtering of correlation over subframes */ - for (n = 0; n <= ORDERLO; n++) { - maskdata->CorrBufLo[n] = FwdA * maskdata->CorrBufLo[n] + corrlo2[n]; - corrlo2[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufLo[n] + (1.0-FwdB) * corrlo2[n]; - } - for (n = 0; n <= ORDERHI; n++) { - maskdata->CorrBufHi[n] = FwdA * maskdata->CorrBufHi[n] + corrhi[n]; - corrhi[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufHi[n] + (1.0-FwdB) * corrhi[n]; - } - - /* compute prediction coefficients */ - WebRtcIsac_LevDurb(a_LO, k_veclo, corrlo2, ORDERLO); - WebRtcIsac_LevDurb(a_HI, k_vechi, corrhi, ORDERHI); - - /* bandwidth expansion */ - tmp = gammaLo; - for (n = 1; n <= ORDERLO; n++) { - a_LO[n] *= tmp; - tmp *= gammaLo; - } - - /* residual energy */ - res_nrg = 0.0; - for (j = 0; j <= ORDERLO; j++) { - for (n = 0; n <= j; n++) { - res_nrg += a_LO[j] * corrlo2[j-n] * a_LO[n]; - } - for (n = j+1; n <= ORDERLO; n++) { - res_nrg += a_LO[j] * corrlo2[n-j] * a_LO[n]; - } - } - - /* add hearing threshold and compute the gain */ - *lo_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H); - - /* copy coefficients to output array */ - for (n = 1; n <= ORDERLO; n++) { - *lo_coeff++ = a_LO[n]; - } - - - /* bandwidth expansion */ - tmp = gammaHi; - for (n = 1; n <= ORDERHI; n++) { - a_HI[n] *= tmp; - tmp *= gammaHi; - } - - /* residual energy */ - res_nrg = 0.0; - for (j = 0; j <= ORDERHI; j++) { - for (n = 0; n <= j; n++) { - res_nrg += a_HI[j] * corrhi[j-n] * a_HI[n]; - } - for (n = j+1; n <= ORDERHI; n++) { - res_nrg += a_HI[j] * corrhi[n-j] * a_HI[n]; - } - } - - /* add hearing threshold and compute of the gain */ - *hi_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H); - - /* copy coefficients to output array */ - for (n = 1; n <= ORDERHI; n++) { - *hi_coeff++ = a_HI[n]; - } - } -} - - - -/****************************************************************************** - * WebRtcIsac_GetLpcCoefUb() - * - * Compute LP coefficients and correlation coefficients. At 12 kHz LP - * coefficients of the first and the last sub-frame is computed. At 16 kHz - * LP coefficients of 4th, 8th and 12th sub-frames are computed. We always - * compute correlation coefficients of all sub-frames. - * - * Inputs: - * -inSignal : Input signal - * -maskdata : a structure keeping signal from previous frame. - * -bandwidth : specifies if the codec is in 0-16 kHz mode or - * 0-12 kHz mode. - * - * Outputs: - * -lpCoeff : pointer to a buffer where A-polynomials are - * written to (first coeff is 1 and it is not - * written) - * -corrMat : a matrix where correlation coefficients of each - * sub-frame are written to one row. - * -varscale : a scale used to compute LPC gains. - */ -void -WebRtcIsac_GetLpcCoefUb( - double* inSignal, - MaskFiltstr* maskdata, - double* lpCoeff, - double corrMat[][UB_LPC_ORDER + 1], - double* varscale, - WebRtc_Word16 bandwidth) -{ - int frameCntr, activeFrameCntr, n, pos1, pos2; - WebRtc_Word16 criterion1; - WebRtc_Word16 criterion2; - WebRtc_Word16 numSubFrames = SUBFRAMES * (1 + (bandwidth == isac16kHz)); - double data[WINLEN]; - double corrSubFrame[UB_LPC_ORDER+2]; - double reflecCoeff[UB_LPC_ORDER]; - - double aPolynom[UB_LPC_ORDER+1]; - double tmp; - - /* bandwdith expansion factors */ - const double gamma = 0.9; - - /* change quallevel depending on pitch gains and level fluctuations */ - WebRtcIsac_GetVarsUB(inSignal, &(maskdata->OldEnergy), varscale); - - /* replace data in buffer by new look-ahead data */ - for(frameCntr = 0, activeFrameCntr = 0; frameCntr < numSubFrames; - frameCntr++) - { - if(frameCntr == SUBFRAMES) - { - // we are in 16 kHz - varscale++; - WebRtcIsac_GetVarsUB(&inSignal[FRAMESAMPLES_HALF], - &(maskdata->OldEnergy), varscale); - } - /* Update input buffer and multiply signal with window */ - for(pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) - { - maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 + - UPDATE/2]; - data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; - } - pos2 = frameCntr * UPDATE/2; - for(n = 0; n < UPDATE/2; n++, pos1++, pos2++) - { - maskdata->DataBufferLo[pos1] = inSignal[pos2]; - data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; - } - - /* Get correlation coefficients */ - /* computing autocorrelation */ - WebRtcIsac_AutoCorr(corrSubFrame, data, WINLEN, UB_LPC_ORDER+1); - memcpy(corrMat[frameCntr], corrSubFrame, - (UB_LPC_ORDER+1)*sizeof(double)); - - criterion1 = ((frameCntr == 0) || (frameCntr == (SUBFRAMES - 1))) && - (bandwidth == isac12kHz); - criterion2 = (((frameCntr+1) % 4) == 0) && - (bandwidth == isac16kHz); - if(criterion1 || criterion2) - { - /* add noise */ - corrSubFrame[0] += 1e-6; - /* compute prediction coefficients */ - WebRtcIsac_LevDurb(aPolynom, reflecCoeff, corrSubFrame, - UB_LPC_ORDER); - - /* bandwidth expansion */ - tmp = gamma; - for (n = 1; n <= UB_LPC_ORDER; n++) - { - *lpCoeff++ = aPolynom[n] * tmp; - tmp *= gamma; - } - activeFrameCntr++; - } - } -} - - - -/****************************************************************************** - * WebRtcIsac_GetLpcGain() - * - * Compute the LPC gains for each sub-frame, given the LPC of each sub-frame - * and the corresponding correlation coefficients. - * - * Inputs: - * -signal_noise_ratio : the desired SNR in dB. - * -numVecs : number of sub-frames - * -corrMat : a matrix of correlation coefficients where - * each row is a set of correlation coefficients of - * one sub-frame. - * -varscale : a scale computed when WebRtcIsac_GetLpcCoefUb() - * is called. - * - * Outputs: - * -gain : pointer to a buffer where LP gains are written. - * - */ -void -WebRtcIsac_GetLpcGain( - double signal_noise_ratio, - const double* filtCoeffVecs, - int numVecs, - double* gain, - double corrMat[][UB_LPC_ORDER + 1], - const double* varscale) -{ - WebRtc_Word16 j, n; - WebRtc_Word16 subFrameCntr; - double aPolynom[ORDERLO + 1]; - double res_nrg; - - const double HearThresOffset = -28.0; - const double H_T_H = pow(10.0, 0.05 * HearThresOffset); - /* divide by sqrt(12) = 3.46 */ - const double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46; - - aPolynom[0] = 1; - for(subFrameCntr = 0; subFrameCntr < numVecs; subFrameCntr++) - { - if(subFrameCntr == SUBFRAMES) - { - // we are in second half of a SWB frame. use new varscale - varscale++; - } - memcpy(&aPolynom[1], &filtCoeffVecs[(subFrameCntr * (UB_LPC_ORDER + 1)) + - 1], sizeof(double) * UB_LPC_ORDER); - - /* residual energy */ - res_nrg = 0.0; - for(j = 0; j <= UB_LPC_ORDER; j++) - { - for(n = 0; n <= j; n++) - { - res_nrg += aPolynom[j] * corrMat[subFrameCntr][j-n] * - aPolynom[n]; - } - for(n = j+1; n <= UB_LPC_ORDER; n++) - { - res_nrg += aPolynom[j] * corrMat[subFrameCntr][n-j] * - aPolynom[n]; - } - } - - /* add hearing threshold and compute the gain */ - gain[subFrameCntr] = S_N_R / (sqrt(res_nrg) / *varscale + H_T_H); - } -} diff --git a/src/mod/codecs/mod_isac/lpc_analysis.h b/src/mod/codecs/mod_isac/lpc_analysis.h deleted file mode 100644 index 4eafeac7bc..0000000000 --- a/src/mod/codecs/mod_isac/lpc_analysis.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * lpc_analysis.h - * - * LPC functions - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYSIS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYSIS_H_ - -#include "settings.h" -#include "structs.h" - -double WebRtcIsac_LevDurb(double *a, double *k, double *r, int order); - -void WebRtcIsac_GetVars(const double *input, const WebRtc_Word16 *pitchGains_Q12, - double *oldEnergy, double *varscale); - -void WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata, - double signal_noise_ratio, const WebRtc_Word16 *pitchGains_Q12, - double *lo_coeff, double *hi_coeff); - - -void WebRtcIsac_GetLpcGain( - double signal_noise_ratio, - const double* filtCoeffVecs, - int numVecs, - double* gain, - double corrLo[][UB_LPC_ORDER + 1], - const double* varscale); - -void WebRtcIsac_GetLpcCoefUb( - double* inSignal, - MaskFiltstr* maskdata, - double* lpCoeff, - double corr[][UB_LPC_ORDER + 1], - double* varscale, - WebRtc_Word16 bandwidth); - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYIS_H_ */ diff --git a/src/mod/codecs/mod_isac/lpc_gain_swb_tables.c b/src/mod/codecs/mod_isac/lpc_gain_swb_tables.c deleted file mode 100644 index 25c69cbfef..0000000000 --- a/src/mod/codecs/mod_isac/lpc_gain_swb_tables.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * SWB_KLT_Tables_LPCGain.c - * - * This file defines tables used for entropy coding of LPC Gain - * of upper-band. - * - */ - -#include "lpc_gain_swb_tables.h" -#include "settings.h" -#include "typedefs.h" - -const double WebRtcIsac_kQSizeLpcGain = 0.100000; - -const double WebRtcIsac_kMeanLpcGain = -3.3822; - -/* -* The smallest reconstruction points for quantiztion of -* LPC gains. -*/ -const double WebRtcIsac_kLeftRecPointLpcGain[SUBFRAMES] = -{ - -0.800000, -1.000000, -1.200000, -2.200000, -3.000000, -12.700000 -}; - -/* -* Number of reconstruction points of quantizers for LPC Gains. -*/ -const WebRtc_Word16 WebRtcIsac_kNumQCellLpcGain[SUBFRAMES] = -{ - 17, 20, 25, 45, 77, 170 -}; -/* -* Starting index for entropy decoder to search for the right interval, -* one entry per LAR coefficient -*/ -const WebRtc_UWord16 WebRtcIsac_kLpcGainEntropySearch[SUBFRAMES] = -{ - 8, 10, 12, 22, 38, 85 -}; - -/* -* The following 6 vectors define CDF of 6 decorrelated LPC -* gains. -*/ -const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec0[18] = -{ - 0, 10, 27, 83, 234, 568, 1601, 4683, 16830, 57534, 63437, - 64767, 65229, 65408, 65483, 65514, 65527, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec1[21] = -{ - 0, 15, 33, 84, 185, 385, 807, 1619, 3529, 7850, 19488, - 51365, 62437, 64548, 65088, 65304, 65409, 65484, 65507, 65522, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec2[26] = -{ - 0, 15, 29, 54, 89, 145, 228, 380, 652, 1493, 4260, - 12359, 34133, 50749, 57224, 60814, 62927, 64078, 64742, 65103, 65311, 65418, - 65473, 65509, 65521, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec3[46] = -{ - 0, 8, 12, 16, 26, 42, 56, 76, 111, 164, 247, - 366, 508, 693, 1000, 1442, 2155, 3188, 4854, 7387, 11249, 17617, - 30079, 46711, 56291, 60127, 62140, 63258, 63954, 64384, 64690, 64891, 65031, - 65139, 65227, 65293, 65351, 65399, 65438, 65467, 65492, 65504, 65510, 65518, - 65523, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec4[78] = -{ - 0, 17, 29, 39, 51, 70, 104, 154, 234, 324, 443, - 590, 760, 971, 1202, 1494, 1845, 2274, 2797, 3366, 4088, 4905, - 5899, 7142, 8683, 10625, 12983, 16095, 20637, 28216, 38859, 47237, 51537, - 54150, 56066, 57583, 58756, 59685, 60458, 61103, 61659, 62144, 62550, 62886, - 63186, 63480, 63743, 63954, 64148, 64320, 64467, 64600, 64719, 64837, 64939, - 65014, 65098, 65160, 65211, 65250, 65290, 65325, 65344, 65366, 65391, 65410, - 65430, 65447, 65460, 65474, 65487, 65494, 65501, 65509, 65513, 65518, 65520, - 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec5[171] = -{ - 0, 10, 12, 14, 16, 18, 23, 29, 35, 42, 51, - 58, 65, 72, 78, 87, 96, 103, 111, 122, 134, 150, - 167, 184, 202, 223, 244, 265, 289, 315, 346, 379, 414, - 450, 491, 532, 572, 613, 656, 700, 751, 802, 853, 905, - 957, 1021, 1098, 1174, 1250, 1331, 1413, 1490, 1565, 1647, 1730, - 1821, 1913, 2004, 2100, 2207, 2314, 2420, 2532, 2652, 2783, 2921, - 3056, 3189, 3327, 3468, 3640, 3817, 3993, 4171, 4362, 4554, 4751, - 4948, 5142, 5346, 5566, 5799, 6044, 6301, 6565, 6852, 7150, 7470, - 7797, 8143, 8492, 8835, 9181, 9547, 9919, 10315, 10718, 11136, 11566, - 12015, 12482, 12967, 13458, 13953, 14432, 14903, 15416, 15936, 16452, 16967, - 17492, 18024, 18600, 19173, 19736, 20311, 20911, 21490, 22041, 22597, 23157, - 23768, 24405, 25034, 25660, 26280, 26899, 27614, 28331, 29015, 29702, 30403, - 31107, 31817, 32566, 33381, 34224, 35099, 36112, 37222, 38375, 39549, 40801, - 42074, 43350, 44626, 45982, 47354, 48860, 50361, 51845, 53312, 54739, 56026, - 57116, 58104, 58996, 59842, 60658, 61488, 62324, 63057, 63769, 64285, 64779, - 65076, 65344, 65430, 65500, 65517, 65535 -}; - -/* -* An array of pointers to CDFs of decorrelated LPC Gains -*/ -const WebRtc_UWord16* WebRtcIsac_kLpcGainCdfMat[SUBFRAMES] = -{ - WebRtcIsac_kLpcGainCdfVec0, WebRtcIsac_kLpcGainCdfVec1, - WebRtcIsac_kLpcGainCdfVec2, WebRtcIsac_kLpcGainCdfVec3, - WebRtcIsac_kLpcGainCdfVec4, WebRtcIsac_kLpcGainCdfVec5 -}; - -/* -* A matrix to decorrellate LPC gains of subframes. -*/ -const double WebRtcIsac_kLpcGainDecorrMat[SUBFRAMES][SUBFRAMES] = -{ - {-0.150860, 0.327872, 0.367220, 0.504613, 0.559270, 0.409234}, - { 0.457128, -0.613591, -0.289283, -0.029734, 0.393760, 0.418240}, - {-0.626043, 0.136489, -0.439118, -0.448323, 0.135987, 0.420869}, - { 0.526617, 0.480187, 0.242552, -0.488754, -0.158713, 0.411331}, - {-0.302587, -0.494953, 0.588112, -0.063035, -0.404290, 0.387510}, - { 0.086378, 0.147714, -0.428875, 0.548300, -0.570121, 0.401391} -}; diff --git a/src/mod/codecs/mod_isac/lpc_gain_swb_tables.h b/src/mod/codecs/mod_isac/lpc_gain_swb_tables.h deleted file mode 100644 index 1eba97c8ba..0000000000 --- a/src/mod/codecs/mod_isac/lpc_gain_swb_tables.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * SWB_KLT_Tables_LPCGain.h - * - * This file declares tables used for entropy coding of LPC Gain - * of upper-band. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_ - -#include "settings.h" -#include "typedefs.h" - -extern const double WebRtcIsac_kQSizeLpcGain; - -extern const double WebRtcIsac_kLeftRecPointLpcGain[SUBFRAMES]; - -extern const WebRtc_Word16 WebRtcIsac_kNumQCellLpcGain[SUBFRAMES]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainEntropySearch[SUBFRAMES]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec0[18]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec1[21]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec2[26]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec3[46]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec4[78]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec5[171]; - -extern const WebRtc_UWord16* WebRtcIsac_kLpcGainCdfMat[SUBFRAMES]; - -extern const double WebRtcIsac_kLpcGainDecorrMat[SUBFRAMES][SUBFRAMES]; - -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_ diff --git a/src/mod/codecs/mod_isac/lpc_shape_swb12_tables.c b/src/mod/codecs/mod_isac/lpc_shape_swb12_tables.c deleted file mode 100644 index 695d583277..0000000000 --- a/src/mod/codecs/mod_isac/lpc_shape_swb12_tables.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * SWB_KLT_Tables.c - * - * This file defines tables used for entropy coding of LPC shape of - * upper-band signal if the bandwidth is 12 kHz. - * - */ - -#include "lpc_shape_swb12_tables.h" -#include "settings.h" -#include "typedefs.h" - -/* -* Mean value of LAR -*/ -const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER] = -{ - 0.03748928306641, 0.09453441192543, -0.01112522344398, 0.03800237516842 -}; - -/* -* A rotation matrix to decorrelate intra-vector correlation, -* i.e. correlation among components of LAR vector. -*/ -const double WebRtcIsac_kIntraVecDecorrMatUb12[UB_LPC_ORDER][UB_LPC_ORDER] = -{ - {-0.00075365493856, -0.05809964887743, -0.23397966154116, 0.97050367376411}, - { 0.00625021257734, -0.17299965610679, 0.95977735920651, 0.22104179375008}, - { 0.20543384258374, -0.96202143495696, -0.15301870801552, -0.09432375099565}, - {-0.97865075648479, -0.20300322280841, -0.02581111653779, -0.01913568980258} -}; - -/* -* A rotation matrix to remove correlation among LAR coefficients -* of different LAR vectors. One might guess that decorrelation matrix -* for the first component should differ from the second component -* but we haven't observed a significant benefit of having different -* decorrelation matrices for different components. -*/ -const double WebRtcIsac_kInterVecDecorrMatUb12 -[UB_LPC_VEC_PER_FRAME][UB_LPC_VEC_PER_FRAME] = -{ - { 0.70650597970460, -0.70770707262373}, - {-0.70770707262373, -0.70650597970460} -}; - -/* -* LAR quantization step-size. -*/ -const double WebRtcIsac_kLpcShapeQStepSizeUb12 = 0.150000; - -/* -* The smallest reconstruction points for quantiztion of LAR coefficients. -*/ -const double WebRtcIsac_kLpcShapeLeftRecPointUb12 -[UB_LPC_ORDER*UB_LPC_VEC_PER_FRAME] = -{ - -0.900000, -1.050000, -1.350000, -1.800000, -1.350000, -1.650000, - -2.250000, -3.450000 -}; - -/* -* Number of reconstruction points of quantizers for LAR coefficients. -*/ -const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb12 -[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] = -{ - 13, 15, 19, 27, 19, 24, 32, 48 -}; - -/* -* Starting index for entropy decoder to search for the right interval, -* one entry per LAR coefficient -*/ -const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb12 -[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] = -{ - 6, 7, 9, 13, 9, 12, 16, 24 -}; - -/* -* The following 8 vectors define CDF of 8 decorrelated LAR -* coefficients. -*/ -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec0Ub12[14] = -{ - 0, 13, 95, 418, 1687, 6498, 21317, 44200, 59029, 63849, 65147, - 65449, 65525, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub12[16] = -{ - 0, 10, 59, 255, 858, 2667, 8200, 22609, 42988, 57202, 62947, - 64743, 65308, 65476, 65522, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub12[20] = -{ - 0, 18, 40, 118, 332, 857, 2017, 4822, 11321, 24330, 41279, - 54342, 60637, 63394, 64659, 65184, 65398, 65482, 65518, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub12[28] = -{ - 0, 21, 38, 90, 196, 398, 770, 1400, 2589, 4650, 8211, - 14933, 26044, 39592, 50814, 57452, 60971, 62884, 63995, 64621, 65019, 65273, - 65410, 65480, 65514, 65522, 65531, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub12[20] = -{ - 0, 7, 46, 141, 403, 969, 2132, 4649, 10633, 24902, 43254, - 54665, 59928, 62674, 64173, 64938, 65293, 65464, 65523, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub12[25] = -{ - 0, 7, 22, 72, 174, 411, 854, 1737, 3545, 6774, 13165, - 25221, 40980, 52821, 58714, 61706, 63472, 64437, 64989, 65287, 65430, 65503, - 65525, 65529, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub12[33] = -{ - 0, 11, 21, 36, 65, 128, 228, 401, 707, 1241, 2126, - 3589, 6060, 10517, 18853, 31114, 42477, 49770, 54271, 57467, 59838, 61569, - 62831, 63772, 64433, 64833, 65123, 65306, 65419, 65466, 65499, 65519, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub12[49] = -{ - 0, 14, 34, 67, 107, 167, 245, 326, 449, 645, 861, - 1155, 1508, 2003, 2669, 3544, 4592, 5961, 7583, 9887, 13256, 18765, - 26519, 34077, 40034, 44349, 47795, 50663, 53262, 55473, 57458, 59122, 60592, - 61742, 62690, 63391, 63997, 64463, 64794, 65045, 65207, 65309, 65394, 65443, - 65478, 65504, 65514, 65523, 65535 -}; - -/* -* An array of pointers to CDFs of decorrelated LARs -*/ -const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb12 -[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] = -{ - WebRtcIsac_kLpcShapeCdfVec0Ub12, WebRtcIsac_kLpcShapeCdfVec1Ub12, - WebRtcIsac_kLpcShapeCdfVec2Ub12, WebRtcIsac_kLpcShapeCdfVec3Ub12, - WebRtcIsac_kLpcShapeCdfVec4Ub12, WebRtcIsac_kLpcShapeCdfVec5Ub12, - WebRtcIsac_kLpcShapeCdfVec6Ub12, WebRtcIsac_kLpcShapeCdfVec7Ub12 -}; diff --git a/src/mod/codecs/mod_isac/lpc_shape_swb12_tables.h b/src/mod/codecs/mod_isac/lpc_shape_swb12_tables.h deleted file mode 100644 index 1e93847fae..0000000000 --- a/src/mod/codecs/mod_isac/lpc_shape_swb12_tables.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * lpc_shape_swb12_tables.h - * - * This file declares tables used for entropy coding of LPC shape of - * upper-band signal if the bandwidth is 12 kHz. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_ - -#include "settings.h" -#include "typedefs.h" - -extern const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER]; - -extern const double WebRtcIsac_kMeanLpcGain; - -extern const double WebRtcIsac_kIntraVecDecorrMatUb12[UB_LPC_ORDER][UB_LPC_ORDER]; - -extern const double WebRtcIsac_kInterVecDecorrMatUb12 -[UB_LPC_VEC_PER_FRAME][UB_LPC_VEC_PER_FRAME]; - -extern const double WebRtcIsac_kLpcShapeQStepSizeUb12; - -extern const double WebRtcIsac_kLpcShapeLeftRecPointUb12 -[UB_LPC_ORDER*UB_LPC_VEC_PER_FRAME]; - - -extern const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb12 -[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb12 -[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec0Ub12[14]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub12[16]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub12[20]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub12[28]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub12[20]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub12[25]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub12[33]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub12[49]; - -extern const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb12 -[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME]; - -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_ diff --git a/src/mod/codecs/mod_isac/lpc_shape_swb16_tables.c b/src/mod/codecs/mod_isac/lpc_shape_swb16_tables.c deleted file mode 100644 index 89f45233f5..0000000000 --- a/src/mod/codecs/mod_isac/lpc_shape_swb16_tables.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * SWB16_KLT_Tables.c - * - * This file defines tables used for entropy coding of LPC shape of - * upper-band signal if the bandwidth is 16 kHz. - * - */ - -#include "lpc_shape_swb16_tables.h" -#include "settings.h" -#include "typedefs.h" - -/* -* Mean value of LAR -*/ -const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER] = -{ -0.454978, 0.364747, 0.102999, 0.104523 -}; - -/* -* A rotation matrix to decorrelate intra-vector correlation, -* i.e. correlation among components of LAR vector. -*/ -const double WebRtcIsac_kIintraVecDecorrMatUb16[UB_LPC_ORDER][UB_LPC_ORDER] = -{ - {-0.020528, -0.085858, -0.002431, 0.996093}, - {-0.033155, 0.036102, 0.998786, 0.004866}, - { 0.202627, 0.974853, -0.028940, 0.088132}, - {-0.978479, 0.202454, -0.039785, -0.002811} -}; - -/* -* A rotation matrix to remove correlation among LAR coefficients -* of different LAR vectors. One might guess that decorrelation matrix -* for the first component should differ from the second component -* but we haven't observed a significant benefit of having different -* decorrelation matrices for different components. -*/ -const double WebRtcIsac_kInterVecDecorrMatUb16 -[UB16_LPC_VEC_PER_FRAME][UB16_LPC_VEC_PER_FRAME] = -{ - { 0.291675, -0.515786, 0.644927, 0.482658}, - {-0.647220, 0.479712, 0.289556, 0.516856}, - { 0.643084, 0.485489, -0.289307, 0.516763}, - {-0.287185, -0.517823, -0.645389, 0.482553} -}; - -/* -* The following 16 vectors define CDF of 16 decorrelated LAR -* coefficients. -*/ -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub16[14] = -{ - 0, 2, 20, 159, 1034, 5688, 20892, 44653, - 59849, 64485, 65383, 65518, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub16[16] = -{ - 0, 1, 7, 43, 276, 1496, 6681, 21653, - 43891, 58859, 64022, 65248, 65489, 65529, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub16[18] = -{ - 0, 1, 9, 54, 238, 933, 3192, 9461, - 23226, 42146, 56138, 62413, 64623, 65300, 65473, 65521, - 65533, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub16[30] = -{ - 0, 2, 4, 8, 17, 36, 75, 155, - 329, 683, 1376, 2662, 5047, 9508, 17526, 29027, - 40363, 48997, 55096, 59180, 61789, 63407, 64400, 64967, - 65273, 65429, 65497, 65526, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub16[16] = -{ - 0, 1, 10, 63, 361, 1785, 7407, 22242, - 43337, 58125, 63729, 65181, 65472, 65527, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub16[17] = -{ - 0, 1, 7, 29, 134, 599, 2443, 8590, - 22962, 42635, 56911, 63060, 64940, 65408, 65513, 65531, - 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub16[21] = -{ - 0, 1, 5, 16, 57, 191, 611, 1808, - 4847, 11755, 24612, 40910, 53789, 60698, 63729, 64924, - 65346, 65486, 65523, 65532, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub16[36] = -{ - 0, 1, 4, 12, 25, 55, 104, 184, - 314, 539, 926, 1550, 2479, 3861, 5892, 8845, - 13281, 20018, 29019, 38029, 45581, 51557, 56057, 59284, - 61517, 63047, 64030, 64648, 65031, 65261, 65402, 65480, - 65518, 65530, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec8Ub16[21] = -{ - 0, 1, 2, 7, 26, 103, 351, 1149, - 3583, 10204, 23846, 41711, 55361, 61917, 64382, 65186, - 65433, 65506, 65528, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub160[21] = -{ - 0, 6, 19, 63, 205, 638, 1799, 4784, - 11721, 24494, 40803, 53805, 60886, 63822, 64931, 65333, - 65472, 65517, 65530, 65533, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub161[28] = -{ - 0, 1, 3, 11, 31, 86, 221, 506, - 1101, 2296, 4486, 8477, 15356, 26079, 38941, 49952, - 57165, 61257, 63426, 64549, 65097, 65351, 65463, 65510, - 65526, 65532, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub162[55] = -{ - 0, 3, 12, 23, 42, 65, 89, 115, - 150, 195, 248, 327, 430, 580, 784, 1099, - 1586, 2358, 3651, 5899, 9568, 14312, 19158, 23776, - 28267, 32663, 36991, 41153, 45098, 48680, 51870, 54729, - 57141, 59158, 60772, 62029, 63000, 63761, 64322, 64728, - 65000, 65192, 65321, 65411, 65463, 65496, 65514, 65523, - 65527, 65529, 65531, 65532, 65533, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub163[26] = -{ - 0, 2, 4, 10, 21, 48, 114, 280, - 701, 1765, 4555, 11270, 24267, 41213, 54285, 61003, - 63767, 64840, 65254, 65421, 65489, 65514, 65526, 65532, - 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub164[28] = -{ - 0, 1, 3, 6, 15, 36, 82, 196, - 453, 1087, 2557, 5923, 13016, 25366, 40449, 52582, - 59539, 62896, 64389, 65033, 65316, 65442, 65494, 65519, - 65529, 65533, 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub165[34] = -{ - 0, 2, 4, 8, 18, 35, 73, 146, - 279, 524, 980, 1789, 3235, 5784, 10040, 16998, - 27070, 38543, 48499, 55421, 59712, 62257, 63748, 64591, - 65041, 65278, 65410, 65474, 65508, 65522, 65530, 65533, - 65534, 65535 -}; - -const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub166[71] = -{ - 0, 1, 2, 6, 13, 26, 55, 92, - 141, 191, 242, 296, 355, 429, 522, 636, - 777, 947, 1162, 1428, 1753, 2137, 2605, 3140, - 3743, 4409, 5164, 6016, 6982, 8118, 9451, 10993, - 12754, 14810, 17130, 19780, 22864, 26424, 30547, 35222, - 40140, 44716, 48698, 52056, 54850, 57162, 59068, 60643, - 61877, 62827, 63561, 64113, 64519, 64807, 65019, 65167, - 65272, 65343, 65399, 65440, 65471, 65487, 65500, 65509, - 65518, 65524, 65527, 65531, 65533, 65534, 65535 -}; - -/* -* An array of pointers to CDFs of decorrelated LARs -*/ -const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] = { - WebRtcIsac_kLpcShapeCdfVec01Ub16, - WebRtcIsac_kLpcShapeCdfVec1Ub16, - WebRtcIsac_kLpcShapeCdfVec2Ub16, - WebRtcIsac_kLpcShapeCdfVec3Ub16, - WebRtcIsac_kLpcShapeCdfVec4Ub16, - WebRtcIsac_kLpcShapeCdfVec5Ub16, - WebRtcIsac_kLpcShapeCdfVec6Ub16, - WebRtcIsac_kLpcShapeCdfVec7Ub16, - WebRtcIsac_kLpcShapeCdfVec8Ub16, - WebRtcIsac_kLpcShapeCdfVec01Ub160, - WebRtcIsac_kLpcShapeCdfVec01Ub161, - WebRtcIsac_kLpcShapeCdfVec01Ub162, - WebRtcIsac_kLpcShapeCdfVec01Ub163, - WebRtcIsac_kLpcShapeCdfVec01Ub164, - WebRtcIsac_kLpcShapeCdfVec01Ub165, - WebRtcIsac_kLpcShapeCdfVec01Ub166 -}; - -/* -* The smallest reconstruction points for quantiztion of LAR coefficients. -*/ -const double WebRtcIsac_kLpcShapeLeftRecPointUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] = -{ - -0.8250, -0.9750, -1.1250, -2.1750, -0.9750, -1.1250, -1.4250, - -2.6250, -1.4250, -1.2750, -1.8750, -3.6750, -1.7250, -1.8750, - -2.3250, -5.4750 -}; - -/* -* Number of reconstruction points of quantizers for LAR coefficients. -*/ -const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] = -{ - 13, 15, 17, 29, 15, 16, 20, 35, 20, - 20, 27, 54, 25, 27, 33, 70 -}; - -/* -* Starting index for entropy decoder to search for the right interval, -* one entry per LAR coefficient -*/ -const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] = -{ - 6, 7, 8, 14, 7, 8, 10, 17, 10, - 10, 13, 27, 12, 13, 16, 35 -}; - -/* -* LAR quantization step-size. -*/ -const double WebRtcIsac_kLpcShapeQStepSizeUb16 = 0.150000; diff --git a/src/mod/codecs/mod_isac/lpc_shape_swb16_tables.h b/src/mod/codecs/mod_isac/lpc_shape_swb16_tables.h deleted file mode 100644 index 68d08b2047..0000000000 --- a/src/mod/codecs/mod_isac/lpc_shape_swb16_tables.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * lpc_shape_swb16_tables.h - * - * This file declares tables used for entropy coding of LPC shape of - * upper-band signal if the bandwidth is 16 kHz. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_ - -#include "settings.h" -#include "typedefs.h" - - -extern const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER]; - -extern const double WebRtcIsac_kIintraVecDecorrMatUb16[UB_LPC_ORDER][UB_LPC_ORDER]; - -extern const double WebRtcIsac_kInterVecDecorrMatUb16 -[UB16_LPC_VEC_PER_FRAME][UB16_LPC_VEC_PER_FRAME]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub16[14]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub16[16]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub16[18]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub16[30]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub16[16]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub16[17]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub16[21]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub16[36]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec8Ub16[21]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub160[21]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub161[28]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub162[55]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub163[26]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub164[28]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub165[34]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub166[71]; - -extern const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - -extern const double WebRtcIsac_kLpcShapeLeftRecPointUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - -extern const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - -extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb16 -[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - -extern const double WebRtcIsac_kLpcShapeQStepSizeUb16; - -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_ diff --git a/src/mod/codecs/mod_isac/lpc_tables.c b/src/mod/codecs/mod_isac/lpc_tables.c deleted file mode 100644 index 7df6121462..0000000000 --- a/src/mod/codecs/mod_isac/lpc_tables.c +++ /dev/null @@ -1,1129 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* coding tables for the KLT coefficients */ - -#include "lpc_tables.h" -#include "settings.h" - -/* indices of KLT coefficients used */ -const WebRtc_UWord16 WebRtcIsac_kQKltSelIndGain[12] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11}; - -const WebRtc_UWord16 WebRtcIsac_kQKltSelIndShape[108] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107}; - -/* cdf array for model indicator */ -const WebRtc_UWord16 WebRtcIsac_kQKltModelCdf[4] = { - 0, 15434, 37548, 65535}; - -/* pointer to cdf array for model indicator */ -const WebRtc_UWord16 *WebRtcIsac_kQKltModelCdfPtr[1] = {WebRtcIsac_kQKltModelCdf}; - -/* initial cdf index for decoder of model indicator */ -const WebRtc_UWord16 WebRtcIsac_kQKltModelInitIndex[1] = {1}; - -/* offset to go from rounded value to quantization index */ -const short WebRtcIsac_kQKltQuantMinGain[12] = { - 3, 6, 4, 6, 6, 9, 5, 16, 11, 34, 32, 47}; - - -const short WebRtcIsac_kQKltQuantMinShape[108] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 2, 2, 2, 3, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 2, 2, 3, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 4, 3, 5, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 2, 1, 2, 2, 3, 4, - 4, 7, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 2, 3, 2, 3, 4, 4, 5, 7, 13, - 0, 1, 1, 2, 3, 2, 2, 2, 4, 4, - 5, 6, 7, 11, 9, 13, 12, 26}; - -/* maximum quantization index */ -const WebRtc_UWord16 WebRtcIsac_kQKltMaxIndGain[12] = { - 6, 12, 8, 14, 10, 19, 12, 31, 22, 56, 52, 138}; - -const WebRtc_UWord16 WebRtcIsac_kQKltMaxIndShape[108] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 2, 2, 2, 2, 4, 4, 5, 6, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 1, 2, 2, - 2, 2, 3, 4, 5, 7, 0, 0, 0, 0, - 2, 0, 2, 2, 2, 2, 3, 2, 2, 4, - 4, 6, 6, 9, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 3, 2, 4, 4, 7, 7, - 9, 13, 0, 0, 2, 2, 2, 2, 2, 2, - 3, 4, 5, 4, 6, 8, 8, 10, 16, 25, - 0, 2, 2, 4, 5, 4, 4, 4, 7, 8, - 9, 10, 13, 19, 17, 23, 25, 49}; - -/* index offset */ -const WebRtc_UWord16 WebRtcIsac_kQKltOffsetGain[3][12] = { -{ 0, 7, 20, 29, 44, 55, 75, 88, 120, 143, - 200, 253}, -{ 0, 7, 19, 27, 42, 53, 73, 86, 117, 140, - 197, 249}, -{ 0, 7, 20, 28, 44, 55, 75, 89, 121, 145, - 202, 257}}; - -const WebRtc_UWord16 WebRtcIsac_kQKltOffsetShape[3][108] = { -{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 11, 14, 17, 20, 23, 28, 33, 39, 46, 47, - 48, 49, 50, 52, 53, 54, 55, 56, 58, 61, - 64, 67, 70, 74, 79, 85, 93, 94, 95, 96, - 97, 100, 101, 104, 107, 110, 113, 117, 120, 123, - 128, 133, 140, 147, 157, 158, 159, 160, 161, 164, - 167, 170, 173, 176, 179, 183, 186, 191, 196, 204, - 212, 222, 236, 237, 238, 241, 244, 247, 250, 253, - 256, 260, 265, 271, 276, 283, 292, 301, 312, 329, - 355, 356, 359, 362, 367, 373, 378, 383, 388, 396, - 405, 415, 426, 440, 460, 478, 502, 528}, -{ 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, - 13, 16, 19, 22, 26, 29, 34, 39, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 55, 57, 60, - 63, 66, 70, 73, 78, 84, 91, 92, 93, 94, - 95, 96, 97, 99, 102, 105, 108, 111, 114, 118, - 123, 128, 134, 141, 151, 152, 153, 154, 156, 159, - 162, 165, 168, 171, 174, 177, 181, 186, 194, 200, - 208, 218, 233, 234, 235, 236, 239, 242, 245, 248, - 251, 254, 258, 263, 270, 277, 288, 297, 308, 324, - 349, 351, 354, 357, 361, 366, 372, 378, 383, 390, - 398, 407, 420, 431, 450, 472, 496, 524}, -{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, - 14, 17, 20, 23, 26, 29, 34, 40, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 58, 61, 64, - 67, 70, 73, 77, 82, 88, 96, 97, 98, 99, - 101, 102, 104, 107, 110, 113, 116, 119, 122, 125, - 129, 134, 141, 150, 160, 161, 162, 163, 166, 168, - 171, 174, 177, 180, 183, 186, 190, 195, 201, 208, - 216, 226, 243, 244, 245, 248, 251, 254, 257, 260, - 263, 268, 273, 278, 284, 291, 299, 310, 323, 340, - 366, 368, 371, 374, 379, 383, 389, 394, 399, 406, - 414, 422, 433, 445, 461, 480, 505, 533}}; - -/* initial cdf index for KLT coefficients */ -const WebRtc_UWord16 WebRtcIsac_kQKltInitIndexGain[3][12] = { -{ 3, 6, 4, 7, 5, 10, 6, 16, 11, 28, - 26, 69}, -{ 3, 6, 4, 7, 5, 10, 6, 15, 11, 28, - 26, 69}, -{ 3, 6, 4, 8, 5, 10, 7, 16, 12, 28, - 27, 70}}; - -const WebRtc_UWord16 WebRtcIsac_kQKltInitIndexShape[3][108] = { -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 2, 2, 3, 3, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 2, 2, 3, 4, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 1, 2, 1, 1, 2, - 2, 3, 3, 5, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 2, 1, 2, 2, 4, 4, - 5, 7, 0, 0, 1, 1, 1, 1, 1, 1, - 2, 2, 3, 2, 3, 4, 4, 5, 8, 13, - 0, 1, 1, 2, 3, 2, 2, 2, 4, 4, - 5, 5, 7, 10, 9, 12, 13, 25}, -{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 1, 1, 1, 2, 1, 2, 2, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 2, 1, 2, 3, 3, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, - 2, 3, 3, 5, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 4, 3, 4, - 5, 7, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 2, 2, 3, 3, 5, 4, 5, 8, 12, - 1, 1, 1, 2, 2, 3, 3, 2, 3, 4, - 4, 6, 5, 9, 11, 12, 14, 25}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 2, 3, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 2, 2, 3, 4, 0, 0, 0, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 3, 4, 5, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, - 5, 8, 0, 0, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 3, 3, 4, 5, 6, 8, 13, - 1, 1, 1, 2, 2, 3, 2, 2, 3, 4, - 4, 5, 6, 8, 9, 12, 14, 25}}; - -/* offsets for quantizer representation levels*/ -const WebRtc_UWord16 WebRtcIsac_kQKltOfLevelsGain[3] = { - 0, 392, 779}; - -const WebRtc_UWord16 WebRtcIsac_kQKltOfLevelsShape[3] = { - 0, 578, 1152}; - -/* quantizer representation levels */ -const double WebRtcIsac_kQKltLevelsGain[1176] = { --2.78127126, -1.76745590, -0.77913790, -0.00437329, 0.79961206, 1.81775776, 2.81389782, -5.78753143, -4.88384084, -3.89320940, --2.88133610, -1.92859977, -0.86347396, 0.02003888, 0.86140400, 1.89667156, 2.97134967, 3.98781964, 4.91727277, 5.82865898, --4.11195874, -2.80898424, -1.87547977, -0.80943825, -0.00679084, 0.79573851, 1.83953397, 2.67586037, 3.76274082, -6.10933968, --4.93034581, -3.89281296, -2.91530625, -1.89684163, -0.85319130, -0.02275767, 0.86862017, 1.91578276, 2.96107339, 3.96543056, - 4.91369908, 5.91058154, 6.83848343, 8.07136925, -5.87470395, -4.84703049, -3.84284597, -2.86168446, -1.89290192, -0.82798145, --0.00080013, 0.82594974, 1.85754329, 2.88351798, 3.96172628, -8.85684885, -7.87387461, -6.97811862, -5.93256270, -4.94301439, --3.95513701, -2.96041544, -1.94031192, -0.87961478, -0.00456201, 0.89911505, 1.91723376, 2.94011511, 3.93302540, 4.97990967, - 5.93133404, 7.02181199, 7.92407762, 8.80155440, 10.04665814, -4.82396678, -3.85612158, -2.89482244, -1.89558408, -0.90036978, --0.00677823, 0.90607989, 1.90937981, 2.91175777, 3.91637730, 4.97565723, 5.84771228, 7.11145863, -16.07879840, -15.03776309, --13.93905670, -12.95671800, -11.89171202, -10.95820934, -9.95923714, -8.94357334, -7.99068299, -6.97481009, -5.94826231, -4.96673988, --3.97490466, -2.97846970, -1.95130435, -0.94215262, -0.01444043, 0.96770704, 1.95848598, 2.94107862, 3.95666119, 4.97253085, - 5.97191122, 6.93277360, 7.96608727, 8.87958779, 10.00264269, 10.86560820, 12.07449071, 13.04491775, 13.97507061, 14.91845261, --10.85696295, -9.83365357, -9.01245635, -7.95915145, -6.95625003, -5.95362618, -4.93468444, -3.98760978, -2.95044407, -1.97041277, --0.97701799, -0.00840234, 0.97834289, 1.98361415, 2.97802439, 3.96415871, 4.95369042, 5.94101770, 6.92756798, 7.94063998, - 8.85951828, 9.97077022, 11.00068503, -33.92030406, -32.81426422, -32.00000000, -31.13243639, -30.11886909, -29.06017570, -28.12598824, --27.22045482, -25.81215858, -25.07849962, -23.93018013, -23.02097643, -21.89529725, -20.99091085, -19.98889048, -18.94327044, -17.96562071, --16.96126218, -15.95054062, -14.98516200, -13.97101012, -13.02106500, -11.98438006, -11.03216748, -9.95930286, -8.97043946, -7.98085082, --6.98360995, -5.98998802, -4.98668173, -4.00032906, -3.00420619, -1.98701132, -0.99324682, -0.00609324, 0.98297834, 1.99483076, - 3.00305044, 3.97142097, 4.97525759, 5.98612258, 6.97448236, 7.97575900, 9.01086211, 9.98665542, 11.00541438, 11.98078628, - 12.92352471, 14.06849675, 14.99949430, 15.94904834, 16.97440321, 18.04040916, 18.88987609, 20.05312391, 21.00000000, 21.79443341, --31.98578825, -31.00000000, -29.89060567, -28.98555686, -27.97114102, -26.84935410, -26.02402230, -24.94195278, -23.92336849, -22.95552382, --21.97932836, -20.96055470, -19.99649553, -19.03436122, -17.96706525, -17.01139515, -16.01363516, -14.99154248, -14.00298333, -12.99630613, --11.99955519, -10.99000421, -10.00819092, -8.99763648, -7.98431793, -7.01769025, -5.99604690, -4.99980697, -3.99334671, -3.01748192, --2.02051217, -1.00848371, -0.01942358, 1.00477757, 1.95477872, 2.98593031, 3.98779079, 4.96862849, 6.02694771, 6.93983733, - 7.89874717, 8.99615862, 10.02367921, 10.96293452, 11.84351528, 12.92207187, 13.85122329, 15.05146877, 15.99371264, 17.00000000, - 18.00000000, 19.00000000, 19.82763573, -47.00000000, -46.00000000, -44.87138498, -44.00000000, -43.00000000, -42.00000000, -41.00000000, --39.88966612, -38.98913239, -37.80306486, -37.23584325, -35.94200288, -34.99881301, -34.11361858, -33.06507360, -32.13129135, -30.90891364, --29.81511907, -28.99250380, -28.04535391, -26.99767800, -26.04418164, -24.95687851, -24.04865595, -23.03392645, -21.89366707, -20.93517364, --19.99388660, -18.91620943, -18.03749683, -16.99532379, -15.98683813, -15.06421479, -13.99359211, -12.99714098, -11.97022520, -10.98500279, --9.98834422, -8.95729330, -8.01232284, -7.00253661, -5.99681626, -5.01207817, -3.95914904, -3.01232178, -1.96615919, -0.97687670, - 0.01228030, 0.98412288, 2.01753544, 3.00580570, 3.97783510, 4.98846894, 6.01321400, 7.00867732, 8.00416375, 9.01771966, - 9.98637729, 10.98255180, 11.99194163, 13.01807333, 14.00999545, 15.00118556, 16.00089224, 17.00584148, 17.98251763, 18.99942091, - 19.96917690, 20.97839265, 21.98207297, 23.00171271, 23.99930737, 24.99746061, 26.00936304, 26.98240132, 28.01126868, 29.01395915, - 29.98153507, 31.01376711, 31.99876818, 33.00475317, 33.99753994, 34.99493913, 35.98933585, 36.95620160, 37.98428461, 38.99317544, - 40.01832073, 40.98048133, 41.95999283, 42.98232091, 43.96523612, 44.99574268, 45.99524194, 47.05464025, 48.03821548, 48.99354366, - 49.96400411, 50.98017973, 51.95184408, 52.96291806, 54.00194392, 54.96603783, 55.95623778, 57.03076595, 58.05889901, 58.99081551, - 59.97928121, 61.05071612, 62.03971580, 63.01286038, 64.01290338, 65.02074503, 65.99454594, 67.00399425, 67.96571257, 68.95305727, - 69.92030664, 70.95594862, 71.98088567, 73.04764124, 74.00285480, 75.02696330, 75.89837673, 76.93459997, 78.16266309, 78.83317543, - 80.00000000, 80.87251574, 82.09803524, 83.10671664, 84.00000000, 84.77023523, 86.00000000, 87.00000000, 87.92946897, 88.69159118, - 90.00000000, 90.90535270, -3.00000000, -2.00000000, -0.77592424, -0.00564307, 0.76727305, 2.00000000, 3.00000000, -6.00000000, --5.00000000, -4.00000000, -2.92897924, -1.85623684, -0.72445303, -0.00119184, 0.72896652, 2.05710416, 3.17909894, 4.00000000, - 5.00000000, -3.00000000, -2.00000000, -0.67480586, -0.00028016, 0.66618169, 2.00000000, 3.00000000, 4.00000000, -7.00000000, --6.00000000, -5.00000000, -3.78336783, -2.84811556, -2.04088844, -0.71114371, 0.03142493, 0.69662772, 1.91417930, 3.00000000, - 4.01411062, 5.00000000, 6.00000000, 7.00000000, -6.00000000, -5.00000000, -4.00000000, -3.00000000, -2.00000000, -0.63703469, - 0.00169604, 0.66294191, 1.83808563, 3.00000000, 4.00000000, -8.00000000, -7.00000000, -6.03082300, -5.00000000, -3.88061019, --2.92670084, -1.99902336, -0.72898996, -0.02880170, 0.73769927, 1.95920233, 2.78356263, 4.08100921, 5.00000000, 6.00000000, - 6.78771437, 8.00000000, 9.00000000, 10.00000000, 11.00000000, -5.00000000, -4.00000000, -2.88150384, -1.89520024, -0.71479482, - 0.00962397, 0.72816030, 1.73583550, 3.00000000, 4.00000000, 5.00000000, 6.00000000, 7.00000000, -16.00000000, -15.00000000, --13.80516401, -13.00000000, -12.00000000, -11.00000000, -10.02723144, -9.11825995, -8.05820112, -7.00000000, -6.17943541, -5.01837980, --3.97546169, -2.92806857, -1.89778775, -0.81138893, -0.02246016, 0.80528415, 1.85705214, 2.96438524, 3.97540151, 4.79684246, - 6.00000000, 6.75549513, 8.12185828, 9.00000000, 10.00000000, 11.00000000, 12.00000000, 13.00000000, 14.00000000, -11.00000000, --10.00000000, -9.00000000, -7.91603344, -6.77865892, -5.85765006, -4.93342332, -3.96679157, -2.84925552, -1.89230732, -0.85384229, - 0.00579591, 0.84863246, 1.89006713, 2.89483818, 3.87322971, 5.13228411, 6.00000000, 7.00000000, 8.00000000, 9.00000000, - 10.00000000, 11.00000000, -34.00000000, -33.00000000, -32.00000000, -31.00000000, -30.00000000, -29.00000000, -28.00000000, -27.00000000, --26.00000000, -25.00000000, -24.00000000, -23.00000000, -22.00000000, -21.00000000, -20.19501953, -19.00000000, -18.00000000, -17.00000000, --16.00000000, -14.89069633, -14.00000000, -13.00000000, -12.16260304, -11.15418282, -9.83543570, -8.85600407, -7.82712677, -7.05664308, --5.97007352, -4.89268438, -3.93822771, -2.94975269, -1.92192127, -0.90702480, 0.03974847, 0.92488359, 1.93747579, 2.94500522, - 3.95181797, 4.95433087, 5.95141808, 7.00212920, 8.02964757, 9.03210585, 9.84644504, 10.82907720, 11.87622530, 12.96908371, - 14.00000000, 15.16963413, 15.94902025, 17.00000000, 18.00000000, 19.00000000, 20.00000000, 21.00000000, 22.00000000, -29.00000000, --27.79780781, -27.00757888, -26.01571026, -24.89695568, -23.99946491, -22.98699614, -21.96678139, -20.99883532, -20.00851529, -18.94738054, --17.98672566, -16.98684787, -15.96917397, -14.99856852, -13.98974852, -12.97786927, -11.96110939, -10.98877093, -9.99875257, -8.99001359, --8.00799989, -6.99471760, -6.00034670, -4.99936372, -4.00581479, -3.00424577, -2.02047620, -0.99713266, -0.00366397, 1.00803955, - 1.98452687, 3.00748501, 4.02714611, 4.97661026, 5.99337271, 6.99754716, 8.00713602, 8.97184974, 9.98047901, 10.97685939, - 11.99533975, 12.96107876, 13.95061478, 15.00756776, 15.94078690, 16.88231059, 17.92069248, 18.78011047, 20.00000000, 21.00000000, - 22.00000000, -55.76988333, -54.96048193, -53.88411581, -52.94117980, -51.80983449, -50.90359699, -50.00000000, -48.99838741, -47.97685542, --47.03288597, -45.97820919, -45.02418374, -43.90081897, -42.88832512, -41.98234549, -40.96745512, -39.98148729, -39.06792854, -37.96493755, --36.98707870, -36.03416079, -35.01192444, -33.95785029, -32.99469087, -31.96633807, -31.01769053, -29.99727691, -28.99329690, -27.98873019, --27.00344273, -25.97657141, -25.00511074, -23.96689479, -23.01566842, -22.01632643, -21.00076343, -19.97788007, -18.97248680, -17.96076284, --16.97585453, -15.98345587, -15.01612745, -13.96862118, -12.96622055, -12.02196641, -11.02078103, -9.98445656, -9.00050060, -8.03442387, --7.00363761, -5.97921358, -4.98886269, -4.00528221, -3.01672947, -1.98599795, -1.00668518, -0.02633490, 1.00794139, 2.00837138, - 2.99213287, 3.98710216, 4.99064334, 6.01416391, 7.01759708, 7.97878151, 8.99665730, 10.02656114, 11.01863887, 12.01207901, - 13.00958725, 13.99237829, 15.00954971, 16.00724653, 17.00606559, 17.99886292, 18.99611967, 19.98808171, 21.01871930, 21.97014763, - 22.99833843, 24.00316842, 24.99949142, 25.98539601, 27.02480733, 27.98075377, 28.98266019, 30.00611445, 30.99409128, 31.94523141, - 32.97688339, 33.98800206, 35.00177074, 35.98639997, 36.98939428, 37.95644255, 39.00114054, 39.99492439, 40.99338254, 41.97050844, - 43.03085663, 43.96757668, 44.97800970, 45.95953358, 46.98109551, 47.99368477, 49.00141209, 49.94459923, 50.93298108, 51.99894661, - 53.06463883, 53.99704669, 55.02037199, 55.98368047, 57.01930954, 58.03813852, 58.96232502, 60.01644186, 61.03254711, 62.01086576, - 62.87962247, 63.98378413, 65.02189831, 65.93003954, 66.92439900, 68.07051633, 68.95928756, 70.03315022, 71.05579859, 72.00000000, - 73.00000000, 74.00000000, 75.00000000, 75.93485291, 77.20950456, 78.00000000, 79.00000000, 79.91519960, 81.00000000, -3.00000000, --2.00000000, -0.65174074, -0.00092112, 0.62967387, 2.00000000, 3.00000000, -6.00000000, -5.00000000, -4.00000000, -2.89861729, --1.69999061, -0.72632201, 0.00219241, 0.72891750, 1.73257865, 3.00000000, 3.76561508, 5.00000000, 6.00000000, -3.00000000, --2.00000000, -0.66227013, 0.00389373, 0.66163500, 2.00000000, 3.00000000, 4.00000000, -8.00000000, -7.00000000, -6.00000000, --4.76421796, -4.04320264, -3.01415201, -1.84346485, -0.77185048, 0.00061977, 0.76274524, 1.84330156, 3.00000000, 4.00000000, - 5.00000000, 6.00000000, 7.00000000, -6.00000000, -5.00000000, -4.00000000, -3.00000000, -1.75749611, -0.72951347, -0.00104394, - 0.72040315, 1.72594036, 3.00000000, 4.00000000, -9.00000000, -8.00000000, -7.00000000, -5.90394062, -5.00000000, -3.75562807, --2.89699407, -1.86696610, -0.79056636, -0.00330943, 0.79744554, 1.85149941, 2.91118681, 3.99520311, 4.96341987, 6.00000000, - 7.00000000, 8.00000000, 9.00000000, 10.00000000, -6.00000000, -4.80151529, -4.00000000, -2.87442856, -1.85285815, -0.77767592, --0.02071301, 0.81752572, 1.82503940, 2.79602150, 3.92870203, 5.00000000, 6.00000000, 7.00000000, -17.00000000, -16.00000000, --15.00000000, -14.00000000, -13.00000000, -12.00000000, -11.00000000, -9.80059874, -9.00000000, -8.00185204, -7.13087808, -5.92942149, --4.77883243, -3.93417708, -2.88004618, -1.89952522, -0.86239337, 0.00332274, 0.86657548, 1.89479279, 2.89701813, 3.90987417, - 4.98910145, 6.07676766, 7.00000000, 8.00000000, 9.00000000, 10.00000000, 11.00000000, 12.00000000, 13.00000000, 14.00000000, --12.00000000, -11.00000000, -9.89996262, -8.85894205, -7.87594823, -6.99685317, -5.94917589, -4.93914916, -3.93317670, -2.93174244, --1.90737478, -0.90982242, 0.00803316, 0.90111563, 1.90362879, 2.90332432, 3.90654662, 4.94461954, 5.87963665, 6.91988113, - 7.79514004, 8.98805413, 10.00000000, 11.00000000, -35.00000000, -34.00000000, -33.00000000, -32.00000000, -31.00000000, -30.00000000, --29.00000000, -28.00000000, -27.00000000, -26.00000000, -25.00000000, -24.00000000, -22.88310970, -22.00000000, -21.00000000, -20.00000000, --19.00000000, -18.00000000, -17.00000000, -16.11854974, -15.00000000, -14.10507667, -13.04497040, -11.94846700, -10.97432494, -9.94514368, --8.97311414, -7.94171496, -6.97232122, -5.98590548, -4.97455572, -3.95477903, -2.93935454, -1.95573532, -0.97120273, -0.02084826, - 0.95689153, 1.96679781, 2.97060165, 3.96660892, 4.96754331, 5.97996089, 6.93822411, 7.96618014, 8.95809791, 9.98891474, - 10.95713402, 11.85433084, 13.03831696, 13.84035295, 15.00729606, 15.98652872, 17.20557599, 18.00000000, 18.90794805, 20.00000000, - 21.00000000, -34.00000000, -33.00000000, -32.00000000, -31.00000000, -30.00000000, -28.97280602, -28.00000000, -27.16255057, -26.04078092, --24.85442050, -24.15783484, -22.78614956, -21.95739865, -21.21844626, -20.03008104, -19.03888543, -17.90460490, -17.02064693, -15.84673652, --14.87140709, -13.87996048, -12.94907251, -11.96795995, -11.00977925, -9.95103238, -8.96674655, -7.96351667, -6.96886200, -5.99335494, --4.97515534, -3.98891694, -2.99581150, -1.98758360, -0.99249128, -0.00001403, 0.98807868, 1.99119869, 2.99019366, 3.98612953, - 5.00312941, 5.98833080, 6.99686651, 7.98373889, 8.97942222, 9.94202752, 10.99671622, 11.94306164, 12.98539825, 13.90728690, - 14.89907642, 15.94836675, 16.89611342, 17.84084949, 18.74910958, 20.00000000, -67.00000000, -66.00000000, -65.00000000, -64.00000000, --63.02511977, -62.00000000, -61.06061493, -59.95964043, -59.12824439, -58.00000000, -57.00000000, -56.00000000, -54.87857996, -54.09689334, --53.00000000, -52.21057366, -50.93867921, -50.03032952, -49.19283867, -47.89439051, -46.99505692, -46.04895543, -44.89687413, -43.78942208, --42.99025156, -41.88436155, -40.99169704, -40.00320429, -38.90181498, -38.06029271, -37.05030818, -36.07554573, -35.03202233, -33.93117946, --32.97736655, -31.98942819, -30.99546798, -30.01511004, -28.97296525, -28.02561164, -26.94386985, -25.99632704, -25.00461143, -24.01578192, --22.99177609, -22.02261094, -20.97939001, -19.96176066, -19.00442980, -18.01529434, -17.00196902, -15.99794828, -14.98675055, -13.97517657, --12.98676283, -11.99718760, -11.00167809, -9.98872268, -9.02138474, -8.00320338, -6.99542797, -6.00059136, -5.01311763, -4.00336943, --3.00348281, -1.99365875, -0.98223019, 0.00126343, 0.99699237, 1.99381968, 3.00054436, 3.99898305, 5.00160508, 6.00310399, - 6.99885096, 8.02740039, 8.99515550, 9.98962151, 11.00642302, 11.98694516, 13.00018933, 13.97726018, 14.99186645, 16.00580131, - 16.97434224, 17.96982658, 19.00066438, 20.01228749, 21.00741822, 21.94988312, 23.00860212, 23.98801542, 24.97638417, 25.98003521, - 27.02336188, 27.99667029, 29.01014125, 30.02481912, 31.01415797, 31.97399854, 33.06214485, 33.99929330, 34.94095386, 35.96368372, - 36.96980925, 37.98389244, 39.01121235, 40.00715026, 41.06382894, 41.96618280, 43.01555590, 43.95430436, 45.01970038, 45.99967821, - 47.19847394, 48.04852502, 49.10609965, 50.04244122, 50.86051406, 51.92983796, 53.02781107, 54.06248545, 54.89942009, 56.08347165, - 57.06887956, 58.09671115, 59.07832400, 59.87005277, 61.14778499, 62.00000000, 63.00000000, 64.00000000, 65.00000000, 66.00000000, - 67.00000000, 68.00000000, 69.00000000, 70.00000000, 71.00000000, 72.00000000}; - -const double WebRtcIsac_kQKltLevelsShape[1735] = { - 0.00032397, 0.00008053, -0.00061202, -0.00012620, 0.00030437, 0.00054764, -0.00027902, 0.00069360, 0.00029449, -0.80219239, - 0.00091089, -0.74514927, -0.00094283, 0.64030631, -0.60509119, 0.00035575, 0.61851665, -0.62129957, 0.00375219, 0.60054900, --0.61554359, 0.00054977, 0.63362016, -1.73118727, -0.65422341, 0.00524568, 0.66165298, 1.76785515, -1.83182018, -0.65997434, --0.00011887, 0.67524299, 1.79933938, -1.76344480, -0.72547708, -0.00133017, 0.73104704, 1.75305377, 2.85164534, -2.80423916, --1.71959639, -0.75419722, -0.00329945, 0.77196760, 1.72211069, 2.87339653, 0.00031089, -0.00015311, 0.00018201, -0.00035035, --0.77357251, 0.00154647, -0.00047625, -0.00045299, 0.00086590, 0.00044762, -0.83383829, 0.00024787, -0.68526258, -0.00122472, - 0.64643255, -0.60904942, -0.00448987, 0.62309184, -0.59626442, -0.00574132, 0.62296546, -0.63222115, 0.00013441, 0.63609545, --0.66911055, -0.00369971, 0.66346095, 2.07281301, -1.77184694, -0.67640425, -0.00010145, 0.64818392, 1.74948973, -1.69420224, --0.71943894, -0.00004680, 0.75303493, 1.81075983, 2.80610041, -2.80005755, -1.79866753, -0.77409777, -0.00084220, 0.80141293, - 1.78291081, 2.73954236, 3.82994169, 0.00015140, -0.00012766, -0.00034241, -0.00119125, -0.76113497, 0.00069246, 0.76722027, - 0.00132862, -0.69107530, 0.00010656, 0.77061578, -0.78012970, 0.00095947, 0.77828502, -0.64787758, 0.00217168, 0.63050167, --0.58601125, 0.00306596, 0.59466308, -0.58603410, 0.00059779, 0.64257970, 1.76512766, -0.61193600, -0.00259517, 0.59767574, --0.61026273, 0.00315811, 0.61725479, -1.69169719, -0.65816029, 0.00067575, 0.65576890, 2.00000000, -1.72689193, -0.69780808, --0.00040990, 0.70668487, 1.74198458, -3.79028154, -3.00000000, -1.73194459, -0.70179341, -0.00106695, 0.71302629, 1.76849782, --2.89332364, -1.78585007, -0.78731491, -0.00132610, 0.79692976, 1.75247009, 2.97828682, -5.26238694, -3.69559829, -2.87286122, --1.84908818, -0.84434577, -0.01167975, 0.84641753, 1.84087672, 2.87628156, 3.83556679, -0.00190204, 0.00092642, 0.00354385, --0.00012982, -0.67742785, 0.00229509, 0.64935672, -0.58444751, 0.00470733, 0.57299534, -0.58456202, -0.00097715, 0.64593607, --0.64060330, -0.00638534, 0.59680157, -0.59287537, 0.00490772, 0.58919707, -0.60306173, -0.00417464, 0.60562100, -1.75218757, --0.63018569, -0.00225922, 0.63863300, -0.63949939, -0.00126421, 0.64268914, -1.75851182, -0.68318060, 0.00510418, 0.69049211, - 1.88178506, -1.71136148, -0.72710534, -0.00815559, 0.73412917, 1.79996711, -2.77111145, -1.73940498, -0.78212945, 0.01074476, - 0.77688916, 1.76873972, 2.87281379, 3.77554698, -3.75832725, -2.95463235, -1.80451491, -0.80017226, 0.00149902, 0.80729206, - 1.78265046, 2.89391793, -3.78236148, -2.83640598, -1.82532067, -0.88844327, -0.00620952, 0.88208030, 1.85757631, 2.81712391, - 3.88430176, 5.16179367, -7.00000000, -5.93805408, -4.87172597, -3.87524433, -2.89399744, -1.92359563, -0.92136341, -0.00172725, - 0.93087018, 1.90528280, 2.89809686, 3.88085708, 4.89147740, 5.89078692, -0.00239502, 0.00312564, -1.00000000, 0.00178325, - 1.00000000, -0.62198029, 0.00143254, 0.65344051, -0.59851220, -0.00676987, 0.61510140, -0.58894151, 0.00385055, 0.59794203, --0.59808568, -0.00038214, 0.57625703, -0.63009713, -0.01107985, 0.61278758, -0.64206758, -0.00154369, 0.65480598, 1.80604162, --1.80909286, -0.67810514, 0.00205762, 0.68571097, 1.79453891, -3.22682422, -1.73808453, -0.71870305, -0.00738594, 0.71486172, - 1.73005326, -1.66891897, -0.73689615, -0.00616203, 0.74262409, 1.73807899, -2.92417482, -1.73866741, -0.78133871, 0.00764425, - 0.80027264, 1.78668732, 2.74992588, -4.00000000, -2.75578740, -1.83697516, -0.83117035, -0.00355191, 0.83527172, 1.82814700, - 2.77377675, 3.80718693, -3.81667698, -2.83575471, -1.83372350, -0.86579471, 0.00547578, 0.87582281, 1.82858793, 2.87265007, - 3.91405377, -4.87521600, -3.78999094, -2.86437014, -1.86964365, -0.90618018, 0.00128243, 0.91497811, 1.87374952, 2.83199819, - 3.91519130, 4.76632822, -6.68713448, -6.01252467, -4.94587936, -3.88795368, -2.91299088, -1.92592211, -0.95504570, -0.00089980, - 0.94565200, 1.93239633, 2.91832808, 3.91363475, 4.88920034, 5.96471415, 6.83905252, 7.86195009, 8.81571018, -12.96141759, --11.73039516, -10.96459719, -9.97382433, -9.04414433, -7.89460619, -6.96628608, -5.93236595, -4.93337924, -3.95479990, -2.96451499, --1.96635876, -0.97271229, -0.00402238, 0.98343930, 1.98348291, 2.96641164, 3.95456471, 4.95517089, 5.98975714, 6.90322073, - 7.90468849, 8.85639467, 9.97255498, 10.79006309, 11.81988596, 0.04950500, -1.00000000, -0.01226628, 1.00000000, -0.59479469, --0.10438305, 0.59822144, -2.00000000, -0.67109149, -0.09256692, 0.65171621, 2.00000000, -3.00000000, -1.68391999, -0.76681039, --0.03354151, 0.71509146, 1.77615472, -2.00000000, -0.68661511, -0.02497881, 0.66478398, 2.00000000, -2.00000000, -0.67032784, --0.00920582, 0.64892756, 2.00000000, -2.00000000, -0.68561894, 0.03641869, 0.73021611, 1.68293863, -4.00000000, -2.72024184, --1.80096059, -0.81696185, 0.03604685, 0.79232033, 1.70070730, 3.00000000, -4.00000000, -2.71795670, -1.80482986, -0.86001162, - 0.03764903, 0.87723968, 1.79970771, 2.72685932, 3.67589143, -5.00000000, -4.00000000, -2.85492548, -1.78996365, -0.83250358, --0.01376828, 0.84195506, 1.78161105, 2.76754458, 4.00000000, -6.00000000, -5.00000000, -3.82268811, -2.77563624, -1.82608163, --0.86486114, -0.02671886, 0.86693165, 1.88422879, 2.86248347, 3.95632216, -7.00000000, -6.00000000, -5.00000000, -3.77533988, --2.86391432, -1.87052039, -0.90513658, 0.06271236, 0.91083620, 1.85734756, 2.86031688, 3.82019418, 4.94420394, 6.00000000, --11.00000000, -10.00000000, -9.00000000, -8.00000000, -6.91952415, -6.00000000, -4.92044374, -3.87845165, -2.87392362, -1.88413020, --0.91915740, 0.00318517, 0.91602800, 1.89664838, 2.88925058, 3.84123856, 4.78988651, 5.94526812, 6.81953917, 8.00000000, --9.00000000, -8.00000000, -7.03319143, -5.94530963, -4.86669720, -3.92438007, -2.88620396, -1.92848070, -0.94365985, 0.01671855, - 0.97349410, 1.93419878, 2.89740109, 3.89662823, 4.83235583, 5.88106535, 6.80328232, 8.00000000, -13.00000000, -12.00000000, --11.00000000, -10.00000000, -9.00000000, -7.86033489, -6.83344055, -5.89844215, -4.90811454, -3.94841298, -2.95820490, -1.98627966, --0.99161468, -0.02286136, 0.96055651, 1.95052433, 2.93969396, 3.94304346, 4.88522624, 5.87434241, 6.78309433, 7.87244101, - 9.00000000, 10.00000000, -12.09117356, -11.00000000, -10.00000000, -8.84766108, -7.86934236, -6.98544896, -5.94233429, -4.95583292, --3.95575986, -2.97085529, -1.98955811, -0.99359873, -0.00485413, 0.98298870, 1.98093258, 2.96430203, 3.95540216, 4.96915010, - 5.96775124, 6.99236918, 7.96503302, 8.99864542, 9.85857723, 10.96541926, 11.91647197, 12.71060069, -26.00000000, -25.00000000, --24.00585596, -23.11642573, -22.14271284, -20.89800711, -19.87815799, -19.05036354, -17.88555651, -16.86471209, -15.97711073, -14.94012359, --14.02661226, -12.98243228, -11.97489256, -10.97402777, -9.96425624, -9.01085220, -7.97372506, -6.98795002, -5.97271328, -5.00191694, --3.98055849, -2.98458048, -1.99470442, -0.99656768, -0.00825666, 1.00272004, 1.99922218, 2.99357669, 4.01407905, 5.01003897, - 5.98115528, 7.00018958, 8.00338125, 8.98981046, 9.98990318, 10.96341479, 11.96866930, 12.99175139, 13.94580443, 14.95745083, - 15.98992869, 16.97484646, 17.99630043, 18.93396897, 19.88347741, 20.96532482, 21.92191032, 23.22314702, 0.00006846, 0.00014352, --0.00056203, 0.00027588, -0.00147678, 1.00000000, 0.00003823, 0.00001975, -0.00033710, -0.00096712, 1.00000000, -1.00000000, - 0.00067511, -1.00000000, 0.00342065, 1.00000000, -1.00000000, 0.00196254, 1.00000000, -1.00000000, 0.00201173, 1.00000000, --2.00000000, -1.00000000, -0.00381686, 1.00000000, -1.00000000, 0.00178037, 1.00000000, -2.00000000, -1.00000000, -0.00320274, - 1.00000000, 2.00000000, -2.00000000, -1.00000000, 0.00426519, 1.00000000, 2.00000000, -3.00000000, -2.00000000, -1.00000000, --0.00074072, 0.64654602, 2.00000000, 0.00031217, 0.00063348, 0.00020247, 0.00047891, 0.00122893, -0.00150669, -0.00148276, - 0.00016848, 0.00147085, 1.00000000, -0.00088160, 1.00000000, -1.00000000, 0.00381641, 1.00000000, -1.00000000, 0.00129816, - 1.00000000, -1.00000000, 0.00074903, 1.00000000, -2.00000000, -0.76230566, -0.00370764, 0.82467977, -0.78769346, -0.00492670, - 0.84532630, -2.00000000, -0.70943195, -0.01257613, 0.75905385, 2.00000000, -2.00000000, -0.62780445, -0.00408633, 0.60272506, - 2.00000000, 3.00000000, -3.00000000, -2.00000000, -0.61412985, 0.00102833, 0.61527589, 2.00000000, 3.00000000, 0.00012115, --0.00080909, 0.00071061, -0.00227957, 0.00179794, 0.00103827, -1.00000000, 0.00444757, -1.00000000, 0.00604068, 1.00000000, --1.00000000, 0.00427327, 1.00000000, -1.00000000, 0.00086662, 1.00000000, -1.00000000, -0.00837492, 1.00000000, -0.65715934, --0.00645342, 0.64004630, -2.00000000, -0.64987682, -0.01449567, 0.69893373, -2.00000000, -0.63221961, 0.00421765, 0.62452105, - 2.00000000, -2.00000000, -0.60027006, -0.00110630, 0.62033821, 2.00000000, -2.00000000, -0.59823932, 0.00928313, 0.62188520, - 2.00000000, 3.00000000, -3.00000000, -2.00000000, -0.63230286, -0.00248555, 0.62632575, 2.00000000, 3.00000000, -5.00000000, --4.00000000, -3.00000000, -2.00000000, -0.66521143, 0.00544305, 0.66930486, 2.00000000, 3.00000000, 4.00000000, 0.00077008, - 0.00061140, -0.00009317, -0.00049643, 1.00000000, -1.00000000, -0.00285084, 1.00000000, -1.00000000, 0.00601784, 1.00000000, --1.00000000, -0.00091887, 0.75122772, -0.71579859, -0.00043545, 1.00000000, -0.85571363, -0.00227654, 0.63816873, -1.00000000, --0.00393484, 0.76748004, -0.58223659, -0.01229777, 0.58080322, -0.61945902, -0.00232238, 0.62277938, 2.00000000, -2.00000000, --0.60595489, -0.00535702, 0.60547736, 2.00000000, -4.00000000, -3.00000000, -2.00000000, -0.62368122, 0.01112097, 0.63997294, - 2.00000000, 3.00000000, -3.00000000, -2.00000000, -0.64318217, 0.00515139, 0.64781184, 2.00000000, -3.00000000, -1.78031579, --0.67122588, 0.02153711, 0.67899877, 2.00000000, 3.00000000, 4.00000000, -4.00000000, -3.00000000, -1.80503233, -0.69835727, --0.00270770, 0.70999554, 1.77332849, 3.00000000, 4.00000000, 5.00000000, -8.00000000, -7.00000000, -6.00000000, -5.00000000, --4.00000000, -2.81600693, -1.72970368, -0.73779413, -0.01384841, 0.75694606, 1.80042618, 3.00000000, 4.00000000, 5.00000000, - 6.00000000, -0.00051787, 0.00059593, -0.00023319, -1.00000000, 0.00191861, 0.79547197, -0.75020995, 0.00217840, 0.69165833, --1.00000000, -0.00304964, 0.67698951, -0.64516943, -0.00657667, 0.59260129, -0.62819301, -0.00456626, 0.59426260, -0.60909519, - 0.00256476, 0.61660408, -0.66560131, -0.00293463, 0.67477566, 2.00000000, -2.00000000, -0.62484067, 0.00505116, 0.63491494, - 2.00000000, -3.00000000, -2.00000000, -0.68427246, 0.00924353, 0.68755774, 2.00000000, 3.00000000, -3.00000000, -2.00000000, --0.65390928, 0.01008025, 0.65849449, 2.00000000, 3.00000000, -5.00000000, -4.00000000, -3.00000000, -1.70848232, -0.72079538, --0.00007674, 0.71556176, 1.76815351, 3.00000000, 4.00000000, 5.00000000, -4.00000000, -3.00000000, -1.82887466, -0.73529886, - 0.00033458, 0.73847588, 1.83009515, 3.00000000, 4.00000000, -5.00000000, -4.00000000, -2.83203553, -1.79500085, -0.77452749, --0.00614320, 0.77416943, 1.82469471, 2.77034612, 4.00000000, 5.00000000, -7.00000000, -6.00000000, -5.00000000, -4.00000000, --2.76574798, -1.84700836, -0.80822297, 0.00054165, 0.80901445, 1.85687331, 2.75680191, 3.81986695, 5.00000000, 6.00000000, - 7.00000000, 8.00000000, -13.00000000, -12.00000000, -11.00000000, -10.00000000, -9.00000000, -8.00000000, -7.00000000, -6.00000000, --5.00000000, -3.88304817, -2.93396067, -1.86645989, -0.84825410, 0.00666207, 0.84853252, 1.88634684, 2.95282618, 3.89813287, - 4.89189079, 6.00000000, 7.00000000, 8.00000000, 9.00000000, 10.00000000, 11.00000000, -0.00344877, 1.00000000, -0.61413659, --0.02115630, 0.59438887, -0.60873054, 0.00844993, 0.62510557, -2.00000000, -0.75002947, 0.00120913, 0.66616051, -2.00000000, --0.72324691, 0.04760499, 0.70532533, 2.00000000, -3.00000000, -1.66577589, -0.78941380, -0.01909714, 0.74993685, 1.70945570, --1.64422308, -0.70992006, -0.02795108, 0.76990363, 1.79682243, 2.96233315, -1.71686461, -0.76572785, -0.00041846, 0.78174132, - 1.66217596, -3.00000000, -1.77033369, -0.79475091, 0.03709740, 0.80097076, 1.83947400, 2.85879773, -4.00000000, -3.16528651, --1.79564411, -0.90078981, 0.02403102, 0.86138856, 1.84207433, 2.74584048, -4.00000000, -2.91249347, -1.87804769, -0.87323549, - 0.08164382, 0.89037056, 1.82505263, 2.71336163, 4.00000000, -4.81262228, -3.87173565, -2.83424209, -1.87517938, -0.86199960, - 0.00268598, 0.89547657, 1.90713511, 2.85219071, 3.86417171, 4.80711781, 6.00000000, 7.00000000, -5.00000000, -3.82388480, --2.82875808, -1.90350457, -0.90795818, 0.03047007, 0.93676836, 1.88844957, 2.83269711, 3.76109686, 5.00000000, -9.00000000, --8.00000000, -6.88037957, -5.88776398, -4.91209139, -3.93902541, -2.90989221, -1.92281230, -0.98960535, -0.07440511, 0.94023957, - 1.91666262, 2.83340828, 3.83651295, 4.77839424, 6.12284019, 7.00000000, 8.00000000, 9.00000000, -12.00000000, -11.00000000, --10.00000000, -9.00000000, -8.00000000, -6.68554513, -5.97994708, -4.98789075, -3.91383581, -2.92952795, -1.91727195, -0.93148075, --0.00568870, 0.93515148, 1.94580068, 2.93838956, 3.92567644, 4.96573603, 5.95402763, 7.00000000, 8.00000000, 9.00000000, --11.00000000, -9.90096030, -8.97868124, -7.93663988, -6.98806055, -5.95937864, -4.93473664, -3.95454756, -2.96518446, -1.97711766, --0.98552111, -0.03317271, 0.95115775, 1.93785086, 2.96310779, 3.93322450, 5.01716212, 5.85909823, 6.89163669, 7.97492693, - 8.85698897, 9.79802946, 11.09373957, 12.00000000, -13.00000000, -12.00000000, -10.67579109, -9.95079100, -8.90576592, -7.93254656, --6.96112672, -5.96015798, -4.95493809, -3.98556269, -2.98182856, -1.98150255, -0.96551153, -0.00399791, 0.98644875, 1.98043830, - 2.97969033, 3.97728257, 4.95173541, 5.95649050, 6.96447378, 7.95591513, 9.07680954, 9.92093070, 10.76496555, 11.97525735, - 13.00000000, 14.00000000, -25.00000000, -24.00000000, -23.00000000, -22.00072357, -21.00000000, -20.00000000, -19.00000000, -18.20003462, --17.01648407, -15.78651996, -14.95660266, -13.99167850, -13.28722978, -11.85013840, -10.92025302, -9.87055810, -8.93841040, -7.95329867, --6.97819441, -6.01593394, -5.00905213, -3.99905285, -2.99171810, -1.99062796, -1.00112466, 0.00140492, 1.00701091, 2.02327185, - 3.00194633, 3.99188294, 5.00313145, 6.00448038, 6.98904951, 7.98158293, 8.98212774, 10.00363404, 10.98641678, 11.98034311, - 12.95176779, 13.95383703, 14.99084578, 15.98600642, 16.99406826, 17.98134623, 19.01793961, 19.86072639, 20.88465474, 21.99287082, - 22.81916620, 23.77946383, 0.00000234, 0.00000298, 0.00000048, 0.00002408, -0.00000165, -0.00001831, -0.00005703, -0.00000184, --1.00000000, 0.00001977, 1.00000000, -1.00000000, 0.00000010, 1.00000000, -1.00000000, -0.00001152, 1.00000000, -1.00000000, - 0.00000840, 1.00000000, -1.00000000, 0.00002353, 1.00000000, -0.75455603, -0.00001433, 1.00000000, -0.65859705, -0.00000703, - 0.62995860, -2.00000000, -0.72724652, -0.00033969, 0.61359174, 2.00000000, -2.00000000, -0.69510998, -0.00031410, 0.66467605, - 2.00000000, 3.00000000, -3.00000000, -2.00000000, -0.65738683, 0.00039019, 0.66554720, 1.91774106, 3.18089124, 0.00000070, - 0.00001152, -0.00000795, -0.00000058, -0.00003502, -0.00001508, -0.00004225, -0.00002165, -1.00000000, 0.00004391, 1.00000000, --1.00000000, 0.00001784, 1.00000000, -1.00000000, -0.00003678, 1.00000000, -0.68878314, -0.00013166, 0.60880149, -0.75291978, - 0.00006493, 1.00000000, -0.76757316, 0.00003057, 0.67140524, -0.61602267, -0.00014495, 0.63625803, 2.00000000, -2.00000000, --0.61253314, -0.00116483, 0.65071851, 2.00000000, -3.00000000, -1.71451667, -0.67799909, -0.00048294, 0.65846019, 2.00000000, --3.02497593, -1.83515395, -0.70317981, 0.00519701, 0.67780009, 1.84218153, 2.88846262, 4.00000000, 0.00001124, 0.00000588, --0.00000172, 0.00002835, 1.00000000, 0.00001012, -0.00008644, 1.00000000, -0.75115901, 0.00004347, 1.00000000, -1.00000000, - 0.00002800, 1.00000000, -1.00000000, -0.00006039, 1.00000000, -0.79763258, -0.00011907, 0.71713616, -0.76791870, -0.00007113, - 0.63583609, -0.62337806, 0.00012891, 0.62242094, -0.60837055, 0.00043216, 0.65515705, -0.63637782, -0.00019749, 0.60423967, - 2.00000000, -2.00000000, -0.65404827, -0.00089304, 0.64706660, 2.00000000, -1.86334076, -0.66410366, 0.00063219, 0.66968004, - 2.00000000, 3.00000000, 4.00000000, -4.00000000, -3.00000000, -1.79048834, -0.69451890, 0.00030677, 0.71009333, 1.70591343, - 3.00000000, 4.00000000, -4.00000000, -2.90176499, -1.78368781, -0.74425178, 0.00234068, 0.74847325, 1.78886822, 2.78478854, - 3.83608985, 4.95996151, 0.00002170, 0.00001281, 0.00002162, -1.00000000, -0.00007266, 1.00000000, -1.00000000, -0.00003250, --0.64088804, 0.00015239, 1.00000000, -0.58450370, -0.00008410, 0.60567186, -1.00000000, -0.00010752, 1.00000000, -0.58922508, --0.00017378, 0.60755779, -0.62797206, -0.00001016, 0.64432847, -0.58497934, -0.00001851, 0.59716791, -0.62642499, -0.00097386, - 0.63568558, 2.00000000, -2.00000000, -0.63236390, -0.00173361, 0.63142762, 1.75629192, -3.00000000, -2.00000000, -0.65596684, - 0.00209364, 0.65419742, 2.00000000, -3.00000000, -1.73856625, -0.67767521, -0.00119512, 0.68973603, 1.70985573, 3.00000000, --3.00000000, -1.81820220, -0.73974134, 0.00695869, 0.72216179, 1.75624461, 3.00000000, 4.00000000, -5.00000000, -4.00000000, --3.17718593, -1.76857567, -0.76822322, 0.00267400, 0.76414602, 1.84309221, 3.04940652, 4.00000000, -7.08189123, -6.00000000, --5.22882249, -3.96477958, -2.79653492, -1.81923435, -0.80050253, -0.01086663, 0.82708565, 1.85804900, 2.89996354, 3.76028554, - 4.80518081, 5.81738096, 7.00000000, 8.00000000, 9.08816091, -0.00002979, -0.00000333, -1.00000000, -0.00011532, 1.00000000, --0.70921122, -0.00005325, 0.68933188, -0.67581263, -0.00023107, 0.57868212, -0.58388312, -0.00020850, 0.60149012, -0.60912457, - 0.00001567, 0.60180554, -0.59130091, -0.00038863, 0.59908653, -2.00000000, -0.63697707, 0.00083913, 0.62040514, 2.00000000, --2.00000000, -0.63216238, -0.00081100, 0.64411071, 2.00000000, -1.76856259, -0.65266989, -0.00243486, 0.66888899, 2.00000000, --1.75427214, -0.71415385, -0.00226376, 0.71296778, 1.66182947, 3.00000000, -3.00000000, -1.72505821, -0.72920134, -0.00360424, - 0.73800767, 1.72848281, 3.00000000, -4.00000000, -2.95284408, -1.72025758, -0.76503859, 0.00418761, 0.75297139, 1.73959808, - 3.00000000, -5.00000000, -3.96232791, -2.74080544, -1.78897123, -0.80233505, -0.00002050, 0.79693417, 1.76182598, 2.78434458, - 3.85693287, 5.00000000, -6.00000000, -4.78439284, -3.83501790, -2.85203629, -1.84909573, -0.85382658, -0.00181019, 0.84735145, - 1.83676575, 2.83656843, 3.86722376, 4.79702431, 6.00000000, -9.00000000, -8.00000000, -7.00000000, -6.07957292, -4.84677515, --3.85093972, -2.88683139, -1.84596391, -0.88058034, -0.00008692, 0.87554746, 1.86933183, 2.84729990, 3.89029797, 4.87311773, - 5.90844023, 7.00000000, -11.00000000, -9.97745420, -8.90015761, -7.94187517, -6.86987726, -5.84795335, -4.86693435, -3.90601819, --2.91031804, -1.91620096, -0.90497055, 0.00659199, 0.90926869, 1.90980821, 2.91070850, 3.93685967, 4.85581177, 6.06727337, - 7.05801043, 8.00000000, 9.00000000, 10.00000000, 10.90825787, 12.00000000, 13.00000000, 14.00000000, -0.00008918, 1.00000000, --0.54405938, 0.00120348, 0.55781920, -0.59227786, -0.00349602, 0.59777231, -1.63717598, -0.69048065, 0.00999281, 0.65770558, - 2.00000000, -2.00000000, -0.71013571, 0.00454518, 0.66991065, -3.00000000, -1.73004867, -0.73743921, 0.01162454, 0.69964842, - 1.83319587, -1.81225491, -0.76806000, 0.00164742, 0.76780397, 1.67168896, -1.64564794, -0.79903361, -0.01522880, 0.84277926, - 1.68873752, -3.00000000, -1.72063244, -0.83687428, 0.00246724, 0.84618697, 1.79464483, 2.77447025, -3.77118426, -2.75025539, --1.82050448, -0.90373722, -0.00187780, 0.90102245, 1.85249394, 2.71364180, -2.71720889, -1.79466125, -0.89860801, -0.02725825, - 0.90877329, 1.90542096, 2.76847902, 3.71496428, -4.70257302, -3.90746659, -2.87078421, -1.88858709, -0.93608993, -0.02157425, - 0.95181182, 1.91155682, 2.83614575, 3.87820801, 4.72172277, -5.02764544, -3.80066801, -2.87484378, -1.90707477, -0.96326017, --0.01060091, 0.96558851, 1.92191548, 2.86970759, 3.85655474, 4.83135970, 5.76387469, -9.00000000, -8.00000000, -6.75261776, --5.86333393, -4.84846871, -3.91871758, -2.93827286, -1.93050320, -0.96359634, -0.00141931, 0.95926312, 1.92541870, 2.93009411, - 3.86699087, 4.82315929, 5.67815206, -8.76594345, -7.70350451, -6.91784020, -5.81539490, -4.92526872, -3.91513203, -2.92134949, --1.95465646, -0.97638102, -0.00742564, 0.96948714, 1.96401112, 2.95256722, 3.93146353, 4.90991357, 5.88139022, 6.88640588, - 7.82610489, 9.00000000, -10.97611369, -9.80036760, -8.91109518, -7.92809404, -6.93865353, -5.91965899, -4.92957669, -3.95206224, --2.97308718, -1.97778214, -0.98552568, -0.00063212, 0.98686014, 1.97511867, 2.97114218, 3.97854244, 4.96578513, 5.96457765, - 6.95180187, 7.95163483, 8.93760897, 9.87666900, 10.88024562, 11.96270158, 12.99519291, -15.00000000, -13.76826291, -12.97229116, --12.00334834, -10.95980884, -9.98190891, -8.93798503, -7.95621309, -6.96109479, -5.96056649, -4.95843419, -3.97688640, -2.98989576, --1.98533395, -0.99580972, 0.00694370, 0.99421120, 1.99033132, 2.98751217, 3.98549580, 4.96482394, 5.96623233, 6.93564626, - 7.93772467, 8.92015276, 9.88785129, 10.97606096, 11.79686057, -23.00000000, -22.00000000, -21.00000000, -20.00000000, -19.00000000, --17.73310977, -16.83574096, -15.90889480, -15.00437366, -13.95007272, -12.99296117, -11.98334751, -10.96970820, -9.97775151, -8.98193840, --7.98378966, -6.98887770, -5.99059477, -5.00228769, -3.99355850, -2.99947486, -1.99897483, -0.99375857, 0.00324880, 1.00215912, - 1.99277083, 3.00503747, 3.99390482, 4.98854283, 5.98753219, 6.98245347, 7.98089893, 8.95960522, 9.95663648, 11.00810285, - 12.01421617, 12.96208687, 13.99227766, 14.97230040, 15.95114804, 16.97347393, 17.97794884, 18.96777118, 19.94446034, 20.94799029, - 22.14740083, 22.84288347, 23.99212109, 25.00000000, 25.96562658}; - -/* cdf tables for quantizer indices */ -const WebRtc_UWord16 WebRtcIsac_kQKltCdfGain[1212] = { - 0, 13, 301, 3730, 61784, 65167, 65489, 65535, 0, 17, - 142, 314, 929, 2466, 7678, 56450, 63463, 64740, 65204, 65426, - 65527, 65535, 0, 8, 100, 724, 6301, 60105, 65125, 65510, - 65531, 65535, 0, 13, 117, 368, 1068, 3010, 11928, 53603, - 61177, 63404, 64505, 65108, 65422, 65502, 65531, 65535, 0, 4, - 17, 96, 410, 1859, 12125, 54361, 64103, 65305, 65497, 65535, - 0, 4, 88, 230, 469, 950, 1746, 3228, 6092, 16592, - 44756, 56848, 61256, 63308, 64325, 64920, 65309, 65460, 65502, 65522, - 65535, 0, 88, 352, 1675, 6339, 20749, 46686, 59284, 63525, - 64949, 65359, 65502, 65527, 65535, 0, 13, 38, 63, 117, - 234, 381, 641, 929, 1407, 2043, 2809, 4032, 5753, 8792, - 14407, 24308, 38941, 48947, 55403, 59293, 61411, 62688, 63630, 64329, - 64840, 65188, 65376, 65472, 65506, 65527, 65531, 65535, 0, 8, - 29, 75, 222, 615, 1327, 2801, 5623, 9931, 16094, 24966, - 34419, 43458, 50676, 56186, 60055, 62500, 63936, 64765, 65225, 65435, - 65514, 65535, 0, 8, 13, 15, 17, 21, 33, 59, - 71, 92, 151, 243, 360, 456, 674, 934, 1223, 1583, - 1989, 2504, 3031, 3617, 4354, 5154, 6163, 7411, 8780, 10747, - 12874, 15591, 18974, 23027, 27436, 32020, 36948, 41830, 46205, 49797, - 53042, 56094, 58418, 60360, 61763, 62818, 63559, 64103, 64509, 64798, - 65045, 65162, 65288, 65363, 65447, 65506, 65522, 65531, 65533, 65535, - 0, 4, 6, 25, 38, 71, 138, 264, 519, 808, - 1227, 1825, 2516, 3408, 4279, 5560, 7092, 9197, 11420, 14108, - 16947, 20300, 23926, 27459, 31164, 34827, 38575, 42178, 45540, 48747, - 51444, 54090, 56426, 58460, 60080, 61595, 62734, 63668, 64275, 64673, - 64936, 65112, 65217, 65334, 65426, 65464, 65477, 65489, 65518, 65527, - 65529, 65531, 65533, 65535, 0, 2, 4, 8, 10, 12, - 14, 16, 21, 33, 50, 71, 84, 92, 105, 138, - 180, 255, 318, 377, 435, 473, 511, 590, 682, 758, - 913, 1097, 1256, 1449, 1671, 1884, 2169, 2445, 2772, 3157, - 3563, 3944, 4375, 4848, 5334, 5820, 6448, 7101, 7716, 8378, - 9102, 9956, 10752, 11648, 12707, 13670, 14758, 15910, 17187, 18472, - 19627, 20649, 21951, 23169, 24283, 25552, 26862, 28227, 29391, 30764, - 31882, 33213, 34432, 35600, 36910, 38116, 39464, 40729, 41872, 43144, - 44371, 45514, 46762, 47813, 48968, 50069, 51032, 51974, 52908, 53737, - 54603, 55445, 56282, 56990, 57572, 58191, 58840, 59410, 59887, 60264, - 60607, 60946, 61269, 61516, 61771, 61960, 62198, 62408, 62558, 62776, - 62985, 63207, 63408, 63546, 63739, 63906, 64070, 64237, 64371, 64551, - 64677, 64836, 64999, 65095, 65213, 65284, 65338, 65380, 65426, 65447, - 65472, 65485, 65487, 65489, 65502, 65510, 65512, 65514, 65516, 65518, - 65522, 65531, 65533, 65535, 0, 2, 4, 6, 65528, 65531, - 65533, 65535, 0, 2, 4, 6, 8, 10, 222, 65321, - 65513, 65528, 65531, 65533, 65535, 0, 2, 4, 50, 65476, - 65529, 65531, 65533, 65535, 0, 2, 4, 6, 8, 12, - 38, 544, 64936, 65509, 65523, 65525, 65529, 65531, 65533, 65535, - 0, 2, 4, 6, 8, 10, 1055, 64508, 65528, 65531, - 65533, 65535, 0, 2, 4, 6, 8, 10, 12, 123, - 3956, 62999, 65372, 65495, 65515, 65521, 65523, 65525, 65527, 65529, - 65531, 65533, 65535, 0, 2, 4, 12, 53, 4707, 59445, - 65467, 65525, 65527, 65529, 65531, 65533, 65535, 0, 2, 4, - 6, 8, 10, 12, 14, 16, 38, 40, 50, 67, - 96, 234, 929, 14345, 55750, 64866, 65389, 65462, 65514, 65517, - 65519, 65521, 65523, 65525, 65527, 65529, 65531, 65533, 65535, 0, - 2, 4, 6, 8, 10, 15, 35, 91, 377, 1946, - 13618, 52565, 63714, 65184, 65465, 65520, 65523, 65525, 65527, 65529, - 65531, 65533, 65535, 0, 2, 4, 6, 8, 10, 12, - 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, - 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, - 54, 82, 149, 362, 751, 1701, 4239, 12893, 38627, 55072, - 60875, 63071, 64158, 64702, 65096, 65283, 65412, 65473, 65494, 65505, - 65508, 65517, 65519, 65521, 65523, 65525, 65527, 65529, 65531, 65533, - 65535, 0, 2, 15, 23, 53, 143, 260, 418, 698, - 988, 1353, 1812, 2411, 3144, 4015, 5143, 6401, 7611, 8999, - 10653, 12512, 14636, 16865, 19404, 22154, 24798, 27521, 30326, 33102, - 35790, 38603, 41415, 43968, 46771, 49435, 52152, 54715, 57143, 59481, - 61178, 62507, 63603, 64489, 64997, 65257, 65427, 65473, 65503, 65520, - 65529, 65531, 65533, 65535, 0, 3, 6, 9, 26, 32, - 44, 46, 64, 94, 111, 164, 205, 254, 327, 409, - 506, 608, 733, 885, 1093, 1292, 1482, 1742, 1993, 2329, - 2615, 3029, 3374, 3798, 4257, 4870, 5405, 5992, 6618, 7225, - 7816, 8418, 9051, 9761, 10532, 11380, 12113, 13010, 13788, 14594, - 15455, 16361, 17182, 18088, 18997, 20046, 20951, 21968, 22947, 24124, - 25296, 26547, 27712, 28775, 29807, 30835, 31709, 32469, 33201, 34014, - 34876, 35773, 36696, 37620, 38558, 39547, 40406, 41277, 42367, 43290, - 44445, 45443, 46510, 47684, 48973, 50157, 51187, 52242, 53209, 54083, - 55006, 55871, 56618, 57293, 57965, 58556, 59222, 59722, 60180, 60554, - 60902, 61250, 61554, 61837, 62100, 62372, 62631, 62856, 63078, 63324, - 63557, 63768, 63961, 64089, 64235, 64352, 64501, 64633, 64770, 64887, - 65001, 65059, 65121, 65188, 65246, 65302, 65346, 65390, 65428, 65463, - 65477, 65506, 65515, 65517, 65519, 65521, 65523, 65525, 65527, 65529, - 65531, 65533, 65535, 0, 2, 4, 109, 65332, 65531, 65533, - 65535, 0, 2, 4, 6, 8, 25, 1817, 63874, 65511, - 65527, 65529, 65531, 65533, 65535, 0, 2, 4, 907, 65014, - 65529, 65531, 65533, 65535, 0, 2, 4, 6, 8, 10, - 12, 132, 2743, 62708, 65430, 65525, 65527, 65529, 65531, 65533, - 65535, 0, 2, 4, 6, 8, 35, 3743, 61666, 65485, - 65531, 65533, 65535, 0, 2, 4, 6, 8, 10, 23, - 109, 683, 6905, 58417, 64911, 65398, 65497, 65518, 65525, 65527, - 65529, 65531, 65533, 65535, 0, 2, 4, 6, 53, 510, - 10209, 55212, 64573, 65441, 65522, 65529, 65531, 65533, 65535, 0, - 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, - 22, 32, 90, 266, 1037, 3349, 14468, 50488, 62394, 64685, - 65341, 65480, 65514, 65519, 65521, 65523, 65525, 65527, 65529, 65531, - 65533, 65535, 0, 2, 4, 6, 9, 16, 37, 106, - 296, 748, 1868, 5733, 18897, 45553, 60165, 63949, 64926, 65314, - 65441, 65508, 65524, 65529, 65531, 65533, 65535, 0, 2, 4, - 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, - 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, - 46, 48, 50, 83, 175, 344, 667, 1293, 2337, 4357, - 8033, 14988, 28600, 43244, 52011, 57042, 59980, 61779, 63065, 63869, - 64390, 64753, 64988, 65164, 65326, 65422, 65462, 65492, 65506, 65522, - 65524, 65526, 65531, 65533, 65535, 0, 2, 4, 6, 8, - 10, 12, 14, 16, 25, 39, 48, 55, 62, 65, - 85, 106, 139, 169, 194, 252, 323, 485, 688, 1074, - 1600, 2544, 3863, 5733, 8303, 11397, 15529, 20273, 25734, 31455, - 36853, 41891, 46410, 50306, 53702, 56503, 58673, 60479, 61880, 62989, - 63748, 64404, 64852, 65124, 65309, 65424, 65480, 65524, 65528, 65533, - 65535, 0, 2, 4, 6, 8, 10, 12, 14, 21, - 23, 25, 27, 29, 31, 39, 41, 43, 48, 60, - 72, 79, 106, 136, 166, 187, 224, 252, 323, 381, - 427, 478, 568, 660, 783, 912, 1046, 1175, 1365, 1567, - 1768, 2024, 2347, 2659, 3049, 3529, 4033, 4623, 5281, 5925, - 6726, 7526, 8417, 9468, 10783, 12141, 13571, 15222, 16916, 18659, - 20350, 22020, 23725, 25497, 27201, 29026, 30867, 32632, 34323, 36062, - 37829, 39466, 41144, 42654, 43981, 45343, 46579, 47759, 49013, 50171, - 51249, 52283, 53245, 54148, 54938, 55669, 56421, 57109, 57791, 58464, - 59092, 59674, 60105, 60653, 61083, 61407, 61757, 62095, 62388, 62649, - 62873, 63157, 63358, 63540, 63725, 63884, 64046, 64155, 64278, 64426, - 64548, 64654, 64806, 64906, 64994, 65077, 65137, 65215, 65277, 65324, - 65354, 65409, 65437, 65455, 65462, 65490, 65495, 65499, 65508, 65511, - 65513, 65515, 65517, 65519, 65521, 65523, 65525, 65527, 65529, 65531, - 65533, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQKltCdfShape[2059] = { - 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, - 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 4, - 65535, 0, 8, 65514, 65535, 0, 29, 65481, 65535, 0, - 121, 65439, 65535, 0, 239, 65284, 65535, 0, 8, 779, - 64999, 65527, 65535, 0, 8, 888, 64693, 65522, 65535, 0, - 29, 2604, 62843, 65497, 65531, 65535, 0, 25, 176, 4576, - 61164, 65275, 65527, 65535, 0, 65535, 0, 65535, 0, 65535, - 0, 65535, 0, 4, 65535, 0, 65535, 0, 65535, 0, - 65535, 0, 65535, 0, 4, 65535, 0, 33, 65502, 65535, - 0, 54, 65481, 65535, 0, 251, 65309, 65535, 0, 611, - 65074, 65535, 0, 1273, 64292, 65527, 65535, 0, 4, 1809, - 63940, 65518, 65535, 0, 88, 4392, 60603, 65426, 65531, 65535, - 0, 25, 419, 7046, 57756, 64961, 65514, 65531, 65535, 0, - 65535, 0, 65535, 0, 65535, 0, 65535, 0, 4, 65531, - 65535, 0, 65535, 0, 8, 65531, 65535, 0, 4, 65527, - 65535, 0, 17, 65510, 65535, 0, 42, 65481, 65535, 0, - 197, 65342, 65531, 65535, 0, 385, 65154, 65535, 0, 1005, - 64522, 65535, 0, 8, 1985, 63469, 65533, 65535, 0, 38, - 3119, 61884, 65514, 65535, 0, 4, 6, 67, 4961, 60804, - 65472, 65535, 0, 17, 565, 9182, 56538, 65087, 65514, 65535, - 0, 8, 63, 327, 2118, 14490, 52774, 63839, 65376, 65522, - 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, - 17, 65522, 65535, 0, 59, 65489, 65535, 0, 50, 65522, - 65535, 0, 54, 65489, 65535, 0, 310, 65179, 65535, 0, - 615, 64836, 65535, 0, 4, 1503, 63965, 65535, 0, 2780, - 63383, 65535, 0, 21, 3919, 61051, 65527, 65535, 0, 84, - 6674, 59929, 65435, 65535, 0, 4, 255, 7976, 55784, 65150, - 65518, 65531, 65535, 0, 4, 8, 582, 10726, 53465, 64949, - 65518, 65535, 0, 29, 339, 3006, 17555, 49517, 62956, 65200, - 65497, 65531, 65535, 0, 2, 33, 138, 565, 2324, 7670, - 22089, 45966, 58949, 63479, 64966, 65380, 65518, 65535, 0, 65535, - 0, 65535, 0, 2, 65533, 65535, 0, 46, 65514, 65535, - 0, 414, 65091, 65535, 0, 540, 64911, 65535, 0, 419, - 65162, 65535, 0, 976, 64790, 65535, 0, 2977, 62495, 65531, - 65535, 0, 4, 3852, 61034, 65527, 65535, 0, 4, 29, - 6021, 60243, 65468, 65535, 0, 84, 6711, 58066, 65418, 65535, - 0, 13, 281, 9550, 54917, 65125, 65506, 65535, 0, 2, - 63, 984, 12108, 52644, 64342, 65435, 65527, 65535, 0, 29, - 251, 2014, 14871, 47553, 62881, 65229, 65518, 65535, 0, 13, - 142, 749, 4220, 18497, 45200, 60913, 64823, 65426, 65527, 65535, - 0, 13, 71, 264, 1176, 3789, 10500, 24480, 43488, 56324, - 62315, 64493, 65242, 65464, 65514, 65522, 65531, 65535, 0, 4, - 13, 38, 109, 205, 448, 850, 1708, 3429, 6276, 11371, - 19221, 29734, 40955, 49391, 55411, 59460, 62102, 63793, 64656, 65150, - 65401, 65485, 65522, 65531, 65535, 0, 65535, 0, 2, 65533, - 65535, 0, 1160, 65476, 65535, 0, 2, 6640, 64763, 65533, - 65535, 0, 2, 38, 9923, 61009, 65527, 65535, 0, 2, - 4949, 63092, 65533, 65535, 0, 2, 3090, 63398, 65533, 65535, - 0, 2, 2520, 58744, 65510, 65535, 0, 2, 13, 544, - 8784, 51403, 65148, 65533, 65535, 0, 2, 25, 1017, 10412, - 43550, 63651, 65489, 65527, 65535, 0, 2, 4, 29, 783, - 13377, 52462, 64524, 65495, 65533, 65535, 0, 2, 4, 6, - 100, 1817, 18451, 52590, 63559, 65376, 65531, 65535, 0, 2, - 4, 6, 46, 385, 2562, 11225, 37416, 60488, 65026, 65487, - 65529, 65533, 65535, 0, 2, 4, 6, 8, 10, 12, - 42, 222, 971, 5221, 19811, 45048, 60312, 64486, 65294, 65474, - 65525, 65529, 65533, 65535, 0, 2, 4, 8, 71, 167, - 666, 2533, 7875, 19622, 38082, 54359, 62108, 64633, 65290, 65495, - 65529, 65533, 65535, 0, 2, 4, 6, 8, 10, 13, - 109, 586, 1930, 4949, 11600, 22641, 36125, 48312, 56899, 61495, - 63927, 64932, 65389, 65489, 65518, 65531, 65533, 65535, 0, 4, - 6, 8, 67, 209, 712, 1838, 4195, 8432, 14432, 22834, - 31723, 40523, 48139, 53929, 57865, 60657, 62403, 63584, 64363, 64907, - 65167, 65372, 65472, 65514, 65535, 0, 2, 4, 13, 25, - 42, 46, 50, 75, 113, 147, 281, 448, 657, 909, - 1185, 1591, 1976, 2600, 3676, 5317, 7398, 9914, 12941, 16169, - 19477, 22885, 26464, 29851, 33360, 37228, 41139, 44802, 48654, 52058, - 55181, 57676, 59581, 61022, 62190, 63107, 63676, 64199, 64547, 64924, - 65158, 65313, 65430, 65481, 65518, 65535, 0, 65535, 0, 65535, - 0, 65535, 0, 65535, 0, 65533, 65535, 0, 65535, 0, - 65535, 0, 65535, 0, 65533, 65535, 0, 2, 65535, 0, - 2, 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, - 65535, 0, 2, 4, 65533, 65535, 0, 2, 65533, 65535, - 0, 2, 4, 65531, 65533, 65535, 0, 2, 4, 65531, - 65533, 65535, 0, 2, 4, 6, 65524, 65533, 65535, 0, - 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, - 65535, 0, 65535, 0, 65535, 0, 65533, 65535, 0, 65533, - 65535, 0, 2, 65533, 65535, 0, 2, 65533, 65535, 0, - 2, 65533, 65535, 0, 2, 4, 65532, 65535, 0, 6, - 65523, 65535, 0, 2, 15, 65530, 65533, 65535, 0, 2, - 35, 65493, 65531, 65533, 65535, 0, 2, 4, 158, 65382, - 65531, 65533, 65535, 0, 65535, 0, 65535, 0, 65535, 0, - 65535, 0, 65535, 0, 65535, 0, 2, 65535, 0, 2, - 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, 65535, - 0, 2, 65533, 65535, 0, 9, 65512, 65535, 0, 2, - 12, 65529, 65535, 0, 2, 73, 65434, 65533, 65535, 0, - 2, 240, 65343, 65533, 65535, 0, 2, 476, 65017, 65531, - 65533, 65535, 0, 2, 4, 1046, 64686, 65531, 65533, 65535, - 0, 2, 4, 6, 8, 1870, 63898, 65529, 65531, 65533, - 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65533, 65535, - 0, 2, 65533, 65535, 0, 2, 65533, 65535, 0, 2, - 65532, 65535, 0, 6, 65533, 65535, 0, 6, 65523, 65535, - 0, 2, 65532, 65535, 0, 137, 65439, 65535, 0, 576, - 64899, 65533, 65535, 0, 2, 289, 65299, 65533, 65535, 0, - 2, 4, 6, 880, 64134, 65531, 65533, 65535, 0, 2, - 4, 1853, 63347, 65533, 65535, 0, 2, 6, 2516, 61762, - 65529, 65531, 65533, 65535, 0, 2, 4, 9, 3980, 61380, - 65503, 65529, 65531, 65533, 65535, 0, 2, 4, 6, 8, - 10, 12, 61, 6393, 59859, 65466, 65527, 65529, 65531, 65533, - 65535, 0, 65535, 0, 65535, 0, 65535, 0, 2, 65532, - 65535, 0, 3, 65529, 65535, 0, 2, 65529, 65535, 0, - 61, 65453, 65535, 0, 234, 65313, 65535, 0, 503, 65138, - 65535, 0, 155, 65402, 65533, 65535, 0, 2, 1058, 64554, - 65533, 65535, 0, 2, 4, 3138, 62109, 65531, 65533, 65535, - 0, 2, 4, 2031, 63339, 65531, 65533, 65535, 0, 2, - 4, 6, 9, 4155, 60778, 65523, 65529, 65531, 65533, 65535, - 0, 2, 4, 41, 6189, 59269, 65490, 65531, 65533, 65535, - 0, 2, 4, 6, 210, 8789, 57043, 65400, 65528, 65531, - 65533, 65535, 0, 2, 4, 6, 8, 26, 453, 10086, - 55499, 64948, 65483, 65524, 65527, 65529, 65531, 65533, 65535, 0, - 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, - 114, 1014, 11202, 52670, 64226, 65356, 65503, 65514, 65523, 65525, - 65527, 65529, 65531, 65533, 65535, 0, 65533, 65535, 0, 15, - 65301, 65535, 0, 152, 64807, 65535, 0, 2, 3328, 63308, - 65535, 0, 2, 4050, 59730, 65533, 65535, 0, 2, 164, - 10564, 61894, 65529, 65535, 0, 15, 6712, 59831, 65076, 65532, - 65535, 0, 32, 7712, 57449, 65459, 65535, 0, 2, 210, - 7849, 53110, 65021, 65523, 65535, 0, 2, 12, 1081, 13883, - 48262, 62870, 65477, 65535, 0, 2, 88, 847, 6145, 37852, - 62012, 65454, 65533, 65535, 0, 9, 47, 207, 1823, 14522, - 45521, 61069, 64891, 65481, 65528, 65531, 65533, 65535, 0, 2, - 9, 488, 2881, 12758, 38703, 58412, 64420, 65410, 65533, 65535, - 0, 2, 4, 6, 61, 333, 1891, 6486, 19720, 43188, - 57547, 62472, 64796, 65421, 65497, 65523, 65529, 65531, 65533, 65535, - 0, 2, 4, 6, 8, 10, 12, 29, 117, 447, - 1528, 6138, 21242, 43133, 56495, 62432, 64746, 65362, 65500, 65529, - 65531, 65533, 65535, 0, 2, 18, 105, 301, 760, 1490, - 3472, 7568, 15002, 26424, 40330, 53029, 60048, 62964, 64274, 64890, - 65337, 65445, 65489, 65513, 65527, 65530, 65533, 65535, 0, 2, - 4, 6, 41, 102, 409, 853, 2031, 4316, 7302, 11328, - 16869, 24825, 34926, 43481, 50877, 56126, 59874, 62103, 63281, 63857, - 64166, 64675, 65382, 65522, 65531, 65533, 65535, 0, 2, 4, - 6, 8, 10, 12, 14, 16, 18, 29, 38, 53, - 58, 96, 181, 503, 1183, 2849, 5590, 8600, 11379, 13942, - 16478, 19453, 22638, 26039, 29411, 32921, 37596, 41433, 44998, 48560, - 51979, 55106, 57666, 59892, 61485, 62616, 63484, 64018, 64375, 64685, - 64924, 65076, 65278, 65395, 65471, 65509, 65529, 65535, 0, 65535, - 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, - 0, 65535, 0, 65535, 0, 2, 65533, 65535, 0, 2, - 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, 65535, - 0, 2, 65533, 65535, 0, 2, 65533, 65535, 0, 7, - 65519, 65535, 0, 2, 14, 65491, 65533, 65535, 0, 2, - 81, 65427, 65531, 65533, 65535, 0, 2, 4, 312, 65293, - 65528, 65533, 65535, 0, 65535, 0, 65535, 0, 65535, 0, - 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, - 2, 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, - 65535, 0, 5, 65523, 65535, 0, 2, 65533, 65535, 0, - 7, 65526, 65535, 0, 46, 65464, 65533, 65535, 0, 2, - 120, 65309, 65533, 65535, 0, 2, 5, 362, 65097, 65533, - 65535, 0, 2, 18, 1164, 64785, 65528, 65531, 65533, 65535, - 0, 65535, 0, 65535, 0, 65535, 0, 65533, 65535, 0, - 65535, 0, 65533, 65535, 0, 2, 65533, 65535, 0, 2, - 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65530, 65535, - 0, 2, 65523, 65535, 0, 69, 65477, 65535, 0, 141, - 65459, 65535, 0, 194, 65325, 65533, 65535, 0, 2, 543, - 64912, 65533, 65535, 0, 5, 1270, 64301, 65529, 65531, 65533, - 65535, 0, 2, 4, 12, 2055, 63538, 65508, 65531, 65533, - 65535, 0, 2, 7, 102, 3775, 61970, 65429, 65526, 65528, - 65533, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 2, - 65533, 65535, 0, 2, 65535, 0, 9, 65533, 65535, 0, - 25, 65512, 65535, 0, 2, 65533, 65535, 0, 44, 65480, - 65535, 0, 48, 65475, 65535, 0, 162, 65373, 65535, 0, - 637, 64806, 65533, 65535, 0, 2, 935, 64445, 65533, 65535, - 0, 2, 4, 1662, 64083, 65533, 65535, 0, 2, 12, - 3036, 62469, 65521, 65533, 65535, 0, 2, 120, 5405, 60468, - 65469, 65531, 65533, 65535, 0, 2, 4, 18, 254, 6663, - 58999, 65272, 65528, 65533, 65535, 0, 2, 4, 9, 12, - 67, 591, 8981, 56781, 64564, 65365, 65508, 65524, 65526, 65529, - 65531, 65533, 65535, 0, 65535, 0, 65535, 0, 2, 65533, - 65535, 0, 9, 65526, 65535, 0, 14, 65503, 65535, 0, - 127, 65390, 65535, 0, 517, 64990, 65535, 0, 178, 65330, - 65535, 0, 2, 1055, 64533, 65533, 65535, 0, 2, 1558, - 63942, 65533, 65535, 0, 2, 2205, 63173, 65533, 65535, 0, - 25, 4493, 60862, 65505, 65533, 65535, 0, 2, 48, 5890, - 59442, 65482, 65533, 65535, 0, 2, 4, 127, 7532, 58191, - 65394, 65533, 65535, 0, 2, 5, 32, 550, 10388, 54924, - 65046, 65510, 65531, 65533, 65535, 0, 2, 4, 30, 150, - 1685, 14340, 51375, 63619, 65288, 65503, 65528, 65533, 65535, 0, - 2, 4, 6, 8, 28, 97, 473, 2692, 15407, 50020, - 62880, 65064, 65445, 65508, 65531, 65533, 65535, 0, 2, 4, - 12, 32, 79, 150, 372, 907, 2184, 5868, 18207, 45431, - 59856, 64031, 65096, 65401, 65481, 65507, 65521, 65523, 65525, 65527, - 65529, 65531, 65533, 65535, 0, 65533, 65535, 0, 182, 65491, - 65535, 0, 877, 64286, 65535, 0, 9, 2708, 63612, 65533, - 65535, 0, 2, 6038, 59532, 65535, 0, 2, 92, 5500, - 60539, 65533, 65535, 0, 268, 8908, 56512, 65385, 65535, 0, - 129, 13110, 52742, 65036, 65535, 0, 2, 806, 14003, 51929, - 64732, 65523, 65535, 0, 7, 92, 2667, 18159, 47678, 62610, - 65355, 65535, 0, 32, 1836, 19676, 48237, 61677, 64960, 65526, - 65535, 0, 21, 159, 967, 5668, 22782, 44709, 58317, 64020, - 65406, 65528, 65535, 0, 7, 162, 1838, 8328, 23929, 43014, - 56394, 63374, 65216, 65484, 65521, 65535, 0, 2, 4, 6, - 28, 268, 1120, 3613, 10688, 24185, 40989, 54917, 61684, 64510, - 65403, 65530, 65535, 0, 2, 16, 44, 139, 492, 1739, - 5313, 13558, 26766, 41566, 52446, 58937, 62815, 64480, 65201, 65454, - 65524, 65533, 65535, 0, 7, 25, 76, 263, 612, 1466, - 3325, 6832, 12366, 20152, 29466, 39255, 47360, 53506, 57740, 60726, - 62845, 64131, 64882, 65260, 65459, 65521, 65528, 65530, 65535, 0, - 2, 4, 14, 48, 136, 312, 653, 1240, 2369, 4327, - 7028, 10759, 15449, 21235, 28027, 35386, 42938, 49562, 54990, 59119, - 62086, 63916, 64863, 65249, 65445, 65493, 65523, 65535, 0, 2, - 4, 6, 8, 10, 12, 21, 83, 208, 409, 723, - 1152, 1868, 2951, 4463, 6460, 8979, 11831, 15195, 18863, 22657, - 26762, 30881, 34963, 39098, 43054, 47069, 50620, 53871, 56821, 59386, - 61340, 62670, 63512, 64023, 64429, 64750, 64944, 65126, 65279, 65366, - 65413, 65445, 65473, 65505, 65510, 65521, 65528, 65530, 65535}; - -/* pointers to cdf tables for quantizer indices */ -const WebRtc_UWord16 *WebRtcIsac_kQKltCdfPtrGain[3][12] = { -{WebRtcIsac_kQKltCdfGain +0 +0, WebRtcIsac_kQKltCdfGain +0 +8, WebRtcIsac_kQKltCdfGain +0 +22, WebRtcIsac_kQKltCdfGain +0 +32, WebRtcIsac_kQKltCdfGain +0 +48, WebRtcIsac_kQKltCdfGain +0 +60, WebRtcIsac_kQKltCdfGain +0 +81, WebRtcIsac_kQKltCdfGain +0 +95, WebRtcIsac_kQKltCdfGain +0 +128, WebRtcIsac_kQKltCdfGain +0 +152, -WebRtcIsac_kQKltCdfGain +0 +210, WebRtcIsac_kQKltCdfGain +0 +264}, -{WebRtcIsac_kQKltCdfGain +404 +0, WebRtcIsac_kQKltCdfGain +404 +8, WebRtcIsac_kQKltCdfGain +404 +21, WebRtcIsac_kQKltCdfGain +404 +30, WebRtcIsac_kQKltCdfGain +404 +46, WebRtcIsac_kQKltCdfGain +404 +58, WebRtcIsac_kQKltCdfGain +404 +79, WebRtcIsac_kQKltCdfGain +404 +93, WebRtcIsac_kQKltCdfGain +404 +125, WebRtcIsac_kQKltCdfGain +404 +149, -WebRtcIsac_kQKltCdfGain +404 +207, WebRtcIsac_kQKltCdfGain +404 +260}, -{WebRtcIsac_kQKltCdfGain +803 +0, WebRtcIsac_kQKltCdfGain +803 +8, WebRtcIsac_kQKltCdfGain +803 +22, WebRtcIsac_kQKltCdfGain +803 +31, WebRtcIsac_kQKltCdfGain +803 +48, WebRtcIsac_kQKltCdfGain +803 +60, WebRtcIsac_kQKltCdfGain +803 +81, WebRtcIsac_kQKltCdfGain +803 +96, WebRtcIsac_kQKltCdfGain +803 +129, WebRtcIsac_kQKltCdfGain +803 +154, -WebRtcIsac_kQKltCdfGain +803 +212, WebRtcIsac_kQKltCdfGain +803 +268}}; - -const WebRtc_UWord16 *WebRtcIsac_kQKltCdfPtrShape[3][108] = { -{WebRtcIsac_kQKltCdfShape +0 +0, WebRtcIsac_kQKltCdfShape +0 +2, WebRtcIsac_kQKltCdfShape +0 +4, WebRtcIsac_kQKltCdfShape +0 +6, WebRtcIsac_kQKltCdfShape +0 +8, WebRtcIsac_kQKltCdfShape +0 +10, WebRtcIsac_kQKltCdfShape +0 +12, WebRtcIsac_kQKltCdfShape +0 +14, WebRtcIsac_kQKltCdfShape +0 +16, WebRtcIsac_kQKltCdfShape +0 +18, -WebRtcIsac_kQKltCdfShape +0 +21, WebRtcIsac_kQKltCdfShape +0 +25, WebRtcIsac_kQKltCdfShape +0 +29, WebRtcIsac_kQKltCdfShape +0 +33, WebRtcIsac_kQKltCdfShape +0 +37, WebRtcIsac_kQKltCdfShape +0 +43, WebRtcIsac_kQKltCdfShape +0 +49, WebRtcIsac_kQKltCdfShape +0 +56, WebRtcIsac_kQKltCdfShape +0 +64, WebRtcIsac_kQKltCdfShape +0 +66, -WebRtcIsac_kQKltCdfShape +0 +68, WebRtcIsac_kQKltCdfShape +0 +70, WebRtcIsac_kQKltCdfShape +0 +72, WebRtcIsac_kQKltCdfShape +0 +75, WebRtcIsac_kQKltCdfShape +0 +77, WebRtcIsac_kQKltCdfShape +0 +79, WebRtcIsac_kQKltCdfShape +0 +81, WebRtcIsac_kQKltCdfShape +0 +83, WebRtcIsac_kQKltCdfShape +0 +86, WebRtcIsac_kQKltCdfShape +0 +90, -WebRtcIsac_kQKltCdfShape +0 +94, WebRtcIsac_kQKltCdfShape +0 +98, WebRtcIsac_kQKltCdfShape +0 +102, WebRtcIsac_kQKltCdfShape +0 +107, WebRtcIsac_kQKltCdfShape +0 +113, WebRtcIsac_kQKltCdfShape +0 +120, WebRtcIsac_kQKltCdfShape +0 +129, WebRtcIsac_kQKltCdfShape +0 +131, WebRtcIsac_kQKltCdfShape +0 +133, WebRtcIsac_kQKltCdfShape +0 +135, -WebRtcIsac_kQKltCdfShape +0 +137, WebRtcIsac_kQKltCdfShape +0 +141, WebRtcIsac_kQKltCdfShape +0 +143, WebRtcIsac_kQKltCdfShape +0 +147, WebRtcIsac_kQKltCdfShape +0 +151, WebRtcIsac_kQKltCdfShape +0 +155, WebRtcIsac_kQKltCdfShape +0 +159, WebRtcIsac_kQKltCdfShape +0 +164, WebRtcIsac_kQKltCdfShape +0 +168, WebRtcIsac_kQKltCdfShape +0 +172, -WebRtcIsac_kQKltCdfShape +0 +178, WebRtcIsac_kQKltCdfShape +0 +184, WebRtcIsac_kQKltCdfShape +0 +192, WebRtcIsac_kQKltCdfShape +0 +200, WebRtcIsac_kQKltCdfShape +0 +211, WebRtcIsac_kQKltCdfShape +0 +213, WebRtcIsac_kQKltCdfShape +0 +215, WebRtcIsac_kQKltCdfShape +0 +217, WebRtcIsac_kQKltCdfShape +0 +219, WebRtcIsac_kQKltCdfShape +0 +223, -WebRtcIsac_kQKltCdfShape +0 +227, WebRtcIsac_kQKltCdfShape +0 +231, WebRtcIsac_kQKltCdfShape +0 +235, WebRtcIsac_kQKltCdfShape +0 +239, WebRtcIsac_kQKltCdfShape +0 +243, WebRtcIsac_kQKltCdfShape +0 +248, WebRtcIsac_kQKltCdfShape +0 +252, WebRtcIsac_kQKltCdfShape +0 +258, WebRtcIsac_kQKltCdfShape +0 +264, WebRtcIsac_kQKltCdfShape +0 +273, -WebRtcIsac_kQKltCdfShape +0 +282, WebRtcIsac_kQKltCdfShape +0 +293, WebRtcIsac_kQKltCdfShape +0 +308, WebRtcIsac_kQKltCdfShape +0 +310, WebRtcIsac_kQKltCdfShape +0 +312, WebRtcIsac_kQKltCdfShape +0 +316, WebRtcIsac_kQKltCdfShape +0 +320, WebRtcIsac_kQKltCdfShape +0 +324, WebRtcIsac_kQKltCdfShape +0 +328, WebRtcIsac_kQKltCdfShape +0 +332, -WebRtcIsac_kQKltCdfShape +0 +336, WebRtcIsac_kQKltCdfShape +0 +341, WebRtcIsac_kQKltCdfShape +0 +347, WebRtcIsac_kQKltCdfShape +0 +354, WebRtcIsac_kQKltCdfShape +0 +360, WebRtcIsac_kQKltCdfShape +0 +368, WebRtcIsac_kQKltCdfShape +0 +378, WebRtcIsac_kQKltCdfShape +0 +388, WebRtcIsac_kQKltCdfShape +0 +400, WebRtcIsac_kQKltCdfShape +0 +418, -WebRtcIsac_kQKltCdfShape +0 +445, WebRtcIsac_kQKltCdfShape +0 +447, WebRtcIsac_kQKltCdfShape +0 +451, WebRtcIsac_kQKltCdfShape +0 +455, WebRtcIsac_kQKltCdfShape +0 +461, WebRtcIsac_kQKltCdfShape +0 +468, WebRtcIsac_kQKltCdfShape +0 +474, WebRtcIsac_kQKltCdfShape +0 +480, WebRtcIsac_kQKltCdfShape +0 +486, WebRtcIsac_kQKltCdfShape +0 +495, -WebRtcIsac_kQKltCdfShape +0 +505, WebRtcIsac_kQKltCdfShape +0 +516, WebRtcIsac_kQKltCdfShape +0 +528, WebRtcIsac_kQKltCdfShape +0 +543, WebRtcIsac_kQKltCdfShape +0 +564, WebRtcIsac_kQKltCdfShape +0 +583, WebRtcIsac_kQKltCdfShape +0 +608, WebRtcIsac_kQKltCdfShape +0 +635}, -{WebRtcIsac_kQKltCdfShape +686 +0, WebRtcIsac_kQKltCdfShape +686 +2, WebRtcIsac_kQKltCdfShape +686 +4, WebRtcIsac_kQKltCdfShape +686 +6, WebRtcIsac_kQKltCdfShape +686 +8, WebRtcIsac_kQKltCdfShape +686 +11, WebRtcIsac_kQKltCdfShape +686 +13, WebRtcIsac_kQKltCdfShape +686 +15, WebRtcIsac_kQKltCdfShape +686 +17, WebRtcIsac_kQKltCdfShape +686 +20, -WebRtcIsac_kQKltCdfShape +686 +23, WebRtcIsac_kQKltCdfShape +686 +27, WebRtcIsac_kQKltCdfShape +686 +31, WebRtcIsac_kQKltCdfShape +686 +35, WebRtcIsac_kQKltCdfShape +686 +40, WebRtcIsac_kQKltCdfShape +686 +44, WebRtcIsac_kQKltCdfShape +686 +50, WebRtcIsac_kQKltCdfShape +686 +56, WebRtcIsac_kQKltCdfShape +686 +63, WebRtcIsac_kQKltCdfShape +686 +65, -WebRtcIsac_kQKltCdfShape +686 +67, WebRtcIsac_kQKltCdfShape +686 +69, WebRtcIsac_kQKltCdfShape +686 +71, WebRtcIsac_kQKltCdfShape +686 +73, WebRtcIsac_kQKltCdfShape +686 +75, WebRtcIsac_kQKltCdfShape +686 +77, WebRtcIsac_kQKltCdfShape +686 +79, WebRtcIsac_kQKltCdfShape +686 +82, WebRtcIsac_kQKltCdfShape +686 +85, WebRtcIsac_kQKltCdfShape +686 +89, -WebRtcIsac_kQKltCdfShape +686 +93, WebRtcIsac_kQKltCdfShape +686 +97, WebRtcIsac_kQKltCdfShape +686 +102, WebRtcIsac_kQKltCdfShape +686 +106, WebRtcIsac_kQKltCdfShape +686 +112, WebRtcIsac_kQKltCdfShape +686 +119, WebRtcIsac_kQKltCdfShape +686 +127, WebRtcIsac_kQKltCdfShape +686 +129, WebRtcIsac_kQKltCdfShape +686 +131, WebRtcIsac_kQKltCdfShape +686 +133, -WebRtcIsac_kQKltCdfShape +686 +135, WebRtcIsac_kQKltCdfShape +686 +137, WebRtcIsac_kQKltCdfShape +686 +139, WebRtcIsac_kQKltCdfShape +686 +142, WebRtcIsac_kQKltCdfShape +686 +146, WebRtcIsac_kQKltCdfShape +686 +150, WebRtcIsac_kQKltCdfShape +686 +154, WebRtcIsac_kQKltCdfShape +686 +158, WebRtcIsac_kQKltCdfShape +686 +162, WebRtcIsac_kQKltCdfShape +686 +167, -WebRtcIsac_kQKltCdfShape +686 +173, WebRtcIsac_kQKltCdfShape +686 +179, WebRtcIsac_kQKltCdfShape +686 +186, WebRtcIsac_kQKltCdfShape +686 +194, WebRtcIsac_kQKltCdfShape +686 +205, WebRtcIsac_kQKltCdfShape +686 +207, WebRtcIsac_kQKltCdfShape +686 +209, WebRtcIsac_kQKltCdfShape +686 +211, WebRtcIsac_kQKltCdfShape +686 +214, WebRtcIsac_kQKltCdfShape +686 +218, -WebRtcIsac_kQKltCdfShape +686 +222, WebRtcIsac_kQKltCdfShape +686 +226, WebRtcIsac_kQKltCdfShape +686 +230, WebRtcIsac_kQKltCdfShape +686 +234, WebRtcIsac_kQKltCdfShape +686 +238, WebRtcIsac_kQKltCdfShape +686 +242, WebRtcIsac_kQKltCdfShape +686 +247, WebRtcIsac_kQKltCdfShape +686 +253, WebRtcIsac_kQKltCdfShape +686 +262, WebRtcIsac_kQKltCdfShape +686 +269, -WebRtcIsac_kQKltCdfShape +686 +278, WebRtcIsac_kQKltCdfShape +686 +289, WebRtcIsac_kQKltCdfShape +686 +305, WebRtcIsac_kQKltCdfShape +686 +307, WebRtcIsac_kQKltCdfShape +686 +309, WebRtcIsac_kQKltCdfShape +686 +311, WebRtcIsac_kQKltCdfShape +686 +315, WebRtcIsac_kQKltCdfShape +686 +319, WebRtcIsac_kQKltCdfShape +686 +323, WebRtcIsac_kQKltCdfShape +686 +327, -WebRtcIsac_kQKltCdfShape +686 +331, WebRtcIsac_kQKltCdfShape +686 +335, WebRtcIsac_kQKltCdfShape +686 +340, WebRtcIsac_kQKltCdfShape +686 +346, WebRtcIsac_kQKltCdfShape +686 +354, WebRtcIsac_kQKltCdfShape +686 +362, WebRtcIsac_kQKltCdfShape +686 +374, WebRtcIsac_kQKltCdfShape +686 +384, WebRtcIsac_kQKltCdfShape +686 +396, WebRtcIsac_kQKltCdfShape +686 +413, -WebRtcIsac_kQKltCdfShape +686 +439, WebRtcIsac_kQKltCdfShape +686 +442, WebRtcIsac_kQKltCdfShape +686 +446, WebRtcIsac_kQKltCdfShape +686 +450, WebRtcIsac_kQKltCdfShape +686 +455, WebRtcIsac_kQKltCdfShape +686 +461, WebRtcIsac_kQKltCdfShape +686 +468, WebRtcIsac_kQKltCdfShape +686 +475, WebRtcIsac_kQKltCdfShape +686 +481, WebRtcIsac_kQKltCdfShape +686 +489, -WebRtcIsac_kQKltCdfShape +686 +498, WebRtcIsac_kQKltCdfShape +686 +508, WebRtcIsac_kQKltCdfShape +686 +522, WebRtcIsac_kQKltCdfShape +686 +534, WebRtcIsac_kQKltCdfShape +686 +554, WebRtcIsac_kQKltCdfShape +686 +577, WebRtcIsac_kQKltCdfShape +686 +602, WebRtcIsac_kQKltCdfShape +686 +631}, -{WebRtcIsac_kQKltCdfShape +1368 +0, WebRtcIsac_kQKltCdfShape +1368 +2, WebRtcIsac_kQKltCdfShape +1368 +4, WebRtcIsac_kQKltCdfShape +1368 +6, WebRtcIsac_kQKltCdfShape +1368 +8, WebRtcIsac_kQKltCdfShape +1368 +10, WebRtcIsac_kQKltCdfShape +1368 +12, WebRtcIsac_kQKltCdfShape +1368 +14, WebRtcIsac_kQKltCdfShape +1368 +16, WebRtcIsac_kQKltCdfShape +1368 +20, -WebRtcIsac_kQKltCdfShape +1368 +24, WebRtcIsac_kQKltCdfShape +1368 +28, WebRtcIsac_kQKltCdfShape +1368 +32, WebRtcIsac_kQKltCdfShape +1368 +36, WebRtcIsac_kQKltCdfShape +1368 +40, WebRtcIsac_kQKltCdfShape +1368 +44, WebRtcIsac_kQKltCdfShape +1368 +50, WebRtcIsac_kQKltCdfShape +1368 +57, WebRtcIsac_kQKltCdfShape +1368 +65, WebRtcIsac_kQKltCdfShape +1368 +67, -WebRtcIsac_kQKltCdfShape +1368 +69, WebRtcIsac_kQKltCdfShape +1368 +71, WebRtcIsac_kQKltCdfShape +1368 +73, WebRtcIsac_kQKltCdfShape +1368 +75, WebRtcIsac_kQKltCdfShape +1368 +77, WebRtcIsac_kQKltCdfShape +1368 +79, WebRtcIsac_kQKltCdfShape +1368 +81, WebRtcIsac_kQKltCdfShape +1368 +85, WebRtcIsac_kQKltCdfShape +1368 +89, WebRtcIsac_kQKltCdfShape +1368 +93, -WebRtcIsac_kQKltCdfShape +1368 +97, WebRtcIsac_kQKltCdfShape +1368 +101, WebRtcIsac_kQKltCdfShape +1368 +105, WebRtcIsac_kQKltCdfShape +1368 +110, WebRtcIsac_kQKltCdfShape +1368 +116, WebRtcIsac_kQKltCdfShape +1368 +123, WebRtcIsac_kQKltCdfShape +1368 +132, WebRtcIsac_kQKltCdfShape +1368 +134, WebRtcIsac_kQKltCdfShape +1368 +136, WebRtcIsac_kQKltCdfShape +1368 +138, -WebRtcIsac_kQKltCdfShape +1368 +141, WebRtcIsac_kQKltCdfShape +1368 +143, WebRtcIsac_kQKltCdfShape +1368 +146, WebRtcIsac_kQKltCdfShape +1368 +150, WebRtcIsac_kQKltCdfShape +1368 +154, WebRtcIsac_kQKltCdfShape +1368 +158, WebRtcIsac_kQKltCdfShape +1368 +162, WebRtcIsac_kQKltCdfShape +1368 +166, WebRtcIsac_kQKltCdfShape +1368 +170, WebRtcIsac_kQKltCdfShape +1368 +174, -WebRtcIsac_kQKltCdfShape +1368 +179, WebRtcIsac_kQKltCdfShape +1368 +185, WebRtcIsac_kQKltCdfShape +1368 +193, WebRtcIsac_kQKltCdfShape +1368 +203, WebRtcIsac_kQKltCdfShape +1368 +214, WebRtcIsac_kQKltCdfShape +1368 +216, WebRtcIsac_kQKltCdfShape +1368 +218, WebRtcIsac_kQKltCdfShape +1368 +220, WebRtcIsac_kQKltCdfShape +1368 +224, WebRtcIsac_kQKltCdfShape +1368 +227, -WebRtcIsac_kQKltCdfShape +1368 +231, WebRtcIsac_kQKltCdfShape +1368 +235, WebRtcIsac_kQKltCdfShape +1368 +239, WebRtcIsac_kQKltCdfShape +1368 +243, WebRtcIsac_kQKltCdfShape +1368 +247, WebRtcIsac_kQKltCdfShape +1368 +251, WebRtcIsac_kQKltCdfShape +1368 +256, WebRtcIsac_kQKltCdfShape +1368 +262, WebRtcIsac_kQKltCdfShape +1368 +269, WebRtcIsac_kQKltCdfShape +1368 +277, -WebRtcIsac_kQKltCdfShape +1368 +286, WebRtcIsac_kQKltCdfShape +1368 +297, WebRtcIsac_kQKltCdfShape +1368 +315, WebRtcIsac_kQKltCdfShape +1368 +317, WebRtcIsac_kQKltCdfShape +1368 +319, WebRtcIsac_kQKltCdfShape +1368 +323, WebRtcIsac_kQKltCdfShape +1368 +327, WebRtcIsac_kQKltCdfShape +1368 +331, WebRtcIsac_kQKltCdfShape +1368 +335, WebRtcIsac_kQKltCdfShape +1368 +339, -WebRtcIsac_kQKltCdfShape +1368 +343, WebRtcIsac_kQKltCdfShape +1368 +349, WebRtcIsac_kQKltCdfShape +1368 +355, WebRtcIsac_kQKltCdfShape +1368 +361, WebRtcIsac_kQKltCdfShape +1368 +368, WebRtcIsac_kQKltCdfShape +1368 +376, WebRtcIsac_kQKltCdfShape +1368 +385, WebRtcIsac_kQKltCdfShape +1368 +397, WebRtcIsac_kQKltCdfShape +1368 +411, WebRtcIsac_kQKltCdfShape +1368 +429, -WebRtcIsac_kQKltCdfShape +1368 +456, WebRtcIsac_kQKltCdfShape +1368 +459, WebRtcIsac_kQKltCdfShape +1368 +463, WebRtcIsac_kQKltCdfShape +1368 +467, WebRtcIsac_kQKltCdfShape +1368 +473, WebRtcIsac_kQKltCdfShape +1368 +478, WebRtcIsac_kQKltCdfShape +1368 +485, WebRtcIsac_kQKltCdfShape +1368 +491, WebRtcIsac_kQKltCdfShape +1368 +497, WebRtcIsac_kQKltCdfShape +1368 +505, -WebRtcIsac_kQKltCdfShape +1368 +514, WebRtcIsac_kQKltCdfShape +1368 +523, WebRtcIsac_kQKltCdfShape +1368 +535, WebRtcIsac_kQKltCdfShape +1368 +548, WebRtcIsac_kQKltCdfShape +1368 +565, WebRtcIsac_kQKltCdfShape +1368 +585, WebRtcIsac_kQKltCdfShape +1368 +611, WebRtcIsac_kQKltCdfShape +1368 +640}}; - -/* code length for all coefficients using different models */ -const double WebRtcIsac_kQKltCodeLenGain[392] = { - 12.29956028, 7.83007500, 4.25642781, 0.17489215, 4.27591254, 7.66908312, 10.47643804, 11.91253716, 9.03421572, 8.57373525, - 6.73555740, 5.41409855, 3.65237863, 0.42623449, 3.22418399, 5.68145719, 7.14201900, 8.20558413, 9.34178852, 13.00000000, - 13.00000000, 9.47643804, 6.71459778, 3.55472644, 0.28457419, 3.70652835, 7.41128536, 11.60768258, 14.00000000, 12.29956028, - 9.29956028, 8.02845645, 6.54878889, 5.07667251, 2.87749552, 0.65310542, 3.11316029, 4.87911416, 5.89540125, 6.76398581, - 7.70537925, 9.67807191, 11.14201900, 14.00000000, 14.00000000, 12.29956028, 9.69621925, 7.70537925, 5.49915812, 2.67441345, - 0.63381441, 2.74999773, 5.76877882, 8.41503750, 10.75207249, 14.00000000, 9.60768258, 8.85025288, 8.09913319, 7.09010692, - 6.36337538, 5.46667027, 4.51618422, 2.64189829, 1.21843537, 2.43823474, 3.89409149, 4.99718498, 6.00989604, 6.78325414, - 7.39637366, 8.76159526, 10.60768258, 11.67807191, 12.29956028, 9.54056838, 7.95560588, 5.63040265, 3.81264793, 2.18521728, - 1.33727600, 2.37909290, 3.94981123, 5.52426657, 7.32051990, 8.84012866, 11.35614381, 13.00000000, 12.29956028, 11.35614381, - 11.35614381, 10.24511250, 9.12963528, 8.80032766, 7.97763219, 7.83007500, 7.09913319, 6.68711704, 6.41879942, 5.74379131, - 5.25096862, 4.43061904, 3.54492969, 2.72664147, 2.16306204, 2.71142226, 3.34357514, 4.07444556, 4.95151313, 5.68145719, - 6.12041675, 6.55085135, 7.00282052, 7.55705650, 8.44541115, 9.41503750, 10.91253716, 11.60768258, 14.00000000, 14.00000000, - 13.00000000, 11.60768258, 10.47643804, 8.80032766, 7.38161450, 6.52426657, 5.47447919, 4.53749773, 3.92719747, 3.41058292, - 2.88495635, 2.79344346, 2.85805254, 3.18261657, 3.57216340, 4.08225499, 4.74438125, 5.51215997, 6.30477171, 7.15450995, - 8.28575448, 9.69621925, 11.60768258, 13.00000000, 13.67807191, 15.00000000, 15.00000000, 14.00000000, 12.41503750, 11.29956028, - 12.41503750, 11.60768258, 10.11735695, 9.47643804, 9.12963528, 9.41503750, 8.23181568, 7.97763219, 7.82507432, 7.50814690, - 7.33466408, 6.99157138, 6.95834085, 6.80524315, 6.47447919, 6.35614381, 6.02128954, 5.71459778, 5.58109327, 5.05821876, - 4.94539568, 4.59220115, 4.27591254, 4.01522554, 3.89376424, 3.83760867, 3.73321346, 3.74674342, 3.90493270, 4.18942837, - 4.33599724, 4.42446075, 4.81760565, 5.07667251, 5.54570071, 5.95697272, 6.46667027, 6.91253716, 7.33466408, 7.82507432, - 8.05163277, 9.12963528, 9.02272008, 9.77118131, 9.60768258, 10.11735695, 12.00000000, 12.83007500, 15.00000000, 15.00000000, - 14.00000000, 15.00000000, 11.75207249, 12.29956028, 10.95560588, 9.93391081, 9.02272008, 8.00564656, 7.82507432, 7.28919357, - 6.77599833, 6.56745810, 6.19910010, 6.23347109, 5.67694524, 5.41879942, 4.96039548, 4.88170777, 4.60768258, 4.52883287, - 4.28876323, 4.17583679, 4.21332197, 4.14474217, 4.16119001, 4.12809476, 4.18501706, 4.28489599, 4.35299136, 4.60286019, - 4.63040265, 4.81017544, 5.00989604, 5.33822190, 5.43489792, 5.84644797, 6.13272126, 6.75444729, 7.36337538, 7.96108101, - 8.54056838, 9.28575448, 9.12963528, 9.47643804, 10.75207249, 12.29956028, 12.41503750, 11.14201900, 12.83007500, 15.00000000, - 15.00000000, 15.00000000, 15.00000000, 15.00000000, 15.00000000, 14.00000000, 15.00000000, 15.00000000, 15.00000000, 15.00000000, - 13.67807191, 12.41503750, 11.91253716, 11.60768258, 12.29956028, 13.00000000, 12.29956028, 10.95560588, 10.60768258, 9.77118131, - 10.02272008, 10.11735695, 10.14201900, 10.75207249, 10.75207249, 9.69621925, 9.47643804, 9.75207249, 8.72387559, 8.47643804, - 8.68711704, 8.40754296, 8.20558413, 8.26529038, 7.84518189, 7.89147554, 7.64685317, 7.41128536, 7.33466408, 7.42635281, - 7.24845594, 7.11430363, 7.07518750, 7.07518750, 6.70537925, 6.64906082, 6.73555740, 6.62931259, 6.50015411, 6.26190774, - 6.36337538, 6.19264508, 5.95151313, 6.08860801, 5.91253716, 5.83007500, 5.68145719, 5.67244736, 5.82632286, 6.00282052, - 5.65348627, 5.74970158, 5.87846648, 5.69052365, 5.64464890, 5.58531476, 5.81512466, 5.57688409, 5.87329553, 5.62170514, - 5.74851759, 5.81017544, 5.64464890, 5.76398581, 5.60339522, 5.69507833, 5.84139031, 5.68711704, 5.73908047, 5.84139031, - 5.71459778, 5.96245305, 5.82632286, 5.89540125, 6.08860801, 6.12041675, 6.13272126, 6.30477171, 6.24177679, 6.28232358, - 6.29091619, 6.53239445, 6.81512466, 6.72620440, 6.65792533, 6.84518189, 7.10215454, 7.44157929, 7.57793523, 7.59485854, - 7.66460965, 8.05163277, 8.00564656, 8.43775758, 8.10518224, 8.28575448, 8.77118131, 8.23181568, 8.29264087, 8.20558413, - 8.34894831, 8.89147554, 8.40754296, 8.61629571, 8.64244800, 8.61629571, 8.93391081, 8.50814690, 9.02272008, 8.68711704, - 8.65127185, 9.41503750, 9.11735695, 9.85025288, 10.24511250, 10.60768258, 10.47643804, 11.60768258, 11.35614381, 12.29956028, - 15.00000000, 15.00000000, 12.29956028, 13.00000000, 15.00000000, 15.00000000, 15.00000000, 15.00000000, 14.00000000, 12.83007500, - 15.00000000, 15.00000000}; - -const double WebRtcIsac_kQKltCodeLenShape[578] = { - 0.00002201, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 14.00000000, - 0.00011007, 13.00000000, 0.00066056, 11.60768258, 11.14201900, 0.00185034, 10.24511250, 9.08113676, 0.00480700, 9.41503750, - 8.09913319, 0.01084946, 8.02845645, 13.00000000, 6.40941295, 0.02926496, 6.95560588, 13.00000000, 13.00000000, 6.21864029, - 0.03861814, 6.30477171, 12.29956028, 11.14201900, 4.66964328, 0.12158980, 4.62604734, 10.91253716, 14.00000000, 11.35614381, - 8.76159526, 3.89671219, 0.21179147, 3.99472634, 8.02272008, 13.00000000, 0.00002201, 0.00002201, 0.00002201, 0.00002201, - 14.00000000, 0.00011007, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 14.00000000, 0.00011007, 10.95560588, 0.00147568, - 10.95560588, 10.24511250, 0.00240150, 10.24511250, 8.02845645, 0.01056115, 8.17982104, 6.74497143, 0.02381629, 7.15137706, - 5.68598330, 0.05650076, 5.72970467, 13.00000000, 14.00000000, 5.18221688, 0.07697435, 5.37611851, 11.91253716, 9.54056838, - 3.92853764, 0.22143514, 3.76428491, 9.28575448, 14.00000000, 11.35614381, 7.37794818, 3.30585980, 0.37001735, 3.18521728, - 6.88886433, 11.91253716, 14.00000000, 0.00002201, 0.00002201, 0.00002201, 0.00002201, 14.00000000, 0.00019814, 14.00000000, - 0.00002201, 13.00000000, 0.00028621, 14.00000000, 14.00000000, 0.00028621, 13.00000000, 11.91253716, 0.00094690, 11.35614381, - 10.60768258, 0.00213692, 10.24511250, 8.37794818, 0.00863317, 8.43775758, 14.00000000, 7.41128536, 0.01698415, 7.42635281, - 6.02702021, 0.04514485, 6.01558154, 13.00000000, 5.05090284, 0.09207659, 4.98877274, 15.00000000, 10.75207249, 4.41081703, - 0.15733047, 4.17424617, 11.60768258, 14.00000000, 15.00000000, 10.06926266, 3.74320161, 0.23091117, 3.81141115, 10.02272008, - 11.91253716, 6.90196792, 2.92703003, 0.46874039, 2.93846004, 7.26190774, 11.60768258, 13.00000000, 10.21864029, 7.95560588, - 5.19345038, 2.40520888, 0.77554605, 2.56628417, 5.41409855, 8.81017544, 12.29956028, 0.00002201, 0.00002201, 0.00002201, - 0.00002201, 11.91253716, 0.00068259, 12.29956028, 10.11735695, 0.00233535, 10.47643804, 10.35614381, 0.00140957, 12.29956028, - 10.24511250, 0.00222511, 10.47643804, 7.72387559, 0.01475842, 7.52426657, 6.73555740, 0.02924249, 6.55085135, 14.00000000, - 5.45021533, 0.06930886, 5.38345116, 4.55913083, 0.11289841, 4.92853764, 11.60768258, 4.07148162, 0.19798859, 3.87200568, - 13.00000000, 9.60768258, 3.31393725, 0.29937064, 3.57321111, 9.35614381, 14.00000000, 8.02845645, 3.08542800, 0.45503557, - 2.80678268, 7.47643804, 12.29956028, 14.00000000, 14.00000000, 14.00000000, 6.83509307, 2.69166097, 0.61673447, 2.51266238, - 6.84771516, 11.91253716, 11.14201900, 7.72387559, 4.61899789, 2.17136763, 1.03592993, 2.28586183, 4.86814304, 7.78568088, - 10.91253716, 14.00000000, 15.00000000, 11.04580369, 9.28575448, 7.26190774, 5.21946023, 3.61575588, 2.18431651, 1.45666604, - 2.33566383, 3.85470467, 5.46181107, 7.30651304, 8.89147554, 11.91253716, 0.00002201, 0.00002201, 15.00000000, 0.00011007, - 15.00000000, 10.47643804, 0.00149771, 11.60768258, 7.30651304, 0.01903486, 7.20558413, 6.92318440, 0.02587674, 6.71459778, - 7.28919357, 0.01756340, 7.45696818, 6.06926266, 0.03841465, 6.45890338, 4.46035649, 0.13896157, 4.43204392, 14.00000000, - 14.00000000, 4.09010692, 0.19672654, 3.86653665, 13.00000000, 14.00000000, 11.35614381, 3.45117809, 0.27340929, 3.64878468, - 9.93391081, 9.60768258, 3.30585980, 0.35178287, 3.15607895, 9.12963528, 12.29956028, 7.93391081, 2.82180202, 0.53064436, - 2.68258739, 7.42635281, 11.14201900, 15.00000000, 10.06926266, 6.15294265, 2.55861197, 0.69308389, 2.48602573, 5.90592231, - 9.47643804, 13.00000000, 11.14201900, 8.20558413, 5.21618324, 2.34973357, 1.00379135, 2.09611815, 4.80278331, 7.82507432, - 11.91253716, 12.29956028, 8.98877274, 6.75444729, 4.23886435, 2.19859476, 1.29528579, 2.06032897, 4.06704711, 6.76398581, - 9.34178852, 13.00000000, 12.29956028, 10.14201900, 8.40754296, 6.16710999, 4.64850859, 3.28768796, 2.22892326, 1.78568088, - 2.35209193, 3.45141888, 4.91121176, 6.45117809, 8.20558413, 10.35614381, 13.00000000, 12.83007500, 14.00000000, 14.00000000, - 12.83007500, 11.35614381, 9.85025288, 9.41503750, 8.07518750, 7.34894831, 6.25516616, 5.25096862, 4.52477322, 3.68513357, - 3.06152306, 2.64011320, 2.54608637, 2.95765662, 3.44445223, 4.01665007, 4.63258525, 5.27633906, 6.24678325, 7.05163277, - 8.02845645, 9.60768258, 10.79054663, 12.83007500, 14.00000000, 0.00002201, 15.00000000, 0.00011007, 15.00000000, 5.82009091, - 0.02710994, 10.11735695, 15.00000000, 3.30346709, 0.17317845, 6.41128536, 15.00000000, 15.00000000, 10.83007500, 2.72897475, - 0.35935964, 3.85853144, 13.00000000, 15.00000000, 3.72766182, 0.17268211, 4.74674342, 15.00000000, 15.00000000, 4.40754296, - 0.11993823, 4.93997965, 15.00000000, 15.00000000, 4.70193743, 0.22110152, 3.27591254, 11.35614381, 15.00000000, 12.54056838, - 6.94743195, 2.99157138, 0.62079088, 2.25338071, 7.41128536, 15.00000000, 15.00000000, 11.47643804, 6.04580369, 2.80232255, - 0.98380109, 1.70502034, 5.15607895, 10.75207249, 13.00000000, 15.00000000, 15.00000000, 11.35614381, 6.44157929, 2.37955105, - 0.74567258, 2.44181848, 6.07667251, 10.75207249, 15.00000000, 15.00000000, 15.00000000, 15.00000000, 9.44541115, 5.25432568, - 1.97815248, 0.94086682, 2.57885561, 5.17265730, 8.72387559, 14.00000000, 15.00000000, 15.00000000, 15.00000000, 10.67807191, - 7.59485854, 4.91187431, 2.91934900, 1.32321648, 1.50614455, 3.85215911, 7.15137706, 10.60768258, 14.00000000, 15.00000000, - 15.00000000, 15.00000000, 15.00000000, 15.00000000, 15.00000000, 15.00000000, 11.09310940, 8.50814690, 6.45117809, 3.94675287, - 2.16730774, 1.37674720, 2.10215454, 3.97278511, 6.34178852, 8.50814690, 10.32757466, 14.00000000, 14.00000000, 15.00000000, - 15.00000000, 15.00000000, 14.00000000, 10.02272008, 9.41503750, 7.03710399, 5.13349379, 3.61683574, 2.47999526, 1.82788507, - 2.00945280, 3.08020557, 4.69793233, 6.64025044, 8.32051990, 10.91253716, 14.00000000, 15.00000000, 15.00000000, 15.00000000, - 15.00000000, 15.00000000, 15.00000000, 14.41503750, 9.41503750, 7.10215454, 5.60768258, 4.44014496, 3.30064444, 2.56941678, - 2.28103909, 2.42694459, 2.93206152, 3.83383692, 4.75207249, 6.02702021, 7.16394964, 9.35614381, 11.14201900, 12.29956028, - 15.00000000, 15.00000000, 14.00000000, 15.00000000, 15.00000000, 10.11735695, 8.85025288, 7.02558541, 5.86300889, 4.79726396, - 3.95117259, 3.44925321, 2.96348293, 2.88219459, 2.89671219, 3.10518224, 3.50065237, 4.05748549, 4.55291677, 5.23016216, - 5.79420675, 6.39452048, 6.91253716, 7.97763219, 8.32051990, 9.35614381, 10.60768258, 11.60768258, 15.00000000, 15.00000000, - 12.83007500, 12.41503750, 11.91253716, 14.00000000, 14.00000000, 11.35614381, 10.75207249, 10.91253716, 8.93391081, 8.61629571, - 8.29264087, 8.02272008, 7.89147554, 7.33466408, 7.41128536, 6.71459778, 5.92853764, 5.31964048, 4.97693875, 4.70308379, - 4.43632704, 4.34357514, 4.30825648, 4.26529038, 4.19465917, 4.27420773, 4.22315577, 4.08262792, 4.06667818, 4.16119001, - 4.08860801, 4.26698468, 4.39128315, 4.71517590, 5.10442472, 5.50714538, 5.81017544, 6.15922208}; - -/* left KLT transforms */ -const double WebRtcIsac_kKltT1Gain[3][4] = { -{-0.79742827, 0.60341375, 0.60341375, 0.79742827}, -{-0.81372390, 0.58125159, 0.58125159, 0.81372390}, -{-0.71832547, 0.69570721, 0.69570721, 0.71832547}}; - -const double WebRtcIsac_kKltT1Shape[3][324] = { -{ 0.00159597, 0.00049320, 0.00513821, 0.00021066, 0.01338581, -0.00422367, -0.00272072, 0.00935107, 0.02047622, 0.02691189, - 0.00478236, 0.03969702, 0.00886698, 0.04877604, -0.10898362, -0.05930891, -0.03415047, 0.98889721, 0.00293558, -0.00035282, - 0.01156321, -0.00195341, -0.00937631, 0.01052213, -0.02551163, 0.01644059, 0.03189927, 0.07754773, -0.08742313, -0.03026338, - 0.05136248, -0.14395974, 0.17725040, 0.22664856, 0.93380230, 0.07076411, 0.00557890, -0.00222834, 0.01377569, 0.01466808, - 0.02847361, -0.00603178, 0.02382480, -0.01210452, 0.03797267, -0.02371480, 0.11260335, -0.07366682, 0.00453436, -0.04136941, --0.07912843, -0.95031418, 0.25295337, -0.05302216, -0.00617554, -0.00044040, -0.00653778, 0.01097838, 0.01529174, 0.01374431, --0.00748512, -0.00020034, 0.02432713, 0.11101570, -0.08556891, 0.09282249, -0.01029446, 0.67556443, -0.67454300, 0.06910063, - 0.20866865, -0.10318050, 0.00932175, 0.00524058, 0.00803610, -0.00594676, -0.01082578, 0.01069906, 0.00546768, 0.01565291, - 0.06816200, 0.10201227, 0.16812734, 0.22984074, 0.58213170, -0.54138651, -0.51379962, 0.06847390, -0.01920037, -0.04592324, --0.00467394, 0.00328858, 0.00377424, -0.00987448, 0.08222096, -0.00377301, 0.04551941, -0.02592517, 0.16317082, 0.13077530, - 0.22702921, -0.31215289, -0.69645962, -0.38047101, -0.39339411, 0.11124777, 0.02508035, -0.00708074, 0.00400344, 0.00040331, - 0.01142402, 0.01725406, 0.01635170, 0.14285366, 0.03949233, -0.05905676, 0.05877154, -0.17497577, -0.32479440, 0.80754464, --0.38085603, -0.17055430, -0.03168622, -0.07531451, 0.02942002, -0.02148095, -0.00754114, -0.00322372, 0.00567812, -0.01701521, --0.12358320, 0.11473564, 0.09070136, 0.06533068, -0.22560802, 0.19209022, 0.81605094, 0.36592275, -0.09919829, 0.16667122, - 0.16300725, 0.04803807, 0.06739263, -0.00156752, -0.01685302, -0.00905240, -0.02297836, -0.00469939, 0.06310613, -0.16391930, - 0.10919511, 0.12529293, 0.85581322, -0.32145522, 0.24539076, 0.07181839, 0.07289591, 0.14066759, 0.10406711, 0.05815518, - 0.01072680, -0.00759339, 0.00053486, -0.00044865, 0.03407361, 0.01645348, 0.08758579, 0.27722240, 0.53665485, -0.74853376, --0.01118192, -0.19805430, 0.06130619, -0.09675299, 0.08978480, 0.03405255, -0.00706867, 0.05102045, 0.03250746, 0.01849966, --0.01216314, -0.01184187, -0.01579288, 0.00114807, 0.11376166, 0.88342114, -0.36425379, 0.13863190, 0.12524180, -0.13553892, - 0.04715856, -0.12341103, 0.04531568, 0.01899360, -0.00206897, 0.00567768, -0.01444163, 0.00411946, -0.00855896, 0.00381663, --0.01664861, -0.05534280, 0.21328278, 0.20161162, 0.72360394, 0.59130708, -0.08043791, 0.08757349, -0.13893918, -0.05147377, - 0.02680690, -0.01144070, 0.00625162, -0.00634215, -0.01248947, -0.00329455, -0.00609625, -0.00136305, -0.05097048, -0.01029851, - 0.25065384, -0.16856837, -0.07123372, 0.15992623, -0.39487617, -0.79972301, 0.18118185, -0.04826639, -0.01805578, -0.02927253, --0.16400618, 0.07472763, 0.10376449, 0.01705406, 0.01065801, -0.01500498, 0.02039914, 0.37776349, -0.84484186, 0.10434286, - 0.15616990, 0.13474456, -0.00906238, -0.25238368, -0.03820885, -0.10650905, -0.03880833, -0.03660028, -0.09640894, 0.00583314, - 0.01922097, 0.01489911, -0.02431117, -0.09372217, 0.39404721, -0.84786223, -0.31277121, 0.03193850, 0.01974060, 0.01887901, - 0.00337911, -0.11359599, -0.02792521, -0.03220184, -0.01533311, 0.00015962, -0.04225043, -0.00933965, 0.00675311, 0.00206060, - 0.15926771, 0.40199829, -0.80792558, -0.35591604, -0.17169764, 0.02830436, 0.02459982, -0.03438589, 0.00718705, -0.01798329, --0.01594508, -0.00702430, -0.00952419, -0.00962701, -0.01307212, -0.01749740, 0.01299602, 0.00587270, -0.36103108, -0.82039266, --0.43092844, -0.08500097, -0.04361674, -0.00333482, 0.01250434, -0.02538295, -0.00921797, 0.01645071, -0.01400872, 0.00317607, - 0.00003277, -0.01617646, -0.00616863, -0.00882661, 0.00466157, 0.00353237, 0.91803104, -0.39503305, -0.02048964, 0.00060125, - 0.01980634, 0.00300109, 0.00313880, 0.00657337, 0.00715163, 0.00000261, 0.00854276, -0.00154825, -0.00516128, 0.00909527, - 0.00095609, 0.00701196, -0.00221867, -0.00156741}, -{-0.00469582, -0.00020403, -0.00587134, 0.00185153, -0.02256479, -0.01185761, -0.02891481, -0.00493792, -0.00182344, 0.00285962, - 0.01558059, -0.02185140, 0.04639438, -0.04357142, 0.12718613, -0.06756136, 0.05542227, 0.98480184, -0.00374376, -0.00236433, --0.00607169, -0.00303290, -0.00127243, -0.01794845, 0.00620033, -0.00732704, -0.02837749, -0.00107164, 0.04820548, 0.00713300, - 0.09784244, -0.16806261, -0.04563341, -0.33406041, 0.91554083, -0.08139655, -0.00415851, -0.00538193, -0.00731198, -0.00534534, --0.00623075, -0.02016943, -0.05480133, -0.03172290, -0.03879603, 0.01518441, 0.09591688, 0.02238470, 0.08126640, 0.08236821, --0.24802119, 0.89516402, 0.32029647, 0.07188887, -0.00220366, 0.00344025, -0.00277284, 0.00358963, -0.08668007, -0.02205910, --0.05289669, -0.03535201, -0.01188017, -0.06456872, -0.09321006, -0.00009617, -0.15804070, 0.24632041, 0.90166119, 0.19250690, - 0.17264619, -0.09699155, -0.00567329, -0.00897700, -0.01442565, -0.01939390, 0.03702127, -0.02999862, -0.04385696, -0.05232394, --0.03339177, 0.03905964, -0.00281424, -0.29213275, 0.02892968, 0.90257613, -0.21546058, -0.18070946, 0.09014567, 0.04117230, --0.01029696, -0.00329116, -0.03354346, 0.02937079, 0.01274208, -0.01260649, -0.03505571, -0.01020645, 0.03787209, 0.12132165, --0.20826840, 0.81556933, -0.43874351, 0.21518682, -0.14564290, -0.05210031, 0.07124563, 0.06127983, -0.00457321, 0.01740496, - 0.04185176, 0.00128036, -0.05033693, -0.01890046, 0.06221734, 0.10280078, -0.03738531, 0.04830209, -0.08408293, -0.46409009, --0.83936263, -0.14817619, -0.13135927, 0.04563506, 0.08340661, 0.04040200, 0.00044396, -0.01365972, 0.01228951, 0.01078273, - 0.09205406, -0.03791500, 0.07135889, 0.08158339, 0.06298278, -0.22875755, -0.92917558, -0.11248260, 0.17801883, -0.03971674, --0.07491915, 0.06477287, 0.04635713, 0.01856159, 0.00130895, -0.01991604, 0.02358176, -0.09376056, 0.02782280, -0.04691559, - 0.13749249, 0.31383132, 0.92274602, 0.04727419, 0.09765196, -0.02108945, 0.00626005, 0.05193322, 0.02009133, 0.03094066, - 0.04573470, 0.00451733, 0.00240169, -0.00982355, -0.03546208, -0.14156875, -0.02480689, 0.22997442, 0.09778317, 0.88834235, --0.32797611, -0.00079977, 0.04917079, 0.06977359, 0.06451185, 0.07816204, 0.03119314, 0.01136506, 0.01062006, 0.00632783, - 0.03241828, -0.03318847, -0.01350502, -0.30055361, 0.07265375, 0.17308022, 0.88795796, -0.23231020, -0.08932700, 0.11759604, - 0.00590705, 0.03525351, 0.00840466, 0.04389942, 0.04387629, 0.04003275, 0.01772966, 0.02709780, -0.02393282, 0.02766178, - 0.00342983, -0.33882220, 0.76612668, 0.44061716, -0.28414784, -0.09364014, 0.03694060, 0.01124120, 0.01130268, -0.02869682, --0.07428963, -0.03504754, 0.05874942, 0.01196795, 0.02003875, 0.00787152, -0.01605561, 0.04501257, -0.06959958, -0.13015784, --0.05738065, 0.04681625, 0.06668700, -0.04492094, 0.02927765, -0.94404277, 0.19243952, 0.09504337, -0.12540826, 0.05394317, --0.07972638, -0.02145188, 0.00136427, 0.01964678, 0.06667373, 0.06204535, 0.17302394, 0.22005905, 0.58329964, -0.68440447, - 0.19628796, 0.15718011, -0.12481840, -0.08222507, 0.11780870, 0.03798206, -0.01818866, 0.00892766, 0.05582263, 0.01126832, --0.00973589, 0.00697442, -0.09937902, 0.06621185, -0.19452202, -0.80004569, -0.13946094, -0.48990700, -0.17595191, -0.00798873, --0.06121856, 0.08768040, -0.04507631, 0.00448896, 0.01153941, -0.04711652, -0.01050749, -0.01660047, -0.03007159, -0.01468906, - 0.12848053, 0.13859838, 0.93863771, -0.22250065, -0.14841278, 0.04666032, -0.06344813, -0.01915105, -0.01840150, -0.02389410, --0.01245496, 0.05023402, 0.02125840, 0.02467318, -0.01893022, -0.00889647, 0.00551817, 0.00481915, -0.40626968, -0.89028236, - 0.18261687, -0.03852330, 0.02621926, -0.05420122, -0.01704117, -0.00072893, -0.02694170, -0.04335124, 0.02256467, 0.00642301, --0.01619484, -0.00871160, 0.00400065, -0.00488820, -0.00752173, -0.00170603, 0.89554989, -0.41825934, -0.08725803, -0.09051404, --0.00916236, -0.02959065, -0.07268075, -0.00816626, -0.00314215, -0.01941078, -0.00036782, -0.00188655, -0.02107724, -0.00771657, --0.00448194, -0.00387517, 0.00082998, 0.00202471}, -{ 0.00167296, -0.00647772, -0.00604394, 0.01490810, -0.00837664, 0.00246438, 0.02082153, 0.01216715, 0.01001396, -0.02850860, --0.01187868, -0.00113289, 0.04140237, -0.11084998, 0.16102260, 0.20084170, -0.28969446, -0.91312256, 0.00087788, -0.00136895, - 0.00004622, 0.00578894, 0.00524119, -0.00044550, 0.00948906, -0.00396910, -0.03312197, -0.00075487, 0.00987494, -0.02088734, - 0.09835550, -0.20080342, 0.13687782, -0.16111863, -0.90089988, 0.30312999, 0.00248784, -0.00975419, -0.01617200, 0.00699371, --0.02151635, -0.01625774, -0.01262800, 0.02588781, -0.05620764, -0.13651454, 0.04242442, -0.02615307, 0.20497288, -0.20422909, - 0.14184406, 0.89712919, 0.01758042, 0.25447787, -0.00207668, -0.00260329, 0.00724812, -0.01007749, 0.00806242, -0.03089729, --0.01161934, -0.00618676, -0.10327342, -0.10160272, 0.11919283, 0.20781533, 0.11564869, -0.19072476, 0.86402008, -0.24650846, - 0.24684161, 0.04775750, 0.00486888, -0.01735569, -0.01868000, -0.01870386, -0.03243262, -0.05883701, -0.03433371, 0.10441236, --0.22831067, -0.22837988, 0.15082544, -0.21313767, 0.13215611, -0.78096079, -0.32270595, -0.21307018, 0.17339271, -0.05435742, --0.00940813, 0.00272520, 0.00542917, -0.05232991, -0.01280809, -0.10773627, -0.17626479, 0.03719285, -0.26297104, -0.21780618, - 0.21406665, 0.15202177, 0.75911044, 0.38627481, -0.16504189, -0.10242997, -0.02394939, -0.06018959, 0.00994733, -0.02617197, --0.01543723, -0.10320051, -0.03010481, -0.19098072, -0.06893233, 0.12253174, -0.25556092, -0.31989059, 0.09542655, 0.72712041, --0.43108921, -0.01568072, -0.16532685, 0.06646835, -0.08885408, -0.00050364, -0.01791050, 0.00245405, 0.00204794, -0.17948691, --0.05193881, -0.16329387, -0.13676259, 0.01214133, -0.30994612, -0.00687734, 0.63254090, -0.47180795, -0.35409214, 0.23658315, - 0.11170294, 0.05229887, -0.06107035, -0.01094212, 0.01523854, -0.01608284, -0.03739206, -0.23864328, -0.03958494, -0.19305719, --0.26019058, 0.24108257, -0.55933566, 0.40623396, -0.53367968, -0.08930957, -0.00599383, -0.00050845, 0.06960811, 0.02664961, - 0.01464197, -0.00486781, -0.01905736, 0.01437578, 0.02379930, -0.26639588, 0.05208876, -0.43525002, -0.63009424, 0.05251889, - 0.56732782, -0.06731164, -0.03705909, -0.03253946, 0.00950673, -0.07941760, 0.02388267, -0.01258409, -0.00343524, 0.00148711, --0.00362107, 0.03981813, -0.07235214, -0.46180041, -0.05595288, -0.55699317, 0.61935853, -0.25379716, 0.06796783, 0.01039267, --0.06329171, -0.02143024, 0.09406929, -0.00799203, -0.01419805, -0.00603024, 0.01313145, 0.00091161, -0.00212107, -0.02405340, - 0.07146405, -0.76695326, -0.14841817, 0.60372663, -0.01478424, 0.06522462, 0.08580016, -0.05817981, 0.02438942, 0.04840904, - 0.02934363, -0.02239678, -0.00582247, -0.00091312, -0.00394148, -0.00285276, -0.03435745, 0.05277435, 0.17882781, -0.06194164, - 0.27321118, 0.01840179, -0.10188148, -0.33168524, -0.03491221, 0.67351789, 0.37017376, 0.32083717, 0.09737800, -0.20998084, --0.10725041, 0.06379186, 0.02169903, -0.02031584, 0.05623799, -0.18300962, -0.17337803, 0.08915172, -0.53835537, -0.08547263, - 0.15163321, 0.56732906, 0.21878115, 0.37274266, 0.26206918, 0.13443927, 0.09178695, -0.03276324, -0.01131664, -0.00236369, - 0.00772568, 0.01008805, -0.17122615, 0.15301569, 0.40135484, -0.06058913, 0.56405128, -0.05176853, 0.24544337, 0.62448073, - 0.07265009, -0.01198695, 0.05151774, -0.03678498, 0.01886154, 0.03724094, 0.01393667, 0.00758055, -0.00254297, 0.00537118, - 0.24169707, -0.41735970, -0.67564355, -0.09270478, 0.53106033, 0.06214579, 0.02574404, 0.09943837, 0.03032542, 0.02194476, - 0.06369772, -0.00133741, 0.01301113, 0.01508494, 0.00036111, -0.00278870, 0.00139205, 0.00015792, -0.43347887, 0.69923146, --0.55406563, -0.01102231, 0.01347767, 0.07012139, -0.02530164, 0.06803192, 0.01177196, 0.04374491, 0.04073027, 0.04037438, - 0.00167330, -0.01807065, -0.00425562, 0.00149653, -0.00035119, -0.00172888, 0.84785495, 0.52289580, 0.01067734, -0.00859194, - 0.01685964, 0.00481442, 0.00434738, 0.07592695, 0.01419942, 0.01005336, 0.03316937, 0.00360465, 0.00435039, 0.00029122, - 0.00171268, 0.00198919, -0.00046889, -0.00094176}}; - -/* right KLT transforms */ -const double WebRtcIsac_kKltT2Gain[3][36] = { -{ 0.14572837, -0.45446306, 0.61990621, -0.52197033, 0.32145074, -0.11026900, -0.20698282, 0.48962182, -0.27127933, -0.33627476, - 0.65094037, -0.32715751, 0.40262573, -0.47844405, -0.33876075, 0.44130653, 0.37383966, -0.39964662, -0.51730480, 0.06611973, - 0.49030187, 0.47512886, -0.02141226, -0.51129451, -0.58578569, -0.39132064, -0.13187771, 0.15649421, 0.40735596, 0.54396897, - 0.40381276, 0.40904942, 0.41179766, 0.41167576, 0.40840251, 0.40468132}, -{-0.11368135, 0.34815515, -0.56434996, 0.61130763, -0.39970336, 0.11795708, 0.28514257, -0.58879243, 0.32775812, 0.27024886, --0.56251299, 0.27411037, 0.42649186, -0.44080232, -0.36408215, 0.35932457, 0.43592895, -0.41484213, -0.49813030, -0.00012592, - 0.49865688, 0.47634953, 0.01094246, -0.52552726, -0.56154082, -0.41110686, -0.14170764, 0.15946614, 0.40818082, 0.55094554, - 0.40051601, 0.41084781, 0.41567800, 0.41450700, 0.40871872, 0.39891823}, -{-0.10719481, 0.34796287, -0.54573957, 0.59521001, -0.43943367, 0.14907223, 0.26554957, -0.59549939, 0.36760692, 0.26040652, --0.55268701, 0.25778784, 0.38994096, -0.45282773, -0.37975656, 0.40213055, 0.43052647, -0.38937904, -0.52698359, 0.02788094, - 0.48284286, 0.47792474, 0.02557759, -0.50922240, -0.57699826, -0.39476779, -0.14708238, 0.12742149, 0.37835245, 0.57464021, - 0.39408127, 0.40327462, 0.40993655, 0.41419345, 0.41506301, 0.41253853}}; - -const double WebRtcIsac_kKltT2Shape[3][36] = { -{ 0.13427386, -0.35132558, 0.52506528, -0.59419077, 0.45075085, -0.16312057, 0.29857439, -0.58660147, 0.34265431, 0.20879510, --0.56063262, 0.30238345, 0.43308283, -0.41186999, -0.35288681, 0.42768996, 0.36094634, -0.45284910, -0.47116680, 0.02893449, - 0.54326135, 0.45249040, -0.06264420, -0.52283830, 0.57137758, 0.44298139, 0.12617554, -0.20819946, -0.42324603, -0.48876443, - 0.39597050, 0.40713935, 0.41389880, 0.41512486, 0.41130400, 0.40575001}, -{ 0.16540737, -0.43379435, 0.58165221, -0.55154773, 0.35734028, -0.11935912, 0.29434254, -0.55954817, 0.23549804, 0.33087258, --0.58848503, 0.29835834, 0.45464789, -0.38316155, -0.41689708, 0.35607296, 0.41260747, -0.41910198, -0.48633899, -0.04144955, - 0.47824583, 0.51050942, 0.01000345, -0.52184032, 0.53488229, 0.42641051, 0.17049774, -0.15849613, -0.43229355, -0.53945045, - 0.39582002, 0.41033103, 0.41788713, 0.41688080, 0.41081697, 0.39719658}, -{ 0.13386268, -0.37919915, 0.54989123, -0.57663572, 0.42402636, -0.15362720, 0.29641577, -0.58806770, 0.31381040, 0.26524954, --0.56271012, 0.28431868, 0.42699898, -0.41058922, -0.40408270, 0.39215865, 0.40788513, -0.40699735, -0.49846482, -0.01521208, - 0.48756040, 0.49479418, -0.00347672, -0.51841384, 0.55513106, 0.41683793, 0.15131217, -0.15613621, -0.41029341, -0.54996461, - 0.39402116, 0.40965305, 0.41862791, 0.41730770, 0.41089648, 0.39837262}}; - -/* means of log gains and LAR coefficients*/ -const double WebRtcIsac_kLpcMeansGain[3][12] = { -{-6.86881911, -5.35075273, -6.86792680, -5.36200897, -6.86401538, -5.36921533, -6.86802969, -5.36893966, -6.86538097, -5.36315063, --6.85535304, -5.35155315}, -{-6.12914600, -4.78070092, -6.12971780, -4.78382183, -6.12858525, -4.79362198, -6.12926491, -4.79017481, -6.12102401, -4.78346122, --6.11441152, -4.78019228}, -{-5.67273484, -3.73876311, -5.65246094, -3.71407895, -5.61716443, -3.68814580, -5.58804560, -3.66334094, -5.54189577, -3.63845640, --5.49293185, -3.61760203}}; - -const double WebRtcIsac_kLpcMeansShape[3][108] = { -{-0.91232981, 0.26258634, -0.33716701, 0.08477430, -0.03378426, 0.14423909, 0.07036185, 0.06155019, 0.01490385, 0.04138740, - 0.01427317, 0.01288970, 0.83872106, 0.25750199, 0.07988929, -0.01957923, 0.00831390, 0.01770300, -0.90957164, 0.25732216, --0.33385344, 0.08735740, -0.03715332, 0.14584917, 0.06998990, 0.06131968, 0.01504379, 0.04067339, 0.01428039, 0.01406460, - 0.83846243, 0.26169862, 0.08109025, -0.01767055, 0.00970539, 0.01954310, -0.90490803, 0.24656405, -0.33578607, 0.08843286, --0.03749139, 0.14443959, 0.07214669, 0.06170993, 0.01449947, 0.04134309, 0.01314762, 0.01413471, 0.83895203, 0.26748062, - 0.08197507, -0.01781298, 0.00885967, 0.01922394, -0.90922472, 0.24495889, -0.33921540, 0.08877169, -0.03581332, 0.14199172, - 0.07444032, 0.06185940, 0.01502054, 0.04185113, 0.01276579, 0.01355457, 0.83645358, 0.26631720, 0.08119697, -0.01835449, - 0.00788512, 0.01846446, -0.90482253, 0.24658310, -0.34019734, 0.08281090, -0.03486038, 0.14359248, 0.07401336, 0.06001471, - 0.01528421, 0.04254560, 0.01321472, 0.01240799, 0.83857127, 0.26281654, 0.08174380, -0.02099842, 0.00755176, 0.01699448, --0.90132307, 0.25174308, -0.33838268, 0.07883863, -0.02877906, 0.14105407, 0.07220290, 0.06000352, 0.01684879, 0.04226844, - 0.01331331, 0.01269244, 0.83832138, 0.25467485, 0.08118028, -0.02120528, 0.00747832, 0.01567212}, -{-1.11639718, 0.35377266, 0.00798929, 0.20165280, 0.07656104, 0.10629964, 0.04894160, 0.10955305, -0.01806405, 0.05082282, - 0.01730794, 0.01345957, 0.73717782, 0.05952284, 0.03176204, 0.08195122, 0.01253148, 0.02253385, -1.12053537, 0.35523538, - 0.00859646, 0.20007706, 0.07715852, 0.10754596, 0.05165976, 0.10927703, -0.01554395, 0.05178866, 0.01752534, 0.01343468, - 0.73489046, 0.06395167, 0.03287798, 0.07972374, 0.01293550, 0.02300929, -1.11772179, 0.35457623, 0.01205524, 0.19926481, - 0.08000866, 0.10817921, 0.05052481, 0.11016167, -0.01552091, 0.05155510, 0.01787163, 0.01343778, 0.73142568, 0.06840830, - 0.03316828, 0.07902608, 0.01525042, 0.02178127, -1.12120164, 0.36405233, 0.00630305, 0.19799738, 0.07829690, 0.10727588, - 0.04017317, 0.10437949, -0.01844109, 0.05021700, 0.01561726, 0.01226571, 0.73438044, 0.06947982, 0.03396317, 0.07858683, - 0.01367105, 0.02041955, -1.12146187, 0.35952226, 0.00340090, 0.19700813, 0.07938222, 0.10904137, 0.03921216, 0.10531403, --0.01833415, 0.04956231, 0.01399539, 0.01323582, 0.74378099, 0.07059589, 0.03367692, 0.08151462, 0.01182040, 0.02075577, --1.11245254, 0.35234230, 0.00687490, 0.20204252, 0.07813186, 0.11081259, 0.04634665, 0.11073238, -0.01637954, 0.05104577, - 0.01675122, 0.01448696, 0.74013627, 0.06239059, 0.03129412, 0.08207461, 0.01249475, 0.02189238}, -{-1.27118948, 0.35834331, -0.33499347, 0.13524073, 0.04829079, 0.19542773, 0.05273835, 0.04157974, -0.01755227, 0.01513442, - 0.00386630, 0.02199463, 1.14439142, 0.21903073, 0.14750213, 0.12743356, 0.08463334, 0.06839691, -1.28367777, 0.35556287, --0.33809405, 0.13627881, 0.04939309, 0.19642571, 0.05354373, 0.04099247, -0.01787481, 0.01472425, 0.00391474, 0.02150716, - 1.14739079, 0.21840872, 0.14643624, 0.12724347, 0.08390642, 0.06811938, -1.29007667, 0.35159558, -0.34154267, 0.13295849, - 0.04883602, 0.19587595, 0.05452759, 0.04174703, -0.01782110, 0.01388270, 0.00374754, 0.02138105, 1.14333767, 0.21690116, - 0.14544599, 0.12606728, 0.08314168, 0.06771389, -1.29856471, 0.35239315, -0.34238732, 0.13277553, 0.04722712, 0.19233156, - 0.05366901, 0.04328110, -0.01657749, 0.01444736, 0.00438108, 0.02102563, 1.13548397, 0.21537812, 0.14357377, 0.12525845, - 0.08230994, 0.06722511, -1.30663540, 0.34366563, -0.34205544, 0.12861679, 0.04655851, 0.18864359, 0.05351285, 0.04358693, --0.01604498, 0.01431907, 0.00395326, 0.02082299, 1.12207794, 0.21167325, 0.14212491, 0.12418671, 0.08155467, 0.06639789, --1.31011673, 0.33686271, -0.34379843, 0.12169569, 0.04480323, 0.18637557, 0.05374078, 0.04260827, -0.01588226, 0.01378294, - 0.00396009, 0.02112406, 1.10466984, 0.20905894, 0.14107033, 0.12303074, 0.08047136, 0.06588031}}; - diff --git a/src/mod/codecs/mod_isac/lpc_tables.h b/src/mod/codecs/mod_isac/lpc_tables.h deleted file mode 100644 index 604d963c37..0000000000 --- a/src/mod/codecs/mod_isac/lpc_tables.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * lpc_tables.h - * - * header file for coding tables for the LPC coefficients - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_ - -#include "structs.h" - -#include "settings.h" - -#define KLT_STEPSIZE 1.00000000 -#define KLT_NUM_AVG_GAIN 0 -#define KLT_NUM_AVG_SHAPE 0 -#define KLT_NUM_MODELS 3 -#define LPC_GAIN_SCALE 4.000f -#define LPC_LOBAND_SCALE 2.100f -#define LPC_LOBAND_ORDER ORDERLO -#define LPC_HIBAND_SCALE 0.450f -#define LPC_HIBAND_ORDER ORDERHI -#define LPC_GAIN_ORDER 2 - -#define LPC_SHAPE_ORDER (LPC_LOBAND_ORDER + LPC_HIBAND_ORDER) - -#define KLT_ORDER_GAIN (LPC_GAIN_ORDER * SUBFRAMES) -#define KLT_ORDER_SHAPE (LPC_SHAPE_ORDER * SUBFRAMES) -/* indices of KLT coefficients used */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltSelIndGain[12]; - -extern const WebRtc_UWord16 WebRtcIsac_kQKltSelIndShape[108]; - -/* cdf array for model indicator */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltModelCdf[KLT_NUM_MODELS+1]; - -/* pointer to cdf array for model indicator */ -extern const WebRtc_UWord16 *WebRtcIsac_kQKltModelCdfPtr[1]; - -/* initial cdf index for decoder of model indicator */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltModelInitIndex[1]; - -/* offset to go from rounded value to quantization index */ -extern const short WebRtcIsac_kQKltQuantMinGain[12]; - -extern const short WebRtcIsac_kQKltQuantMinShape[108]; - -/* maximum quantization index */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltMaxIndGain[12]; - -extern const WebRtc_UWord16 WebRtcIsac_kQKltMaxIndShape[108]; - -/* index offset */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltOffsetGain[KLT_NUM_MODELS][12]; - -extern const WebRtc_UWord16 WebRtcIsac_kQKltOffsetShape[KLT_NUM_MODELS][108]; - -/* initial cdf index for KLT coefficients */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltInitIndexGain[KLT_NUM_MODELS][12]; - -extern const WebRtc_UWord16 WebRtcIsac_kQKltInitIndexShape[KLT_NUM_MODELS][108]; - -/* offsets for quantizer representation levels */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltOfLevelsGain[3]; - -extern const WebRtc_UWord16 WebRtcIsac_kQKltOfLevelsShape[3]; - -/* quantizer representation levels */ -extern const double WebRtcIsac_kQKltLevelsGain[1176]; - -extern const double WebRtcIsac_kQKltLevelsShape[1735]; - -/* cdf tables for quantizer indices */ -extern const WebRtc_UWord16 WebRtcIsac_kQKltCdfGain[1212]; - -extern const WebRtc_UWord16 WebRtcIsac_kQKltCdfShape[2059]; - -/* pointers to cdf tables for quantizer indices */ -extern const WebRtc_UWord16 *WebRtcIsac_kQKltCdfPtrGain[KLT_NUM_MODELS][12]; - -extern const WebRtc_UWord16 *WebRtcIsac_kQKltCdfPtrShape[KLT_NUM_MODELS][108]; - -/* code length for all coefficients using different models */ -extern const double WebRtcIsac_kQKltCodeLenGain[392]; - -extern const double WebRtcIsac_kQKltCodeLenShape[578]; - -/* left KLT transforms */ -extern const double WebRtcIsac_kKltT1Gain[KLT_NUM_MODELS][4]; - -extern const double WebRtcIsac_kKltT1Shape[KLT_NUM_MODELS][324]; - -/* right KLT transforms */ -extern const double WebRtcIsac_kKltT2Gain[KLT_NUM_MODELS][36]; - -extern const double WebRtcIsac_kKltT2Shape[KLT_NUM_MODELS][36]; - -/* means of log gains and LAR coefficients */ -extern const double WebRtcIsac_kLpcMeansGain[KLT_NUM_MODELS][12]; - -extern const double WebRtcIsac_kLpcMeansShape[KLT_NUM_MODELS][108]; - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_ */ diff --git a/src/mod/codecs/mod_isac/lpc_to_refl_coef.c b/src/mod/codecs/mod_isac/lpc_to_refl_coef.c deleted file mode 100644 index 2cb83c2e1d..0000000000 --- a/src/mod/codecs/mod_isac/lpc_to_refl_coef.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_LpcToReflCoef(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER 50 - -void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* a16, int use_order, WebRtc_Word16* k16) -{ - int m, k; - WebRtc_Word32 tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER]; - WebRtc_Word32 tmp_inv_denom32; - WebRtc_Word16 tmp_inv_denom16; - - k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15 - for (m = use_order - 1; m > 0; m--) - { - // (1 - k^2) in Q30 - tmp_inv_denom32 = ((WebRtc_Word32)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); - // (1 - k^2) in Q15 - tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15); - - for (k = 1; k <= m; k++) - { - // tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]); - - // [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28 - tmp32[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16) - - WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1); - - tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13 - } - - for (k = 1; k < m; k++) - { - a16[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12 - } - - tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191); - k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15 - } - return; -} diff --git a/src/mod/codecs/mod_isac/min_max_operations.c b/src/mod/codecs/mod_isac/min_max_operations.c deleted file mode 100644 index 57eaff7b71..0000000000 --- a/src/mod/codecs/mod_isac/min_max_operations.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file contains the implementation of functions - * WebRtcSpl_MaxAbsValueW16() - * WebRtcSpl_MaxAbsIndexW16() - * WebRtcSpl_MaxAbsValueW32() - * WebRtcSpl_MaxValueW16() - * WebRtcSpl_MaxIndexW16() - * WebRtcSpl_MaxValueW32() - * WebRtcSpl_MaxIndexW32() - * WebRtcSpl_MinValueW16() - * WebRtcSpl_MinIndexW16() - * WebRtcSpl_MinValueW32() - * WebRtcSpl_MinIndexW32() - * - * The description header can be found in signal_processing_library.h. - * - */ - -#include "signal_processing_library.h" - -#if !(defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON)) - -// Maximum absolute value of word16 vector. -WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMax = 0; - WebRtc_Word32 absVal; - WebRtc_Word16 totMax; - int i; - G_CONST WebRtc_Word16 *tmpvector = vector; - - for (i = 0; i < length; i++) - { - absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); - if (absVal > tempMax) - { - tempMax = absVal; - } - tmpvector++; - } - totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX); - return totMax; -} - -#endif - -// Index of maximum absolute value in a word16 vector. -WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMax; - WebRtc_Word16 absTemp; - WebRtc_Word16 tempMaxIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word16 *tmpvector = vector; - - tempMax = WEBRTC_SPL_ABS_W16(*tmpvector); - tmpvector++; - for (i = 1; i < length; i++) - { - absTemp = WEBRTC_SPL_ABS_W16(*tmpvector); - tmpvector++; - if (absTemp > tempMax) - { - tempMax = absTemp; - tempMaxIndex = i; - } - } - return tempMaxIndex; -} - -// Maximum absolute value of word32 vector. -WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtc_UWord32 tempMax = 0; - WebRtc_UWord32 absVal; - WebRtc_Word32 retval; - int i; - G_CONST WebRtc_Word32 *tmpvector = vector; - - for (i = 0; i < length; i++) - { - absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); - if (absVal > tempMax) - { - tempMax = absVal; - } - tmpvector++; - } - retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX)); - return retval; -} - -// Maximum value of word16 vector. -#ifndef XSCALE_OPT -WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMax; - WebRtc_Word16 i; - G_CONST WebRtc_Word16 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - tempMax = vector[i]; - } - return tempMax; -} -#else -#pragma message(">> WebRtcSpl_MaxValueW16 is excluded from this build") -#endif - -// Index of maximum value in a word16 vector. -WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMax; - WebRtc_Word16 tempMaxIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word16 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - { - tempMax = vector[i]; - tempMaxIndex = i; - } - } - return tempMaxIndex; -} - -// Maximum value of word32 vector. -#ifndef XSCALE_OPT -WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMax; - WebRtc_Word16 i; - G_CONST WebRtc_Word32 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - tempMax = vector[i]; - } - return tempMax; -} -#else -#pragma message(">> WebRtcSpl_MaxValueW32 is excluded from this build") -#endif - -// Index of maximum value in a word32 vector. -WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMax; - WebRtc_Word16 tempMaxIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word32 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - { - tempMax = vector[i]; - tempMaxIndex = i; - } - } - return tempMaxIndex; -} - -// Minimum value of word16 vector. -WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMin; - WebRtc_Word16 i; - G_CONST WebRtc_Word16 *tmpvector = vector; - - // Find the minimum value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - tempMin = (vector[i]); - } - return tempMin; -} - -// Index of minimum value in a word16 vector. -#ifndef XSCALE_OPT -WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMin; - WebRtc_Word16 tempMinIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word16* tmpvector = vector; - - // Find index of smallest value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - { - tempMin = vector[i]; - tempMinIndex = i; - } - } - return tempMinIndex; -} -#else -#pragma message(">> WebRtcSpl_MinIndexW16 is excluded from this build") -#endif - -// Minimum value of word32 vector. -WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMin; - WebRtc_Word16 i; - G_CONST WebRtc_Word32 *tmpvector = vector; - - // Find the minimum value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - tempMin = (vector[i]); - } - return tempMin; -} - -// Index of minimum value in a word32 vector. -#ifndef XSCALE_OPT -WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMin; - WebRtc_Word16 tempMinIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word32 *tmpvector = vector; - - // Find index of smallest value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - { - tempMin = vector[i]; - tempMinIndex = i; - } - } - return tempMinIndex; -} -#else -#pragma message(">> WebRtcSpl_MinIndexW32 is excluded from this build") -#endif diff --git a/src/mod/codecs/mod_isac/min_max_operations_neon.c b/src/mod/codecs/mod_isac/min_max_operations_neon.c deleted file mode 100644 index 158bcc1837..0000000000 --- a/src/mod/codecs/mod_isac/min_max_operations_neon.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if (defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON)) - -#include - -#include "signal_processing_library.h" - -// Maximum absolute value of word16 vector. -WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16* vector, - WebRtc_Word16 length) { - WebRtc_Word32 temp_max = 0; - WebRtc_Word32 abs_val; - WebRtc_Word16 tot_max; - int i; - - __asm__("vmov.i16 d25, #0" : : : "d25"); - - for (i = 0; i < length - 7; i += 8) { - __asm__("vld1.16 {d26, d27}, [%0]" : : "r"(&vector[i]) : "q13"); - __asm__("vabs.s16 q13, q13" : : : "q13"); - __asm__("vpmax.s16 d26, d27" : : : "q13"); - __asm__("vpmax.s16 d25, d26" : : : "d25", "d26"); - } - __asm__("vpmax.s16 d25, d25" : : : "d25"); - __asm__("vpmax.s16 d25, d25" : : : "d25"); - __asm__("vmov.s16 %0, d25[0]" : "=r"(temp_max): : "d25"); - - for (; i < length; i++) { - abs_val = WEBRTC_SPL_ABS_W32((vector[i])); - if (abs_val > temp_max) { - temp_max = abs_val; - } - } - tot_max = (WebRtc_Word16)WEBRTC_SPL_MIN(temp_max, WEBRTC_SPL_WORD16_MAX); - return tot_max; -} - -#endif diff --git a/src/mod/codecs/mod_isac/mod_iSAC.2017.vcxproj b/src/mod/codecs/mod_isac/mod_iSAC.2017.vcxproj deleted file mode 100644 index 7014223742..0000000000 --- a/src/mod/codecs/mod_isac/mod_iSAC.2017.vcxproj +++ /dev/null @@ -1,254 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_iSAC - {7F1610F1-DD5A-4CF7-8610-30AB12C60ADD} - mod_iSAC - Win32Proj - - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - NativeMinimumRules.ruleset - false - - - NativeMinimumRules.ruleset - false - - - NativeMinimumRules.ruleset - false - - - NativeMinimumRules.ruleset - false - - - - - - _CRT_SECURE_NO_WARNINGS;_DEBUG;DEBUG;%(PreprocessorDefinitions) - 4206;4100;4244;6340;6246;6011;6387;%(DisableSpecificWarnings) - false - - - false - - - - - - - X64 - - - - - _CRT_SECURE_NO_WARNINGS;_DEBUG;DEBUG;%(PreprocessorDefinitions) - 4206;4100;4244;6340;6246;6011;6387;%(DisableSpecificWarnings) - false - - - false - - - MachineX64 - - - - - - - _CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) - 4206;4100;4244;6340;6246;6011;6387;%(DisableSpecificWarnings) - false - - - false - - - - - - - X64 - - - - - _CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) - 4206;4100;4244;6340;6246;6011;6387;%(DisableSpecificWarnings) - false - - - false - - - MachineX64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/mod/codecs/mod_isac/mod_isac.c b/src/mod/codecs/mod_isac/mod_isac.c deleted file mode 100644 index 5746e62aa7..0000000000 --- a/src/mod/codecs/mod_isac/mod_isac.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / ISAC codec module - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Anthony Minessale II - * - * - * mod_isac.c -- isac Codec Module - * - */ - -#include -#include "isac.h" - -SWITCH_MODULE_LOAD_FUNCTION(mod_isac_codec_load); -SWITCH_MODULE_DEFINITION(mod_isac, mod_isac_codec_load, NULL, NULL); - -struct isac_context { - ISACStruct *ISAC_main_inst; -}; - -static switch_status_t switch_isac_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - uint32_t encoding, decoding; - WebRtc_Word16 err; - struct isac_context *context = NULL; - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - if (!(encoding || decoding)) { - return SWITCH_STATUS_FALSE; - } - - if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) { - return SWITCH_STATUS_FALSE; - } - - codec->private_info = context; - - err = WebRtcIsac_Create(&context->ISAC_main_inst); - - if (err < 0) return SWITCH_STATUS_FALSE; - - - if (encoding) { - if (WebRtcIsac_EncoderInit(context->ISAC_main_inst, 0) < 0) { - return SWITCH_STATUS_FALSE; - } - WebRtcIsac_SetEncSampRate(context->ISAC_main_inst, codec->implementation->actual_samples_per_second / 1000); - } - - if (decoding) { - if (WebRtcIsac_DecoderInit(context->ISAC_main_inst) < 0) { - return SWITCH_STATUS_FALSE; - } - WebRtcIsac_SetDecSampRate(context->ISAC_main_inst, codec->implementation->actual_samples_per_second / 1000); - } - - if (codec->implementation->actual_samples_per_second == 16000) { - if (WebRtcIsac_ControlBwe(context->ISAC_main_inst, 32000, codec->implementation->microseconds_per_packet / 1000, 1) < 0) { - return SWITCH_STATUS_FALSE; - } - - if (WebRtcIsac_SetMaxPayloadSize(context->ISAC_main_inst, 400) < 0) { - return SWITCH_STATUS_FALSE; - } - - } else { - if (WebRtcIsac_Control(context->ISAC_main_inst, 32000, codec->implementation->microseconds_per_packet / 1000) < 0) { - return SWITCH_STATUS_FALSE; - } - - if (WebRtcIsac_SetMaxPayloadSize(context->ISAC_main_inst, 600) < 0) { - return SWITCH_STATUS_FALSE; - } - } - - - - if (WebRtcIsac_SetMaxRate(context->ISAC_main_inst, codec->implementation->bits_per_second) < 0) { - return SWITCH_STATUS_FALSE; - } - - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_isac_encode(switch_codec_t *codec, switch_codec_t *other_codec, - void *decoded_data, - uint32_t decoded_data_len, - uint32_t decoded_rate, - void *encoded_data, - uint32_t *encoded_data_len, - uint32_t *encoded_rate, - unsigned int *flag) -{ - struct isac_context *context = codec->private_info; - WebRtc_Word16 len = 0, *in, *out; - int rise = (codec->implementation->actual_samples_per_second / 100); - - in = decoded_data; - out = encoded_data; - - while(len == 0) { - len = WebRtcIsac_Encode(context->ISAC_main_inst, in, out); - in += rise; - } - - if (len < 0) { - return SWITCH_STATUS_GENERR; - } - - *encoded_data_len = (uint32_t) len; - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_isac_decode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *encoded_data, - uint32_t encoded_data_len, - uint32_t encoded_rate, - void *decoded_data, - uint32_t *decoded_data_len, - uint32_t *decoded_rate, - unsigned int *flag) -{ - struct isac_context *context = codec->private_info; - WebRtc_Word16 len, speechType[1]; - - if ((*flag & SFF_PLC)) { - len = WebRtcIsac_DecodePlc(context->ISAC_main_inst, decoded_data, 1); - } else { - len = WebRtcIsac_Decode(context->ISAC_main_inst, encoded_data, encoded_data_len, decoded_data, speechType); - } - - if (len < 0) { - *decoded_data_len = 0; - return SWITCH_STATUS_GENERR; - } - - *decoded_data_len = (uint32_t) len * 2; - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_isac_destroy(switch_codec_t *codec) -{ - struct isac_context *context = codec->private_info; - - WebRtcIsac_Free(context->ISAC_main_inst); - - return SWITCH_STATUS_SUCCESS; -} - - -SWITCH_MODULE_LOAD_FUNCTION(mod_isac_codec_load) -{ - switch_codec_interface_t *codec_interface; - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_CODEC(codec_interface, "isac"); /* 8.0kbit */ - - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_AUDIO, - 99, - "isac", - "ibitrate=32000;maxbitrate=53400", - 16000, - 16000, - 53400, - 30000, - 480, - 960, - 0, - 1, - 3, - switch_isac_init, - switch_isac_encode, - switch_isac_decode, - switch_isac_destroy); - - - - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_AUDIO, - 99, - "isac", - "ibitrate=32000;maxbitrate=53400", - 16000, - 16000, - 53400, - 60000, - 960, - 1920, - 0, - 1, - 6, - switch_isac_init, - switch_isac_encode, - switch_isac_decode, - switch_isac_destroy); - - - - - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_AUDIO, - 99, - "isac", - "ibitrate=32000;maxbitrate=160000", - 32000, - 32000, - 160000, - 30000, - 960, - 1920, - 0, - 1, - 6, - switch_isac_init, - switch_isac_encode, - switch_isac_decode, - switch_isac_destroy); - - - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_AUDIO, - 99, - "isac", - "ibitrate=32000;maxbitrate=160000", - 32000, - 32000, - 160000, - 60000, - 1920, - 3840, - 0, - 1, - 6, - switch_isac_init, - switch_isac_encode, - switch_isac_decode, - switch_isac_destroy); - - - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/codecs/mod_isac/os_specific_inline.h b/src/mod/codecs/mod_isac/os_specific_inline.h deleted file mode 100644 index c469c2ec9c..0000000000 --- a/src/mod/codecs/mod_isac/os_specific_inline.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_ - -#include -#include "typedefs.h" - -// TODO(turaj): switch to WEBRTC_POSIX when available -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) -#define WebRtcIsac_lrint lrint -#elif (defined(WEBRTC_ARCH_X86) && defined(WIN32)) -static __inline long int WebRtcIsac_lrint(double x_dbl) { - long int x_int; - - __asm { - fld x_dbl - fistp x_int - }; - - return x_int; -} -#else // Do a slow but correct implementation of lrint - -static __inline long int WebRtcIsac_lrint(double x_dbl) { - long int x_int; - x_int = (long int)floor(x_dbl + 0.499999999999); - return x_int; -} - -#endif - -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_ diff --git a/src/mod/codecs/mod_isac/pitch_estimator.c b/src/mod/codecs/mod_isac/pitch_estimator.c deleted file mode 100644 index 75525f69d4..0000000000 --- a/src/mod/codecs/mod_isac/pitch_estimator.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pitch_estimator.h" - -#include -#include -#ifdef WEBRTC_ANDROID -#include -#endif - -static const double kInterpolWin[8] = {-0.00067556028640, 0.02184247643159, -0.12203175715679, 0.60086484101160, - 0.60086484101160, -0.12203175715679, 0.02184247643159, -0.00067556028640}; - -/* interpolation filter */ -__inline static void IntrepolFilter(double *data_ptr, double *intrp) -{ - *intrp = kInterpolWin[0] * data_ptr[-3]; - *intrp += kInterpolWin[1] * data_ptr[-2]; - *intrp += kInterpolWin[2] * data_ptr[-1]; - *intrp += kInterpolWin[3] * data_ptr[0]; - *intrp += kInterpolWin[4] * data_ptr[1]; - *intrp += kInterpolWin[5] * data_ptr[2]; - *intrp += kInterpolWin[6] * data_ptr[3]; - *intrp += kInterpolWin[7] * data_ptr[4]; -} - - -/* 2D parabolic interpolation */ -/* probably some 0.5 factors can be eliminated, and the square-roots can be removed from the Cholesky fact. */ -__inline static void Intrpol2D(double T[3][3], double *x, double *y, double *peak_val) -{ - double c, b[2], A[2][2]; - double t1, t2, d; - double delta1, delta2; - - - // double T[3][3] = {{-1.25, -.25,-.25}, {-.25, .75, .75}, {-.25, .75, .75}}; - // should result in: delta1 = 0.5; delta2 = 0.0; peak_val = 1.0 - - c = T[1][1]; - b[0] = 0.5 * (T[1][2] + T[2][1] - T[0][1] - T[1][0]); - b[1] = 0.5 * (T[1][0] + T[2][1] - T[0][1] - T[1][2]); - A[0][1] = -0.5 * (T[0][1] + T[2][1] - T[1][0] - T[1][2]); - t1 = 0.5 * (T[0][0] + T[2][2]) - c; - t2 = 0.5 * (T[2][0] + T[0][2]) - c; - d = (T[0][1] + T[1][2] + T[1][0] + T[2][1]) - 4.0 * c - t1 - t2; - A[0][0] = -t1 - 0.5 * d; - A[1][1] = -t2 - 0.5 * d; - - /* deal with singularities or ill-conditioned cases */ - if ( (A[0][0] < 1e-7) || ((A[0][0] * A[1][1] - A[0][1] * A[0][1]) < 1e-7) ) { - *peak_val = T[1][1]; - return; - } - - /* Cholesky decomposition: replace A by upper-triangular factor */ - A[0][0] = sqrt(A[0][0]); - A[0][1] = A[0][1] / A[0][0]; - A[1][1] = sqrt(A[1][1] - A[0][1] * A[0][1]); - - /* compute [x; y] = -0.5 * inv(A) * b */ - t1 = b[0] / A[0][0]; - t2 = (b[1] - t1 * A[0][1]) / A[1][1]; - delta2 = t2 / A[1][1]; - delta1 = 0.5 * (t1 - delta2 * A[0][1]) / A[0][0]; - delta2 *= 0.5; - - /* limit norm */ - t1 = delta1 * delta1 + delta2 * delta2; - if (t1 > 1.0) { - delta1 /= t1; - delta2 /= t1; - } - - *peak_val = 0.5 * (b[0] * delta1 + b[1] * delta2) + c; - - *x += delta1; - *y += delta2; -} - - -static void PCorr(const double *in, double *outcorr) -{ - double sum, ysum, prod; - const double *x, *inptr; - int k, n; - - //ysum = 1e-6; /* use this with float (i.s.o. double)! */ - ysum = 1e-13; - sum = 0.0; - x = in + PITCH_MAX_LAG/2 + 2; - for (n = 0; n < PITCH_CORR_LEN2; n++) { - ysum += in[n] * in[n]; - sum += x[n] * in[n]; - } - - outcorr += PITCH_LAG_SPAN2 - 1; /* index of last element in array */ - *outcorr = sum / sqrt(ysum); - - for (k = 1; k < PITCH_LAG_SPAN2; k++) { - ysum -= in[k-1] * in[k-1]; - ysum += in[PITCH_CORR_LEN2 + k - 1] * in[PITCH_CORR_LEN2 + k - 1]; - sum = 0.0; - inptr = &in[k]; - prod = x[0] * inptr[0]; - for (n = 1; n < PITCH_CORR_LEN2; n++) { - sum += prod; - prod = x[n] * inptr[n]; - } - sum += prod; - outcorr--; - *outcorr = sum / sqrt(ysum); - } -} - - -void WebRtcIsac_InitializePitch(const double *in, - const double old_lag, - const double old_gain, - PitchAnalysisStruct *State, - double *lags) -{ - double buf_dec[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2]; - double ratio, log_lag, gain_bias; - double bias; - double corrvec1[PITCH_LAG_SPAN2]; - double corrvec2[PITCH_LAG_SPAN2]; - int m, k; - // Allocating 10 extra entries at the begining of the CorrSurf - double corrSurfBuff[10 + (2*PITCH_BW+3)*(PITCH_LAG_SPAN2+4)]; - double* CorrSurf[2*PITCH_BW+3]; - double *CorrSurfPtr1, *CorrSurfPtr2; - double LagWin[3] = {0.2, 0.5, 0.98}; - int ind1, ind2, peaks_ind, peak, max_ind; - int peaks[PITCH_MAX_NUM_PEAKS]; - double adj, gain_tmp; - double corr, corr_max; - double intrp_a, intrp_b, intrp_c, intrp_d; - double peak_vals[PITCH_MAX_NUM_PEAKS]; - double lags1[PITCH_MAX_NUM_PEAKS]; - double lags2[PITCH_MAX_NUM_PEAKS]; - double T[3][3]; - int row; - - for(k = 0; k < 2*PITCH_BW+3; k++) - { - CorrSurf[k] = &corrSurfBuff[10 + k * (PITCH_LAG_SPAN2+4)]; - } - /* reset CorrSurf matrix */ - memset(corrSurfBuff, 0, sizeof(double) * (10 + (2*PITCH_BW+3) * (PITCH_LAG_SPAN2+4))); - - //warnings -DH - max_ind = 0; - peak = 0; - - /* copy old values from state buffer */ - memcpy(buf_dec, State->dec_buffer, sizeof(double) * (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2)); - - /* decimation; put result after the old values */ - WebRtcIsac_DecimateAllpass(in, State->decimator_state, PITCH_FRAME_LEN, - &buf_dec[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]); - - /* low-pass filtering */ - for (k = PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2; k++) - buf_dec[k] += 0.75 * buf_dec[k-1] - 0.25 * buf_dec[k-2]; - - /* copy end part back into state buffer */ - memcpy(State->dec_buffer, buf_dec+PITCH_FRAME_LEN/2, sizeof(double) * (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2)); - - /* compute correlation for first and second half of the frame */ - PCorr(buf_dec, corrvec1); - PCorr(buf_dec + PITCH_CORR_STEP2, corrvec2); - - /* bias towards pitch lag of previous frame */ - log_lag = log(0.5 * old_lag); - gain_bias = 4.0 * old_gain * old_gain; - if (gain_bias > 0.8) gain_bias = 0.8; - for (k = 0; k < PITCH_LAG_SPAN2; k++) - { - ratio = log((double) (k + (PITCH_MIN_LAG/2-2))) - log_lag; - bias = 1.0 + gain_bias * exp(-5.0 * ratio * ratio); - corrvec1[k] *= bias; - } - - /* taper correlation functions */ - for (k = 0; k < 3; k++) { - gain_tmp = LagWin[k]; - corrvec1[k] *= gain_tmp; - corrvec2[k] *= gain_tmp; - corrvec1[PITCH_LAG_SPAN2-1-k] *= gain_tmp; - corrvec2[PITCH_LAG_SPAN2-1-k] *= gain_tmp; - } - - corr_max = 0.0; - /* fill middle row of correlation surface */ - ind1 = 0; - ind2 = 0; - CorrSurfPtr1 = &CorrSurf[PITCH_BW][2]; - for (k = 0; k < PITCH_LAG_SPAN2; k++) { - corr = corrvec1[ind1++] + corrvec2[ind2++]; - CorrSurfPtr1[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]); - } - } - /* fill first and last rows of correlation surface */ - ind1 = 0; - ind2 = PITCH_BW; - CorrSurfPtr1 = &CorrSurf[0][2]; - CorrSurfPtr2 = &CorrSurf[2*PITCH_BW][PITCH_BW+2]; - for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW; k++) { - ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12)); - adj = 0.2 * ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */ - corr = adj * (corrvec1[ind1] + corrvec2[ind2]); - CorrSurfPtr1[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]); - } - corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]); - CorrSurfPtr2[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]); - } - } - /* fill second and next to last rows of correlation surface */ - ind1 = 0; - ind2 = PITCH_BW-1; - CorrSurfPtr1 = &CorrSurf[1][2]; - CorrSurfPtr2 = &CorrSurf[2*PITCH_BW-1][PITCH_BW+1]; - for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW+1; k++) { - ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12)); - adj = 0.9 * ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */ - corr = adj * (corrvec1[ind1] + corrvec2[ind2]); - CorrSurfPtr1[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]); - } - corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]); - CorrSurfPtr2[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]); - } - } - /* fill remainder of correlation surface */ - for (m = 2; m < PITCH_BW; m++) { - ind1 = 0; - ind2 = PITCH_BW - m; /* always larger than ind1 */ - CorrSurfPtr1 = &CorrSurf[m][2]; - CorrSurfPtr2 = &CorrSurf[2*PITCH_BW-m][PITCH_BW+2-m]; - for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW+m; k++) { - ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12)); - adj = ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */ - corr = adj * (corrvec1[ind1] + corrvec2[ind2]); - CorrSurfPtr1[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]); - } - corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]); - CorrSurfPtr2[k] = corr; - if (corr > corr_max) { - corr_max = corr; /* update maximum */ - max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]); - } - } - } - - /* threshold value to qualify as a peak */ - corr_max *= 0.6; - - peaks_ind = 0; - /* find peaks */ - for (m = 1; m < PITCH_BW+1; m++) { - if (peaks_ind == PITCH_MAX_NUM_PEAKS) break; - CorrSurfPtr1 = &CorrSurf[m][2]; - for (k = 2; k < PITCH_LAG_SPAN2-PITCH_BW-2+m; k++) { - corr = CorrSurfPtr1[k]; - if (corr > corr_max) { - if ( (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+5)]) && (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+4)]) ) { - if ( (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+4)]) && (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+5)]) ) { - /* found a peak; store index into matrix */ - peaks[peaks_ind++] = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]); - if (peaks_ind == PITCH_MAX_NUM_PEAKS) break; - } - } - } - } - } - for (m = PITCH_BW+1; m < 2*PITCH_BW; m++) { - if (peaks_ind == PITCH_MAX_NUM_PEAKS) break; - CorrSurfPtr1 = &CorrSurf[m][2]; - for (k = 2+m-PITCH_BW; k < PITCH_LAG_SPAN2-2; k++) { - corr = CorrSurfPtr1[k]; - if (corr > corr_max) { - if ( (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+5)]) && (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+4)]) ) { - if ( (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+4)]) && (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+5)]) ) { - /* found a peak; store index into matrix */ - peaks[peaks_ind++] = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]); - if (peaks_ind == PITCH_MAX_NUM_PEAKS) break; - } - } - } - } - } - - if (peaks_ind > 0) { - /* examine each peak */ - CorrSurfPtr1 = &CorrSurf[0][0]; - for (k = 0; k < peaks_ind; k++) { - peak = peaks[k]; - - /* compute four interpolated values around current peak */ - IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)], &intrp_a); - IntrepolFilter(&CorrSurfPtr1[peak - 1 ], &intrp_b); - IntrepolFilter(&CorrSurfPtr1[peak ], &intrp_c); - IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)], &intrp_d); - - /* determine maximum of the interpolated values */ - corr = CorrSurfPtr1[peak]; - corr_max = intrp_a; - if (intrp_b > corr_max) corr_max = intrp_b; - if (intrp_c > corr_max) corr_max = intrp_c; - if (intrp_d > corr_max) corr_max = intrp_d; - - /* determine where the peak sits and fill a 3x3 matrix around it */ - row = peak / (PITCH_LAG_SPAN2+4); - lags1[k] = (double) ((peak - row * (PITCH_LAG_SPAN2+4)) + PITCH_MIN_LAG/2 - 4); - lags2[k] = (double) (lags1[k] + PITCH_BW - row); - if ( corr > corr_max ) { - T[0][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)]; - T[2][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)]; - T[1][1] = corr; - T[0][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)]; - T[2][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)]; - T[1][0] = intrp_a; - T[0][1] = intrp_b; - T[2][1] = intrp_c; - T[1][2] = intrp_d; - } else { - if (intrp_a == corr_max) { - lags1[k] -= 0.5; - lags2[k] += 0.5; - IntrepolFilter(&CorrSurfPtr1[peak - 2*(PITCH_LAG_SPAN2+5)], &T[0][0]); - IntrepolFilter(&CorrSurfPtr1[peak - (2*PITCH_LAG_SPAN2+9)], &T[2][0]); - T[1][1] = intrp_a; - T[0][2] = intrp_b; - T[2][2] = intrp_c; - T[1][0] = CorrSurfPtr1[peak - (2*PITCH_LAG_SPAN2+9)]; - T[0][1] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)]; - T[2][1] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)]; - T[1][2] = corr; - } else if (intrp_b == corr_max) { - lags1[k] -= 0.5; - lags2[k] -= 0.5; - IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+6)], &T[0][0]); - T[2][0] = intrp_a; - T[1][1] = intrp_b; - IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+3)], &T[0][2]); - T[2][2] = intrp_d; - T[1][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)]; - T[0][1] = CorrSurfPtr1[peak - 1]; - T[2][1] = corr; - T[1][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)]; - } else if (intrp_c == corr_max) { - lags1[k] += 0.5; - lags2[k] += 0.5; - T[0][0] = intrp_a; - IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)], &T[2][0]); - T[1][1] = intrp_c; - T[0][2] = intrp_d; - IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)], &T[2][2]); - T[1][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)]; - T[0][1] = corr; - T[2][1] = CorrSurfPtr1[peak + 1]; - T[1][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)]; - } else { - lags1[k] += 0.5; - lags2[k] -= 0.5; - T[0][0] = intrp_b; - T[2][0] = intrp_c; - T[1][1] = intrp_d; - IntrepolFilter(&CorrSurfPtr1[peak + 2*(PITCH_LAG_SPAN2+4)], &T[0][2]); - IntrepolFilter(&CorrSurfPtr1[peak + (2*PITCH_LAG_SPAN2+9)], &T[2][2]); - T[1][0] = corr; - T[0][1] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)]; - T[2][1] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)]; - T[1][2] = CorrSurfPtr1[peak + (2*PITCH_LAG_SPAN2+9)]; - } - } - - /* 2D parabolic interpolation gives more accurate lags and peak value */ - Intrpol2D(T, &lags1[k], &lags2[k], &peak_vals[k]); - } - - /* determine the highest peak, after applying a bias towards short lags */ - corr_max = 0.0; - for (k = 0; k < peaks_ind; k++) { - corr = peak_vals[k] * pow(PITCH_PEAK_DECAY, log(lags1[k] + lags2[k])); - if (corr > corr_max) { - corr_max = corr; - peak = k; - } - } - - lags1[peak] *= 2.0; - lags2[peak] *= 2.0; - - if (lags1[peak] < (double) PITCH_MIN_LAG) lags1[peak] = (double) PITCH_MIN_LAG; - if (lags2[peak] < (double) PITCH_MIN_LAG) lags2[peak] = (double) PITCH_MIN_LAG; - if (lags1[peak] > (double) PITCH_MAX_LAG) lags1[peak] = (double) PITCH_MAX_LAG; - if (lags2[peak] > (double) PITCH_MAX_LAG) lags2[peak] = (double) PITCH_MAX_LAG; - - /* store lags of highest peak in output array */ - lags[0] = lags1[peak]; - lags[1] = lags1[peak]; - lags[2] = lags2[peak]; - lags[3] = lags2[peak]; - } - else - { - row = max_ind / (PITCH_LAG_SPAN2+4); - lags1[0] = (double) ((max_ind - row * (PITCH_LAG_SPAN2+4)) + PITCH_MIN_LAG/2 - 4); - lags2[0] = (double) (lags1[0] + PITCH_BW - row); - - if (lags1[0] < (double) PITCH_MIN_LAG) lags1[0] = (double) PITCH_MIN_LAG; - if (lags2[0] < (double) PITCH_MIN_LAG) lags2[0] = (double) PITCH_MIN_LAG; - if (lags1[0] > (double) PITCH_MAX_LAG) lags1[0] = (double) PITCH_MAX_LAG; - if (lags2[0] > (double) PITCH_MAX_LAG) lags2[0] = (double) PITCH_MAX_LAG; - - /* store lags of highest peak in output array */ - lags[0] = lags1[0]; - lags[1] = lags1[0]; - lags[2] = lags2[0]; - lags[3] = lags2[0]; - } -} - - - -/* create weighting matrix by orthogonalizing a basis of polynomials of increasing order - * t = (0:4)'; - * A = [t.^0, t.^1, t.^2, t.^3, t.^4]; - * [Q, dummy] = qr(A); - * P.Weight = Q * diag([0, .1, .5, 1, 1]) * Q'; */ -static const double kWeight[5][5] = { - { 0.29714285714286, -0.30857142857143, -0.05714285714286, 0.05142857142857, 0.01714285714286}, - {-0.30857142857143, 0.67428571428571, -0.27142857142857, -0.14571428571429, 0.05142857142857}, - {-0.05714285714286, -0.27142857142857, 0.65714285714286, -0.27142857142857, -0.05714285714286}, - { 0.05142857142857, -0.14571428571429, -0.27142857142857, 0.67428571428571, -0.30857142857143}, - { 0.01714285714286, 0.05142857142857, -0.05714285714286, -0.30857142857143, 0.29714285714286} -}; - - -void WebRtcIsac_PitchAnalysis(const double *in, /* PITCH_FRAME_LEN samples */ - double *out, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */ - PitchAnalysisStruct *State, - double *lags, - double *gains) -{ - double HPin[PITCH_FRAME_LEN]; - double Weighted[PITCH_FRAME_LEN]; - double Whitened[PITCH_FRAME_LEN + QLOOKAHEAD]; - double inbuf[PITCH_FRAME_LEN + QLOOKAHEAD]; - double out_G[PITCH_FRAME_LEN + QLOOKAHEAD]; // could be removed by using out instead - double out_dG[4][PITCH_FRAME_LEN + QLOOKAHEAD]; - double old_lag, old_gain; - double nrg_wht, tmp; - double Wnrg, Wfluct, Wgain; - double H[4][4]; - double grad[4]; - double dG[4]; - int k, m, n, iter; - - /* high pass filtering using second order pole-zero filter */ - WebRtcIsac_Highpass(in, HPin, State->hp_state, PITCH_FRAME_LEN); - - /* copy from state into buffer */ - memcpy(Whitened, State->whitened_buf, sizeof(double) * QLOOKAHEAD); - - /* compute weighted and whitened signals */ - WebRtcIsac_WeightingFilter(HPin, &Weighted[0], &Whitened[QLOOKAHEAD], &(State->Wghtstr)); - - /* copy from buffer into state */ - memcpy(State->whitened_buf, Whitened+PITCH_FRAME_LEN, sizeof(double) * QLOOKAHEAD); - - old_lag = State->PFstr_wght.oldlagp[0]; - old_gain = State->PFstr_wght.oldgainp[0]; - - /* inital pitch estimate */ - WebRtcIsac_InitializePitch(Weighted, old_lag, old_gain, State, lags); - - - /* Iterative optimization of lags - to be done */ - - /* compute energy of whitened signal */ - nrg_wht = 0.0; - for (k = 0; k < PITCH_FRAME_LEN + QLOOKAHEAD; k++) - nrg_wht += Whitened[k] * Whitened[k]; - - - /* Iterative optimization of gains */ - - /* set weights for energy, gain fluctiation, and spectral gain penalty functions */ - Wnrg = 1.0 / nrg_wht; - Wgain = 0.005; - Wfluct = 3.0; - - /* set initial gains */ - for (k = 0; k < 4; k++) - gains[k] = PITCH_MAX_GAIN_06; - - /* two iterations should be enough */ - for (iter = 0; iter < 2; iter++) { - /* compute Jacobian of pre-filter output towards gains */ - WebRtcIsac_PitchfilterPre_gains(Whitened, out_G, out_dG, &(State->PFstr_wght), lags, gains); - - /* gradient and approximate Hessian (lower triangle) for minimizing the filter's output power */ - for (k = 0; k < 4; k++) { - tmp = 0.0; - for (n = 0; n < PITCH_FRAME_LEN + QLOOKAHEAD; n++) - tmp += out_G[n] * out_dG[k][n]; - grad[k] = tmp * Wnrg; - } - for (k = 0; k < 4; k++) { - for (m = 0; m <= k; m++) { - tmp = 0.0; - for (n = 0; n < PITCH_FRAME_LEN + QLOOKAHEAD; n++) - tmp += out_dG[m][n] * out_dG[k][n]; - H[k][m] = tmp * Wnrg; - } - } - - /* add gradient and Hessian (lower triangle) for dampening fast gain changes */ - for (k = 0; k < 4; k++) { - tmp = kWeight[k+1][0] * old_gain; - for (m = 0; m < 4; m++) - tmp += kWeight[k+1][m+1] * gains[m]; - grad[k] += tmp * Wfluct; - } - for (k = 0; k < 4; k++) { - for (m = 0; m <= k; m++) { - H[k][m] += kWeight[k+1][m+1] * Wfluct; - } - } - - /* add gradient and Hessian for dampening gain */ - for (k = 0; k < 3; k++) { - tmp = 1.0 / (1 - gains[k]); - grad[k] += tmp * tmp * Wgain; - H[k][k] += 2.0 * tmp * (tmp * tmp * Wgain); - } - tmp = 1.0 / (1 - gains[3]); - grad[3] += 1.33 * (tmp * tmp * Wgain); - H[3][3] += 2.66 * tmp * (tmp * tmp * Wgain); - - - /* compute Cholesky factorization of Hessian - * by overwritting the upper triangle; scale factors on diagonal - * (for non pc-platforms store the inverse of the diagonals seperately to minimize divisions) */ - H[0][1] = H[1][0] / H[0][0]; - H[0][2] = H[2][0] / H[0][0]; - H[0][3] = H[3][0] / H[0][0]; - H[1][1] -= H[0][0] * H[0][1] * H[0][1]; - H[1][2] = (H[2][1] - H[0][1] * H[2][0]) / H[1][1]; - H[1][3] = (H[3][1] - H[0][1] * H[3][0]) / H[1][1]; - H[2][2] -= H[0][0] * H[0][2] * H[0][2] + H[1][1] * H[1][2] * H[1][2]; - H[2][3] = (H[3][2] - H[0][2] * H[3][0] - H[1][2] * H[1][1] * H[1][3]) / H[2][2]; - H[3][3] -= H[0][0] * H[0][3] * H[0][3] + H[1][1] * H[1][3] * H[1][3] + H[2][2] * H[2][3] * H[2][3]; - - /* Compute update as delta_gains = -inv(H) * grad */ - /* copy and negate */ - for (k = 0; k < 4; k++) - dG[k] = -grad[k]; - /* back substitution */ - dG[1] -= dG[0] * H[0][1]; - dG[2] -= dG[0] * H[0][2] + dG[1] * H[1][2]; - dG[3] -= dG[0] * H[0][3] + dG[1] * H[1][3] + dG[2] * H[2][3]; - /* scale */ - for (k = 0; k < 4; k++) - dG[k] /= H[k][k]; - /* back substitution */ - dG[2] -= dG[3] * H[2][3]; - dG[1] -= dG[3] * H[1][3] + dG[2] * H[1][2]; - dG[0] -= dG[3] * H[0][3] + dG[2] * H[0][2] + dG[1] * H[0][1]; - - /* update gains and check range */ - for (k = 0; k < 4; k++) { - gains[k] += dG[k]; - if (gains[k] > PITCH_MAX_GAIN) - gains[k] = PITCH_MAX_GAIN; - else if (gains[k] < 0.0) - gains[k] = 0.0; - } - } - - /* update state for next frame */ - WebRtcIsac_PitchfilterPre(Whitened, out, &(State->PFstr_wght), lags, gains); - - /* concatenate previous input's end and current input */ - memcpy(inbuf, State->inbuf, sizeof(double) * QLOOKAHEAD); - memcpy(inbuf+QLOOKAHEAD, in, sizeof(double) * PITCH_FRAME_LEN); - - /* lookahead pitch filtering for masking analysis */ - WebRtcIsac_PitchfilterPre_la(inbuf, out, &(State->PFstr), lags, gains); - - /* store last part of input */ - for (k = 0; k < QLOOKAHEAD; k++) - State->inbuf[k] = inbuf[k + PITCH_FRAME_LEN]; -} diff --git a/src/mod/codecs/mod_isac/pitch_estimator.h b/src/mod/codecs/mod_isac/pitch_estimator.h deleted file mode 100644 index f5d93564be..0000000000 --- a/src/mod/codecs/mod_isac/pitch_estimator.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * pitch_estimator.h - * - * Pitch functions - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_ - -#include "structs.h" - - - -void WebRtcIsac_PitchAnalysis(const double *in, /* PITCH_FRAME_LEN samples */ - double *out, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */ - PitchAnalysisStruct *State, - double *lags, - double *gains); - -void WebRtcIsac_InitializePitch(const double *in, - const double old_lag, - const double old_gain, - PitchAnalysisStruct *State, - double *lags); - -void WebRtcIsac_PitchfilterPre(double *indat, - double *outdat, - PitchFiltstr *pfp, - double *lags, - double *gains); - -void WebRtcIsac_PitchfilterPost(double *indat, - double *outdat, - PitchFiltstr *pfp, - double *lags, - double *gains); - -void WebRtcIsac_PitchfilterPre_la(double *indat, - double *outdat, - PitchFiltstr *pfp, - double *lags, - double *gains); - -void WebRtcIsac_PitchfilterPre_gains(double *indat, - double *outdat, - double out_dG[][PITCH_FRAME_LEN + QLOOKAHEAD], - PitchFiltstr *pfp, - double *lags, - double *gains); - -void WebRtcIsac_WeightingFilter(const double *in, double *weiout, double *whiout, WeightFiltstr *wfdata); - -void WebRtcIsac_Highpass(const double *in, double *out, double *state, int N); - -void WebRtcIsac_DecimateAllpass(const double *in, - double *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */ - int N, /* number of input samples */ - double *out); /* array of size N/2 */ - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_ */ diff --git a/src/mod/codecs/mod_isac/pitch_filter.c b/src/mod/codecs/mod_isac/pitch_filter.c deleted file mode 100644 index ccc8d214da..0000000000 --- a/src/mod/codecs/mod_isac/pitch_filter.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pitch_estimator.h" -#include "os_specific_inline.h" - -#include -#include -#include - -static const double kDampFilter[PITCH_DAMPORDER] = {-0.07, 0.25, 0.64, 0.25, -0.07}; - -/* interpolation coefficients; generated by design_pitch_filter.m */ -static const double kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = { - {-0.02239172458614, 0.06653315052934, -0.16515880017569, 0.60701333734125, 0.64671399919202, -0.20249000396417, 0.09926548334755, -0.04765933793109, 0.01754159521746}, - {-0.01985640750434, 0.05816126837866, -0.13991265473714, 0.44560418147643, 0.79117042386876, -0.20266133815188, 0.09585268418555, -0.04533310458084, 0.01654127246314}, - {-0.01463300534216, 0.04229888475060, -0.09897034715253, 0.28284326017787, 0.90385267956632, -0.16976950138649, 0.07704272393639, -0.03584218578311, 0.01295781500709}, - {-0.00764851320885, 0.02184035544377, -0.04985561057281, 0.13083306574393, 0.97545011664662, -0.10177807997561, 0.04400901776474, -0.02010737175166, 0.00719783432422}, - {-0.00000000000000, 0.00000000000000, -0.00000000000001, 0.00000000000001, 0.99999999999999, 0.00000000000001, -0.00000000000001, 0.00000000000000, -0.00000000000000}, - { 0.00719783432422, -0.02010737175166, 0.04400901776474, -0.10177807997562, 0.97545011664663, 0.13083306574393, -0.04985561057280, 0.02184035544377, -0.00764851320885}, - { 0.01295781500710, -0.03584218578312, 0.07704272393640, -0.16976950138650, 0.90385267956634, 0.28284326017785, -0.09897034715252, 0.04229888475059, -0.01463300534216}, - { 0.01654127246315, -0.04533310458085, 0.09585268418557, -0.20266133815190, 0.79117042386878, 0.44560418147640, -0.13991265473712, 0.05816126837865, -0.01985640750433} -}; - - -void WebRtcIsac_PitchfilterPre(double *indat, - double *outdat, - PitchFiltstr *pfp, - double *lags, - double *gains) -{ - - double ubuf[PITCH_INTBUFFSIZE]; - const double *fracoeff = NULL; - double curgain, curlag, gaindelta, lagdelta; - double sum, inystate[PITCH_DAMPORDER]; - double ftmp, oldlag, oldgain; - int k, n, m, pos, ind, pos2, Li, frc; - - Li = 0; - /* Set up buffer and states */ - memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE); - memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER); - - oldlag = *pfp->oldlagp; - oldgain = *pfp->oldgainp; - - /* No interpolation if pitch lag step is big */ - if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) { - oldlag = lags[0]; - oldgain = gains[0]; - } - - ind=0; - for (k=0;k0;m--) - inystate[m] = inystate[m-1]; - - /* Filter to get fractional pitch */ - pos = ind + PITCH_BUFFSIZE; - pos2 = pos - Li; - sum=0; - for (m=0;mubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE); - memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER); - - *pfp->oldlagp = oldlag; - *pfp->oldgainp = oldgain; - -} - - -void WebRtcIsac_PitchfilterPre_la(double *indat, - double *outdat, - PitchFiltstr *pfp, - double *lags, - double *gains) -{ - double ubuf[PITCH_INTBUFFSIZE+QLOOKAHEAD]; - const double *fracoeff = NULL; - double curgain, curlag, gaindelta, lagdelta; - double sum, inystate[PITCH_DAMPORDER]; - double ftmp; - double oldlag, oldgain; - int k, n, m, pos, ind, pos2, Li, frc; - - Li = 0; - /* Set up buffer and states */ - memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE); - memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER); - - oldlag = *pfp->oldlagp; - oldgain = *pfp->oldgainp; - - /* No interpolation if pitch lag step is big */ - if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) { - oldlag = lags[0]; - oldgain = gains[0]; - } - - - ind=0; - for (k=0;k0;m--) - inystate[m] = inystate[m-1]; - - /* Filter to get fractional pitch */ - pos = ind + PITCH_BUFFSIZE; - pos2 = pos - Li; - sum=0.0; - for (m=0;mubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE); - memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER); - - *pfp->oldlagp = oldlag; - *pfp->oldgainp = oldgain; - - - /* Filter look-ahead segment */ - for (n=0;n0;m--) - inystate[m] = inystate[m-1]; - - /* Filter to get fractional pitch */ - pos = ind + PITCH_BUFFSIZE; - pos2 = pos - Li; - sum=0.0; - for (m=0;mubuf, sizeof(double) * PITCH_BUFFSIZE); - memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER); - - /* clear some buffers */ - for (k = 0; k < 4; k++) { - gain_mult[k] = 0.0; - for (n = 0; n < PITCH_DAMPORDER; n++) - inystate_dG[k][n] = 0.0; - } - - oldlag = *pfp->oldlagp; - oldgain = *pfp->oldgainp; - - /* No interpolation if pitch lag step is big */ - if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) { - oldlag = lags[0]; - oldgain = gains[0]; - gain_mult[0] = 1.0; - } - - - ind=0; - for (k=0;k 1.0) gain_mult[k] = 1.0; - if (k > 0) gain_mult[k-1] -= 0.2; - } - - /* shift low pass filter states */ - for (m=PITCH_DAMPORDER-1;m>0;m--) { - inystate[m] = inystate[m-1]; - for (j = 0; j < 4; j++) - inystate_dG[j][m] = inystate_dG[j][m-1]; - } - - pos = ind + PITCH_BUFFSIZE; - pos2 = pos - Li; - - /* Filter to get fractional pitch */ - sum=0.0; - for (m=0;m 0) ? Li-ind : 0; - for (j = 0; j < k+1; j++) { - /* filter */ - sum2 = 0.0; - for (m = PITCH_FRACORDER-1; m >= m_tmp; m--) - sum2 += out_dG[j][ind-Li + m] * fracoeff[m]; - inystate_dG[j][0] = gain_mult[j] * sum + curgain * sum2; - } - - /* Low pass filter */ - sum=0.0; - for (m=0;m0;m--) { - inystate[m] = inystate[m-1]; - for (j = 0; j < 4; j++) - inystate_dG[j][m] = inystate_dG[j][m-1]; - } - - pos = ind + PITCH_BUFFSIZE; - pos2 = pos - Li; - - /* Filter to get fractional pitch */ - sum=0.0; - for (m=0;m 0) ? Li-ind : 0; - for (j = 0; (j= m_tmp; m--) - sum2 += out_dG[j][ind-Li + m] * fracoeff[m]; - inystate_dG[j][0] = gain_mult[j] * sum + curgain * sum2; - } - - /* Low pass filter */ - sum=0.0; - for (m=0;mubuf, sizeof(double) * PITCH_BUFFSIZE); - memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER); - - oldlag = *pfp->oldlagp; - oldgain = *pfp->oldgainp; - - /* make output more periodic */ - for (k=0;k (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) { - oldlag = lags[0]; - oldgain = gains[0]; - } - - - ind=0; - for (k=0;k0;m--) - inystate[m] = inystate[m-1]; - - /* Filter to get fractional pitch */ - pos = ind + PITCH_BUFFSIZE; - pos2 = pos - Li; - sum=0.0; - for (m=0;mubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE); - memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER); - - *pfp->oldlagp = oldlag; - *pfp->oldgainp = oldgain; - -} diff --git a/src/mod/codecs/mod_isac/pitch_gain_tables.c b/src/mod/codecs/mod_isac/pitch_gain_tables.c deleted file mode 100644 index 5d998a2928..0000000000 --- a/src/mod/codecs/mod_isac/pitch_gain_tables.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pitch_gain_tables.h" - -#include "settings.h" - -/* header file for coding tables for the pitch filter side-info in the entropy coder */ -/********************* Pitch Filter Gain Coefficient Tables ************************/ -/* cdf for quantized pitch filter gains */ -const WebRtc_UWord16 WebRtcIsac_kQPitchGainCdf[255] = { - 0, 2, 4, 6, 64, 901, 903, 905, 16954, 16956, - 16961, 17360, 17362, 17364, 17366, 17368, 17370, 17372, 17374, 17411, - 17514, 17516, 17583, 18790, 18796, 18802, 20760, 20777, 20782, 21722, - 21724, 21728, 21738, 21740, 21742, 21744, 21746, 21748, 22224, 22227, - 22230, 23214, 23229, 23239, 25086, 25108, 25120, 26088, 26094, 26098, - 26175, 26177, 26179, 26181, 26183, 26185, 26484, 26507, 26522, 27705, - 27731, 27750, 29767, 29799, 29817, 30866, 30883, 30885, 31025, 31029, - 31031, 31033, 31035, 31037, 31114, 31126, 31134, 32687, 32722, 32767, - 35718, 35742, 35757, 36943, 36952, 36954, 37115, 37128, 37130, 37132, - 37134, 37136, 37143, 37145, 37152, 38843, 38863, 38897, 47458, 47467, - 47474, 49040, 49061, 49063, 49145, 49157, 49159, 49161, 49163, 49165, - 49167, 49169, 49171, 49757, 49770, 49782, 61333, 61344, 61346, 62860, - 62883, 62885, 62887, 62889, 62891, 62893, 62895, 62897, 62899, 62901, - 62903, 62905, 62907, 62909, 65496, 65498, 65500, 65521, 65523, 65525, - 65527, 65529, 65531, 65533, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535}; - -/* index limits and ranges */ -const WebRtc_Word16 WebRtcIsac_kIndexLowerLimitGain[3] = { - -7, -2, -1}; - -const WebRtc_Word16 WebRtcIsac_kIndexUpperLimitGain[3] = { - 0, 3, 1}; - -const WebRtc_UWord16 WebRtcIsac_kIndexMultsGain[2] = { - 18, 3}; - -/* size of cdf table */ -const WebRtc_UWord16 WebRtcIsac_kQCdfTableSizeGain[1] = { - 256}; - -///////////////////////////FIXED POINT -/* mean values of pitch filter gains in FIXED point */ -const WebRtc_Word16 WebRtcIsac_kQMeanGain1Q12[144] = { - 843, 1092, 1336, 1222, 1405, 1656, 1500, 1815, 1843, 1838, 1839, 1843, 1843, 1843, 1843, 1843, - 1843, 1843, 814, 846, 1092, 1013, 1174, 1383, 1391, 1511, 1584, 1734, 1753, 1843, 1843, 1843, - 1843, 1843, 1843, 1843, 524, 689, 777, 845, 947, 1069, 1090, 1263, 1380, 1447, 1559, 1676, - 1645, 1749, 1843, 1843, 1843, 1843, 81, 477, 563, 611, 706, 806, 849, 1012, 1192, 1128, - 1330, 1489, 1425, 1576, 1826, 1741, 1843, 1843, 0, 290, 305, 356, 488, 575, 602, 741, - 890, 835, 1079, 1196, 1182, 1376, 1519, 1506, 1680, 1843, 0, 47, 97, 69, 289, 381, - 385, 474, 617, 664, 803, 1079, 935, 1160, 1269, 1265, 1506, 1741, 0, 0, 0, 0, - 112, 120, 190, 283, 442, 343, 526, 809, 684, 935, 1134, 1020, 1265, 1506, 0, 0, - 0, 0, 0, 0, 0, 111, 256, 87, 373, 597, 430, 684, 935, 770, 1020, 1265}; - -const WebRtc_Word16 WebRtcIsac_kQMeanGain2Q12[144] = { - 1760, 1525, 1285, 1747, 1671, 1393, 1843, 1826, 1555, 1843, 1784, 1606, 1843, 1843, 1711, 1843, - 1843, 1814, 1389, 1275, 1040, 1564, 1414, 1252, 1610, 1495, 1343, 1753, 1592, 1405, 1804, 1720, - 1475, 1843, 1814, 1581, 1208, 1061, 856, 1349, 1148, 994, 1390, 1253, 1111, 1495, 1343, 1178, - 1770, 1465, 1234, 1814, 1581, 1342, 1040, 793, 713, 1053, 895, 737, 1128, 1003, 861, 1277, - 1094, 981, 1475, 1192, 1019, 1581, 1342, 1098, 855, 570, 483, 833, 648, 540, 948, 744, - 572, 1009, 844, 636, 1234, 934, 685, 1342, 1217, 984, 537, 318, 124, 603, 423, 350, - 687, 479, 322, 791, 581, 430, 987, 671, 488, 1098, 849, 597, 283, 27, 0, 397, - 222, 38, 513, 271, 124, 624, 325, 157, 737, 484, 233, 849, 597, 343, 27, 0, - 0, 141, 0, 0, 256, 69, 0, 370, 87, 0, 484, 229, 0, 597, 343, 87}; - -const WebRtc_Word16 WebRtcIsac_kQMeanGain3Q12[144] = { - 1843, 1843, 1711, 1843, 1818, 1606, 1843, 1827, 1511, 1814, 1639, 1393, 1760, 1525, 1285, 1656, - 1419, 1176, 1835, 1718, 1475, 1841, 1650, 1387, 1648, 1498, 1287, 1600, 1411, 1176, 1522, 1299, - 1040, 1419, 1176, 928, 1773, 1461, 1128, 1532, 1355, 1202, 1429, 1260, 1115, 1398, 1151, 1025, - 1172, 1080, 790, 1176, 928, 677, 1475, 1147, 1019, 1276, 1096, 922, 1214, 1010, 901, 1057, - 893, 800, 1040, 796, 734, 928, 677, 424, 1137, 897, 753, 1120, 830, 710, 875, 751, - 601, 795, 642, 583, 790, 544, 475, 677, 474, 140, 987, 750, 482, 697, 573, 450, - 691, 487, 303, 661, 394, 332, 537, 303, 220, 424, 168, 0, 737, 484, 229, 624, - 348, 153, 441, 261, 136, 397, 166, 51, 283, 27, 0, 168, 0, 0, 484, 229, - 0, 370, 57, 0, 256, 43, 0, 141, 0, 0, 27, 0, 0, 0, 0, 0}; - - -const WebRtc_Word16 WebRtcIsac_kQMeanGain4Q12[144] = { - 1843, 1843, 1843, 1843, 1841, 1843, 1500, 1821, 1843, 1222, 1434, 1656, 843, 1092, 1336, 504, - 757, 1007, 1843, 1843, 1843, 1838, 1791, 1843, 1265, 1505, 1599, 965, 1219, 1425, 730, 821, - 1092, 249, 504, 757, 1783, 1819, 1843, 1351, 1567, 1727, 1096, 1268, 1409, 805, 961, 1131, - 444, 670, 843, 0, 249, 504, 1425, 1655, 1743, 1096, 1324, 1448, 822, 1019, 1199, 490, - 704, 867, 81, 450, 555, 0, 0, 249, 1247, 1428, 1530, 881, 1073, 1283, 610, 759, - 939, 278, 464, 645, 0, 200, 270, 0, 0, 0, 935, 1163, 1410, 528, 790, 1068, - 377, 499, 717, 173, 240, 274, 0, 43, 62, 0, 0, 0, 684, 935, 1182, 343, - 551, 735, 161, 262, 423, 0, 55, 27, 0, 0, 0, 0, 0, 0, 430, 684, - 935, 87, 377, 597, 0, 46, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/mod/codecs/mod_isac/pitch_gain_tables.h b/src/mod/codecs/mod_isac/pitch_gain_tables.h deleted file mode 100644 index f958f5df45..0000000000 --- a/src/mod/codecs/mod_isac/pitch_gain_tables.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * pitch_gain_tables.h - * - * This file contains tables for the pitch filter side-info in the entropy coder. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_ - -#include "typedefs.h" - -/* header file for coding tables for the pitch filter side-info in the entropy coder */ -/********************* Pitch Filter Gain Coefficient Tables ************************/ -/* cdf for quantized pitch filter gains */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchGainCdf[255]; - -/* index limits and ranges */ -extern const WebRtc_Word16 WebRtcIsac_kIndexLowerLimitGain[3]; - -extern const WebRtc_Word16 WebRtcIsac_kIndexUpperLimitGain[3]; -extern const WebRtc_UWord16 WebRtcIsac_kIndexMultsGain[2]; - -/* mean values of pitch filter gains */ -//(Y) -extern const WebRtc_Word16 WebRtcIsac_kQMeanGain1Q12[144]; -extern const WebRtc_Word16 WebRtcIsac_kQMeanGain2Q12[144]; -extern const WebRtc_Word16 WebRtcIsac_kQMeanGain3Q12[144]; -extern const WebRtc_Word16 WebRtcIsac_kQMeanGain4Q12[144]; -//(Y) - -/* size of cdf table */ -extern const WebRtc_UWord16 WebRtcIsac_kQCdfTableSizeGain[1]; - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_ */ diff --git a/src/mod/codecs/mod_isac/pitch_lag_tables.c b/src/mod/codecs/mod_isac/pitch_lag_tables.c deleted file mode 100644 index 72a031e227..0000000000 --- a/src/mod/codecs/mod_isac/pitch_lag_tables.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pitch_lag_tables.h" -#include "settings.h" - -/* header file for coding tables for the pitch filter side-info in the entropy coder */ -/********************* Pitch Filter Gain Coefficient Tables ************************/ - -/* tables for use with small pitch gain */ - -/* cdf for quantized pitch filter lags */ -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Lo[127] = { - 0, 134, 336, 549, 778, 998, 1264, 1512, 1777, 2070, - 2423, 2794, 3051, 3361, 3708, 3979, 4315, 4610, 4933, 5269, - 5575, 5896, 6155, 6480, 6816, 7129, 7477, 7764, 8061, 8358, - 8718, 9020, 9390, 9783, 10177, 10543, 10885, 11342, 11795, 12213, - 12680, 13096, 13524, 13919, 14436, 14903, 15349, 15795, 16267, 16734, - 17266, 17697, 18130, 18632, 19080, 19447, 19884, 20315, 20735, 21288, - 21764, 22264, 22723, 23193, 23680, 24111, 24557, 25022, 25537, 26082, - 26543, 27090, 27620, 28139, 28652, 29149, 29634, 30175, 30692, 31273, - 31866, 32506, 33059, 33650, 34296, 34955, 35629, 36295, 36967, 37726, - 38559, 39458, 40364, 41293, 42256, 43215, 44231, 45253, 46274, 47359, - 48482, 49678, 50810, 51853, 53016, 54148, 55235, 56263, 57282, 58363, - 59288, 60179, 61076, 61806, 62474, 63129, 63656, 64160, 64533, 64856, - 65152, 65535, 65535, 65535, 65535, 65535, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Lo[20] = { - 0, 429, 3558, 5861, 8558, 11639, 15210, 19502, 24773, 31983, - 42602, 48567, 52601, 55676, 58160, 60172, 61889, 63235, 65383, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Lo[2] = { - 0, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Lo[10] = { - 0, 2966, 6368, 11182, 19431, 37793, 48532, 55353, 60626, 65535}; - -const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrLo[4] = {WebRtcIsac_kQPitchLagCdf1Lo, WebRtcIsac_kQPitchLagCdf2Lo, WebRtcIsac_kQPitchLagCdf3Lo, WebRtcIsac_kQPitchLagCdf4Lo}; - -/* size of first cdf table */ -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeLo[1] = {128}; - -/* index limits and ranges */ -const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagLo[4] = { --140, -9, 0, -4}; - -const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagLo[4] = { --20, 9, 0, 4}; - -/* initial index for arithmetic decoder */ -const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagLo[3] = { - 10, 1, 5}; - -/* mean values of pitch filter lags */ -const double WebRtcIsac_kQMeanLag2Lo[19] = { --17.21385070, -15.82678944, -14.07123081, -12.03003877, -10.01311864, -8.00794627, -5.91162987, -3.89231876, -1.90220980, -0.01879275, - 1.89144232, 3.88123171, 5.92146992, 7.96435361, 9.98923648, 11.98266347, 13.96101002, 15.74855713, 17.10976611}; - -const double WebRtcIsac_kQMeanLag3Lo[1] = { - 0.00000000}; - -const double WebRtcIsac_kQMeanLag4Lo[9] = { --7.76246496, -5.92083980, -3.94095226, -1.89502305, 0.03724681, 1.93054221, 3.96443467, 5.91726366, 7.78434291}; - -const double WebRtcIsac_kQPitchLagStepsizeLo = 2.000000; - - -/* tables for use with medium pitch gain */ - -/* cdf for quantized pitch filter lags */ -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Mid[255] = { - 0, 28, 61, 88, 121, 149, 233, 331, 475, 559, - 624, 661, 689, 712, 745, 791, 815, 843, 866, 922, - 959, 1024, 1061, 1117, 1178, 1238, 1280, 1350, 1453, 1513, - 1564, 1625, 1671, 1741, 1788, 1904, 2072, 2421, 2626, 2770, - 2840, 2900, 2942, 3012, 3068, 3115, 3147, 3194, 3254, 3319, - 3366, 3520, 3678, 3780, 3850, 3911, 3957, 4032, 4106, 4185, - 4292, 4474, 4683, 4842, 5019, 5191, 5321, 5428, 5540, 5675, - 5763, 5847, 5959, 6127, 6304, 6564, 6839, 7090, 7263, 7421, - 7556, 7728, 7872, 7984, 8142, 8361, 8580, 8743, 8938, 9227, - 9409, 9539, 9674, 9795, 9930, 10060, 10177, 10382, 10614, 10861, - 11038, 11271, 11415, 11629, 11792, 12044, 12193, 12416, 12574, 12821, - 13007, 13235, 13445, 13654, 13901, 14134, 14488, 15000, 15703, 16285, - 16504, 16797, 17086, 17328, 17579, 17807, 17998, 18268, 18538, 18836, - 19087, 19274, 19474, 19716, 19935, 20270, 20833, 21303, 21532, 21741, - 21978, 22207, 22523, 22770, 23054, 23613, 23943, 24204, 24399, 24651, - 24832, 25074, 25270, 25549, 25759, 26015, 26150, 26424, 26713, 27048, - 27342, 27504, 27681, 27854, 28021, 28207, 28412, 28664, 28859, 29064, - 29278, 29548, 29748, 30107, 30377, 30656, 30856, 31164, 31452, 31755, - 32011, 32328, 32626, 32919, 33319, 33789, 34329, 34925, 35396, 35973, - 36443, 36964, 37551, 38156, 38724, 39357, 40023, 40908, 41587, 42602, - 43924, 45037, 45810, 46597, 47421, 48291, 49092, 50051, 51448, 52719, - 53440, 54241, 54944, 55977, 56676, 57299, 57872, 58389, 59059, 59688, - 60237, 60782, 61094, 61573, 61890, 62290, 62658, 63030, 63217, 63454, - 63622, 63882, 64003, 64273, 64427, 64529, 64581, 64697, 64758, 64902, - 65414, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Mid[36] = { - 0, 71, 335, 581, 836, 1039, 1323, 1795, 2258, 2608, - 3005, 3591, 4243, 5344, 7163, 10583, 16848, 28078, 49448, 57007, - 60357, 61850, 62837, 63437, 63872, 64188, 64377, 64614, 64774, 64949, - 65039, 65115, 65223, 65360, 65474, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Mid[2] = { - 0, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Mid[20] = { - 0, 28, 246, 459, 667, 1045, 1523, 2337, 4337, 11347, - 44231, 56709, 60781, 62243, 63161, 63969, 64608, 65062, 65502, 65535}; - -const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrMid[4] = {WebRtcIsac_kQPitchLagCdf1Mid, WebRtcIsac_kQPitchLagCdf2Mid, WebRtcIsac_kQPitchLagCdf3Mid, WebRtcIsac_kQPitchLagCdf4Mid}; - -/* size of first cdf table */ -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeMid[1] = {256}; - -/* index limits and ranges */ -const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagMid[4] = { --280, -17, 0, -9}; - -const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagMid[4] = { --40, 17, 0, 9}; - -/* initial index for arithmetic decoder */ -const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagMid[3] = { - 18, 1, 10}; - -/* mean values of pitch filter lags */ -const double WebRtcIsac_kQMeanLag2Mid[35] = { --16.89183900, -15.86949778, -15.05476653, -14.00664348, -13.02793036, -12.07324237, -11.00542532, -10.11250602, -8.90792971, -8.02474753, --7.00426767, -5.94055287, -4.98251338, -3.91053158, -2.98820425, -1.93524245, -0.92978085, -0.01722509, 0.91317387, 1.92973955, - 2.96908851, 3.93728974, 4.96308471, 5.92244151, 7.08673497, 8.00993708, 9.04656316, 9.98538742, 10.97851694, 11.94772884, - 13.02426166, 14.00039951, 15.01347042, 15.80758023, 16.94086895}; - -const double WebRtcIsac_kQMeanLag3Mid[1] = { - 0.00000000}; - -const double WebRtcIsac_kQMeanLag4Mid[19] = { --8.60409403, -7.89198395, -7.03450280, -5.86260421, -4.93822322, -3.93078706, -2.91302322, -1.91824007, -0.87003282, 0.02822649, - 0.89951758, 1.87495484, 2.91802604, 3.96874074, 5.06571703, 5.93618227, 7.00520185, 7.88497726, 8.64160364}; - -const double WebRtcIsac_kQPitchLagStepsizeMid = 1.000000; - - -/* tables for use with large pitch gain */ - -/* cdf for quantized pitch filter lags */ -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Hi[511] = { - 0, 7, 18, 33, 69, 105, 156, 228, 315, 612, - 680, 691, 709, 724, 735, 738, 742, 746, 749, 753, - 756, 760, 764, 774, 782, 785, 789, 796, 800, 803, - 807, 814, 818, 822, 829, 832, 847, 854, 858, 869, - 876, 883, 898, 908, 934, 977, 1010, 1050, 1060, 1064, - 1075, 1078, 1086, 1089, 1093, 1104, 1111, 1122, 1133, 1136, - 1151, 1162, 1183, 1209, 1252, 1281, 1339, 1364, 1386, 1401, - 1411, 1415, 1426, 1430, 1433, 1440, 1448, 1455, 1462, 1477, - 1487, 1495, 1502, 1506, 1509, 1516, 1524, 1531, 1535, 1542, - 1553, 1556, 1578, 1589, 1611, 1625, 1639, 1643, 1654, 1665, - 1672, 1687, 1694, 1705, 1708, 1719, 1730, 1744, 1752, 1759, - 1791, 1795, 1820, 1867, 1886, 1915, 1936, 1943, 1965, 1987, - 2041, 2099, 2161, 2175, 2200, 2211, 2226, 2233, 2244, 2251, - 2266, 2280, 2287, 2298, 2309, 2316, 2331, 2342, 2356, 2378, - 2403, 2418, 2447, 2497, 2544, 2602, 2863, 2895, 2903, 2935, - 2950, 2971, 3004, 3011, 3018, 3029, 3040, 3062, 3087, 3127, - 3152, 3170, 3199, 3243, 3293, 3322, 3340, 3377, 3402, 3427, - 3474, 3518, 3543, 3579, 3601, 3637, 3659, 3706, 3731, 3760, - 3818, 3847, 3869, 3901, 3920, 3952, 4068, 4169, 4220, 4271, - 4524, 4571, 4604, 4632, 4672, 4730, 4777, 4806, 4857, 4904, - 4951, 5002, 5031, 5060, 5107, 5150, 5212, 5266, 5331, 5382, - 5432, 5490, 5544, 5610, 5700, 5762, 5812, 5874, 5972, 6022, - 6091, 6163, 6232, 6305, 6402, 6540, 6685, 6880, 7090, 7271, - 7379, 7452, 7542, 7625, 7687, 7770, 7843, 7911, 7966, 8024, - 8096, 8190, 8252, 8320, 8411, 8501, 8585, 8639, 8751, 8842, - 8918, 8986, 9066, 9127, 9203, 9269, 9345, 9406, 9464, 9536, - 9612, 9667, 9735, 9844, 9931, 10036, 10119, 10199, 10260, 10358, - 10441, 10514, 10666, 10734, 10872, 10951, 11053, 11125, 11223, 11324, - 11516, 11664, 11737, 11816, 11892, 12008, 12120, 12200, 12280, 12392, - 12490, 12576, 12685, 12812, 12917, 13003, 13108, 13210, 13300, 13384, - 13470, 13579, 13673, 13771, 13879, 13999, 14136, 14201, 14368, 14614, - 14759, 14867, 14958, 15030, 15121, 15189, 15280, 15385, 15461, 15555, - 15653, 15768, 15884, 15971, 16069, 16145, 16210, 16279, 16380, 16463, - 16539, 16615, 16688, 16818, 16919, 17017, 18041, 18338, 18523, 18649, - 18790, 18917, 19047, 19167, 19315, 19460, 19601, 19731, 19858, 20068, - 20173, 20318, 20466, 20625, 20741, 20911, 21045, 21201, 21396, 21588, - 21816, 22022, 22305, 22547, 22786, 23072, 23322, 23600, 23879, 24168, - 24433, 24769, 25120, 25511, 25895, 26289, 26792, 27219, 27683, 28077, - 28566, 29094, 29546, 29977, 30491, 30991, 31573, 32105, 32594, 33173, - 33788, 34497, 35181, 35833, 36488, 37255, 37921, 38645, 39275, 39894, - 40505, 41167, 41790, 42431, 43096, 43723, 44385, 45134, 45858, 46607, - 47349, 48091, 48768, 49405, 49955, 50555, 51167, 51985, 52611, 53078, - 53494, 53965, 54435, 54996, 55601, 56125, 56563, 56838, 57244, 57566, - 57967, 58297, 58771, 59093, 59419, 59647, 59886, 60143, 60461, 60693, - 60917, 61170, 61416, 61634, 61891, 62122, 62310, 62455, 62632, 62839, - 63103, 63436, 63639, 63805, 63906, 64015, 64192, 64355, 64475, 64558, - 64663, 64742, 64811, 64865, 64916, 64956, 64981, 65025, 65068, 65115, - 65195, 65314, 65419, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, - 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Hi[68] = { - 0, 7, 11, 22, 37, 52, 56, 59, 81, 85, - 89, 96, 115, 130, 137, 152, 170, 181, 193, 200, - 207, 233, 237, 259, 289, 318, 363, 433, 592, 992, - 1607, 3062, 6149, 12206, 25522, 48368, 58223, 61918, 63640, 64584, - 64943, 65098, 65206, 65268, 65294, 65335, 65350, 65372, 65387, 65402, - 65413, 65420, 65428, 65435, 65439, 65450, 65454, 65468, 65472, 65476, - 65483, 65491, 65498, 65505, 65516, 65520, 65528, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Hi[2] = { - 0, 65535}; - -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Hi[35] = { - 0, 7, 19, 30, 41, 48, 63, 74, 82, 96, - 122, 152, 215, 330, 701, 2611, 10931, 48106, 61177, 64341, - 65112, 65238, 65309, 65338, 65364, 65379, 65401, 65427, 65453, 65465, - 65476, 65490, 65509, 65528, 65535}; - -const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrHi[4] = {WebRtcIsac_kQPitchLagCdf1Hi, WebRtcIsac_kQPitchLagCdf2Hi, WebRtcIsac_kQPitchLagCdf3Hi, WebRtcIsac_kQPitchLagCdf4Hi}; - -/* size of first cdf table */ -const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeHi[1] = {512}; - -/* index limits and ranges */ -const WebRtc_Word16 WebRtcIsac_kQindexLowerLimitLagHi[4] = { --552, -34, 0, -16}; - -const WebRtc_Word16 WebRtcIsac_kQindexUpperLimitLagHi[4] = { --80, 32, 0, 17}; - -/* initial index for arithmetic decoder */ -const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagHi[3] = { - 34, 1, 18}; - -/* mean values of pitch filter lags */ -const double WebRtcIsac_kQMeanLag2Hi[67] = { --17.07263295, -16.50000000, -15.83966081, -15.55613708, -14.96948007, -14.50000000, -14.00000000, -13.48377986, -13.00000000, -12.50000000, --11.93199636, -11.44530414, -11.04197641, -10.39910301, -10.15202337, -9.51322461, -8.93357741, -8.46456632, -8.10270672, -7.53751847, --6.98686404, -6.50000000, -6.08463150, -5.46872991, -5.00864717, -4.50163760, -4.01382410, -3.43856708, -2.96898001, -2.46554810, --1.96861004, -1.47106701, -0.97197237, -0.46561654, -0.00531409, 0.45767857, 0.96777907, 1.47507903, 1.97740425, 2.46695420, - 3.00695774, 3.47167185, 4.02712538, 4.49280007, 5.01087640, 5.48191963, 6.04916550, 6.51511058, 6.97297819, 7.46565499, - 8.01489405, 8.39912001, 8.91819757, 9.50000000, 10.11654065, 10.50000000, 11.03712583, 11.50000000, 12.00000000, 12.38964346, - 12.89466127, 13.43657881, 13.96013840, 14.46279912, 15.00000000, 15.39412269, 15.96662441}; - -const double WebRtcIsac_kQMeanLag3Hi[1] = { - 0.00000000}; - -const double WebRtcIsac_kQMeanLag4Hi[34] = { --7.98331221, -7.47988769, -7.03626557, -6.52708003, -6.06982173, -5.51856292, -5.05827033, -4.45909878, -3.99125864, -3.45308135, --3.02328139, -2.47297273, -1.94341995, -1.44699056, -0.93612243, -0.43012406, 0.01120357, 0.44054812, 0.93199883, 1.45669587, - 1.97218322, 2.50187419, 2.98748690, 3.49343202, 4.01660147, 4.50984306, 5.01402683, 5.58936797, 5.91787793, 6.59998900, - 6.85034315, 7.53503316, 7.87711194, 8.53631648}; - -const double WebRtcIsac_kQPitchLagStepsizeHi = 0.500000; - -/* transform matrix */ -const double WebRtcIsac_kTransform[4][4] = { -{-0.50000000, -0.50000000, -0.50000000, -0.50000000}, -{ 0.67082039, 0.22360680, -0.22360680, -0.67082039}, -{ 0.50000000, -0.50000000, -0.50000000, 0.50000000}, -{ 0.22360680, -0.67082039, 0.67082039, -0.22360680}}; - -/* transpose transform matrix */ -const double WebRtcIsac_kTransformTranspose[4][4] = { -{-0.50000000, 0.67082039, 0.50000000, 0.22360680}, -{-0.50000000, 0.22360680, -0.50000000, -0.67082039}, -{-0.50000000, -0.22360680, -0.50000000, 0.67082039}, -{-0.50000000, -0.67082039, 0.50000000, -0.22360680}}; - diff --git a/src/mod/codecs/mod_isac/pitch_lag_tables.h b/src/mod/codecs/mod_isac/pitch_lag_tables.h deleted file mode 100644 index 67b02e5e4d..0000000000 --- a/src/mod/codecs/mod_isac/pitch_lag_tables.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * pitch_lag_tables.h - * - * This file contains tables for the pitch filter side-info in the entropy coder. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_ - -#include "typedefs.h" -/* header file for coding tables for the pitch filter side-info in the entropy coder */ -/********************* Pitch Filter Lag Coefficient Tables ************************/ - -/* tables for use with small pitch gain */ - -/* cdfs for quantized pitch lags */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Lo[127]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Lo[20]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Lo[2]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Lo[10]; - -extern const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrLo[4]; - -/* size of first cdf table */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeLo[1]; - -/* index limits and ranges */ -extern const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagLo[4]; -extern const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagLo[4]; - -/* initial index for arithmetic decoder */ -extern const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagLo[3]; - -/* mean values of pitch filter lags */ -extern const double WebRtcIsac_kQMeanLag2Lo[19]; -extern const double WebRtcIsac_kQMeanLag3Lo[1]; -extern const double WebRtcIsac_kQMeanLag4Lo[9]; - -extern const double WebRtcIsac_kQPitchLagStepsizeLo; - - -/* tables for use with medium pitch gain */ - -/* cdfs for quantized pitch lags */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Mid[255]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Mid[36]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Mid[2]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Mid[20]; - -extern const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrMid[4]; - -/* size of first cdf table */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeMid[1]; - -/* index limits and ranges */ -extern const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagMid[4]; -extern const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagMid[4]; - -/* initial index for arithmetic decoder */ -extern const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagMid[3]; - -/* mean values of pitch filter lags */ -extern const double WebRtcIsac_kQMeanLag2Mid[35]; -extern const double WebRtcIsac_kQMeanLag3Mid[1]; -extern const double WebRtcIsac_kQMeanLag4Mid[19]; - -extern const double WebRtcIsac_kQPitchLagStepsizeMid; - - -/* tables for use with large pitch gain */ - -/* cdfs for quantized pitch lags */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Hi[511]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Hi[68]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Hi[2]; -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Hi[35]; - -extern const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrHi[4]; - -/* size of first cdf table */ -extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeHi[1]; - -/* index limits and ranges */ -extern const WebRtc_Word16 WebRtcIsac_kQindexLowerLimitLagHi[4]; -extern const WebRtc_Word16 WebRtcIsac_kQindexUpperLimitLagHi[4]; - -/* initial index for arithmetic decoder */ -extern const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagHi[3]; - -/* mean values of pitch filter lags */ -extern const double WebRtcIsac_kQMeanLag2Hi[67]; -extern const double WebRtcIsac_kQMeanLag3Hi[1]; -extern const double WebRtcIsac_kQMeanLag4Hi[34]; - -extern const double WebRtcIsac_kQPitchLagStepsizeHi; - -/* transform matrix */ -extern const double WebRtcIsac_kTransform[4][4]; - -/* transpose transform matrix */ -extern const double WebRtcIsac_kTransformTranspose[4][4]; - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_ */ diff --git a/src/mod/codecs/mod_isac/randomization_functions.c b/src/mod/codecs/mod_isac/randomization_functions.c deleted file mode 100644 index 04271ada4d..0000000000 --- a/src/mod/codecs/mod_isac/randomization_functions.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the randomization functions - * WebRtcSpl_IncreaseSeed() - * WebRtcSpl_RandU() - * WebRtcSpl_RandN() - * WebRtcSpl_RandUArray() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -static const WebRtc_Word16 kRandNTable[] = { - 9178, -7260, 40, 10189, 4894, -3531, -13779, 14764, - -4008, -8884, -8990, 1008, 7368, 5184, 3251, -5817, - -9786, 5963, 1770, 8066, -7135, 10772, -2298, 1361, - 6484, 2241, -8633, 792, 199, -3344, 6553, -10079, - -15040, 95, 11608, -12469, 14161, -4176, 2476, 6403, - 13685, -16005, 6646, 2239, 10916, -3004, -602, -3141, - 2142, 14144, -5829, 5305, 8209, 4713, 2697, -5112, - 16092, -1210, -2891, -6631, -5360, -11878, -6781, -2739, - -6392, 536, 10923, 10872, 5059, -4748, -7770, 5477, - 38, -1025, -2892, 1638, 6304, 14375, -11028, 1553, - -1565, 10762, -393, 4040, 5257, 12310, 6554, -4799, - 4899, -6354, 1603, -1048, -2220, 8247, -186, -8944, - -12004, 2332, 4801, -4933, 6371, 131, 8614, -5927, - -8287, -22760, 4033, -15162, 3385, 3246, 3153, -5250, - 3766, 784, 6494, -62, 3531, -1582, 15572, 662, - -3952, -330, -3196, 669, 7236, -2678, -6569, 23319, - -8645, -741, 14830, -15976, 4903, 315, -11342, 10311, - 1858, -7777, 2145, 5436, 5677, -113, -10033, 826, - -1353, 17210, 7768, 986, -1471, 8291, -4982, 8207, - -14911, -6255, -2449, -11881, -7059, -11703, -4338, 8025, - 7538, -2823, -12490, 9470, -1613, -2529, -10092, -7807, - 9480, 6970, -12844, 5123, 3532, 4816, 4803, -8455, - -5045, 14032, -4378, -1643, 5756, -11041, -2732, -16618, - -6430, -18375, -3320, 6098, 5131, -4269, -8840, 2482, - -7048, 1547, -21890, -6505, -7414, -424, -11722, 7955, - 1653, -17299, 1823, 473, -9232, 3337, 1111, 873, - 4018, -8982, 9889, 3531, -11763, -3799, 7373, -4539, - 3231, 7054, -8537, 7616, 6244, 16635, 447, -2915, - 13967, 705, -2669, -1520, -1771, -16188, 5956, 5117, - 6371, -9936, -1448, 2480, 5128, 7550, -8130, 5236, - 8213, -6443, 7707, -1950, -13811, 7218, 7031, -3883, - 67, 5731, -2874, 13480, -3743, 9298, -3280, 3552, - -4425, -18, -3785, -9988, -5357, 5477, -11794, 2117, - 1416, -9935, 3376, 802, -5079, -8243, 12652, 66, - 3653, -2368, 6781, -21895, -7227, 2487, 7839, -385, - 6646, -7016, -4658, 5531, -1705, 834, 129, 3694, - -1343, 2238, -22640, -6417, -11139, 11301, -2945, -3494, - -5626, 185, -3615, -2041, -7972, -3106, -60, -23497, - -1566, 17064, 3519, 2518, 304, -6805, -10269, 2105, - 1936, -426, -736, -8122, -1467, 4238, -6939, -13309, - 360, 7402, -7970, 12576, 3287, 12194, -6289, -16006, - 9171, 4042, -9193, 9123, -2512, 6388, -4734, -8739, - 1028, -5406, -1696, 5889, -666, -4736, 4971, 3565, - 9362, -6292, 3876, -3652, -19666, 7523, -4061, 391, - -11773, 7502, -3763, 4929, -9478, 13278, 2805, 4496, - 7814, 16419, 12455, -14773, 2127, -2746, 3763, 4847, - 3698, 6978, 4751, -6957, -3581, -45, 6252, 1513, - -4797, -7925, 11270, 16188, -2359, -5269, 9376, -10777, - 7262, 20031, -6515, -2208, -5353, 8085, -1341, -1303, - 7333, 5576, 3625, 5763, -7931, 9833, -3371, -10305, - 6534, -13539, -9971, 997, 8464, -4064, -1495, 1857, - 13624, 5458, 9490, -11086, -4524, 12022, -550, -198, - 408, -8455, -7068, 10289, 9712, -3366, 9028, -7621, - -5243, 2362, 6909, 4672, -4933, -1799, 4709, -4563, - -62, -566, 1624, -7010, 14730, -17791, -3697, -2344, - -1741, 7099, -9509, -6855, -1989, 3495, -2289, 2031, - 12784, 891, 14189, -3963, -5683, 421, -12575, 1724, - -12682, -5970, -8169, 3143, -1824, -5488, -5130, 8536, - 12799, 794, 5738, 3459, -11689, -258, -3738, -3775, - -8742, 2333, 8312, -9383, 10331, 13119, 8398, 10644, - -19433, -6446, -16277, -11793, 16284, 9345, 15222, 15834, - 2009, -7349, 130, -14547, 338, -5998, 3337, 21492, - 2406, 7703, -951, 11196, -564, 3406, 2217, 4806, - 2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492 -}; - -WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32 *seed) -{ - seed[0] = (seed[0] * ((WebRtc_Word32)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1); - return seed[0]; -} - -WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32 *seed) -{ - return (WebRtc_Word16)(WebRtcSpl_IncreaseSeed(seed) >> 16); -} - -WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32 *seed) -{ - return kRandNTable[WebRtcSpl_IncreaseSeed(seed) >> 23]; -} - -// Creates an array of uniformly distributed variables -WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector, - WebRtc_Word16 vector_length, - WebRtc_UWord32* seed) -{ - int i; - for (i = 0; i < vector_length; i++) - { - vector[i] = WebRtcSpl_RandU(seed); - } - return vector_length; -} diff --git a/src/mod/codecs/mod_isac/refl_coef_to_lpc.c b/src/mod/codecs/mod_isac/refl_coef_to_lpc.c deleted file mode 100644 index d07804dee7..0000000000 --- a/src/mod/codecs/mod_isac/refl_coef_to_lpc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_ReflCoefToLpc(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a) -{ - WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; - WebRtc_Word16 *aptr, *aptr2, *anyptr; - G_CONST WebRtc_Word16 *kptr; - int m, i; - - kptr = k; - *a = 4096; // i.e., (Word16_MAX >> 3)+1. - *any = *a; - a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3); - - for (m = 1; m < use_order; m++) - { - kptr++; - aptr = a; - aptr++; - aptr2 = &a[m]; - anyptr = any; - anyptr++; - - any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3); - for (i = 0; i < m; i++) - { - *anyptr = (*aptr) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15); - anyptr++; - aptr++; - aptr2--; - } - - aptr = a; - anyptr = any; - for (i = 0; i < (m + 2); i++) - { - *aptr = *anyptr; - aptr++; - anyptr++; - } - } -} diff --git a/src/mod/codecs/mod_isac/resample.c b/src/mod/codecs/mod_isac/resample.c deleted file mode 100644 index 19d1778558..0000000000 --- a/src/mod/codecs/mod_isac/resample.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the resampling functions for 22 kHz. - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" -#include "resample_by_2_internal.h" - -// Declaration of internally used functions -static void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, WebRtc_Word16 *Out, - const WebRtc_Word32 K); - -void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K); - -// interpolation coefficients -static const WebRtc_Word16 kCoefficients32To22[5][9] = { - {127, -712, 2359, -6333, 23456, 16775, -3695, 945, -154}, - {-39, 230, -830, 2785, 32366, -2324, 760, -218, 38}, - {117, -663, 2222, -6133, 26634, 13070, -3174, 831, -137}, - {-77, 457, -1677, 5958, 31175, -4136, 1405, -408, 71}, - { 98, -560, 1900, -5406, 29240, 9423, -2480, 663, -110} -}; - -////////////////////// -// 22 kHz -> 16 kHz // -////////////////////// - -// number of subblocks; options: 1, 2, 4, 5, 10 -#define SUB_BLOCKS_22_16 5 - -// 22 -> 16 resampler -void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State22khzTo16khz* state, WebRtc_Word32* tmpmem) -{ - int k; - - // process two blocks of 10/SUB_BLOCKS_22_16 ms (to reduce temp buffer size) - for (k = 0; k < SUB_BLOCKS_22_16; k++) - { - ///// 22 --> 44 ///// - // WebRtc_Word16 in[220/SUB_BLOCKS_22_16] - // WebRtc_Word32 out[440/SUB_BLOCKS_22_16] - ///// - WebRtcSpl_UpBy2ShortToInt(in, 220 / SUB_BLOCKS_22_16, tmpmem + 16, state->S_22_44); - - ///// 44 --> 32 ///// - // WebRtc_Word32 in[440/SUB_BLOCKS_22_16] - // WebRtc_Word32 out[320/SUB_BLOCKS_22_16] - ///// - // copy state to and from input array - tmpmem[8] = state->S_44_32[0]; - tmpmem[9] = state->S_44_32[1]; - tmpmem[10] = state->S_44_32[2]; - tmpmem[11] = state->S_44_32[3]; - tmpmem[12] = state->S_44_32[4]; - tmpmem[13] = state->S_44_32[5]; - tmpmem[14] = state->S_44_32[6]; - tmpmem[15] = state->S_44_32[7]; - state->S_44_32[0] = tmpmem[440 / SUB_BLOCKS_22_16 + 8]; - state->S_44_32[1] = tmpmem[440 / SUB_BLOCKS_22_16 + 9]; - state->S_44_32[2] = tmpmem[440 / SUB_BLOCKS_22_16 + 10]; - state->S_44_32[3] = tmpmem[440 / SUB_BLOCKS_22_16 + 11]; - state->S_44_32[4] = tmpmem[440 / SUB_BLOCKS_22_16 + 12]; - state->S_44_32[5] = tmpmem[440 / SUB_BLOCKS_22_16 + 13]; - state->S_44_32[6] = tmpmem[440 / SUB_BLOCKS_22_16 + 14]; - state->S_44_32[7] = tmpmem[440 / SUB_BLOCKS_22_16 + 15]; - - WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 40 / SUB_BLOCKS_22_16); - - ///// 32 --> 16 ///// - // WebRtc_Word32 in[320/SUB_BLOCKS_22_16] - // WebRtc_Word32 out[160/SUB_BLOCKS_22_16] - ///// - WebRtcSpl_DownBy2IntToShort(tmpmem, 320 / SUB_BLOCKS_22_16, out, state->S_32_16); - - // move input/output pointers 10/SUB_BLOCKS_22_16 ms seconds ahead - in += 220 / SUB_BLOCKS_22_16; - out += 160 / SUB_BLOCKS_22_16; - } -} - -// initialize state of 22 -> 16 resampler -void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state) -{ - int k; - for (k = 0; k < 8; k++) - { - state->S_22_44[k] = 0; - state->S_44_32[k] = 0; - state->S_32_16[k] = 0; - } -} - -////////////////////// -// 16 kHz -> 22 kHz // -////////////////////// - -// number of subblocks; options: 1, 2, 4, 5, 10 -#define SUB_BLOCKS_16_22 4 - -// 16 -> 22 resampler -void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State16khzTo22khz* state, WebRtc_Word32* tmpmem) -{ - int k; - - // process two blocks of 10/SUB_BLOCKS_16_22 ms (to reduce temp buffer size) - for (k = 0; k < SUB_BLOCKS_16_22; k++) - { - ///// 16 --> 32 ///// - // WebRtc_Word16 in[160/SUB_BLOCKS_16_22] - // WebRtc_Word32 out[320/SUB_BLOCKS_16_22] - ///// - WebRtcSpl_UpBy2ShortToInt(in, 160 / SUB_BLOCKS_16_22, tmpmem + 8, state->S_16_32); - - ///// 32 --> 22 ///// - // WebRtc_Word32 in[320/SUB_BLOCKS_16_22] - // WebRtc_Word32 out[220/SUB_BLOCKS_16_22] - ///// - // copy state to and from input array - tmpmem[0] = state->S_32_22[0]; - tmpmem[1] = state->S_32_22[1]; - tmpmem[2] = state->S_32_22[2]; - tmpmem[3] = state->S_32_22[3]; - tmpmem[4] = state->S_32_22[4]; - tmpmem[5] = state->S_32_22[5]; - tmpmem[6] = state->S_32_22[6]; - tmpmem[7] = state->S_32_22[7]; - state->S_32_22[0] = tmpmem[320 / SUB_BLOCKS_16_22]; - state->S_32_22[1] = tmpmem[320 / SUB_BLOCKS_16_22 + 1]; - state->S_32_22[2] = tmpmem[320 / SUB_BLOCKS_16_22 + 2]; - state->S_32_22[3] = tmpmem[320 / SUB_BLOCKS_16_22 + 3]; - state->S_32_22[4] = tmpmem[320 / SUB_BLOCKS_16_22 + 4]; - state->S_32_22[5] = tmpmem[320 / SUB_BLOCKS_16_22 + 5]; - state->S_32_22[6] = tmpmem[320 / SUB_BLOCKS_16_22 + 6]; - state->S_32_22[7] = tmpmem[320 / SUB_BLOCKS_16_22 + 7]; - - WebRtcSpl_32khzTo22khzIntToShort(tmpmem, out, 20 / SUB_BLOCKS_16_22); - - // move input/output pointers 10/SUB_BLOCKS_16_22 ms seconds ahead - in += 160 / SUB_BLOCKS_16_22; - out += 220 / SUB_BLOCKS_16_22; - } -} - -// initialize state of 16 -> 22 resampler -void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state) -{ - int k; - for (k = 0; k < 8; k++) - { - state->S_16_32[k] = 0; - state->S_32_22[k] = 0; - } -} - -////////////////////// -// 22 kHz -> 8 kHz // -////////////////////// - -// number of subblocks; options: 1, 2, 5, 10 -#define SUB_BLOCKS_22_8 2 - -// 22 -> 8 resampler -void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State22khzTo8khz* state, WebRtc_Word32* tmpmem) -{ - int k; - - // process two blocks of 10/SUB_BLOCKS_22_8 ms (to reduce temp buffer size) - for (k = 0; k < SUB_BLOCKS_22_8; k++) - { - ///// 22 --> 22 lowpass ///// - // WebRtc_Word16 in[220/SUB_BLOCKS_22_8] - // WebRtc_Word32 out[220/SUB_BLOCKS_22_8] - ///// - WebRtcSpl_LPBy2ShortToInt(in, 220 / SUB_BLOCKS_22_8, tmpmem + 16, state->S_22_22); - - ///// 22 --> 16 ///// - // WebRtc_Word32 in[220/SUB_BLOCKS_22_8] - // WebRtc_Word32 out[160/SUB_BLOCKS_22_8] - ///// - // copy state to and from input array - tmpmem[8] = state->S_22_16[0]; - tmpmem[9] = state->S_22_16[1]; - tmpmem[10] = state->S_22_16[2]; - tmpmem[11] = state->S_22_16[3]; - tmpmem[12] = state->S_22_16[4]; - tmpmem[13] = state->S_22_16[5]; - tmpmem[14] = state->S_22_16[6]; - tmpmem[15] = state->S_22_16[7]; - state->S_22_16[0] = tmpmem[220 / SUB_BLOCKS_22_8 + 8]; - state->S_22_16[1] = tmpmem[220 / SUB_BLOCKS_22_8 + 9]; - state->S_22_16[2] = tmpmem[220 / SUB_BLOCKS_22_8 + 10]; - state->S_22_16[3] = tmpmem[220 / SUB_BLOCKS_22_8 + 11]; - state->S_22_16[4] = tmpmem[220 / SUB_BLOCKS_22_8 + 12]; - state->S_22_16[5] = tmpmem[220 / SUB_BLOCKS_22_8 + 13]; - state->S_22_16[6] = tmpmem[220 / SUB_BLOCKS_22_8 + 14]; - state->S_22_16[7] = tmpmem[220 / SUB_BLOCKS_22_8 + 15]; - - WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 20 / SUB_BLOCKS_22_8); - - ///// 16 --> 8 ///// - // WebRtc_Word32 in[160/SUB_BLOCKS_22_8] - // WebRtc_Word32 out[80/SUB_BLOCKS_22_8] - ///// - WebRtcSpl_DownBy2IntToShort(tmpmem, 160 / SUB_BLOCKS_22_8, out, state->S_16_8); - - // move input/output pointers 10/SUB_BLOCKS_22_8 ms seconds ahead - in += 220 / SUB_BLOCKS_22_8; - out += 80 / SUB_BLOCKS_22_8; - } -} - -// initialize state of 22 -> 8 resampler -void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state) -{ - int k; - for (k = 0; k < 8; k++) - { - state->S_22_22[k] = 0; - state->S_22_22[k + 8] = 0; - state->S_22_16[k] = 0; - state->S_16_8[k] = 0; - } -} - -////////////////////// -// 8 kHz -> 22 kHz // -////////////////////// - -// number of subblocks; options: 1, 2, 5, 10 -#define SUB_BLOCKS_8_22 2 - -// 8 -> 22 resampler -void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State8khzTo22khz* state, WebRtc_Word32* tmpmem) -{ - int k; - - // process two blocks of 10/SUB_BLOCKS_8_22 ms (to reduce temp buffer size) - for (k = 0; k < SUB_BLOCKS_8_22; k++) - { - ///// 8 --> 16 ///// - // WebRtc_Word16 in[80/SUB_BLOCKS_8_22] - // WebRtc_Word32 out[160/SUB_BLOCKS_8_22] - ///// - WebRtcSpl_UpBy2ShortToInt(in, 80 / SUB_BLOCKS_8_22, tmpmem + 18, state->S_8_16); - - ///// 16 --> 11 ///// - // WebRtc_Word32 in[160/SUB_BLOCKS_8_22] - // WebRtc_Word32 out[110/SUB_BLOCKS_8_22] - ///// - // copy state to and from input array - tmpmem[10] = state->S_16_11[0]; - tmpmem[11] = state->S_16_11[1]; - tmpmem[12] = state->S_16_11[2]; - tmpmem[13] = state->S_16_11[3]; - tmpmem[14] = state->S_16_11[4]; - tmpmem[15] = state->S_16_11[5]; - tmpmem[16] = state->S_16_11[6]; - tmpmem[17] = state->S_16_11[7]; - state->S_16_11[0] = tmpmem[160 / SUB_BLOCKS_8_22 + 10]; - state->S_16_11[1] = tmpmem[160 / SUB_BLOCKS_8_22 + 11]; - state->S_16_11[2] = tmpmem[160 / SUB_BLOCKS_8_22 + 12]; - state->S_16_11[3] = tmpmem[160 / SUB_BLOCKS_8_22 + 13]; - state->S_16_11[4] = tmpmem[160 / SUB_BLOCKS_8_22 + 14]; - state->S_16_11[5] = tmpmem[160 / SUB_BLOCKS_8_22 + 15]; - state->S_16_11[6] = tmpmem[160 / SUB_BLOCKS_8_22 + 16]; - state->S_16_11[7] = tmpmem[160 / SUB_BLOCKS_8_22 + 17]; - - WebRtcSpl_32khzTo22khzIntToInt(tmpmem + 10, tmpmem, 10 / SUB_BLOCKS_8_22); - - ///// 11 --> 22 ///// - // WebRtc_Word32 in[110/SUB_BLOCKS_8_22] - // WebRtc_Word16 out[220/SUB_BLOCKS_8_22] - ///// - WebRtcSpl_UpBy2IntToShort(tmpmem, 110 / SUB_BLOCKS_8_22, out, state->S_11_22); - - // move input/output pointers 10/SUB_BLOCKS_8_22 ms seconds ahead - in += 80 / SUB_BLOCKS_8_22; - out += 220 / SUB_BLOCKS_8_22; - } -} - -// initialize state of 8 -> 22 resampler -void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state) -{ - int k; - for (k = 0; k < 8; k++) - { - state->S_8_16[k] = 0; - state->S_16_11[k] = 0; - state->S_11_22[k] = 0; - } -} - -// compute two inner-products and store them to output array -static void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Word32* in2, - const WebRtc_Word16* coef_ptr, WebRtc_Word32* out1, - WebRtc_Word32* out2) -{ - WebRtc_Word32 tmp1 = 16384; - WebRtc_Word32 tmp2 = 16384; - WebRtc_Word16 coef; - - coef = coef_ptr[0]; - tmp1 += coef * in1[0]; - tmp2 += coef * in2[-0]; - - coef = coef_ptr[1]; - tmp1 += coef * in1[1]; - tmp2 += coef * in2[-1]; - - coef = coef_ptr[2]; - tmp1 += coef * in1[2]; - tmp2 += coef * in2[-2]; - - coef = coef_ptr[3]; - tmp1 += coef * in1[3]; - tmp2 += coef * in2[-3]; - - coef = coef_ptr[4]; - tmp1 += coef * in1[4]; - tmp2 += coef * in2[-4]; - - coef = coef_ptr[5]; - tmp1 += coef * in1[5]; - tmp2 += coef * in2[-5]; - - coef = coef_ptr[6]; - tmp1 += coef * in1[6]; - tmp2 += coef * in2[-6]; - - coef = coef_ptr[7]; - tmp1 += coef * in1[7]; - tmp2 += coef * in2[-7]; - - coef = coef_ptr[8]; - *out1 = tmp1 + coef * in1[8]; - *out2 = tmp2 + coef * in2[-8]; -} - -// compute two inner-products and store them to output array -static void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_Word32* in2, - const WebRtc_Word16* coef_ptr, WebRtc_Word16* out1, - WebRtc_Word16* out2) -{ - WebRtc_Word32 tmp1 = 16384; - WebRtc_Word32 tmp2 = 16384; - WebRtc_Word16 coef; - - coef = coef_ptr[0]; - tmp1 += coef * in1[0]; - tmp2 += coef * in2[-0]; - - coef = coef_ptr[1]; - tmp1 += coef * in1[1]; - tmp2 += coef * in2[-1]; - - coef = coef_ptr[2]; - tmp1 += coef * in1[2]; - tmp2 += coef * in2[-2]; - - coef = coef_ptr[3]; - tmp1 += coef * in1[3]; - tmp2 += coef * in2[-3]; - - coef = coef_ptr[4]; - tmp1 += coef * in1[4]; - tmp2 += coef * in2[-4]; - - coef = coef_ptr[5]; - tmp1 += coef * in1[5]; - tmp2 += coef * in2[-5]; - - coef = coef_ptr[6]; - tmp1 += coef * in1[6]; - tmp2 += coef * in2[-6]; - - coef = coef_ptr[7]; - tmp1 += coef * in1[7]; - tmp2 += coef * in2[-7]; - - coef = coef_ptr[8]; - tmp1 += coef * in1[8]; - tmp2 += coef * in2[-8]; - - // scale down, round and saturate - tmp1 >>= 15; - if (tmp1 > (WebRtc_Word32)0x00007FFF) - tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) - tmp1 = 0xFFFF8000; - tmp2 >>= 15; - if (tmp2 > (WebRtc_Word32)0x00007FFF) - tmp2 = 0x00007FFF; - if (tmp2 < (WebRtc_Word32)0xFFFF8000) - tmp2 = 0xFFFF8000; - *out1 = (WebRtc_Word16)tmp1; - *out2 = (WebRtc_Word16)tmp2; -} - -// Resampling ratio: 11/16 -// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 11 * K -// K: Number of blocks - -void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In, - WebRtc_Word32* Out, - const WebRtc_Word32 K) -{ - ///////////////////////////////////////////////////////////// - // Filter operation: - // - // Perform resampling (16 input samples -> 11 output samples); - // process in sub blocks of size 16 samples. - WebRtc_Word32 m; - - for (m = 0; m < K; m++) - { - // first output sample - Out[0] = ((WebRtc_Word32)In[3] << 15) + (1 << 14); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToInt(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToInt(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToInt(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToInt(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToInt(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]); - - // update pointers - In += 16; - Out += 11; - } -} - -// Resampling ratio: 11/16 -// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K -// output: WebRtc_Word16 (saturated) :: size 11 * K -// K: Number of blocks - -void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, - WebRtc_Word16 *Out, - const WebRtc_Word32 K) -{ - ///////////////////////////////////////////////////////////// - // Filter operation: - // - // Perform resampling (16 input samples -> 11 output samples); - // process in sub blocks of size 16 samples. - WebRtc_Word32 tmp; - WebRtc_Word32 m; - - for (m = 0; m < K; m++) - { - // first output sample - tmp = In[3]; - if (tmp > (WebRtc_Word32)0x00007FFF) - tmp = 0x00007FFF; - if (tmp < (WebRtc_Word32)0xFFFF8000) - tmp = 0xFFFF8000; - Out[0] = (WebRtc_Word16)tmp; - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToShort(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToShort(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToShort(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToShort(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_DotProdIntToShort(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]); - - // update pointers - In += 16; - Out += 11; - } -} diff --git a/src/mod/codecs/mod_isac/resample_48khz.c b/src/mod/codecs/mod_isac/resample_48khz.c deleted file mode 100644 index 31cbe6b6a9..0000000000 --- a/src/mod/codecs/mod_isac/resample_48khz.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains resampling functions between 48 kHz and nb/wb. - * The description header can be found in signal_processing_library.h - * - */ - -#include -#include "signal_processing_library.h" -#include "resample_by_2_internal.h" - -//////////////////////////// -///// 48 kHz -> 16 kHz ///// -//////////////////////////// - -// 48 -> 16 resampler -void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State48khzTo16khz* state, WebRtc_Word32* tmpmem) -{ - ///// 48 --> 48(LP) ///// - // WebRtc_Word16 in[480] - // WebRtc_Word32 out[480] - ///// - WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48); - - ///// 48 --> 32 ///// - // WebRtc_Word32 in[480] - // WebRtc_Word32 out[320] - ///// - // copy state to and from input array - memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(WebRtc_Word32)); - WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160); - - ///// 32 --> 16 ///// - // WebRtc_Word32 in[320] - // WebRtc_Word16 out[160] - ///// - WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16); -} - -// initialize state of 48 -> 16 resampler -void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state) -{ - memset(state->S_48_48, 0, 16 * sizeof(WebRtc_Word32)); - memset(state->S_48_32, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_32_16, 0, 8 * sizeof(WebRtc_Word32)); -} - -//////////////////////////// -///// 16 kHz -> 48 kHz ///// -//////////////////////////// - -// 16 -> 48 resampler -void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State16khzTo48khz* state, WebRtc_Word32* tmpmem) -{ - ///// 16 --> 32 ///// - // WebRtc_Word16 in[160] - // WebRtc_Word32 out[320] - ///// - WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32); - - ///// 32 --> 24 ///// - // WebRtc_Word32 in[320] - // WebRtc_Word32 out[240] - // copy state to and from input array - ///// - memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(WebRtc_Word32)); - WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80); - - ///// 24 --> 48 ///// - // WebRtc_Word32 in[240] - // WebRtc_Word16 out[480] - ///// - WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); -} - -// initialize state of 16 -> 48 resampler -void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state) -{ - memset(state->S_16_32, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_32_24, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32)); -} - -//////////////////////////// -///// 48 kHz -> 8 kHz ///// -//////////////////////////// - -// 48 -> 8 resampler -void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State48khzTo8khz* state, WebRtc_Word32* tmpmem) -{ - ///// 48 --> 24 ///// - // WebRtc_Word16 in[480] - // WebRtc_Word32 out[240] - ///// - WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24); - - ///// 24 --> 24(LP) ///// - // WebRtc_Word32 in[240] - // WebRtc_Word32 out[240] - ///// - WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24); - - ///// 24 --> 16 ///// - // WebRtc_Word32 in[240] - // WebRtc_Word32 out[160] - ///// - // copy state to and from input array - memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(WebRtc_Word32)); - WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80); - - ///// 16 --> 8 ///// - // WebRtc_Word32 in[160] - // WebRtc_Word16 out[80] - ///// - WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8); -} - -// initialize state of 48 -> 8 resampler -void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state) -{ - memset(state->S_48_24, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_24_24, 0, 16 * sizeof(WebRtc_Word32)); - memset(state->S_24_16, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_16_8, 0, 8 * sizeof(WebRtc_Word32)); -} - -//////////////////////////// -///// 8 kHz -> 48 kHz ///// -//////////////////////////// - -// 8 -> 48 resampler -void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State8khzTo48khz* state, WebRtc_Word32* tmpmem) -{ - ///// 8 --> 16 ///// - // WebRtc_Word16 in[80] - // WebRtc_Word32 out[160] - ///// - WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16); - - ///// 16 --> 12 ///// - // WebRtc_Word32 in[160] - // WebRtc_Word32 out[120] - ///// - // copy state to and from input array - memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(WebRtc_Word32)); - WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40); - - ///// 12 --> 24 ///// - // WebRtc_Word32 in[120] - // WebRtc_Word16 out[240] - ///// - WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24); - - ///// 24 --> 48 ///// - // WebRtc_Word32 in[240] - // WebRtc_Word16 out[480] - ///// - WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); -} - -// initialize state of 8 -> 48 resampler -void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state) -{ - memset(state->S_8_16, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_16_12, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_12_24, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32)); -} diff --git a/src/mod/codecs/mod_isac/resample_by_2.c b/src/mod/codecs/mod_isac/resample_by_2.c deleted file mode 100644 index ead598d2c6..0000000000 --- a/src/mod/codecs/mod_isac/resample_by_2.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the resampling by two functions. - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#ifdef WEBRTC_ARCH_ARM_V7A - -// allpass filter coefficients. -static const WebRtc_UWord32 kResampleAllpass1[3] = {3284, 24441, 49528 << 15}; -static const WebRtc_UWord32 kResampleAllpass2[3] = - {12199, 37471 << 15, 60255 << 15}; - -// Multiply two 32-bit values and accumulate to another input value. -// Return: state + ((diff * tbl_value) >> 16) - -static __inline WebRtc_Word32 MUL_ACCUM_1(WebRtc_Word32 tbl_value, - WebRtc_Word32 diff, - WebRtc_Word32 state) { - WebRtc_Word32 result; - __asm__("smlawb %r0, %r1, %r2, %r3": "=r"(result): "r"(diff), - "r"(tbl_value), "r"(state)); - return result; -} - -// Multiply two 32-bit values and accumulate to another input value. -// Return: Return: state + (((diff << 1) * tbl_value) >> 32) -// -// The reason to introduce this function is that, in case we can't use smlawb -// instruction (in MUL_ACCUM_1) due to input value range, we can still use -// smmla to save some cycles. - -static __inline WebRtc_Word32 MUL_ACCUM_2(WebRtc_Word32 tbl_value, - WebRtc_Word32 diff, - WebRtc_Word32 state) { - WebRtc_Word32 result; - __asm__("smmla %r0, %r1, %r2, %r3": "=r"(result): "r"(diff << 1), - "r"(tbl_value), "r"(state)); - return result; -} - -#else - -// allpass filter coefficients. -static const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528}; -static const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255}; - -// Multiply a 32-bit value with a 16-bit value and accumulate to another input: -#define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c) -#define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c) - -#endif // WEBRTC_ARCH_ARM_V7A - - -// decimator -void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, - WebRtc_Word16* out, WebRtc_Word32* filtState) { - WebRtc_Word32 tmp1, tmp2, diff, in32, out32; - WebRtc_Word16 i; - - register WebRtc_Word32 state0 = filtState[0]; - register WebRtc_Word32 state1 = filtState[1]; - register WebRtc_Word32 state2 = filtState[2]; - register WebRtc_Word32 state3 = filtState[3]; - register WebRtc_Word32 state4 = filtState[4]; - register WebRtc_Word32 state5 = filtState[5]; - register WebRtc_Word32 state6 = filtState[6]; - register WebRtc_Word32 state7 = filtState[7]; - - for (i = (len >> 1); i > 0; i--) { - // lower allpass filter - in32 = (WebRtc_Word32)(*in++) << 10; - diff = in32 - state1; - tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0); - state0 = in32; - diff = tmp1 - state2; - tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1); - state1 = tmp1; - diff = tmp2 - state3; - state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2); - state2 = tmp2; - - // upper allpass filter - in32 = (WebRtc_Word32)(*in++) << 10; - diff = in32 - state5; - tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4); - state4 = in32; - diff = tmp1 - state6; - tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5); - state5 = tmp1; - diff = tmp2 - state7; - state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6); - state6 = tmp2; - - // add two allpass outputs, divide by two and round - out32 = (state3 + state7 + 1024) >> 11; - - // limit amplitude to prevent wrap-around, and write to output array - *out++ = WebRtcSpl_SatW32ToW16(out32); - } - - filtState[0] = state0; - filtState[1] = state1; - filtState[2] = state2; - filtState[3] = state3; - filtState[4] = state4; - filtState[5] = state5; - filtState[6] = state6; - filtState[7] = state7; -} - - -void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, - WebRtc_Word16* out, WebRtc_Word32* filtState) { - WebRtc_Word32 tmp1, tmp2, diff, in32, out32; - WebRtc_Word16 i; - - register WebRtc_Word32 state0 = filtState[0]; - register WebRtc_Word32 state1 = filtState[1]; - register WebRtc_Word32 state2 = filtState[2]; - register WebRtc_Word32 state3 = filtState[3]; - register WebRtc_Word32 state4 = filtState[4]; - register WebRtc_Word32 state5 = filtState[5]; - register WebRtc_Word32 state6 = filtState[6]; - register WebRtc_Word32 state7 = filtState[7]; - - for (i = len; i > 0; i--) { - // lower allpass filter - in32 = (WebRtc_Word32)(*in++) << 10; - diff = in32 - state1; - tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state0); - state0 = in32; - diff = tmp1 - state2; - tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state1); - state1 = tmp1; - diff = tmp2 - state3; - state3 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state2); - state2 = tmp2; - - // round; limit amplitude to prevent wrap-around; write to output array - out32 = (state3 + 512) >> 10; - *out++ = WebRtcSpl_SatW32ToW16(out32); - - // upper allpass filter - diff = in32 - state5; - tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state4); - state4 = in32; - diff = tmp1 - state6; - tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state5); - state5 = tmp1; - diff = tmp2 - state7; - state7 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state6); - state6 = tmp2; - - // round; limit amplitude to prevent wrap-around; write to output array - out32 = (state7 + 512) >> 10; - *out++ = WebRtcSpl_SatW32ToW16(out32); - } - - filtState[0] = state0; - filtState[1] = state1; - filtState[2] = state2; - filtState[3] = state3; - filtState[4] = state4; - filtState[5] = state5; - filtState[6] = state6; - filtState[7] = state7; -} diff --git a/src/mod/codecs/mod_isac/resample_by_2_internal.c b/src/mod/codecs/mod_isac/resample_by_2_internal.c deleted file mode 100644 index cbd2395803..0000000000 --- a/src/mod/codecs/mod_isac/resample_by_2_internal.c +++ /dev/null @@ -1,679 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file contains some internal resampling functions. - * - */ - -#include "resample_by_2_internal.h" - -// allpass filter coefficients. -static const WebRtc_Word16 kResampleAllpass[2][3] = { - {821, 6110, 12382}, - {3050, 9368, 15063} -}; - -// -// decimator -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN! -// output: WebRtc_Word16 (saturated) (of length len/2) -// state: filter state array; length = 8 - -void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, - WebRtc_Word32 *state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - len >>= 1; - - // lower allpass filter (operates on even input samples) - for (i = 0; i < len; i++) - { - tmp0 = in[i << 1]; - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // divide by two and store temporarily - in[i << 1] = (state[3] >> 1); - } - - in++; - - // upper allpass filter (operates on odd input samples) - for (i = 0; i < len; i++) - { - tmp0 = in[i << 1]; - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // divide by two and store temporarily - in[i << 1] = (state[7] >> 1); - } - - in--; - - // combine allpass outputs - for (i = 0; i < len; i += 2) - { - // divide by two, add both allpass outputs and round - tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15; - tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15; - if (tmp0 > (WebRtc_Word32)0x00007FFF) - tmp0 = 0x00007FFF; - if (tmp0 < (WebRtc_Word32)0xFFFF8000) - tmp0 = 0xFFFF8000; - out[i] = (WebRtc_Word16)tmp0; - if (tmp1 > (WebRtc_Word32)0x00007FFF) - tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) - tmp1 = 0xFFFF8000; - out[i + 1] = (WebRtc_Word16)tmp1; - } -} - -// -// decimator -// input: WebRtc_Word16 -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2) -// state: filter state array; length = 8 - -void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, - WebRtc_Word32 len, - WebRtc_Word32 *out, - WebRtc_Word32 *state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - len >>= 1; - - // lower allpass filter (operates on even input samples) - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // divide by two and store temporarily - out[i] = (state[3] >> 1); - } - - in++; - - // upper allpass filter (operates on odd input samples) - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // divide by two and store temporarily - out[i] += (state[7] >> 1); - } - - in--; -} - -// -// interpolator -// input: WebRtc_Word16 -// output: WebRtc_Word32 (normalized, not saturated) (of length len*2) -// state: filter state array; length = 8 -void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out, - WebRtc_Word32 *state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - // upper allpass filter (generates odd output samples) - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14); - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // scale down, round and store - out[i << 1] = state[7] >> 15; - } - - out++; - - // lower allpass filter (generates even output samples) - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14); - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // scale down, round and store - out[i << 1] = state[3] >> 15; - } -} - -// -// interpolator -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2) -// state: filter state array; length = 8 -void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out, - WebRtc_Word32 *state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - // upper allpass filter (generates odd output samples) - for (i = 0; i < len; i++) - { - tmp0 = in[i]; - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // scale down, round and store - out[i << 1] = state[7]; - } - - out++; - - // lower allpass filter (generates even output samples) - for (i = 0; i < len; i++) - { - tmp0 = in[i]; - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // scale down, round and store - out[i << 1] = state[3]; - } -} - -// -// interpolator -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) -// output: WebRtc_Word16 (saturated) (of length len*2) -// state: filter state array; length = 8 -void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, - WebRtc_Word32 *state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - // upper allpass filter (generates odd output samples) - for (i = 0; i < len; i++) - { - tmp0 = in[i]; - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // scale down, saturate and store - tmp1 = state[7] >> 15; - if (tmp1 > (WebRtc_Word32)0x00007FFF) - tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) - tmp1 = 0xFFFF8000; - out[i << 1] = (WebRtc_Word16)tmp1; - } - - out++; - - // lower allpass filter (generates even output samples) - for (i = 0; i < len; i++) - { - tmp0 = in[i]; - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // scale down, saturate and store - tmp1 = state[3] >> 15; - if (tmp1 > (WebRtc_Word32)0x00007FFF) - tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) - tmp1 = 0xFFFF8000; - out[i << 1] = (WebRtc_Word16)tmp1; - } -} - -// lowpass filter -// input: WebRtc_Word16 -// output: WebRtc_Word32 (normalized, not saturated) -// state: filter state array; length = 8 -void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out, - WebRtc_Word32* state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - len >>= 1; - - // lower allpass filter: odd input -> even output samples - in++; - // initial state of polyphase delay element - tmp0 = state[12]; - for (i = 0; i < len; i++) - { - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // scale down, round and store - out[i << 1] = state[3] >> 1; - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); - } - in--; - - // upper allpass filter: even input -> even output samples - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // average the two allpass outputs, scale down and store - out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; - } - - // switch to odd output samples - out++; - - // lower allpass filter: even input -> odd output samples - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); - diff = tmp0 - state[9]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[8] + diff * kResampleAllpass[1][0]; - state[8] = tmp0; - diff = tmp1 - state[10]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[9] + diff * kResampleAllpass[1][1]; - state[9] = tmp1; - diff = tmp0 - state[11]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[11] = state[10] + diff * kResampleAllpass[1][2]; - state[10] = tmp0; - - // scale down, round and store - out[i << 1] = state[11] >> 1; - } - - // upper allpass filter: odd input -> odd output samples - in++; - for (i = 0; i < len; i++) - { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); - diff = tmp0 - state[13]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[12] + diff * kResampleAllpass[0][0]; - state[12] = tmp0; - diff = tmp1 - state[14]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[13] + diff * kResampleAllpass[0][1]; - state[13] = tmp1; - diff = tmp0 - state[15]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[15] = state[14] + diff * kResampleAllpass[0][2]; - state[14] = tmp0; - - // average the two allpass outputs, scale down and store - out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; - } -} - -// lowpass filter -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) -// output: WebRtc_Word32 (normalized, not saturated) -// state: filter state array; length = 8 -void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out, - WebRtc_Word32* state) -{ - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; - - len >>= 1; - - // lower allpass filter: odd input -> even output samples - in++; - // initial state of polyphase delay element - tmp0 = state[12]; - for (i = 0; i < len; i++) - { - diff = tmp0 - state[1]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[0] + diff * kResampleAllpass[1][0]; - state[0] = tmp0; - diff = tmp1 - state[2]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[1] + diff * kResampleAllpass[1][1]; - state[1] = tmp1; - diff = tmp0 - state[3]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[3] = state[2] + diff * kResampleAllpass[1][2]; - state[2] = tmp0; - - // scale down, round and store - out[i << 1] = state[3] >> 1; - tmp0 = in[i << 1]; - } - in--; - - // upper allpass filter: even input -> even output samples - for (i = 0; i < len; i++) - { - tmp0 = in[i << 1]; - diff = tmp0 - state[5]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[4] + diff * kResampleAllpass[0][0]; - state[4] = tmp0; - diff = tmp1 - state[6]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[5] + diff * kResampleAllpass[0][1]; - state[5] = tmp1; - diff = tmp0 - state[7]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[7] = state[6] + diff * kResampleAllpass[0][2]; - state[6] = tmp0; - - // average the two allpass outputs, scale down and store - out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; - } - - // switch to odd output samples - out++; - - // lower allpass filter: even input -> odd output samples - for (i = 0; i < len; i++) - { - tmp0 = in[i << 1]; - diff = tmp0 - state[9]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[8] + diff * kResampleAllpass[1][0]; - state[8] = tmp0; - diff = tmp1 - state[10]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[9] + diff * kResampleAllpass[1][1]; - state[9] = tmp1; - diff = tmp0 - state[11]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[11] = state[10] + diff * kResampleAllpass[1][2]; - state[10] = tmp0; - - // scale down, round and store - out[i << 1] = state[11] >> 1; - } - - // upper allpass filter: odd input -> odd output samples - in++; - for (i = 0; i < len; i++) - { - tmp0 = in[i << 1]; - diff = tmp0 - state[13]; - // scale down and round - diff = (diff + (1 << 13)) >> 14; - tmp1 = state[12] + diff * kResampleAllpass[0][0]; - state[12] = tmp0; - diff = tmp1 - state[14]; - // scale down and round - diff = diff >> 14; - if (diff < 0) - diff += 1; - tmp0 = state[13] + diff * kResampleAllpass[0][1]; - state[13] = tmp1; - diff = tmp0 - state[15]; - // scale down and truncate - diff = diff >> 14; - if (diff < 0) - diff += 1; - state[15] = state[14] + diff * kResampleAllpass[0][2]; - state[14] = tmp0; - - // average the two allpass outputs, scale down and store - out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; - } -} diff --git a/src/mod/codecs/mod_isac/resample_by_2_internal.h b/src/mod/codecs/mod_isac/resample_by_2_internal.h deleted file mode 100644 index b6ac9f0cb4..0000000000 --- a/src/mod/codecs/mod_isac/resample_by_2_internal.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file contains some internal resampling functions. - * - */ - -#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ -#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ - -#include "typedefs.h" - -/******************************************************************* - * resample_by_2_fast.c - * Functions for internal use in the other resample functions - ******************************************************************/ -void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, - WebRtc_Word32 *state); - -void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, - WebRtc_Word32 *out, WebRtc_Word32 *state); - -void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, - WebRtc_Word32 *out, WebRtc_Word32 *state); - -void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out, - WebRtc_Word32 *state); - -void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, - WebRtc_Word16 *out, WebRtc_Word32 *state); - -void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, - WebRtc_Word32* out, WebRtc_Word32* state); - -void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out, - WebRtc_Word32* state); - -#endif // WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ diff --git a/src/mod/codecs/mod_isac/resample_fractional.c b/src/mod/codecs/mod_isac/resample_fractional.c deleted file mode 100644 index 51003d45d7..0000000000 --- a/src/mod/codecs/mod_isac/resample_fractional.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the resampling functions between 48, 44, 32 and 24 kHz. - * The description headers can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -// interpolation coefficients -static const WebRtc_Word16 kCoefficients48To32[2][8] = { - {778, -2050, 1087, 23285, 12903, -3783, 441, 222}, - {222, 441, -3783, 12903, 23285, 1087, -2050, 778} -}; - -static const WebRtc_Word16 kCoefficients32To24[3][8] = { - {767, -2362, 2434, 24406, 10620, -3838, 721, 90}, - {386, -381, -2646, 19062, 19062, -2646, -381, 386}, - {90, 721, -3838, 10620, 24406, 2434, -2362, 767} -}; - -static const WebRtc_Word16 kCoefficients44To32[4][9] = { - {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138}, - {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91}, - {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53}, - {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126} -}; - -// Resampling ratio: 2/3 -// input: WebRtc_Word32 (normalized, not saturated) :: size 3 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K -// K: number of blocks - -void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K) -{ - ///////////////////////////////////////////////////////////// - // Filter operation: - // - // Perform resampling (3 input samples -> 2 output samples); - // process in sub blocks of size 3 samples. - WebRtc_Word32 tmp; - WebRtc_Word32 m; - - for (m = 0; m < K; m++) - { - tmp = 1 << 14; - tmp += kCoefficients48To32[0][0] * In[0]; - tmp += kCoefficients48To32[0][1] * In[1]; - tmp += kCoefficients48To32[0][2] * In[2]; - tmp += kCoefficients48To32[0][3] * In[3]; - tmp += kCoefficients48To32[0][4] * In[4]; - tmp += kCoefficients48To32[0][5] * In[5]; - tmp += kCoefficients48To32[0][6] * In[6]; - tmp += kCoefficients48To32[0][7] * In[7]; - Out[0] = tmp; - - tmp = 1 << 14; - tmp += kCoefficients48To32[1][0] * In[1]; - tmp += kCoefficients48To32[1][1] * In[2]; - tmp += kCoefficients48To32[1][2] * In[3]; - tmp += kCoefficients48To32[1][3] * In[4]; - tmp += kCoefficients48To32[1][4] * In[5]; - tmp += kCoefficients48To32[1][5] * In[6]; - tmp += kCoefficients48To32[1][6] * In[7]; - tmp += kCoefficients48To32[1][7] * In[8]; - Out[1] = tmp; - - // update pointers - In += 3; - Out += 2; - } -} - -// Resampling ratio: 3/4 -// input: WebRtc_Word32 (normalized, not saturated) :: size 4 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K -// K: number of blocks - -void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K) -{ - ///////////////////////////////////////////////////////////// - // Filter operation: - // - // Perform resampling (4 input samples -> 3 output samples); - // process in sub blocks of size 4 samples. - WebRtc_Word32 m; - WebRtc_Word32 tmp; - - for (m = 0; m < K; m++) - { - tmp = 1 << 14; - tmp += kCoefficients32To24[0][0] * In[0]; - tmp += kCoefficients32To24[0][1] * In[1]; - tmp += kCoefficients32To24[0][2] * In[2]; - tmp += kCoefficients32To24[0][3] * In[3]; - tmp += kCoefficients32To24[0][4] * In[4]; - tmp += kCoefficients32To24[0][5] * In[5]; - tmp += kCoefficients32To24[0][6] * In[6]; - tmp += kCoefficients32To24[0][7] * In[7]; - Out[0] = tmp; - - tmp = 1 << 14; - tmp += kCoefficients32To24[1][0] * In[1]; - tmp += kCoefficients32To24[1][1] * In[2]; - tmp += kCoefficients32To24[1][2] * In[3]; - tmp += kCoefficients32To24[1][3] * In[4]; - tmp += kCoefficients32To24[1][4] * In[5]; - tmp += kCoefficients32To24[1][5] * In[6]; - tmp += kCoefficients32To24[1][6] * In[7]; - tmp += kCoefficients32To24[1][7] * In[8]; - Out[1] = tmp; - - tmp = 1 << 14; - tmp += kCoefficients32To24[2][0] * In[2]; - tmp += kCoefficients32To24[2][1] * In[3]; - tmp += kCoefficients32To24[2][2] * In[4]; - tmp += kCoefficients32To24[2][3] * In[5]; - tmp += kCoefficients32To24[2][4] * In[6]; - tmp += kCoefficients32To24[2][5] * In[7]; - tmp += kCoefficients32To24[2][6] * In[8]; - tmp += kCoefficients32To24[2][7] * In[9]; - Out[2] = tmp; - - // update pointers - In += 4; - Out += 3; - } -} - -// -// fractional resampling filters -// Fout = 11/16 * Fin -// Fout = 8/11 * Fin -// - -// compute two inner-products and store them to output array -static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2, - const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1, - WebRtc_Word32 *out2) -{ - WebRtc_Word32 tmp1 = 16384; - WebRtc_Word32 tmp2 = 16384; - WebRtc_Word16 coef; - - coef = coef_ptr[0]; - tmp1 += coef * in1[0]; - tmp2 += coef * in2[-0]; - - coef = coef_ptr[1]; - tmp1 += coef * in1[1]; - tmp2 += coef * in2[-1]; - - coef = coef_ptr[2]; - tmp1 += coef * in1[2]; - tmp2 += coef * in2[-2]; - - coef = coef_ptr[3]; - tmp1 += coef * in1[3]; - tmp2 += coef * in2[-3]; - - coef = coef_ptr[4]; - tmp1 += coef * in1[4]; - tmp2 += coef * in2[-4]; - - coef = coef_ptr[5]; - tmp1 += coef * in1[5]; - tmp2 += coef * in2[-5]; - - coef = coef_ptr[6]; - tmp1 += coef * in1[6]; - tmp2 += coef * in2[-6]; - - coef = coef_ptr[7]; - tmp1 += coef * in1[7]; - tmp2 += coef * in2[-7]; - - coef = coef_ptr[8]; - *out1 = tmp1 + coef * in1[8]; - *out2 = tmp2 + coef * in2[-8]; -} - -// Resampling ratio: 8/11 -// input: WebRtc_Word32 (normalized, not saturated) :: size 11 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 8 * K -// K: number of blocks - -void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K) -{ - ///////////////////////////////////////////////////////////// - // Filter operation: - // - // Perform resampling (11 input samples -> 8 output samples); - // process in sub blocks of size 11 samples. - WebRtc_Word32 tmp; - WebRtc_Word32 m; - - for (m = 0; m < K; m++) - { - tmp = 1 << 14; - - // first output sample - Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp; - - // sum and accumulate filter coefficients and input samples - tmp += kCoefficients44To32[3][0] * In[5]; - tmp += kCoefficients44To32[3][1] * In[6]; - tmp += kCoefficients44To32[3][2] * In[7]; - tmp += kCoefficients44To32[3][3] * In[8]; - tmp += kCoefficients44To32[3][4] * In[9]; - tmp += kCoefficients44To32[3][5] * In[10]; - tmp += kCoefficients44To32[3][6] * In[11]; - tmp += kCoefficients44To32[3][7] * In[12]; - tmp += kCoefficients44To32[3][8] * In[13]; - Out[4] = tmp; - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]); - - // sum and accumulate filter coefficients and input samples - WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]); - - // update pointers - In += 11; - Out += 8; - } -} diff --git a/src/mod/codecs/mod_isac/settings.h b/src/mod/codecs/mod_isac/settings.h deleted file mode 100644 index b7aed77065..0000000000 --- a/src/mod/codecs/mod_isac/settings.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * settings.h - * - * Declaration of #defines used in the iSAC codec - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_ - -/* sampling frequency (Hz) */ -#define FS 16000 - -/* number of samples per frame (either 320 (20ms), 480 (30ms) or 960 (60ms)) */ -#define INITIAL_FRAMESAMPLES 960 - - -#define MAXFFTSIZE 2048 -#define NFACTOR 11 - - - -/* do not modify the following; this will have to be modified if we have a 20ms framesize option */ -/*************************************************************************************************/ -/* miliseconds */ -#define FRAMESIZE 30 -/* number of samples per frame processed in the encoder, 480 */ -#define FRAMESAMPLES 480 /* ((FRAMESIZE*FS)/1000) */ -#define FRAMESAMPLES_HALF 240 -#define FRAMESAMPLES_QUARTER 120 -/*************************************************************************************************/ - - - -/* max number of samples per frame (= 60 ms frame) */ -#define MAX_FRAMESAMPLES 960 -#define MAX_SWBFRAMESAMPLES (MAX_FRAMESAMPLES * 2) -/* number of samples per 10ms frame */ -#define FRAMESAMPLES_10ms ((10*FS)/1000) -#define SWBFRAMESAMPLES_10ms (FRAMESAMPLES_10ms * 2) -/* number of samples in 30 ms frame */ -#define FRAMESAMPLES_30ms 480 -/* number of subframes */ -#define SUBFRAMES 6 -/* length of a subframe */ -#define UPDATE 80 -/* length of half a subframe (low/high band) */ -#define HALF_SUBFRAMELEN (UPDATE/2) -/* samples of look ahead (in a half-band, so actually half the samples of look ahead @ FS) */ -#define QLOOKAHEAD 24 /* 3 ms */ -/* order of AR model in spectral entropy coder */ -#define AR_ORDER 6 -/* order of LP model in spectral entropy coder */ -#define LP_ORDER 0 - -/* window length (masking analysis) */ -#define WINLEN 256 -/* order of low-band pole filter used to approximate masking curve */ -#define ORDERLO 12 -/* order of hi-band pole filter used to approximate masking curve */ -#define ORDERHI 6 - -#define UB_LPC_ORDER 4 -#define UB_LPC_VEC_PER_FRAME 2 -#define UB16_LPC_VEC_PER_FRAME 4 -#define UB_ACTIVE_SUBFRAMES 2 -#define UB_MAX_LPC_ORDER 6 -#define UB_INTERPOL_SEGMENTS 1 -#define UB16_INTERPOL_SEGMENTS 3 -#define LB_TOTAL_DELAY_SAMPLES 48 -enum ISACBandwidth {isac8kHz = 8, isac12kHz = 12, isac16kHz = 16}; -enum ISACBand{isacLowerBand = 0, isacUpperBand = 1}; -#define UB_LPC_GAIN_DIM SUBFRAMES -#define FB_STATE_SIZE_WORD32 6 - - -/* order for post_filter_bank */ -#define POSTQORDER 3 -/* order for pre-filterbank */ -#define QORDER 3 -/* another order */ -#define QORDER_ALL (POSTQORDER+QORDER-1) -/* for decimator */ -#define ALLPASSSECTIONS 2 - - -/* array size for byte stream in number of bytes. */ -#define STREAM_SIZE_MAX 600 /* The old maximum size still needed for the decoding */ -#define STREAM_SIZE_MAX_30 200 /* 200 bytes = 53.4 kbit/s @ 30 ms.framelength */ -#define STREAM_SIZE_MAX_60 400 /* 400 bytes = 53.4 kbit/s @ 60 ms.framelength */ - -/* storage size for bit counts */ -#define BIT_COUNTER_SIZE 30 -/* maximum order of any AR model or filter */ -#define MAX_AR_MODEL_ORDER 12//50 - - -/* For pitch analysis */ -#define PITCH_FRAME_LEN (FRAMESAMPLES_HALF) /* 30 ms */ -#define PITCH_MAX_LAG 140 /* 57 Hz */ -#define PITCH_MIN_LAG 20 /* 400 Hz */ -#define PITCH_MAX_GAIN 0.45 -#define PITCH_MAX_GAIN_06 0.27 /* PITCH_MAX_GAIN*0.6 */ -#define PITCH_MAX_GAIN_Q12 1843 -#define PITCH_LAG_SPAN2 (PITCH_MAX_LAG/2-PITCH_MIN_LAG/2+5) -#define PITCH_CORR_LEN2 60 /* 15 ms */ -#define PITCH_CORR_STEP2 (PITCH_FRAME_LEN/4) -#define PITCH_BW 11 /* half the band width of correlation surface */ -#define PITCH_SUBFRAMES 4 -#define PITCH_GRAN_PER_SUBFRAME 5 -#define PITCH_SUBFRAME_LEN (PITCH_FRAME_LEN/PITCH_SUBFRAMES) -#define PITCH_UPDATE (PITCH_SUBFRAME_LEN/PITCH_GRAN_PER_SUBFRAME) -/* maximum number of peaks to be examined in correlation surface */ -#define PITCH_MAX_NUM_PEAKS 10 -#define PITCH_PEAK_DECAY 0.85 -/* For weighting filter */ -#define PITCH_WLPCORDER 6 -#define PITCH_WLPCWINLEN PITCH_FRAME_LEN -#define PITCH_WLPCASYM 0.3 /* asymmetry parameter */ -#define PITCH_WLPCBUFLEN PITCH_WLPCWINLEN -/* For pitch filter */ -#define PITCH_BUFFSIZE (PITCH_MAX_LAG + 50) /* Extra 50 for fraction and LP filters */ -#define PITCH_INTBUFFSIZE (PITCH_FRAME_LEN+PITCH_BUFFSIZE) -/* Max rel. step for interpolation */ -#define PITCH_UPSTEP 1.5 -/* Max rel. step for interpolation */ -#define PITCH_DOWNSTEP 0.67 -#define PITCH_FRACS 8 -#define PITCH_FRACORDER 9 -#define PITCH_DAMPORDER 5 -#define PITCH_FILTDELAY 1.5f -/* stepsize for quantization of the pitch Gain */ -#define PITCH_GAIN_STEPSIZE 0.125 - - - -/* Order of high pass filter */ -#define HPORDER 2 - -/* some mathematical constants */ -#define LOG2EXP 1.44269504088896 /* log2(exp) */ -#define PI 3.14159265358979 - -/* Maximum number of iterations allowed to limit payload size */ -#define MAX_PAYLOAD_LIMIT_ITERATION 5 - -/* Redundant Coding */ -#define RCU_BOTTLENECK_BPS 16000 -#define RCU_TRANSCODING_SCALE 0.40f -#define RCU_TRANSCODING_SCALE_INVERSE 2.5f - -#define RCU_TRANSCODING_SCALE_UB 0.50f -#define RCU_TRANSCODING_SCALE_UB_INVERSE 2.0f - - -/* Define Error codes */ -/* 6000 General */ -#define ISAC_MEMORY_ALLOCATION_FAILED 6010 -#define ISAC_MODE_MISMATCH 6020 -#define ISAC_DISALLOWED_BOTTLENECK 6030 -#define ISAC_DISALLOWED_FRAME_LENGTH 6040 -#define ISAC_UNSUPPORTED_SAMPLING_FREQUENCY 6050 - -/* 6200 Bandwidth estimator */ -#define ISAC_RANGE_ERROR_BW_ESTIMATOR 6240 -/* 6400 Encoder */ -#define ISAC_ENCODER_NOT_INITIATED 6410 -#define ISAC_DISALLOWED_CODING_MODE 6420 -#define ISAC_DISALLOWED_FRAME_MODE_ENCODER 6430 -#define ISAC_DISALLOWED_BITSTREAM_LENGTH 6440 -#define ISAC_PAYLOAD_LARGER_THAN_LIMIT 6450 -#define ISAC_DISALLOWED_ENCODER_BANDWIDTH 6460 -/* 6600 Decoder */ -#define ISAC_DECODER_NOT_INITIATED 6610 -#define ISAC_EMPTY_PACKET 6620 -#define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630 -#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640 -#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650 -#define ISAC_RANGE_ERROR_DECODE_PITCH_GAIN 6660 -#define ISAC_RANGE_ERROR_DECODE_PITCH_LAG 6670 -#define ISAC_RANGE_ERROR_DECODE_LPC 6680 -#define ISAC_RANGE_ERROR_DECODE_SPECTRUM 6690 -#define ISAC_LENGTH_MISMATCH 6730 -#define ISAC_RANGE_ERROR_DECODE_BANDWITH 6740 -#define ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER 6750 -/* 6800 Call setup formats */ -#define ISAC_INCOMPATIBLE_FORMATS 6810 - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_ */ diff --git a/src/mod/codecs/mod_isac/signal_processing_library.h b/src/mod/codecs/mod_isac/signal_processing_library.h deleted file mode 100644 index 4433bc175f..0000000000 --- a/src/mod/codecs/mod_isac/signal_processing_library.h +++ /dev/null @@ -1,1686 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes all of the fix point signal processing library (SPL) function - * descriptions and declarations. - * For specific function calls, see bottom of file. - */ - -#ifndef WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ -#define WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ - -#include -#include "typedefs.h" - -#ifdef ARM_WINM -#include // intrinsic file for windows mobile -#endif - -// Macros specific for the fixed point implementation -#define WEBRTC_SPL_WORD16_MAX 32767 -#define WEBRTC_SPL_WORD16_MIN -32768 -#define WEBRTC_SPL_WORD32_MAX (WebRtc_Word32)0x7fffffff -#define WEBRTC_SPL_WORD32_MIN (WebRtc_Word32)0x80000000 -#define WEBRTC_SPL_MAX_LPC_ORDER 14 -#define WEBRTC_SPL_MAX_SEED_USED 0x80000000L -#define WEBRTC_SPL_MIN(A, B) (A < B ? A : B) // Get min value -#define WEBRTC_SPL_MAX(A, B) (A > B ? A : B) // Get max value -#define WEBRTC_SPL_ABS_W16(a) \ - (((WebRtc_Word16)a >= 0) ? ((WebRtc_Word16)a) : -((WebRtc_Word16)a)) -#define WEBRTC_SPL_ABS_W32(a) \ - (((WebRtc_Word32)a >= 0) ? ((WebRtc_Word32)a) : -((WebRtc_Word32)a)) - -#if (defined WEBRTC_TARGET_PC)||(defined __TARGET_XSCALE) -#define WEBRTC_SPL_GET_BYTE(a, nr) (((WebRtc_Word8 *)a)[nr]) -#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ - (((WebRtc_Word8 *)d_ptr)[index] = (val)) -#elif defined WEBRTC_BIG_ENDIAN -#define WEBRTC_SPL_GET_BYTE(a, nr) \ - ((((WebRtc_Word16 *)a)[nr >> 1]) >> (((nr + 1) & 0x1) * 8) & 0x00ff) -#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ - ((WebRtc_Word16 *)d_ptr)[index >> 1] = \ - ((((WebRtc_Word16 *)d_ptr)[index >> 1]) \ - & (0x00ff << (8 * ((index) & 0x1)))) | (val << (8 * ((index + 1) & 0x1))) -#else -#define WEBRTC_SPL_GET_BYTE(a,nr) \ - ((((WebRtc_Word16 *)(a))[(nr) >> 1]) >> (((nr) & 0x1) * 8) & 0x00ff) -#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ - ((WebRtc_Word16 *)(d_ptr))[(index) >> 1] = \ - ((((WebRtc_Word16 *)(d_ptr))[(index) >> 1]) \ - & (0x00ff << (8 * (((index) + 1) & 0x1)))) | \ - ((val) << (8 * ((index) & 0x1))) -#endif - -#define WEBRTC_SPL_MUL(a, b) \ - ((WebRtc_Word32) ((WebRtc_Word32)(a) * (WebRtc_Word32)(b))) -#define WEBRTC_SPL_UMUL(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b))) -#define WEBRTC_SPL_UMUL_RSFT16(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b)) >> 16) -#define WEBRTC_SPL_UMUL_16_16(a, b) \ - ((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) -#define WEBRTC_SPL_UMUL_16_16_RSFT16(a, b) \ - (((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) >> 16) -#define WEBRTC_SPL_UMUL_32_16(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b))) -#define WEBRTC_SPL_UMUL_32_16_RSFT16(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b)) >> 16) -#define WEBRTC_SPL_MUL_16_U16(a, b) \ - ((WebRtc_Word32)(WebRtc_Word16)(a) * (WebRtc_UWord16)(b)) -#define WEBRTC_SPL_DIV(a, b) \ - ((WebRtc_Word32) ((WebRtc_Word32)(a) / (WebRtc_Word32)(b))) -#define WEBRTC_SPL_UDIV(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) / (WebRtc_UWord32)(b))) - -#ifndef WEBRTC_ARCH_ARM_V7A -// For ARMv7 platforms, these are inline functions in spl_inl_armv7.h -#define WEBRTC_SPL_MUL_16_16(a, b) \ - ((WebRtc_Word32) (((WebRtc_Word16)(a)) * ((WebRtc_Word16)(b)))) -#define WEBRTC_SPL_MUL_16_32_RSFT16(a, b) \ - (WEBRTC_SPL_MUL_16_16(a, b >> 16) \ - + ((WEBRTC_SPL_MUL_16_16(a, (b & 0xffff) >> 1) + 0x4000) >> 15)) -#define WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, b32) \ - ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(a32a, b32) \ - + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32) >> 16))) -#define WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, b32) \ - ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(( \ - (WebRtc_Word16)(a32 >> 16)), b32) + \ - (WEBRTC_SPL_MUL_16_32_RSFT16(( \ - (WebRtc_Word16)((a32 & 0x0000FFFF) >> 1)), b32) >> 15))) -#endif - -#define WEBRTC_SPL_MUL_16_32_RSFT11(a, b) \ - ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 5) \ - + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x0200) >> 10)) -#define WEBRTC_SPL_MUL_16_32_RSFT14(a, b) \ - ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 2) \ - + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x1000) >> 13)) -#define WEBRTC_SPL_MUL_16_32_RSFT15(a, b) \ - ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 1) \ - + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x2000) >> 14)) - -#ifdef ARM_WINM -#define WEBRTC_SPL_MUL_16_16(a, b) \ - _SmulLo_SW_SL((WebRtc_Word16)(a), (WebRtc_Word16)(b)) -#endif - -#define WEBRTC_SPL_MUL_16_16_RSFT(a, b, c) \ - (WEBRTC_SPL_MUL_16_16(a, b) >> (c)) - -#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, c) \ - ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) \ - (((WebRtc_Word32)1) << ((c) - 1)))) >> (c)) -#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b) \ - ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) (1 << 14))) >> 15) - -// C + the 32 most significant bits of A * B -#define WEBRTC_SPL_SCALEDIFF32(A, B, C) \ - (C + (B >> 16) * A + (((WebRtc_UWord32)(0x0000FFFF & B) * A) >> 16)) - -#define WEBRTC_SPL_ADD_SAT_W32(a, b) WebRtcSpl_AddSatW32(a, b) -#define WEBRTC_SPL_SAT(a, b, c) (b > a ? a : b < c ? c : b) -#define WEBRTC_SPL_MUL_32_16(a, b) ((a) * (b)) - -#define WEBRTC_SPL_SUB_SAT_W32(a, b) WebRtcSpl_SubSatW32(a, b) -#define WEBRTC_SPL_ADD_SAT_W16(a, b) WebRtcSpl_AddSatW16(a, b) -#define WEBRTC_SPL_SUB_SAT_W16(a, b) WebRtcSpl_SubSatW16(a, b) - -// We cannot do casting here due to signed/unsigned problem -#define WEBRTC_SPL_IS_NEG(a) ((a) & 0x80000000) -// Shifting with negative numbers allowed -// Positive means left shift -#define WEBRTC_SPL_SHIFT_W16(x, c) \ - (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) -#define WEBRTC_SPL_SHIFT_W32(x, c) \ - (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) - -// Shifting with negative numbers not allowed -// We cannot do casting here due to signed/unsigned problem -#define WEBRTC_SPL_RSHIFT_W16(x, c) ((x) >> (c)) -#define WEBRTC_SPL_LSHIFT_W16(x, c) ((x) << (c)) -#define WEBRTC_SPL_RSHIFT_W32(x, c) ((x) >> (c)) -#define WEBRTC_SPL_LSHIFT_W32(x, c) ((x) << (c)) - -#define WEBRTC_SPL_RSHIFT_U16(x, c) ((WebRtc_UWord16)(x) >> (c)) -#define WEBRTC_SPL_LSHIFT_U16(x, c) ((WebRtc_UWord16)(x) << (c)) -#define WEBRTC_SPL_RSHIFT_U32(x, c) ((WebRtc_UWord32)(x) >> (c)) -#define WEBRTC_SPL_LSHIFT_U32(x, c) ((WebRtc_UWord32)(x) << (c)) - -#define WEBRTC_SPL_VNEW(t, n) (t *) malloc (sizeof (t) * (n)) -#define WEBRTC_SPL_FREE free - -#define WEBRTC_SPL_RAND(a) \ - ((WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT((a), 18816, 7) & 0x00007fff)) - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define WEBRTC_SPL_MEMCPY_W8(v1, v2, length) \ - memcpy(v1, v2, (length) * sizeof(char)) -#define WEBRTC_SPL_MEMCPY_W16(v1, v2, length) \ - memcpy(v1, v2, (length) * sizeof(WebRtc_Word16)) - -#define WEBRTC_SPL_MEMMOVE_W16(v1, v2, length) \ - memmove(v1, v2, (length) * sizeof(WebRtc_Word16)) - -// inline functions: -#include "spl_inl.h" - -// Get SPL Version -WebRtc_Word16 WebRtcSpl_get_version(char* version, - WebRtc_Word16 length_in_bytes); - -int WebRtcSpl_GetScalingSquare(WebRtc_Word16* in_vector, - int in_vector_length, - int times); - -// Copy and set operations. Implementation in copy_set_operations.c. -// Descriptions at bottom of file. -void WebRtcSpl_MemSetW16(WebRtc_Word16* vector, - WebRtc_Word16 set_value, - int vector_length); -void WebRtcSpl_MemSetW32(WebRtc_Word32* vector, - WebRtc_Word32 set_value, - int vector_length); -void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* out_vector, - WebRtc_Word16* in_vector, - int vector_length); -WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16 in_vector_length, - WebRtc_Word16 samples, - WebRtc_Word16* out_vector); -WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16* vector, - WebRtc_Word16 vector_length); -WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32* vector, - WebRtc_Word16 vector_length); -WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16* vector, - WebRtc_Word16 vector_length); -WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32* vector, - WebRtc_Word16 vector_length); -// End: Copy and set operations. - -// Minimum and maximum operations. Implementation in min_max_operations.c. -// Descriptions at bottom of file. -WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); - -WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -// End: Minimum and maximum operations. - -// Vector scaling operations. Implementation in vector_scaling_operations.c. -// Description at bottom of file. -void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16* out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16 right_shifts); -void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32* out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word32* in_vector, - WebRtc_Word16 right_shifts); -void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16* out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word32* in_vector, - WebRtc_Word16 right_shifts); - -void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16 gain, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16 gain, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16* in_vector1, - WebRtc_Word16 gain1, int right_shifts1, - G_CONST WebRtc_Word16* in_vector2, - WebRtc_Word16 gain2, int right_shifts2, - WebRtc_Word16* out_vector, - int vector_length); -// End: Vector scaling operations. - -// iLBC specific functions. Implementations in ilbc_specific_functions.c. -// Description at bottom of file. -void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16* in_vector1, - WebRtc_Word16 scale1, - WebRtc_Word16* in_vector2, - WebRtc_Word16 scale2, - WebRtc_Word16 right_shifts, - WebRtc_Word16* out_vector, - WebRtc_Word16 vector_length); -void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16* out_vector, - G_CONST WebRtc_Word16* in_vector, - G_CONST WebRtc_Word16* window, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16* out_vector, - G_CONST WebRtc_Word16* in_vector, - G_CONST WebRtc_Word16* window, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16* out_vector, - G_CONST WebRtc_Word16* in_vector1, - G_CONST WebRtc_Word16* in_vector2, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16* out_vector, - WebRtc_Word16* in_vector, - WebRtc_Word16 gain, - WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, - int vector_length); -void WebRtcSpl_AffineTransformVector(WebRtc_Word16* out_vector, - WebRtc_Word16* in_vector, - WebRtc_Word16 gain, - WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, - int vector_length); -// End: iLBC specific functions. - -// Signal processing operations. Descriptions at bottom of this file. -int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* vector, - int vector_length, int order, - WebRtc_Word32* result_vector, - int* scale); -WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32* auto_corr, - WebRtc_Word16* lpc_coef, - WebRtc_Word16* refl_coef, - WebRtc_Word16 order); -void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16* refl_coef, - int use_order, - WebRtc_Word16* lpc_coef); -void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* lpc_coef, - int use_order, - WebRtc_Word16* refl_coef); -void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32* auto_corr, - int use_order, - WebRtc_Word16* refl_coef); -void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_corr, - WebRtc_Word16* vector1, - WebRtc_Word16* vector2, - WebRtc_Word16 dim_vector, - WebRtc_Word16 dim_cross_corr, - WebRtc_Word16 right_shifts, - WebRtc_Word16 step_vector2); -void WebRtcSpl_GetHanningWindow(WebRtc_Word16* window, WebRtc_Word16 size); -void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16* in_vector, - int vector_length, - WebRtc_Word16* out_vector); -// End: Signal processing operations. - -// Randomization functions. Implementations collected in randomization_functions.c and -// descriptions at bottom of this file. -WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32* seed); -WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32* seed); -WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32* seed); -WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector, - WebRtc_Word16 vector_length, - WebRtc_UWord32* seed); -// End: Randomization functions. - -// Math functions -WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value); -WebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value); - -// Divisions. Implementations collected in division_operations.c and -// descriptions at bottom of this file. -WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den); -WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den); -WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den); -WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den); -WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, - WebRtc_Word16 den_low); -// End: Divisions. - -WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, - int vector_length, - int* scale_factor); - -WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16* vector1, - WebRtc_Word16* vector2, - int vector_length, - int scaling); - -// Filter operations. -int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* ar_coef, int ar_coef_length, - G_CONST WebRtc_Word16* in_vector, int in_vector_length, - WebRtc_Word16* filter_state, int filter_state_length, - WebRtc_Word16* filter_state_low, - int filter_state_low_length, WebRtc_Word16* out_vector, - WebRtc_Word16* out_vector_low, int out_vector_low_length); - -void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16* ma_coef, - WebRtc_Word16 ma_coef_length, - WebRtc_Word16 vector_length); -void WebRtcSpl_FilterARFastQ12(WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16* ar_coef, - WebRtc_Word16 ar_coef_length, - WebRtc_Word16 vector_length); -int WebRtcSpl_DownsampleFast(WebRtc_Word16* in_vector, - WebRtc_Word16 in_vector_length, - WebRtc_Word16* out_vector, - WebRtc_Word16 out_vector_length, - WebRtc_Word16* ma_coef, - WebRtc_Word16 ma_coef_length, - WebRtc_Word16 factor, - WebRtc_Word16 delay); -// End: Filter operations. - -// FFT operations -int WebRtcSpl_ComplexFFT(WebRtc_Word16 vector[], int stages, int mode); -int WebRtcSpl_ComplexIFFT(WebRtc_Word16 vector[], int stages, int mode); -void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 vector[], int stages); -// End: FFT operations - -/************************************************************ - * - * RESAMPLING FUNCTIONS AND THEIR STRUCTS ARE DEFINED BELOW - * - ************************************************************/ - -/******************************************************************* - * resample.c - * - * Includes the following resampling combinations - * 22 kHz -> 16 kHz - * 16 kHz -> 22 kHz - * 22 kHz -> 8 kHz - * 8 kHz -> 22 kHz - * - ******************************************************************/ - -// state structure for 22 -> 16 resampler -typedef struct -{ - WebRtc_Word32 S_22_44[8]; - WebRtc_Word32 S_44_32[8]; - WebRtc_Word32 S_32_16[8]; -} WebRtcSpl_State22khzTo16khz; - -void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, - WebRtc_Word16* out, - WebRtcSpl_State22khzTo16khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state); - -// state structure for 16 -> 22 resampler -typedef struct -{ - WebRtc_Word32 S_16_32[8]; - WebRtc_Word32 S_32_22[8]; -} WebRtcSpl_State16khzTo22khz; - -void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, - WebRtc_Word16* out, - WebRtcSpl_State16khzTo22khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state); - -// state structure for 22 -> 8 resampler -typedef struct -{ - WebRtc_Word32 S_22_22[16]; - WebRtc_Word32 S_22_16[8]; - WebRtc_Word32 S_16_8[8]; -} WebRtcSpl_State22khzTo8khz; - -void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State22khzTo8khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state); - -// state structure for 8 -> 22 resampler -typedef struct -{ - WebRtc_Word32 S_8_16[8]; - WebRtc_Word32 S_16_11[8]; - WebRtc_Word32 S_11_22[8]; -} WebRtcSpl_State8khzTo22khz; - -void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State8khzTo22khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state); - -/******************************************************************* - * resample_fractional.c - * Functions for internal use in the other resample functions - * - * Includes the following resampling combinations - * 48 kHz -> 32 kHz - * 32 kHz -> 24 kHz - * 44 kHz -> 32 kHz - * - ******************************************************************/ - -void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, - const WebRtc_Word32 K); - -void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32* In, WebRtc_Word32* Out, - const WebRtc_Word32 K); - -void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, - const WebRtc_Word32 K); - -/******************************************************************* - * resample_48khz.c - * - * Includes the following resampling combinations - * 48 kHz -> 16 kHz - * 16 kHz -> 48 kHz - * 48 kHz -> 8 kHz - * 8 kHz -> 48 kHz - * - ******************************************************************/ - -typedef struct -{ - WebRtc_Word32 S_48_48[16]; - WebRtc_Word32 S_48_32[8]; - WebRtc_Word32 S_32_16[8]; -} WebRtcSpl_State48khzTo16khz; - -void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State48khzTo16khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state); - -typedef struct -{ - WebRtc_Word32 S_16_32[8]; - WebRtc_Word32 S_32_24[8]; - WebRtc_Word32 S_24_48[8]; -} WebRtcSpl_State16khzTo48khz; - -void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State16khzTo48khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state); - -typedef struct -{ - WebRtc_Word32 S_48_24[8]; - WebRtc_Word32 S_24_24[16]; - WebRtc_Word32 S_24_16[8]; - WebRtc_Word32 S_16_8[8]; -} WebRtcSpl_State48khzTo8khz; - -void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State48khzTo8khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state); - -typedef struct -{ - WebRtc_Word32 S_8_16[8]; - WebRtc_Word32 S_16_12[8]; - WebRtc_Word32 S_12_24[8]; - WebRtc_Word32 S_24_48[8]; -} WebRtcSpl_State8khzTo48khz; - -void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State8khzTo48khz* state, - WebRtc_Word32* tmpmem); - -void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state); - -/******************************************************************* - * resample_by_2.c - * - * Includes down and up sampling by a factor of two. - * - ******************************************************************/ - -void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, - WebRtc_Word16* out, WebRtc_Word32* filtState); - -void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out, - WebRtc_Word32* filtState); - -/************************************************************ - * END OF RESAMPLING FUNCTIONS - ************************************************************/ -void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, - WebRtc_Word16* low_band, - WebRtc_Word16* high_band, - WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2); -void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, - const WebRtc_Word16* high_band, - WebRtc_Word16* out_data, - WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2); - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ - -// -// WebRtcSpl_AddSatW16(...) -// WebRtcSpl_AddSatW32(...) -// -// Returns the result of a saturated 16-bit, respectively 32-bit, addition of -// the numbers specified by the |var1| and |var2| parameters. -// -// Input: -// - var1 : Input variable 1 -// - var2 : Input variable 2 -// -// Return value : Added and saturated value -// - -// -// WebRtcSpl_SubSatW16(...) -// WebRtcSpl_SubSatW32(...) -// -// Returns the result of a saturated 16-bit, respectively 32-bit, subtraction -// of the numbers specified by the |var1| and |var2| parameters. -// -// Input: -// - var1 : Input variable 1 -// - var2 : Input variable 2 -// -// Returned value : Subtracted and saturated value -// - -// -// WebRtcSpl_GetSizeInBits(...) -// -// Returns the # of bits that are needed at the most to represent the number -// specified by the |value| parameter. -// -// Input: -// - value : Input value -// -// Return value : Number of bits needed to represent |value| -// - -// -// WebRtcSpl_NormW32(...) -// -// Norm returns the # of left shifts required to 32-bit normalize the 32-bit -// signed number specified by the |value| parameter. -// -// Input: -// - value : Input value -// -// Return value : Number of bit shifts needed to 32-bit normalize |value| -// - -// -// WebRtcSpl_NormW16(...) -// -// Norm returns the # of left shifts required to 16-bit normalize the 16-bit -// signed number specified by the |value| parameter. -// -// Input: -// - value : Input value -// -// Return value : Number of bit shifts needed to 32-bit normalize |value| -// - -// -// WebRtcSpl_NormU32(...) -// -// Norm returns the # of left shifts required to 32-bit normalize the unsigned -// 32-bit number specified by the |value| parameter. -// -// Input: -// - value : Input value -// -// Return value : Number of bit shifts needed to 32-bit normalize |value| -// - -// -// WebRtcSpl_GetScalingSquare(...) -// -// Returns the # of bits required to scale the samples specified in the -// |in_vector| parameter so that, if the squares of the samples are added the -// # of times specified by the |times| parameter, the 32-bit addition will not -// overflow (result in WebRtc_Word32). -// -// Input: -// - in_vector : Input vector to check scaling on -// - in_vector_length : Samples in |in_vector| -// - times : Number of additions to be performed -// -// Return value : Number of right bit shifts needed to avoid -// overflow in the addition calculation -// - -// -// WebRtcSpl_MemSetW16(...) -// -// Sets all the values in the WebRtc_Word16 vector |vector| of length -// |vector_length| to the specified value |set_value| -// -// Input: -// - vector : Pointer to the WebRtc_Word16 vector -// - set_value : Value specified -// - vector_length : Length of vector -// - -// -// WebRtcSpl_MemSetW32(...) -// -// Sets all the values in the WebRtc_Word32 vector |vector| of length -// |vector_length| to the specified value |set_value| -// -// Input: -// - vector : Pointer to the WebRtc_Word16 vector -// - set_value : Value specified -// - vector_length : Length of vector -// - -// -// WebRtcSpl_MemCpyReversedOrder(...) -// -// Copies all the values from the source WebRtc_Word16 vector |in_vector| to a -// destination WebRtc_Word16 vector |out_vector|. It is done in reversed order, -// meaning that the first sample of |in_vector| is copied to the last sample of -// the |out_vector|. The procedure continues until the last sample of -// |in_vector| has been copied to the first sample of |out_vector|. This -// creates a reversed vector. Used in e.g. prediction in iLBC. -// -// Input: -// - in_vector : Pointer to the first sample in a WebRtc_Word16 vector -// of length |length| -// - vector_length : Number of elements to copy -// -// Output: -// - out_vector : Pointer to the last sample in a WebRtc_Word16 vector -// of length |length| -// - -// -// WebRtcSpl_CopyFromEndW16(...) -// -// Copies the rightmost |samples| of |in_vector| (of length |in_vector_length|) -// to the vector |out_vector|. -// -// Input: -// - in_vector : Input vector -// - in_vector_length : Number of samples in |in_vector| -// - samples : Number of samples to extract (from right side) -// from |in_vector| -// -// Output: -// - out_vector : Vector with the requested samples -// -// Return value : Number of copied samples in |out_vector| -// - -// -// WebRtcSpl_ZerosArrayW16(...) -// WebRtcSpl_ZerosArrayW32(...) -// -// Inserts the value "zero" in all positions of a w16 and a w32 vector -// respectively. -// -// Input: -// - vector_length : Number of samples in vector -// -// Output: -// - vector : Vector containing all zeros -// -// Return value : Number of samples in vector -// - -// -// WebRtcSpl_OnesArrayW16(...) -// WebRtcSpl_OnesArrayW32(...) -// -// Inserts the value "one" in all positions of a w16 and a w32 vector -// respectively. -// -// Input: -// - vector_length : Number of samples in vector -// -// Output: -// - vector : Vector containing all ones -// -// Return value : Number of samples in vector -// - -// -// WebRtcSpl_MinValueW16(...) -// WebRtcSpl_MinValueW32(...) -// -// Returns the minimum value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Minimum sample value in vector -// - -// -// WebRtcSpl_MaxValueW16(...) -// WebRtcSpl_MaxValueW32(...) -// -// Returns the maximum value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Maximum sample value in vector -// - -// -// WebRtcSpl_MaxAbsValueW16(...) -// WebRtcSpl_MaxAbsValueW32(...) -// -// Returns the largest absolute value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Maximum absolute value in vector -// - -// -// WebRtcSpl_MaxAbsIndexW16(...) -// -// Returns the vector index to the largest absolute value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Index to maximum absolute value in vector -// - -// -// WebRtcSpl_MinIndexW16(...) -// WebRtcSpl_MinIndexW32(...) -// -// Returns the vector index to the minimum sample value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Index to minimum sample value in vector -// - -// -// WebRtcSpl_MaxIndexW16(...) -// WebRtcSpl_MaxIndexW32(...) -// -// Returns the vector index to the maximum sample value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Index to maximum sample value in vector -// - -// -// WebRtcSpl_VectorBitShiftW16(...) -// WebRtcSpl_VectorBitShiftW32(...) -// -// Bit shifts all the values in a vector up or downwards. Different calls for -// WebRtc_Word16 and WebRtc_Word32 vectors respectively. -// -// Input: -// - vector_length : Length of vector -// - in_vector : Pointer to the vector that should be bit shifted -// - right_shifts : Number of right bit shifts (negative value gives left -// shifts) -// -// Output: -// - out_vector : Pointer to the result vector (can be the same as -// |in_vector|) -// - -// -// WebRtcSpl_VectorBitShiftW32ToW16(...) -// -// Bit shifts all the values in a WebRtc_Word32 vector up or downwards and -// stores the result as a WebRtc_Word16 vector -// -// Input: -// - vector_length : Length of vector -// - in_vector : Pointer to the vector that should be bit shifted -// - right_shifts : Number of right bit shifts (negative value gives left -// shifts) -// -// Output: -// - out_vector : Pointer to the result vector (can be the same as -// |in_vector|) -// - -// -// WebRtcSpl_ScaleVector(...) -// -// Performs the vector operation: -// out_vector[k] = (gain*in_vector[k])>>right_shifts -// -// Input: -// - in_vector : Input vector -// - gain : Scaling gain -// - vector_length : Elements in the |in_vector| -// - right_shifts : Number of right bit shifts applied -// -// Output: -// - out_vector : Output vector (can be the same as |in_vector|) -// - -// -// WebRtcSpl_ScaleVectorWithSat(...) -// -// Performs the vector operation: -// out_vector[k] = SATURATE( (gain*in_vector[k])>>right_shifts ) -// -// Input: -// - in_vector : Input vector -// - gain : Scaling gain -// - vector_length : Elements in the |in_vector| -// - right_shifts : Number of right bit shifts applied -// -// Output: -// - out_vector : Output vector (can be the same as |in_vector|) -// - -// -// WebRtcSpl_ScaleAndAddVectors(...) -// -// Performs the vector operation: -// out_vector[k] = (gain1*in_vector1[k])>>right_shifts1 -// + (gain2*in_vector2[k])>>right_shifts2 -// -// Input: -// - in_vector1 : Input vector 1 -// - gain1 : Gain to be used for vector 1 -// - right_shifts1 : Right bit shift to be used for vector 1 -// - in_vector2 : Input vector 2 -// - gain2 : Gain to be used for vector 2 -// - right_shifts2 : Right bit shift to be used for vector 2 -// - vector_length : Elements in the input vectors -// -// Output: -// - out_vector : Output vector -// - -// -// WebRtcSpl_ScaleAndAddVectorsWithRound(...) -// -// Performs the vector operation: -// -// out_vector[k] = ((scale1*in_vector1[k]) + (scale2*in_vector2[k]) -// + round_value) >> right_shifts -// -// where: -// -// round_value = (1<>1 -// -// Input: -// - in_vector1 : Input vector 1 -// - scale1 : Gain to be used for vector 1 -// - in_vector2 : Input vector 2 -// - scale2 : Gain to be used for vector 2 -// - right_shifts : Number of right bit shifts to be applied -// - vector_length : Number of elements in the input vectors -// -// Output: -// - out_vector : Output vector -// - -// -// WebRtcSpl_ReverseOrderMultArrayElements(...) -// -// Performs the vector operation: -// out_vector[n] = (in_vector[n]*window[-n])>>right_shifts -// -// Input: -// - in_vector : Input vector -// - window : Window vector (should be reversed). The pointer -// should be set to the last value in the vector -// - right_shifts : Number of right bit shift to be applied after the -// multiplication -// - vector_length : Number of elements in |in_vector| -// -// Output: -// - out_vector : Output vector (can be same as |in_vector|) -// - -// -// WebRtcSpl_ElementwiseVectorMult(...) -// -// Performs the vector operation: -// out_vector[n] = (in_vector[n]*window[n])>>right_shifts -// -// Input: -// - in_vector : Input vector -// - window : Window vector. -// - right_shifts : Number of right bit shift to be applied after the -// multiplication -// - vector_length : Number of elements in |in_vector| -// -// Output: -// - out_vector : Output vector (can be same as |in_vector|) -// - -// -// WebRtcSpl_AddVectorsAndShift(...) -// -// Performs the vector operation: -// out_vector[k] = (in_vector1[k] + in_vector2[k])>>right_shifts -// -// Input: -// - in_vector1 : Input vector 1 -// - in_vector2 : Input vector 2 -// - right_shifts : Number of right bit shift to be applied after the -// multiplication -// - vector_length : Number of elements in |in_vector1| and |in_vector2| -// -// Output: -// - out_vector : Output vector (can be same as |in_vector1|) -// - -// -// WebRtcSpl_AddAffineVectorToVector(...) -// -// Adds an affine transformed vector to another vector |out_vector|, i.e, -// performs -// out_vector[k] += (in_vector[k]*gain+add_constant)>>right_shifts -// -// Input: -// - in_vector : Input vector -// - gain : Gain value, used to multiply the in vector with -// - add_constant : Constant value to add (usually 1<<(right_shifts-1), -// but others can be used as well -// - right_shifts : Number of right bit shifts (0-16) -// - vector_length : Number of samples in |in_vector| and |out_vector| -// -// Output: -// - out_vector : Vector with the output -// - -// -// WebRtcSpl_AffineTransformVector(...) -// -// Affine transforms a vector, i.e, performs -// out_vector[k] = (in_vector[k]*gain+add_constant)>>right_shifts -// -// Input: -// - in_vector : Input vector -// - gain : Gain value, used to multiply the in vector with -// - add_constant : Constant value to add (usually 1<<(right_shifts-1), -// but others can be used as well -// - right_shifts : Number of right bit shifts (0-16) -// - vector_length : Number of samples in |in_vector| and |out_vector| -// -// Output: -// - out_vector : Vector with the output -// - -// -// WebRtcSpl_AutoCorrelation(...) -// -// A 32-bit fix-point implementation of auto-correlation computation -// -// Input: -// - vector : Vector to calculate autocorrelation upon -// - vector_length : Length (in samples) of |vector| -// - order : The order up to which the autocorrelation should be -// calculated -// -// Output: -// - result_vector : auto-correlation values (values should be seen -// relative to each other since the absolute values -// might have been down shifted to avoid overflow) -// -// - scale : The number of left shifts required to obtain the -// auto-correlation in Q0 -// -// Return value : Number of samples in |result_vector|, i.e., (order+1) -// - -// -// WebRtcSpl_LevinsonDurbin(...) -// -// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that -// does NOT use the 64 bit class -// -// Input: -// - auto_corr : Vector with autocorrelation values of length >= -// |use_order|+1 -// - use_order : The LPC filter order (support up to order 20) -// -// Output: -// - lpc_coef : lpc_coef[0..use_order] LPC coefficients in Q12 -// - refl_coef : refl_coef[0...use_order-1]| Reflection coefficients in -// Q15 -// -// Return value : 1 for stable 0 for unstable -// - -// -// WebRtcSpl_ReflCoefToLpc(...) -// -// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|. -// This version is a 16 bit operation. -// -// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a -// "slightly unstable" filter (i.e., a pole just outside the unit circle) in -// "rare" cases even if the reflection coefficients are stable. -// -// Input: -// - refl_coef : Reflection coefficients in Q15 that should be converted -// to LPC coefficients -// - use_order : Number of coefficients in |refl_coef| -// -// Output: -// - lpc_coef : LPC coefficients in Q12 -// - -// -// WebRtcSpl_LpcToReflCoef(...) -// -// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|. -// This version is a 16 bit operation. -// The conversion is implemented by the step-down algorithm. -// -// Input: -// - lpc_coef : LPC coefficients in Q12, that should be converted to -// reflection coefficients -// - use_order : Number of coefficients in |lpc_coef| -// -// Output: -// - refl_coef : Reflection coefficients in Q15. -// - -// -// WebRtcSpl_AutoCorrToReflCoef(...) -// -// Calculates reflection coefficients (16 bit) from auto-correlation values -// -// Input: -// - auto_corr : Auto-correlation values -// - use_order : Number of coefficients wanted be calculated -// -// Output: -// - refl_coef : Reflection coefficients in Q15. -// - -// -// WebRtcSpl_CrossCorrelation(...) -// -// Calculates the cross-correlation between two sequences |vector1| and -// |vector2|. |vector1| is fixed and |vector2| slides as the pointer is -// increased with the amount |step_vector2| -// -// Input: -// - vector1 : First sequence (fixed throughout the correlation) -// - vector2 : Second sequence (slides |step_vector2| for each -// new correlation) -// - dim_vector : Number of samples to use in the cross-correlation -// - dim_cross_corr : Number of cross-correlations to calculate (the -// start position for |vector2| is updated for each -// new one) -// - right_shifts : Number of right bit shifts to use. This will -// become the output Q-domain. -// - step_vector2 : How many (positive or negative) steps the -// |vector2| pointer should be updated for each new -// cross-correlation value. -// -// Output: -// - cross_corr : The cross-correlation in Q(-right_shifts) -// - -// -// WebRtcSpl_GetHanningWindow(...) -// -// Creates (the first half of) a Hanning window. Size must be at least 1 and -// at most 512. -// -// Input: -// - size : Length of the requested Hanning window (1 to 512) -// -// Output: -// - window : Hanning vector in Q14. -// - -// -// WebRtcSpl_SqrtOfOneMinusXSquared(...) -// -// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector -// |in_vector|. Input and output values are in Q15. -// -// Inputs: -// - in_vector : Values to calculate sqrt(1 - x^2) of -// - vector_length : Length of vector |in_vector| -// -// Output: -// - out_vector : Output values in Q15 -// - -// -// WebRtcSpl_IncreaseSeed(...) -// -// Increases the seed (and returns the new value) -// -// Input: -// - seed : Seed for random calculation -// -// Output: -// - seed : Updated seed value -// -// Return value : The new seed value -// - -// -// WebRtcSpl_RandU(...) -// -// Produces a uniformly distributed value in the WebRtc_Word16 range -// -// Input: -// - seed : Seed for random calculation -// -// Output: -// - seed : Updated seed value -// -// Return value : Uniformly distributed value in the range -// [Word16_MIN...Word16_MAX] -// - -// -// WebRtcSpl_RandN(...) -// -// Produces a normal distributed value in the WebRtc_Word16 range -// -// Input: -// - seed : Seed for random calculation -// -// Output: -// - seed : Updated seed value -// -// Return value : N(0,1) value in the Q13 domain -// - -// -// WebRtcSpl_RandUArray(...) -// -// Produces a uniformly distributed vector with elements in the WebRtc_Word16 -// range -// -// Input: -// - vector_length : Samples wanted in the vector -// - seed : Seed for random calculation -// -// Output: -// - vector : Vector with the uniform values -// - seed : Updated seed value -// -// Return value : Number of samples in vector, i.e., |vector_length| -// - -// -// WebRtcSpl_Sqrt(...) -// -// Returns the square root of the input value |value|. The precision of this -// function is integer precision, i.e., sqrt(8) gives 2 as answer. -// If |value| is a negative number then 0 is returned. -// -// Algorithm: -// -// A sixth order Taylor Series expansion is used here to compute the square -// root of a number y^0.5 = (1+x)^0.5 -// where -// x = y-1 -// = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5) -// 0.5 <= x < 1 -// -// Input: -// - value : Value to calculate sqrt of -// -// Return value : Result of the sqrt calculation -// - -// -// WebRtcSpl_SqrtFloor(...) -// -// Returns the square root of the input value |value|. The precision of this -// function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer. -// If |value| is a negative number then 0 is returned. -// -// Algorithm: -// -// An iterative 4 cylce/bit routine -// -// Input: -// - value : Value to calculate sqrt of -// -// Return value : Result of the sqrt calculation -// - -// -// WebRtcSpl_DivU32U16(...) -// -// Divides a WebRtc_UWord32 |num| by a WebRtc_UWord16 |den|. -// -// If |den|==0, (WebRtc_UWord32)0xFFFFFFFF is returned. -// -// Input: -// - num : Numerator -// - den : Denominator -// -// Return value : Result of the division (as a WebRtc_UWord32), i.e., the -// integer part of num/den. -// - -// -// WebRtcSpl_DivW32W16(...) -// -// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|. -// -// If |den|==0, (WebRtc_Word32)0x7FFFFFFF is returned. -// -// Input: -// - num : Numerator -// - den : Denominator -// -// Return value : Result of the division (as a WebRtc_Word32), i.e., the -// integer part of num/den. -// - -// -// WebRtcSpl_DivW32W16ResW16(...) -// -// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the -// result is less than 32768, otherwise an unpredictable result will occur. -// -// If |den|==0, (WebRtc_Word16)0x7FFF is returned. -// -// Input: -// - num : Numerator -// - den : Denominator -// -// Return value : Result of the division (as a WebRtc_Word16), i.e., the -// integer part of num/den. -// - -// -// WebRtcSpl_DivResultInQ31(...) -// -// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the -// absolute value of the denominator is larger than the numerator, otherwise -// an unpredictable result will occur. -// -// Input: -// - num : Numerator -// - den : Denominator -// -// Return value : Result of the division in Q31. -// - -// -// WebRtcSpl_DivW32HiLow(...) -// -// Divides a WebRtc_Word32 |num| by a denominator in hi, low format. The -// absolute value of the denominator has to be larger (or equal to) the -// numerator. -// -// Input: -// - num : Numerator -// - den_hi : High part of denominator -// - den_low : Low part of denominator -// -// Return value : Divided value in Q31 -// - -// -// WebRtcSpl_Energy(...) -// -// Calculates the energy of a vector -// -// Input: -// - vector : Vector which the energy should be calculated on -// - vector_length : Number of samples in vector -// -// Output: -// - scale_factor : Number of left bit shifts needed to get the physical -// energy value, i.e, to get the Q0 value -// -// Return value : Energy value in Q(-|scale_factor|) -// - -// -// WebRtcSpl_FilterAR(...) -// -// Performs a 32-bit AR filtering on a vector in Q12 -// -// Input: -// - ar_coef : AR-coefficient vector (values in Q12), -// ar_coef[0] must be 4096. -// - ar_coef_length : Number of coefficients in |ar_coef|. -// - in_vector : Vector to be filtered. -// - in_vector_length : Number of samples in |in_vector|. -// - filter_state : Current state (higher part) of the filter. -// - filter_state_length : Length (in samples) of |filter_state|. -// - filter_state_low : Current state (lower part) of the filter. -// - filter_state_low_length : Length (in samples) of |filter_state_low|. -// - out_vector_low_length : Maximum length (in samples) of -// |out_vector_low|. -// -// Output: -// - filter_state : Updated state (upper part) vector. -// - filter_state_low : Updated state (lower part) vector. -// - out_vector : Vector containing the upper part of the -// filtered values. -// - out_vector_low : Vector containing the lower part of the -// filtered values. -// -// Return value : Number of samples in the |out_vector|. -// - -// -// WebRtcSpl_FilterMAFastQ12(...) -// -// Performs a MA filtering on a vector in Q12 -// -// Input: -// - in_vector : Input samples (state in positions -// in_vector[-order] .. in_vector[-1]) -// - ma_coef : Filter coefficients (in Q12) -// - ma_coef_length : Number of B coefficients (order+1) -// - vector_length : Number of samples to be filtered -// -// Output: -// - out_vector : Filtered samples -// - -// -// WebRtcSpl_FilterARFastQ12(...) -// -// Performs a AR filtering on a vector in Q12 -// -// Input: -// - in_vector : Input samples -// - out_vector : State information in positions -// out_vector[-order] .. out_vector[-1] -// - ar_coef : Filter coefficients (in Q12) -// - ar_coef_length : Number of B coefficients (order+1) -// - vector_length : Number of samples to be filtered -// -// Output: -// - out_vector : Filtered samples -// - -// -// WebRtcSpl_DownsampleFast(...) -// -// Performs a MA down sampling filter on a vector -// -// Input: -// - in_vector : Input samples (state in positions -// in_vector[-order] .. in_vector[-1]) -// - in_vector_length : Number of samples in |in_vector| to be filtered. -// This must be at least -// |delay| + |factor|*(|out_vector_length|-1) + 1) -// - out_vector_length : Number of down sampled samples desired -// - ma_coef : Filter coefficients (in Q12) -// - ma_coef_length : Number of B coefficients (order+1) -// - factor : Decimation factor -// - delay : Delay of filter (compensated for in out_vector) -// -// Output: -// - out_vector : Filtered samples -// -// Return value : 0 if OK, -1 if |in_vector| is too short -// - -// -// WebRtcSpl_DotProductWithScale(...) -// -// Calculates the dot product between two (WebRtc_Word16) vectors -// -// Input: -// - vector1 : Vector 1 -// - vector2 : Vector 2 -// - vector_length : Number of samples used in the dot product -// - scaling : The number of right bit shifts to apply on each term -// during calculation to avoid overflow, i.e., the -// output will be in Q(-|scaling|) -// -// Return value : The dot product in Q(-scaling) -// - -// -// WebRtcSpl_ComplexIFFT(...) -// -// Complex Inverse FFT -// -// Computes an inverse complex 2^|stages|-point FFT on the input vector, which -// is in bit-reversed order. The original content of the vector is destroyed in -// the process, since the input is overwritten by the output, normal-ordered, -// FFT vector. With X as the input complex vector, y as the output complex -// vector and with M = 2^|stages|, the following is computed: -// -// M-1 -// y(k) = sum[X(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]] -// i=0 -// -// The implementations are optimized for speed, not for code size. It uses the -// decimation-in-time algorithm with radix-2 butterfly technique. -// -// Input: -// - vector : In pointer to complex vector containing 2^|stages| -// real elements interleaved with 2^|stages| imaginary -// elements. -// [ReImReImReIm....] -// The elements are in Q(-scale) domain, see more on Return -// Value below. -// -// - stages : Number of FFT stages. Must be at least 3 and at most 10, -// since the table WebRtcSpl_kSinTable1024[] is 1024 -// elements long. -// -// - mode : This parameter gives the user to choose how the FFT -// should work. -// mode==0: Low-complexity and Low-accuracy mode -// mode==1: High-complexity and High-accuracy mode -// -// Output: -// - vector : Out pointer to the FFT vector (the same as input). -// -// Return Value : The scale value that tells the number of left bit shifts -// that the elements in the |vector| should be shifted with -// in order to get Q0 values, i.e. the physically correct -// values. The scale parameter is always 0 or positive, -// except if N>1024 (|stages|>10), which returns a scale -// value of -1, indicating error. -// - -// -// WebRtcSpl_ComplexFFT(...) -// -// Complex FFT -// -// Computes a complex 2^|stages|-point FFT on the input vector, which is in -// bit-reversed order. The original content of the vector is destroyed in -// the process, since the input is overwritten by the output, normal-ordered, -// FFT vector. With x as the input complex vector, Y as the output complex -// vector and with M = 2^|stages|, the following is computed: -// -// M-1 -// Y(k) = 1/M * sum[x(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]] -// i=0 -// -// The implementations are optimized for speed, not for code size. It uses the -// decimation-in-time algorithm with radix-2 butterfly technique. -// -// This routine prevents overflow by scaling by 2 before each FFT stage. This is -// a fixed scaling, for proper normalization - there will be log2(n) passes, so -// this results in an overall factor of 1/n, distributed to maximize arithmetic -// accuracy. -// -// Input: -// - vector : In pointer to complex vector containing 2^|stages| real -// elements interleaved with 2^|stages| imaginary elements. -// [ReImReImReIm....] -// The output is in the Q0 domain. -// -// - stages : Number of FFT stages. Must be at least 3 and at most 10, -// since the table WebRtcSpl_kSinTable1024[] is 1024 -// elements long. -// -// - mode : This parameter gives the user to choose how the FFT -// should work. -// mode==0: Low-complexity and Low-accuracy mode -// mode==1: High-complexity and High-accuracy mode -// -// Output: -// - vector : The output FFT vector is in the Q0 domain. -// -// Return value : The scale parameter is always 0, except if N>1024, -// which returns a scale value of -1, indicating error. -// - -// -// WebRtcSpl_ComplexBitReverse(...) -// -// Complex Bit Reverse -// -// This function bit-reverses the position of elements in the complex input -// vector into the output vector. -// -// If you bit-reverse a linear-order array, you obtain a bit-reversed order -// array. If you bit-reverse a bit-reversed order array, you obtain a -// linear-order array. -// -// Input: -// - vector : In pointer to complex vector containing 2^|stages| real -// elements interleaved with 2^|stages| imaginary elements. -// [ReImReImReIm....] -// - stages : Number of FFT stages. Must be at least 3 and at most 10, -// since the table WebRtcSpl_kSinTable1024[] is 1024 -// elements long. -// -// Output: -// - vector : Out pointer to complex vector in bit-reversed order. -// The input vector is over written. -// - -// -// WebRtcSpl_AnalysisQMF(...) -// -// Splits a 0-2*F Hz signal into two sub bands: 0-F Hz and F-2*F Hz. The -// current version has F = 8000, therefore, a super-wideband audio signal is -// split to lower-band 0-8 kHz and upper-band 8-16 kHz. -// -// Input: -// - in_data : Wide band speech signal, 320 samples (10 ms) -// -// Input & Output: -// - filter_state1 : Filter state for first All-pass filter -// - filter_state2 : Filter state for second All-pass filter -// -// Output: -// - low_band : Lower-band signal 0-8 kHz band, 160 samples (10 ms) -// - high_band : Upper-band signal 8-16 kHz band (flipped in frequency -// domain), 160 samples (10 ms) -// - -// -// WebRtcSpl_SynthesisQMF(...) -// -// Combines the two sub bands (0-F and F-2*F Hz) into a signal of 0-2*F -// Hz, (current version has F = 8000 Hz). So the filter combines lower-band -// (0-8 kHz) and upper-band (8-16 kHz) channels to obtain super-wideband 0-16 -// kHz audio. -// -// Input: -// - low_band : The signal with the 0-8 kHz band, 160 samples (10 ms) -// - high_band : The signal with the 8-16 kHz band, 160 samples (10 ms) -// -// Input & Output: -// - filter_state1 : Filter state for first All-pass filter -// - filter_state2 : Filter state for second All-pass filter -// -// Output: -// - out_data : Super-wideband speech signal, 0-16 kHz -// - -// WebRtc_Word16 WebRtcSpl_SatW32ToW16(...) -// -// This function saturates a 32-bit word into a 16-bit word. -// -// Input: -// - value32 : The value of a 32-bit word. -// -// Output: -// - out16 : the saturated 16-bit word. -// - -// int32_t WebRtc_MulAccumW16(...) -// -// This function multiply a 16-bit word by a 16-bit word, and accumulate this -// value to a 32-bit integer. -// -// Input: -// - a : The value of the first 16-bit word. -// - b : The value of the second 16-bit word. -// - c : The value of an 32-bit integer. -// -// Return Value: The value of a * b + c. -// - -// WebRtc_Word16 WebRtcSpl_get_version(...) -// -// This function gives the version string of the Signal Processing Library. -// -// Input: -// - length_in_bytes : The size of Allocated space (in Bytes) where -// the version number is written to (in string format). -// -// Output: -// - version : Pointer to a buffer where the version number is written to. -// diff --git a/src/mod/codecs/mod_isac/spectrum_ar_model_tables.c b/src/mod/codecs/mod_isac/spectrum_ar_model_tables.c deleted file mode 100644 index 92b9c4d626..0000000000 --- a/src/mod/codecs/mod_isac/spectrum_ar_model_tables.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "spectrum_ar_model_tables.h" -#include "settings.h" - -/********************* AR Coefficient Tables ************************/ -/* cdf for quantized reflection coefficient 1 */ -const WebRtc_UWord16 WebRtcIsac_kQArRc1Cdf[12] = { - 0, 2, 4, 129, 7707, 57485, 65495, 65527, 65529, 65531, - 65533, 65535}; - -/* cdf for quantized reflection coefficient 2 */ -const WebRtc_UWord16 WebRtcIsac_kQArRc2Cdf[12] = { - 0, 2, 4, 7, 531, 25298, 64525, 65526, 65529, 65531, - 65533, 65535}; - -/* cdf for quantized reflection coefficient 3 */ -const WebRtc_UWord16 WebRtcIsac_kQArRc3Cdf[12] = { - 0, 2, 4, 6, 620, 22898, 64843, 65527, 65529, 65531, - 65533, 65535}; - -/* cdf for quantized reflection coefficient 4 */ -const WebRtc_UWord16 WebRtcIsac_kQArRc4Cdf[12] = { - 0, 2, 4, 6, 35, 10034, 60733, 65506, 65529, 65531, - 65533, 65535}; - -/* cdf for quantized reflection coefficient 5 */ -const WebRtc_UWord16 WebRtcIsac_kQArRc5Cdf[12] = { - 0, 2, 4, 6, 36, 7567, 56727, 65385, 65529, 65531, - 65533, 65535}; - -/* cdf for quantized reflection coefficient 6 */ -const WebRtc_UWord16 WebRtcIsac_kQArRc6Cdf[12] = { - 0, 2, 4, 6, 14, 6579, 57360, 65409, 65529, 65531, - 65533, 65535}; - -/* representation levels for quantized reflection coefficient 1 */ -const WebRtc_Word16 WebRtcIsac_kQArRc1Levels[11] = { - -32104, -29007, -23202, -15496, -9279, -2577, 5934, 17535, 24512, 29503, 32104 -}; - -/* representation levels for quantized reflection coefficient 2 */ -const WebRtc_Word16 WebRtcIsac_kQArRc2Levels[11] = { - -32104, -29503, -23494, -15261, -7309, -1399, 6158, 16381, 24512, 29503, 32104 -}; - -/* representation levels for quantized reflection coefficient 3 */ -const WebRtc_Word16 WebRtcIsac_kQArRc3Levels[11] = { --32104, -29503, -23157, -15186, -7347, -1359, 5829, 17535, 24512, 29503, 32104 -}; - -/* representation levels for quantized reflection coefficient 4 */ -const WebRtc_Word16 WebRtcIsac_kQArRc4Levels[11] = { --32104, -29503, -24512, -15362, -6665, -342, 6596, 14585, 24512, 29503, 32104 -}; - -/* representation levels for quantized reflection coefficient 5 */ -const WebRtc_Word16 WebRtcIsac_kQArRc5Levels[11] = { --32104, -29503, -24512, -15005, -6564, -106, 7123, 14920, 24512, 29503, 32104 -}; - -/* representation levels for quantized reflection coefficient 6 */ -const WebRtc_Word16 WebRtcIsac_kQArRc6Levels[11] = { --32104, -29503, -24512, -15096, -6656, -37, 7036, 14847, 24512, 29503, 32104 -}; - -/* quantization boundary levels for reflection coefficients */ -const WebRtc_Word16 WebRtcIsac_kQArBoundaryLevels[12] = { --32768, -31441, -27566, -21458, -13612, -4663, 4663, 13612, 21458, 27566, 31441, 32767 -}; - -/* initial index for AR reflection coefficient quantizer and cdf table search */ -const WebRtc_UWord16 WebRtcIsac_kQArRcInitIndex[6] = { - 5, 5, 5, 5, 5, 5}; - -/* pointers to AR cdf tables */ -const WebRtc_UWord16 *WebRtcIsac_kQArRcCdfPtr[AR_ORDER] = { - WebRtcIsac_kQArRc1Cdf, WebRtcIsac_kQArRc2Cdf, WebRtcIsac_kQArRc3Cdf, - WebRtcIsac_kQArRc4Cdf, WebRtcIsac_kQArRc5Cdf, WebRtcIsac_kQArRc6Cdf -}; - -/* pointers to AR representation levels tables */ -const WebRtc_Word16 *WebRtcIsac_kQArRcLevelsPtr[AR_ORDER] = { - WebRtcIsac_kQArRc1Levels, WebRtcIsac_kQArRc2Levels, WebRtcIsac_kQArRc3Levels, - WebRtcIsac_kQArRc4Levels, WebRtcIsac_kQArRc5Levels, WebRtcIsac_kQArRc6Levels -}; - - -/******************** GAIN Coefficient Tables ***********************/ -/* cdf for Gain coefficient */ -const WebRtc_UWord16 WebRtcIsac_kQGainCdf[19] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 1172, - 11119, 29411, 51699, 64445, 65527, 65529, 65531, 65533, 65535}; - -/* representation levels for quantized squared Gain coefficient */ -const WebRtc_Word32 WebRtcIsac_kQGain2Levels[18] = { -// 17, 28, 46, 76, 128, 215, 364, 709, 1268, 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000}; - 128, 128, 128, 128, 128, 215, 364, 709, 1268, 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000}; -/* quantization boundary levels for squared Gain coefficient */ -const WebRtc_Word32 WebRtcIsac_kQGain2BoundaryLevels[19] = { -0, 21, 35, 59, 99, 166, 280, 475, 815, 1414, 2495, 4505, 8397, 16405, 34431, 81359, 240497, 921600, 0x7FFFFFFF}; - -/* pointers to Gain cdf table */ -const WebRtc_UWord16 *WebRtcIsac_kQGainCdf_ptr[1] = {WebRtcIsac_kQGainCdf}; - -/* Gain initial index for gain quantizer and cdf table search */ -const WebRtc_UWord16 WebRtcIsac_kQGainInitIndex[1] = {11}; - -/************************* Cosine Tables ****************************/ -/* Cosine table */ -const WebRtc_Word16 WebRtcIsac_kCos[6][60] = { -{512, 512, 511, 510, 508, 507, 505, 502, 499, 496, 493, 489, 485, 480, 476, 470, 465, 459, 453, 447, -440, 433, 426, 418, 410, 402, 394, 385, 376, 367, 357, 348, 338, 327, 317, 306, 295, 284, 273, 262, -250, 238, 226, 214, 202, 190, 177, 165, 152, 139, 126, 113, 100, 87, 73, 60, 47, 33, 20, 7}, -{512, 510, 508, 503, 498, 491, 483, 473, 462, 450, 437, 422, 406, 389, 371, 352, 333, 312, 290, 268, -244, 220, 196, 171, 145, 120, 93, 67, 40, 13, -13, -40, -67, -93, -120, -145, -171, -196, -220, -244, --268, -290, -312, -333, -352, -371, -389, -406, -422, -437, -450, -462, -473, -483, -491, -498, -503, -508, -510, -512}, -{512, 508, 502, 493, 480, 465, 447, 426, 402, 376, 348, 317, 284, 250, 214, 177, 139, 100, 60, 20, --20, -60, -100, -139, -177, -214, -250, -284, -317, -348, -376, -402, -426, -447, -465, -480, -493, -502, -508, -512, --512, -508, -502, -493, -480, -465, -447, -426, -402, -376, -348, -317, -284, -250, -214, -177, -139, -100, -60, -20}, -{511, 506, 495, 478, 456, 429, 398, 362, 322, 279, 232, 183, 133, 80, 27, -27, -80, -133, -183, -232, --279, -322, -362, -398, -429, -456, -478, -495, -506, -511, -511, -506, -495, -478, -456, -429, -398, -362, -322, -279, --232, -183, -133, -80, -27, 27, 80, 133, 183, 232, 279, 322, 362, 398, 429, 456, 478, 495, 506, 511}, -{511, 502, 485, 459, 426, 385, 338, 284, 226, 165, 100, 33, -33, -100, -165, -226, -284, -338, -385, -426, --459, -485, -502, -511, -511, -502, -485, -459, -426, -385, -338, -284, -226, -165, -100, -33, 33, 100, 165, 226, -284, 338, 385, 426, 459, 485, 502, 511, 511, 502, 485, 459, 426, 385, 338, 284, 226, 165, 100, 33}, -{510, 498, 473, 437, 389, 333, 268, 196, 120, 40, -40, -120, -196, -268, -333, -389, -437, -473, -498, -510, --510, -498, -473, -437, -389, -333, -268, -196, -120, -40, 40, 120, 196, 268, 333, 389, 437, 473, 498, 510, -510, 498, 473, 437, 389, 333, 268, 196, 120, 40, -40, -120, -196, -268, -333, -389, -437, -473, -498, -510} -}; diff --git a/src/mod/codecs/mod_isac/spectrum_ar_model_tables.h b/src/mod/codecs/mod_isac/spectrum_ar_model_tables.h deleted file mode 100644 index b6ea85ba77..0000000000 --- a/src/mod/codecs/mod_isac/spectrum_ar_model_tables.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * spectrum_ar_model_tables.h - * - * This file contains definitions of tables with AR coefficients, - * Gain coefficients and cosine tables. - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ - -#include "structs.h" - -/********************* AR Coefficient Tables ************************/ -/* cdf for quantized reflection coefficient 1 */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRc1Cdf[12]; - -/* cdf for quantized reflection coefficient 2 */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRc2Cdf[12]; - -/* cdf for quantized reflection coefficient 3 */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRc3Cdf[12]; - -/* cdf for quantized reflection coefficient 4 */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRc4Cdf[12]; - -/* cdf for quantized reflection coefficient 5 */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRc5Cdf[12]; - -/* cdf for quantized reflection coefficient 6 */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRc6Cdf[12]; - -/* quantization boundary levels for reflection coefficients */ -extern const WebRtc_Word16 WebRtcIsac_kQArBoundaryLevels[12]; - -/* initial indices for AR reflection coefficient quantizer and cdf table search */ -extern const WebRtc_UWord16 WebRtcIsac_kQArRcInitIndex[AR_ORDER]; - -/* pointers to AR cdf tables */ -extern const WebRtc_UWord16 *WebRtcIsac_kQArRcCdfPtr[AR_ORDER]; - -/* pointers to AR representation levels tables */ -extern const WebRtc_Word16 *WebRtcIsac_kQArRcLevelsPtr[AR_ORDER]; - - -/******************** GAIN Coefficient Tables ***********************/ -/* cdf for Gain coefficient */ -extern const WebRtc_UWord16 WebRtcIsac_kQGainCdf[19]; - -/* representation levels for quantized Gain coefficient */ -extern const WebRtc_Word32 WebRtcIsac_kQGain2Levels[18]; - -/* squared quantization boundary levels for Gain coefficient */ -extern const WebRtc_Word32 WebRtcIsac_kQGain2BoundaryLevels[19]; - -/* pointer to Gain cdf table */ -extern const WebRtc_UWord16 *WebRtcIsac_kQGainCdf_ptr[1]; - -/* Gain initial index for gain quantizer and cdf table search */ -extern const WebRtc_UWord16 WebRtcIsac_kQGainInitIndex[1]; - -/************************* Cosine Tables ****************************/ -/* Cosine table */ -extern const WebRtc_Word16 WebRtcIsac_kCos[6][60]; - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ */ diff --git a/src/mod/codecs/mod_isac/spl_inl.h b/src/mod/codecs/mod_isac/spl_inl.h deleted file mode 100644 index 23b32099a3..0000000000 --- a/src/mod/codecs/mod_isac/spl_inl.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -// This header file includes the inline functions in -// the fix point signal processing library. - -#ifndef WEBRTC_SPL_SPL_INL_H_ -#define WEBRTC_SPL_SPL_INL_H_ - -#ifdef WEBRTC_ARCH_ARM_V7A -#include "spl_inl_armv7.h" -#else - -static __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) { - WebRtc_Word16 out16 = (WebRtc_Word16) value32; - - if (value32 > 32767) - out16 = 32767; - else if (value32 < -32768) - out16 = -32768; - - return out16; -} - -static __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, - WebRtc_Word16 b) { - return WebRtcSpl_SatW32ToW16((WebRtc_Word32) a + (WebRtc_Word32) b); -} - -static __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_sum; - - // perform long addition - l_sum = l_var1 + l_var2; - - // check for under or overflow - if (WEBRTC_SPL_IS_NEG(l_var1)) { - if (WEBRTC_SPL_IS_NEG(l_var2) && !WEBRTC_SPL_IS_NEG(l_sum)) { - l_sum = (WebRtc_Word32)0x80000000; - } - } else { - if (!WEBRTC_SPL_IS_NEG(l_var2) && WEBRTC_SPL_IS_NEG(l_sum)) { - l_sum = (WebRtc_Word32)0x7FFFFFFF; - } - } - - return l_sum; -} - -static __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, - WebRtc_Word16 var2) { - return WebRtcSpl_SatW32ToW16((WebRtc_Word32) var1 - (WebRtc_Word32) var2); -} - -static __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_diff; - - // perform subtraction - l_diff = l_var1 - l_var2; - - // check for underflow - if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0)) - l_diff = (WebRtc_Word32)0x80000000; - // check for overflow - if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0)) - l_diff = (WebRtc_Word32)0x7FFFFFFF; - - return l_diff; -} - -static __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) { - int bits; - - if (0xFFFF0000 & n) { - bits = 16; - } else { - bits = 0; - } - if (0x0000FF00 & (n >> bits)) bits += 8; - if (0x000000F0 & (n >> bits)) bits += 4; - if (0x0000000C & (n >> bits)) bits += 2; - if (0x00000002 & (n >> bits)) bits += 1; - if (0x00000001 & (n >> bits)) bits += 1; - - return bits; -} - -static __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) { - int zeros; - - if (a <= 0) a ^= 0xFFFFFFFF; - - if (!(0xFFFF8000 & a)) { - zeros = 16; - } else { - zeros = 0; - } - if (!(0xFF800000 & (a << zeros))) zeros += 8; - if (!(0xF8000000 & (a << zeros))) zeros += 4; - if (!(0xE0000000 & (a << zeros))) zeros += 2; - if (!(0xC0000000 & (a << zeros))) zeros += 1; - - return zeros; -} - -static __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) { - int zeros; - - if (a == 0) return 0; - - if (!(0xFFFF0000 & a)) { - zeros = 16; - } else { - zeros = 0; - } - if (!(0xFF000000 & (a << zeros))) zeros += 8; - if (!(0xF0000000 & (a << zeros))) zeros += 4; - if (!(0xC0000000 & (a << zeros))) zeros += 2; - if (!(0x80000000 & (a << zeros))) zeros += 1; - - return zeros; -} - -static __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) { - int zeros; - - if (a <= 0) a ^= 0xFFFF; - - if (!(0xFF80 & a)) { - zeros = 8; - } else { - zeros = 0; - } - if (!(0xF800 & (a << zeros))) zeros += 4; - if (!(0xE000 & (a << zeros))) zeros += 2; - if (!(0xC000 & (a << zeros))) zeros += 1; - - return zeros; -} - -static __inline int32_t WebRtc_MulAccumW16(int16_t a, - int16_t b, - int32_t c) { - return (a * b + c); -} - -#endif // WEBRTC_ARCH_ARM_V7A - -#endif // WEBRTC_SPL_SPL_INL_H_ diff --git a/src/mod/codecs/mod_isac/spl_inl_armv7.h b/src/mod/codecs/mod_isac/spl_inl_armv7.h deleted file mode 100644 index 689c2baeea..0000000000 --- a/src/mod/codecs/mod_isac/spl_inl_armv7.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -// This header file includes the inline functions for ARM processors in -// the fix point signal processing library. - -#ifndef WEBRTC_SPL_SPL_INL_ARMV7_H_ -#define WEBRTC_SPL_SPL_INL_ARMV7_H_ - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, - WebRtc_Word32 b) { - WebRtc_Word32 tmp; - __asm__("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a)); - return tmp; -} - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a, - WebRtc_Word16 b, - WebRtc_Word32 c) { - WebRtc_Word32 tmp; - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(tmp) : "r"(b), "r"(a)); - __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(tmp), "r"(c)); - return tmp; -} - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI(WebRtc_Word32 a, - WebRtc_Word32 b) { - WebRtc_Word32 tmp; - __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); - return tmp; -} - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a, - WebRtc_Word16 b) { - WebRtc_Word32 tmp; - __asm__("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); - return tmp; -} - -static __inline int32_t WebRtc_MulAccumW16(int16_t a, - int16_t b, - int32_t c) { - int32_t tmp = 0; - __asm__("smlabb %0, %1, %2, %3":"=r"(tmp):"r"(a), "r"(b), "r"(c)); - return tmp; -} - -static __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, - WebRtc_Word16 b) { - WebRtc_Word32 s_sum; - - __asm__("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b)); - - return (WebRtc_Word16) s_sum; -} - -static __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_sum; - - __asm__("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2)); - - return l_sum; -} - -static __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, - WebRtc_Word16 var2) { - WebRtc_Word32 s_sub; - - __asm__("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2)); - - return (WebRtc_Word16)s_sub; -} - -static __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_sub; - - __asm__("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2)); - - return l_sub; -} - -static __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) { - WebRtc_Word32 tmp; - - __asm__("clz %0, %1":"=r"(tmp):"r"(n)); - - return (WebRtc_Word16)(32 - tmp); -} - -static __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) { - WebRtc_Word32 tmp; - - if (a <= 0) a ^= 0xFFFFFFFF; - - __asm__("clz %0, %1":"=r"(tmp):"r"(a)); - - return tmp - 1; -} - -static __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) { - int tmp; - - if (a == 0) return 0; - - __asm__("clz %0, %1":"=r"(tmp):"r"(a)); - - return tmp; -} - -static __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) { - WebRtc_Word32 tmp; - - if (a <= 0) a ^= 0xFFFFFFFF; - - __asm__("clz %0, %1":"=r"(tmp):"r"(a)); - - return tmp - 17; -} - -static __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) { - WebRtc_Word16 out16; - - __asm__("ssat %r0, #16, %r1" : "=r"(out16) : "r"(value32)); - - return out16; -} -#endif // WEBRTC_SPL_SPL_INL_ARMV7_H_ diff --git a/src/mod/codecs/mod_isac/spl_sqrt.c b/src/mod/codecs/mod_isac/spl_sqrt.c deleted file mode 100644 index cfe2cd3f34..0000000000 --- a/src/mod/codecs/mod_isac/spl_sqrt.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_Sqrt(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in); - -WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in) -{ - - WebRtc_Word16 x_half, t16; - WebRtc_Word32 A, B, x2; - - /* The following block performs: - y=in/2 - x=y-2^30 - x_half=x/2^31 - t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4) - + 0.875*((x_half)^5) - */ - - B = in; - - B = WEBRTC_SPL_RSHIFT_W32(B, 1); // B = in/2 - B = B - ((WebRtc_Word32)0x40000000); // B = in/2 - 1/2 - x_half = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(B, 16);// x_half = x/2 = (in-1)/2 - B = B + ((WebRtc_Word32)0x40000000); // B = 1 + x/2 - B = B + ((WebRtc_Word32)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31) - - x2 = ((WebRtc_Word32)x_half) * ((WebRtc_Word32)x_half) * 2; // A = (x/2)^2 - A = -x2; // A = -(x/2)^2 - B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2 - - A = WEBRTC_SPL_RSHIFT_W32(A, 16); - A = A * A * 2; // A = (x/2)^4 - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); - B = B + WEBRTC_SPL_MUL_16_16(-20480, t16) * 2; // B = B - 0.625*A - // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 - - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); - A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = (x/2)^5 - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); - B = B + WEBRTC_SPL_MUL_16_16(28672, t16) * 2; // B = B + 0.875*A - // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5 - - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(x2, 16); - A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = x/2^3 - - B = B + (A >> 1); // B = B + 0.5*A - // After this, B = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 + 0.875*(x/2)^5 - - B = B + ((WebRtc_Word32)32768); // Round off bit - - return B; -} - -WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value) -{ - /* - Algorithm: - - Six term Taylor Series is used here to compute the square root of a number - y^0.5 = (1+x)^0.5 where x = y-1 - = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5) - 0.5 <= x < 1 - - Example of how the algorithm works, with ut=sqrt(in), and - with in=73632 and ut=271 (even shift value case): - - in=73632 - y= in/131072 - x=y-1 - t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5) - ut=t*(1/sqrt(2))*512 - - or: - - in=73632 - in2=73632*2^14 - y= in2/2^31 - x=y-1 - t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5) - ut=t*(1/sqrt(2)) - ut2=ut*2^9 - - which gives: - - in = 73632 - in2 = 1206386688 - y = 0.56176757812500 - x = -0.43823242187500 - t = 0.74973506527313 - ut = 0.53014274874797 - ut2 = 2.714330873589594e+002 - - or: - - in=73632 - in2=73632*2^14 - y=in2/2 - x=y-2^30 - x_half=x/2^31 - t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4) - + 0.875*((x_half)^5) - ut=t*(1/sqrt(2)) - ut2=ut*2^9 - - which gives: - - in = 73632 - in2 = 1206386688 - y = 603193344 - x = -470548480 - x_half = -0.21911621093750 - t = 0.74973506527313 - ut = 0.53014274874797 - ut2 = 2.714330873589594e+002 - - */ - - WebRtc_Word16 x_norm, nshift, t16, sh; - WebRtc_Word32 A; - - WebRtc_Word16 k_sqrt_2 = 23170; // 1/sqrt2 (==5a82) - - A = value; - - if (A == 0) - return (WebRtc_Word32)0; // sqrt(0) = 0 - - sh = WebRtcSpl_NormW32(A); // # shifts to normalize A - A = WEBRTC_SPL_LSHIFT_W32(A, sh); // Normalize A - if (A < (WEBRTC_SPL_WORD32_MAX - 32767)) - { - A = A + ((WebRtc_Word32)32768); // Round off bit - } else - { - A = WEBRTC_SPL_WORD32_MAX; - } - - x_norm = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // x_norm = AH - - nshift = WEBRTC_SPL_RSHIFT_W16(sh, 1); // nshift = sh>>1 - nshift = -nshift; // Negate the power for later de-normalization - - A = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x_norm, 16); - A = WEBRTC_SPL_ABS_W32(A); // A = abs(x_norm<<16) - A = WebRtcSpl_SqrtLocal(A); // A = sqrt(A) - - if ((-2 * nshift) == sh) - { // Even shift value case - - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // t16 = AH - - A = WEBRTC_SPL_MUL_16_16(k_sqrt_2, t16) * 2; // A = 1/sqrt(2)*t16 - A = A + ((WebRtc_Word32)32768); // Round off - A = A & ((WebRtc_Word32)0x7fff0000); // Round off - - A = WEBRTC_SPL_RSHIFT_W32(A, 15); // A = A>>16 - - } else - { - A = WEBRTC_SPL_RSHIFT_W32(A, 16); // A = A>>16 - } - - A = A & ((WebRtc_Word32)0x0000ffff); - A = (WebRtc_Word32)WEBRTC_SPL_SHIFT_W32(A, nshift); // De-normalize the result - - return A; -} diff --git a/src/mod/codecs/mod_isac/spl_sqrt_floor.c b/src/mod/codecs/mod_isac/spl_sqrt_floor.c deleted file mode 100644 index aa36459ec4..0000000000 --- a/src/mod/codecs/mod_isac/spl_sqrt_floor.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file contains the function WebRtcSpl_SqrtFloor(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define WEBRTC_SPL_SQRT_ITER(N) \ - try1 = root + (1 << (N)); \ - if (value >= try1 << (N)) \ - { \ - value -= try1 << (N); \ - root |= 2 << (N); \ - } - -// (out) Square root of input parameter -WebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value) -{ - // new routine for performance, 4 cycles/bit in ARM - // output precision is 16 bits - - WebRtc_Word32 root = 0, try1; - - WEBRTC_SPL_SQRT_ITER (15); - WEBRTC_SPL_SQRT_ITER (14); - WEBRTC_SPL_SQRT_ITER (13); - WEBRTC_SPL_SQRT_ITER (12); - WEBRTC_SPL_SQRT_ITER (11); - WEBRTC_SPL_SQRT_ITER (10); - WEBRTC_SPL_SQRT_ITER ( 9); - WEBRTC_SPL_SQRT_ITER ( 8); - WEBRTC_SPL_SQRT_ITER ( 7); - WEBRTC_SPL_SQRT_ITER ( 6); - WEBRTC_SPL_SQRT_ITER ( 5); - WEBRTC_SPL_SQRT_ITER ( 4); - WEBRTC_SPL_SQRT_ITER ( 3); - WEBRTC_SPL_SQRT_ITER ( 2); - WEBRTC_SPL_SQRT_ITER ( 1); - WEBRTC_SPL_SQRT_ITER ( 0); - - return root >> 1; -} diff --git a/src/mod/codecs/mod_isac/spl_version.c b/src/mod/codecs/mod_isac/spl_version.c deleted file mode 100644 index 936925ea14..0000000000 --- a/src/mod/codecs/mod_isac/spl_version.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_get_version(). - * The description header can be found in signal_processing_library.h - * - */ - -#include -#include "signal_processing_library.h" - -WebRtc_Word16 WebRtcSpl_get_version(char* version, WebRtc_Word16 length_in_bytes) -{ - strncpy(version, "1.2.0", length_in_bytes); - return 0; -} diff --git a/src/mod/codecs/mod_isac/splitting_filter.c b/src/mod/codecs/mod_isac/splitting_filter.c deleted file mode 100644 index f1acf675f9..0000000000 --- a/src/mod/codecs/mod_isac/splitting_filter.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file contains the splitting filter functions. - * - */ - -#include "signal_processing_library.h" - -// Number of samples in a low/high-band frame. -enum -{ - kBandFrameLength = 160 -}; - -// QMF filter coefficients in Q16. -static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261}; -static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -// WebRtcSpl_AllPassQMF(...) -// -// Allpass filter used by the analysis and synthesis parts of the QMF filter. -// -// Input: -// - in_data : Input data sequence (Q10) -// - data_length : Length of data sequence (>2) -// - filter_coefficients : Filter coefficients (length 3, Q16) -// -// Input & Output: -// - filter_state : Filter state (length 6, Q10). -// -// Output: -// - out_data : Output data sequence (Q10), length equal to -// |data_length| -// - -void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_length, - WebRtc_Word32* out_data, const WebRtc_UWord16* filter_coefficients, - WebRtc_Word32* filter_state) -{ - // The procedure is to filter the input with three first order all pass filters - // (cascade operations). - // - // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1 - // y[n] = ----------- ----------- ----------- x[n] - // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1 - // - // The input vector |filter_coefficients| includes these three filter coefficients. - // The filter state contains the in_data state, in_data[-1], followed by - // the out_data state, out_data[-1]. This is repeated for each cascade. - // The first cascade filter will filter the |in_data| and store the output in - // |out_data|. The second will the take the |out_data| as input and make an - // intermediate storage in |in_data|, to save memory. The third, and final, cascade - // filter operation takes the |in_data| (which is the output from the previous cascade - // filter) and store the output in |out_data|. - // Note that the input vector values are changed during the process. - WebRtc_Word16 k; - WebRtc_Word32 diff; - // First all-pass cascade; filter from in_data to out_data. - - // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at - // vector position n. Then the final output will be y[n] = y_3[n] - - // First loop, use the states stored in memory. - // "diff" should be safe from wrap around since max values are 2^25 - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[1]); // = (x[0] - y_1[-1]) - // y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1]) - out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]); - - // For the remaining loops, use previous values. - for (k = 1; k < data_length; k++) - { - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (x[n] - y_1[n-1]) - // y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1]) - out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]); - } - - // Update states. - filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time - filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time - - // Second all-pass cascade; filter from out_data to in_data. - diff = WEBRTC_SPL_SUB_SAT_W32(out_data[0], filter_state[3]); // = (y_1[0] - y_2[-1]) - // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) - in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]); - for (k = 1; k < data_length; k++) - { - diff = WEBRTC_SPL_SUB_SAT_W32(out_data[k], in_data[k - 1]); // =(y_1[n] - y_2[n-1]) - // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) - in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]); - } - - filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time - filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time - - // Third all-pass cascade; filter from in_data to out_data. - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[5]); // = (y_2[0] - y[-1]) - // y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1]) - out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]); - for (k = 1; k < data_length; k++) - { - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (y_2[n] - y[n-1]) - // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) - out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]); - } - filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time - filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time -} - -void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, WebRtc_Word16* low_band, - WebRtc_Word16* high_band, WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2) -{ - WebRtc_Word16 i; - WebRtc_Word16 k; - WebRtc_Word32 tmp; - WebRtc_Word32 half_in1[kBandFrameLength]; - WebRtc_Word32 half_in2[kBandFrameLength]; - WebRtc_Word32 filter1[kBandFrameLength]; - WebRtc_Word32 filter2[kBandFrameLength]; - - // Split even and odd samples. Also shift them to Q10. - for (i = 0, k = 0; i < kBandFrameLength; i++, k += 2) - { - half_in2[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k], 10); - half_in1[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k + 1], 10); - } - - // All pass filter even and odd samples, independently. - WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter1, - filter_state1); - WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter2, - filter_state2); - - // Take the sum and difference of filtered version of odd and even - // branches to get upper & lower band. - for (i = 0; i < kBandFrameLength; i++) - { - tmp = filter1[i] + filter2[i] + 1024; - tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11); - low_band[i] = WebRtcSpl_SatW32ToW16(tmp); - - tmp = filter1[i] - filter2[i] + 1024; - tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11); - high_band[i] = WebRtcSpl_SatW32ToW16(tmp); - } -} - -void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, const WebRtc_Word16* high_band, - WebRtc_Word16* out_data, WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2) -{ - WebRtc_Word32 tmp; - WebRtc_Word32 half_in1[kBandFrameLength]; - WebRtc_Word32 half_in2[kBandFrameLength]; - WebRtc_Word32 filter1[kBandFrameLength]; - WebRtc_Word32 filter2[kBandFrameLength]; - WebRtc_Word16 i; - WebRtc_Word16 k; - - // Obtain the sum and difference channels out of upper and lower-band channels. - // Also shift to Q10 domain. - for (i = 0; i < kBandFrameLength; i++) - { - tmp = (WebRtc_Word32)low_band[i] + (WebRtc_Word32)high_band[i]; - half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); - tmp = (WebRtc_Word32)low_band[i] - (WebRtc_Word32)high_band[i]; - half_in2[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); - } - - // all-pass filter the sum and difference channels - WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter2, - filter_state1); - WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter1, - filter_state2); - - // The filtered signals are even and odd samples of the output. Combine - // them. The signals are Q10 should shift them back to Q0 and take care of - // saturation. - for (i = 0, k = 0; i < kBandFrameLength; i++) - { - tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10); - out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); - - tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10); - out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); - } - -} diff --git a/src/mod/codecs/mod_isac/sqrt_of_one_minus_x_squared.c b/src/mod/codecs/mod_isac/sqrt_of_one_minus_x_squared.c deleted file mode 100644 index 9fb2c73bc5..0000000000 --- a/src/mod/codecs/mod_isac/sqrt_of_one_minus_x_squared.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_SqrtOfOneMinusXSquared(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16 *xQ15, int vector_length, - WebRtc_Word16 *yQ15) -{ - WebRtc_Word32 sq; - int m; - WebRtc_Word16 tmp; - - for (m = 0; m < vector_length; m++) - { - tmp = xQ15[m]; - sq = WEBRTC_SPL_MUL_16_16(tmp, tmp); // x^2 in Q30 - sq = 1073741823 - sq; // 1-x^2, where 1 ~= 0.99999999906 is 1073741823 in Q30 - sq = WebRtcSpl_Sqrt(sq); // sqrt(1-x^2) in Q15 - yQ15[m] = (WebRtc_Word16)sq; - } -} diff --git a/src/mod/codecs/mod_isac/structs.h b/src/mod/codecs/mod_isac/structs.h deleted file mode 100644 index 7523ad6e4a..0000000000 --- a/src/mod/codecs/mod_isac/structs.h +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * structs.h - * - * This header file contains all the structs used in the ISAC codec - * - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ - - -#include "typedefs.h" -#include "settings.h" -#include "isac.h" - -typedef struct Bitstreamstruct { - - WebRtc_UWord8 stream[STREAM_SIZE_MAX]; - WebRtc_UWord32 W_upper; - WebRtc_UWord32 streamval; - WebRtc_UWord32 stream_index; - -} Bitstr; - -typedef struct { - - double DataBufferLo[WINLEN]; - double DataBufferHi[WINLEN]; - - double CorrBufLo[ORDERLO+1]; - double CorrBufHi[ORDERHI+1]; - - float PreStateLoF[ORDERLO+1]; - float PreStateLoG[ORDERLO+1]; - float PreStateHiF[ORDERHI+1]; - float PreStateHiG[ORDERHI+1]; - float PostStateLoF[ORDERLO+1]; - float PostStateLoG[ORDERLO+1]; - float PostStateHiF[ORDERHI+1]; - float PostStateHiG[ORDERHI+1]; - - double OldEnergy; - -} MaskFiltstr; - - -typedef struct { - - //state vectors for each of the two analysis filters - double INSTAT1[2*(QORDER-1)]; - double INSTAT2[2*(QORDER-1)]; - double INSTATLA1[2*(QORDER-1)]; - double INSTATLA2[2*(QORDER-1)]; - double INLABUF1[QLOOKAHEAD]; - double INLABUF2[QLOOKAHEAD]; - - float INSTAT1_float[2*(QORDER-1)]; - float INSTAT2_float[2*(QORDER-1)]; - float INSTATLA1_float[2*(QORDER-1)]; - float INSTATLA2_float[2*(QORDER-1)]; - float INLABUF1_float[QLOOKAHEAD]; - float INLABUF2_float[QLOOKAHEAD]; - - /* High pass filter */ - double HPstates[HPORDER]; - float HPstates_float[HPORDER]; - -} PreFiltBankstr; - - -typedef struct { - - //state vectors for each of the two analysis filters - double STATE_0_LOWER[2*POSTQORDER]; - double STATE_0_UPPER[2*POSTQORDER]; - - /* High pass filter */ - double HPstates1[HPORDER]; - double HPstates2[HPORDER]; - - float STATE_0_LOWER_float[2*POSTQORDER]; - float STATE_0_UPPER_float[2*POSTQORDER]; - - float HPstates1_float[HPORDER]; - float HPstates2_float[HPORDER]; - -} PostFiltBankstr; - -typedef struct { - - //data buffer for pitch filter - double ubuf[PITCH_BUFFSIZE]; - - //low pass state vector - double ystate[PITCH_DAMPORDER]; - - //old lag and gain - double oldlagp[1]; - double oldgainp[1]; - -} PitchFiltstr; - -typedef struct { - - //data buffer - double buffer[PITCH_WLPCBUFLEN]; - - //state vectors - double istate[PITCH_WLPCORDER]; - double weostate[PITCH_WLPCORDER]; - double whostate[PITCH_WLPCORDER]; - - //LPC window -> should be a global array because constant - double window[PITCH_WLPCWINLEN]; - -} WeightFiltstr; - -typedef struct { - - //for inital estimator - double dec_buffer[PITCH_CORR_LEN2 + PITCH_CORR_STEP2 + - PITCH_MAX_LAG/2 - PITCH_FRAME_LEN/2+2]; - double decimator_state[2*ALLPASSSECTIONS+1]; - double hp_state[2]; - - double whitened_buf[QLOOKAHEAD]; - - double inbuf[QLOOKAHEAD]; - - PitchFiltstr PFstr_wght; - PitchFiltstr PFstr; - WeightFiltstr Wghtstr; - -} PitchAnalysisStruct; - - - -/* Have instance of struct together with other iSAC structs */ -typedef struct { - - /* Previous frame length (in ms) */ - WebRtc_Word32 prev_frame_length; - - /* Previous RTP timestamp from received - packet (in samples relative beginning) */ - WebRtc_Word32 prev_rec_rtp_number; - - /* Send timestamp for previous packet (in ms using timeGetTime()) */ - WebRtc_UWord32 prev_rec_send_ts; - - /* Arrival time for previous packet (in ms using timeGetTime()) */ - WebRtc_UWord32 prev_rec_arr_ts; - - /* rate of previous packet, derived from RTP timestamps (in bits/s) */ - float prev_rec_rtp_rate; - - /* Time sinse the last update of the BN estimate (in ms) */ - WebRtc_UWord32 last_update_ts; - - /* Time sinse the last reduction (in ms) */ - WebRtc_UWord32 last_reduction_ts; - - /* How many times the estimate was update in the beginning */ - WebRtc_Word32 count_tot_updates_rec; - - /* The estimated bottle neck rate from there to here (in bits/s) */ - WebRtc_Word32 rec_bw; - float rec_bw_inv; - float rec_bw_avg; - float rec_bw_avg_Q; - - /* The estimated mean absolute jitter value, - as seen on this side (in ms) */ - float rec_jitter; - float rec_jitter_short_term; - float rec_jitter_short_term_abs; - float rec_max_delay; - float rec_max_delay_avg_Q; - - /* (assumed) bitrate for headers (bps) */ - float rec_header_rate; - - /* The estimated bottle neck rate from here to there (in bits/s) */ - float send_bw_avg; - - /* The estimated mean absolute jitter value, as seen on - the other siee (in ms) */ - float send_max_delay_avg; - - // number of packets received since last update - int num_pkts_rec; - - int num_consec_rec_pkts_over_30k; - - // flag for marking that a high speed network has been - // detected downstream - int hsn_detect_rec; - - int num_consec_snt_pkts_over_30k; - - // flag for marking that a high speed network has - // been detected upstream - int hsn_detect_snd; - - WebRtc_UWord32 start_wait_period; - - int in_wait_period; - - int change_to_WB; - - WebRtc_UWord32 senderTimestamp; - WebRtc_UWord32 receiverTimestamp; - //enum IsacSamplingRate incomingStreamSampFreq; - WebRtc_UWord16 numConsecLatePkts; - float consecLatency; - WebRtc_Word16 inWaitLatePkts; -} BwEstimatorstr; - - -typedef struct { - - /* boolean, flags if previous packet exceeded B.N. */ - int PrevExceed; - /* ms */ - int ExceedAgo; - /* packets left to send in current burst */ - int BurstCounter; - /* packets */ - int InitCounter; - /* ms remaining in buffer when next packet will be sent */ - double StillBuffered; - -} RateModel; - - -typedef struct { - - unsigned int SpaceAlloced; - unsigned int MaxPermAlloced; - double Tmp0[MAXFFTSIZE]; - double Tmp1[MAXFFTSIZE]; - double Tmp2[MAXFFTSIZE]; - double Tmp3[MAXFFTSIZE]; - int Perm[MAXFFTSIZE]; - int factor [NFACTOR]; - -} FFTstr; - - -/* The following strutc is used to store data from encoding, to make it - fast and easy to construct a new bitstream with a different Bandwidth - estimate. All values (except framelength and minBytes) is double size to - handle 60 ms of data. -*/ -typedef struct { - - /* Used to keep track of if it is first or second part of 60 msec packet */ - int startIdx; - - /* Frame length in samples */ - WebRtc_Word16 framelength; - - /* Pitch Gain */ - int pitchGain_index[2]; - - /* Pitch Lag */ - double meanGain[2]; - int pitchIndex[PITCH_SUBFRAMES*2]; - - /* LPC */ - int LPCmodel[2]; - int LPCindex_s[108*2]; /* KLT_ORDER_SHAPE = 108 */ - int LPCindex_g[12*2]; /* KLT_ORDER_GAIN = 12 */ - double LPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*2]; - double LPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*2]; - - /* Encode Spec */ - WebRtc_Word16 fre[FRAMESAMPLES]; - WebRtc_Word16 fim[FRAMESAMPLES]; - WebRtc_Word16 AvgPitchGain[2]; - - /* Used in adaptive mode only */ - int minBytes; - -} ISAC_SaveEncData_t; - - -typedef struct { - - int indexLPCShape[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - double lpcGain[SUBFRAMES<<1]; - int lpcGainIndex[SUBFRAMES<<1]; - - Bitstr bitStreamObj; - - WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; - WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; -} ISACUBSaveEncDataStruct; - - - -typedef struct { - - Bitstr bitstr_obj; - MaskFiltstr maskfiltstr_obj; - PreFiltBankstr prefiltbankstr_obj; - PitchFiltstr pitchfiltstr_obj; - PitchAnalysisStruct pitchanalysisstr_obj; - FFTstr fftstr_obj; - ISAC_SaveEncData_t SaveEnc_obj; - - int buffer_index; - WebRtc_Word16 current_framesamples; - - float data_buffer_float[FRAMESAMPLES_30ms]; - - int frame_nb; - double bottleneck; - WebRtc_Word16 new_framelength; - double s2nr; - - /* Maximum allowed number of bits for a 30 msec packet */ - WebRtc_Word16 payloadLimitBytes30; - /* Maximum allowed number of bits for a 30 msec packet */ - WebRtc_Word16 payloadLimitBytes60; - /* Maximum allowed number of bits for both 30 and 60 msec packet */ - WebRtc_Word16 maxPayloadBytes; - /* Maximum allowed rate in bytes per 30 msec packet */ - WebRtc_Word16 maxRateInBytes; - - /*--- - If set to 1 iSAC will not addapt the frame-size, if used in - channel-adaptive mode. The initial value will be used for all rates. - ---*/ - WebRtc_Word16 enforceFrameSize; - - /*----- - This records the BWE index the encoder injected into the bit-stream. - It will be used in RCU. The same BWE index of main paylaod will be in - the redundant payload. We can not retrive it from BWE because it is - a recursive procedure (WebRtcIsac_GetDownlinkBwJitIndexImpl) and has to be - called only once per each encode. - -----*/ - WebRtc_Word16 lastBWIdx; -} ISACLBEncStruct; - -typedef struct { - - Bitstr bitstr_obj; - MaskFiltstr maskfiltstr_obj; - PreFiltBankstr prefiltbankstr_obj; - FFTstr fftstr_obj; - ISACUBSaveEncDataStruct SaveEnc_obj; - - int buffer_index; - float data_buffer_float[MAX_FRAMESAMPLES + - LB_TOTAL_DELAY_SAMPLES]; - double bottleneck; - /* Maximum allowed number of bits for a 30 msec packet */ - //WebRtc_Word16 payloadLimitBytes30; - /* Maximum allowed number of bits for both 30 and 60 msec packet */ - //WebRtc_Word16 maxPayloadBytes; - WebRtc_Word16 maxPayloadSizeBytes; - - double lastLPCVec[UB_LPC_ORDER]; - WebRtc_Word16 numBytesUsed; - WebRtc_Word16 lastJitterInfo; -} ISACUBEncStruct; - - - -typedef struct { - - Bitstr bitstr_obj; - MaskFiltstr maskfiltstr_obj; - PostFiltBankstr postfiltbankstr_obj; - PitchFiltstr pitchfiltstr_obj; - FFTstr fftstr_obj; - -} ISACLBDecStruct; - -typedef struct { - - Bitstr bitstr_obj; - MaskFiltstr maskfiltstr_obj; - PostFiltBankstr postfiltbankstr_obj; - FFTstr fftstr_obj; - -} ISACUBDecStruct; - - - -typedef struct { - - ISACLBEncStruct ISACencLB_obj; - ISACLBDecStruct ISACdecLB_obj; -} ISACLBStruct; - - -typedef struct { - - ISACUBEncStruct ISACencUB_obj; - ISACUBDecStruct ISACdecUB_obj; -} ISACUBStruct; - -/* - This struct is used to take a snapshot of the entropy coder and LPC gains - right before encoding LPC gains. This allows us to go back to that state - if we like to limit the payload size. -*/ -typedef struct { - /* 6 lower-band & 6 upper-band */ - double loFiltGain[SUBFRAMES]; - double hiFiltGain[SUBFRAMES]; - /* Upper boundary of interval W */ - WebRtc_UWord32 W_upper; - WebRtc_UWord32 streamval; - /* Index to the current position in bytestream */ - WebRtc_UWord32 stream_index; - WebRtc_UWord8 stream[3]; -} transcode_obj; - - -typedef struct { - // lower-band codec instance - ISACLBStruct instLB; - // upper-band codec instance - ISACUBStruct instUB; - - // Bandwidth Estimator and model for the rate. - BwEstimatorstr bwestimator_obj; - RateModel rate_data_obj; - double MaxDelay; - - /* 0 = adaptive; 1 = instantaneous */ - WebRtc_Word16 codingMode; - - // overall bottleneck of the codec - WebRtc_Word32 bottleneck; - - // QMF Filter state - WebRtc_Word32 analysisFBState1[FB_STATE_SIZE_WORD32]; - WebRtc_Word32 analysisFBState2[FB_STATE_SIZE_WORD32]; - WebRtc_Word32 synthesisFBState1[FB_STATE_SIZE_WORD32]; - WebRtc_Word32 synthesisFBState2[FB_STATE_SIZE_WORD32]; - - // Error Code - WebRtc_Word16 errorCode; - - // bandwidth of the encoded audio 8, 12 or 16 kHz - enum ISACBandwidth bandwidthKHz; - // Sampling rate of audio, encoder and decode, 8 or 16 kHz - enum IsacSamplingRate encoderSamplingRateKHz; - enum IsacSamplingRate decoderSamplingRateKHz; - // Flag to keep track of initializations, lower & upper-band - // encoder and decoder. - WebRtc_Word16 initFlag; - - // Flag to to indicate signal bandwidth switch - WebRtc_Word16 resetFlag_8kHz; - - // Maximum allowed rate, measured in Bytes per 30 ms. - WebRtc_Word16 maxRateBytesPer30Ms; - // Maximum allowed payload-size, measured in Bytes. - WebRtc_Word16 maxPayloadSizeBytes; -} ISACMainStruct; - -#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ */ diff --git a/src/mod/codecs/mod_isac/transform.c b/src/mod/codecs/mod_isac/transform.c deleted file mode 100644 index 97b801ac49..0000000000 --- a/src/mod/codecs/mod_isac/transform.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "settings.h" -#include "fft.h" -#include "codec.h" -#include "os_specific_inline.h" -#include - -static double costab1[FRAMESAMPLES_HALF]; -static double sintab1[FRAMESAMPLES_HALF]; -static double costab2[FRAMESAMPLES_QUARTER]; -static double sintab2[FRAMESAMPLES_QUARTER]; - -void WebRtcIsac_InitTransform() -{ - int k; - double fact, phase; - - fact = PI / (FRAMESAMPLES_HALF); - phase = 0.0; - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - costab1[k] = cos(phase); - sintab1[k] = sin(phase); - phase += fact; - } - - fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF); - phase = 0.5 * fact; - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { - costab2[k] = cos(phase); - sintab2[k] = sin(phase); - phase += fact; - } -} - - -void WebRtcIsac_Time2Spec(double *inre1, - double *inre2, - WebRtc_Word16 *outreQ7, - WebRtc_Word16 *outimQ7, - FFTstr *fftstr_obj) -{ - - int k; - int dims[1]; - double tmp1r, tmp1i, xr, xi, yr, yi, fact; - double tmpre[FRAMESAMPLES_HALF], tmpim[FRAMESAMPLES_HALF]; - - - dims[0] = FRAMESAMPLES_HALF; - - - /* Multiply with complex exponentials and combine into one complex vector */ - fact = 0.5 / sqrt(FRAMESAMPLES_HALF); - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - tmp1r = costab1[k]; - tmp1i = sintab1[k]; - tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact; - tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact; - } - - - /* Get DFT */ - WebRtcIsac_Fftns(1, dims, tmpre, tmpim, -1, 1.0, fftstr_obj); - - /* Use symmetry to separate into two complex vectors and center frames in time around zero */ - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { - xr = tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k]; - yi = -tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k]; - xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k]; - yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k]; - - tmp1r = costab2[k]; - tmp1i = sintab2[k]; - outreQ7[k] = (WebRtc_Word16)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0); - outimQ7[k] = (WebRtc_Word16)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0); - outreQ7[FRAMESAMPLES_HALF - 1 - k] = (WebRtc_Word16)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0); - outimQ7[FRAMESAMPLES_HALF - 1 - k] = (WebRtc_Word16)WebRtcIsac_lrint((-yr * tmp1r + yi * tmp1i) * 128.0); - } -} - - -void WebRtcIsac_Spec2time(double *inre, double *inim, double *outre1, double *outre2, FFTstr *fftstr_obj) -{ - - int k; - double tmp1r, tmp1i, xr, xi, yr, yi, fact; - - int dims; - - dims = FRAMESAMPLES_HALF; - - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { - /* Move zero in time to beginning of frames */ - tmp1r = costab2[k]; - tmp1i = sintab2[k]; - xr = inre[k] * tmp1r + inim[k] * tmp1i; - xi = inim[k] * tmp1r - inre[k] * tmp1i; - yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i; - yi = -inre[FRAMESAMPLES_HALF - 1 - k] * tmp1r + inim[FRAMESAMPLES_HALF - 1 - k] * tmp1i; - - /* Combine into one vector, z = x + j * y */ - outre1[k] = xr - yi; - outre1[FRAMESAMPLES_HALF - 1 - k] = xr + yi; - outre2[k] = xi + yr; - outre2[FRAMESAMPLES_HALF - 1 - k] = -xi + yr; - } - - - /* Get IDFT */ - WebRtcIsac_Fftns(1, &dims, outre1, outre2, 1, FRAMESAMPLES_HALF, fftstr_obj); - - - /* Demodulate and separate */ - fact = sqrt(FRAMESAMPLES_HALF); - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - tmp1r = costab1[k]; - tmp1i = sintab1[k]; - xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact; - outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact; - outre1[k] = xr; - } -} diff --git a/src/mod/codecs/mod_isac/typedefs.h b/src/mod/codecs/mod_isac/typedefs.h deleted file mode 100644 index df0df45723..0000000000 --- a/src/mod/codecs/mod_isac/typedefs.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file contains platform-specific typedefs and defines. - -#ifndef WEBRTC_TYPEDEFS_H_ -#define WEBRTC_TYPEDEFS_H_ - -// Reserved words definitions -// TODO(andrew): Look at removing these. -#define WEBRTC_EXTERN extern -#define G_CONST const -#define WEBRTC_INLINE extern __inline - -// Define WebRTC preprocessor identifiers based on the current build platform. -// TODO(andrew): Clean these up. We can probably remove everything in this -// block. -// - TARGET_MAC_INTEL and TARGET_MAC aren't used anywhere. -// - In the few places where TARGET_PC is used, it should be replaced by -// something more specific. -// - Do we really support PowerPC? Probably not. Remove WEBRTC_MAC_INTEL -// from build/common.gypi as well. -#if defined(WIN32) - // Windows & Windows Mobile. - #if !defined(WEBRTC_TARGET_PC) - #define WEBRTC_TARGET_PC - #endif -#elif defined(__APPLE__) - // Mac OS X. - #if defined(__LITTLE_ENDIAN__ ) - #if !defined(WEBRTC_TARGET_MAC_INTEL) - #define WEBRTC_TARGET_MAC_INTEL - #endif - #else - #if !defined(WEBRTC_TARGET_MAC) - #define WEBRTC_TARGET_MAC - #endif - #endif -#else - // Linux etc. - #if !defined(WEBRTC_TARGET_PC) - #define WEBRTC_TARGET_PC - #endif -#endif - -// Derived from Chromium's build/build_config.h -// Processor architecture detection. For more info on what's defined, see: -// http://msdn.microsoft.com/en-us/library/b0084kay.aspx -// http://www.agner.org/optimize/calling_conventions.pdf -// or with gcc, run: "echo | gcc -E -dM -" -// TODO(andrew): replace WEBRTC_LITTLE_ENDIAN with WEBRTC_ARCH_LITTLE_ENDIAN? -#if defined(_M_X64) || defined(__x86_64__) -#define WEBRTC_ARCH_X86_FAMILY -#define WEBRTC_ARCH_X86_64 -#define WEBRTC_ARCH_64_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#elif defined(__aarch64__) -#define WEBRTC_ARCH_64_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#elif defined(_M_IX86) || defined(__i386__) -#define WEBRTC_ARCH_X86_FAMILY -#define WEBRTC_ARCH_X86 -#define WEBRTC_ARCH_32_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#elif defined(__ARMEL__) -// TODO(andrew): We'd prefer to control platform defines here, but this is -// currently provided by the Android makefiles. Commented to avoid duplicate -// definition warnings. -//#define WEBRTC_ARCH_ARM -// TODO(andrew): Chromium uses the following two defines. Should we switch? -//#define WEBRTC_ARCH_ARM_FAMILY -//#define WEBRTC_ARCH_ARMEL -#define WEBRTC_ARCH_32_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#elif defined(__MIPSEB__) -#define WEBRTC_ARCH_BIG_ENDIAN -#elif defined(__MIPSEL__) -#define WEBRTC_ARCH_LITTLE_ENDIAN -#else -#error Please add support for your architecture in typedefs.h -#endif - -#if defined(__SSE2__) || defined(_MSC_VER) -#define WEBRTC_USE_SSE2 -#endif - -#if defined(WEBRTC_TARGET_PC) - -#if !defined(_MSC_VER) - #include -#else - // Define C99 equivalent types. - // Since MSVC doesn't include these headers, we have to write our own - // version to provide a compatibility layer between MSVC and the WebRTC - // headers. - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef signed long long int64_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - typedef unsigned long long uint64_t; -#endif - -#if defined(WIN32) - typedef __int64 WebRtc_Word64; - typedef unsigned __int64 WebRtc_UWord64; -#else - typedef int64_t WebRtc_Word64; - typedef uint64_t WebRtc_UWord64; -#endif - typedef int32_t WebRtc_Word32; - typedef uint32_t WebRtc_UWord32; - typedef int16_t WebRtc_Word16; - typedef uint16_t WebRtc_UWord16; - typedef char WebRtc_Word8; - typedef uint8_t WebRtc_UWord8; - - // Define endian for the platform - #define WEBRTC_LITTLE_ENDIAN - -#elif defined(WEBRTC_TARGET_MAC_INTEL) - #include - - typedef int64_t WebRtc_Word64; - typedef uint64_t WebRtc_UWord64; - typedef int32_t WebRtc_Word32; - typedef uint32_t WebRtc_UWord32; - typedef int16_t WebRtc_Word16; - typedef char WebRtc_Word8; - typedef uint16_t WebRtc_UWord16; - typedef uint8_t WebRtc_UWord8; - - // Define endian for the platform - #define WEBRTC_LITTLE_ENDIAN - -#else - #error "No platform defined for WebRTC type definitions (typedefs.h)" -#endif - -#endif // WEBRTC_TYPEDEFS_H_ diff --git a/src/mod/codecs/mod_isac/vector_scaling_operations.c b/src/mod/codecs/mod_isac/vector_scaling_operations.c deleted file mode 100644 index 20d239cabe..0000000000 --- a/src/mod/codecs/mod_isac/vector_scaling_operations.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the functions - * WebRtcSpl_VectorBitShiftW16() - * WebRtcSpl_VectorBitShiftW32() - * WebRtcSpl_VectorBitShiftW32ToW16() - * WebRtcSpl_ScaleVector() - * WebRtcSpl_ScaleVectorWithSat() - * WebRtcSpl_ScaleAndAddVectors() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16 *res, - WebRtc_Word16 length, - G_CONST WebRtc_Word16 *in, - WebRtc_Word16 right_shifts) -{ - int i; - - if (right_shifts > 0) - { - for (i = length; i > 0; i--) - { - (*res++) = ((*in++) >> right_shifts); - } - } else - { - for (i = length; i > 0; i--) - { - (*res++) = ((*in++) << (-right_shifts)); - } - } -} - -void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32 *out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word32 *in_vector, - WebRtc_Word16 right_shifts) -{ - int i; - - if (right_shifts > 0) - { - for (i = vector_length; i > 0; i--) - { - (*out_vector++) = ((*in_vector++) >> right_shifts); - } - } else - { - for (i = vector_length; i > 0; i--) - { - (*out_vector++) = ((*in_vector++) << (-right_shifts)); - } - } -} - -void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16 *res, - WebRtc_Word16 length, - G_CONST WebRtc_Word32 *in, - WebRtc_Word16 right_shifts) -{ - int i; - - if (right_shifts >= 0) - { - for (i = length; i > 0; i--) - { - (*res++) = (WebRtc_Word16)((*in++) >> right_shifts); - } - } else - { - WebRtc_Word16 left_shifts = -right_shifts; - for (i = length; i > 0; i--) - { - (*res++) = (WebRtc_Word16)((*in++) << left_shifts); - } - } -} - -void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector, - WebRtc_Word16 gain, WebRtc_Word16 in_vector_length, - WebRtc_Word16 right_shifts) -{ - // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts - int i; - G_CONST WebRtc_Word16 *inptr; - WebRtc_Word16 *outptr; - - inptr = in_vector; - outptr = out_vector; - - for (i = 0; i < in_vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts); - } -} - -void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector, - WebRtc_Word16 gain, WebRtc_Word16 in_vector_length, - WebRtc_Word16 right_shifts) -{ - // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts - int i; - WebRtc_Word32 tmpW32; - G_CONST WebRtc_Word16 *inptr; - WebRtc_Word16 *outptr; - - inptr = in_vector; - outptr = out_vector; - - for (i = 0; i < in_vector_length; i++) - { - tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts); - (*outptr++) = WebRtcSpl_SatW32ToW16(tmpW32); - } -} - -void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16 *in1, WebRtc_Word16 gain1, int shift1, - G_CONST WebRtc_Word16 *in2, WebRtc_Word16 gain2, int shift2, - WebRtc_Word16 *out, int vector_length) -{ - // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2 - int i; - G_CONST WebRtc_Word16 *in1ptr; - G_CONST WebRtc_Word16 *in2ptr; - WebRtc_Word16 *outptr; - - in1ptr = in1; - in2ptr = in2; - outptr = out; - - for (i = 0; i < vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2); - } -} diff --git a/src/mod/codecs/mod_isac/webrtc_fft_t_1024_8.c b/src/mod/codecs/mod_isac/webrtc_fft_t_1024_8.c deleted file mode 100644 index b587380523..0000000000 --- a/src/mod/codecs/mod_isac/webrtc_fft_t_1024_8.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the Q14 radix-8 tables used in ARM9e optimizations. - * - */ - -extern const int s_Q14S_8; -const int s_Q14S_8 = 1024; -extern const unsigned short t_Q14S_8[2032]; -const unsigned short t_Q14S_8[2032] = { - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , - 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , - 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , - 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , - 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , - 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , - 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , - 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , - 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , - 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , - 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , - 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , - 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , - 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , - 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , - 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , - 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , - 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , - 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , - 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , - 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , - 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , - 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , - 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , - 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , - 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , - 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , - 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , - 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , - 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , - 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , - 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , - 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , - 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , - 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , - 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , - 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b , - 0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 , - 0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e , - 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , - 0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 , - 0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 , - 0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 , - 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , - 0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 , - 0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 , - 0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 , - 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , - 0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 , - 0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c , - 0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 , - 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , - 0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e , - 0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 , - 0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 , - 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , - 0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 , - 0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a , - 0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 , - 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , - 0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef , - 0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 , - 0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 , - 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , - 0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 , - 0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b , - 0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 , - 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , - 0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd , - 0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 , - 0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 , - 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , - 0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d , - 0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f , - 0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b , - 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , - 0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 , - 0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb , - 0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff , - 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , - 0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 , - 0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 , - 0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 , - 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , - 0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 , - 0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf , - 0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 , - 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , - 0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d , - 0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 , - 0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 , - 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , - 0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b , - 0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 , - 0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 , - 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , - 0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 , - 0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 , - 0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 , - 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , - 0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f , - 0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce , - 0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe , - 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , - 0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 , - 0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d , - 0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a , - 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , - 0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 , - 0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef , - 0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 , - 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , - 0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 , - 0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 , - 0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca , - 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , - 0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b , - 0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 , - 0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e , - 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , - 0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 , - 0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e , - 0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 , - 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , - 0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 , - 0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f , - 0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf , - 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , - 0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d , - 0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed , - 0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 , - 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , - 0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 , - 0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a , - 0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 , - 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , - 0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 , - 0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 , - 0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f , - 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , - 0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b , - 0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df , - 0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 , - 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , - 0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 , - 0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c , - 0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 , - 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , - 0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 , - 0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 , - 0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 , - 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , - 0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d , - 0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a , - 0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b , - 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , - 0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d , - 0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e , - 0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 , - 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , - 0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 , - 0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c , - 0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b , - 0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 , - 0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 , - 0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 , - 0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 , - 0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e , - 0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa , - 0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 , - 0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 , - 0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b , - 0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 , - 0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c , - 0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 , - 0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca , - 0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee , - 0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 , - 0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 , - 0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 , - 0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 , - 0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 , - 0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab , - 0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 , - 0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db , - 0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef , - 0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 , - 0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 , - 0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 , - 0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b , - 0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 , - 0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a , - 0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d , - 0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d , - 0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b , - 0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 , - 0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c , - 0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 , - 0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 , - 0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe , - 0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 , - 0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce , - 0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 , - 0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f , - 0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a , - 0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 , - 0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 , - 0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 , - 0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf , - 0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 , - 0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 , - 0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 , - 0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 , - 0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 , - 0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 , - 0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 , - 0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e , - 0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 , - 0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 , - 0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b , - 0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 , - 0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 , - 0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd , - 0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 , - 0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 , - 0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 , - 0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa , - 0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d , - 0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda , - 0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 , - 0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 , - 0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 , - 0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b , - 0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf , - 0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc , - 0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 , - 0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 , - 0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 , - 0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd , - 0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 , - 0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d , - 0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 , - 0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 , - 0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 , - 0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb , - 0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec , - 0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 , - 0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff , - 0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 , - 0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb , - 0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 , - 0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 , - 0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc , - 0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 , - 0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 , - 0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b , - 0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 , - 0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f , - 0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 , - 0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d , - 0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c , - 0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 , - 0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 , - 0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 , - 0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 , - 0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 , - 0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 , - 0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd , - 0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 , - 0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 , - 0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab , - 0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 , - 0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 , - 0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b , - 0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 , - 0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 , - 0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e , - 0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 , - 0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 , - 0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 , - 0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff , - 0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 , - 0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 , - 0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef , - 0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 , - 0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 , - 0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 , - 0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 , - 0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 , - 0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a , - 0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 , - 0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 , - 0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 , - 0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb , - 0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a , - 0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 , - 0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c , - 0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 , - 0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 , - 0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e , - 0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 , - 0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e , - 0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 , - 0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 , - 0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 , - 0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c , - 0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 , - 0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 , - 0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c , - 0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d , - 0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b , - 0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 , - 0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 , - 0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 , - 0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee , - 0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 , - 0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 , - 0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 , - 0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 , - 0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 , - 0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b , - 0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 , - 0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf , - 0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 , - 0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e , - 0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 , - 0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 , - 0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e , - 0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 , - 0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 , - 0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 , - 0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b , - 0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e , - 0xbf38,0x00c9 ,0xbf9c,0x0065 }; - - -extern const int s_Q14R_8; -const int s_Q14R_8 = 1024; -extern const unsigned short t_Q14R_8[2032]; -const unsigned short t_Q14R_8[2032] = { - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , - 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , - 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , - 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , - 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , - 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , - 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , - 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , - 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , - 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , - 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , - 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , - 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , - 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , - 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , - 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , - 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , - 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , - 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , - 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , - 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , - 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , - 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , - 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , - 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , - 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , - 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , - 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , - 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , - 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , - 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , - 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , - 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , - 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , - 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , - 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , - 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b , - 0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 , - 0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e , - 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , - 0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 , - 0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 , - 0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 , - 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , - 0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 , - 0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 , - 0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 , - 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , - 0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 , - 0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c , - 0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 , - 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , - 0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e , - 0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 , - 0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 , - 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , - 0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 , - 0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a , - 0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 , - 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , - 0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef , - 0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 , - 0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 , - 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , - 0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 , - 0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b , - 0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 , - 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , - 0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd , - 0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 , - 0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 , - 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , - 0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d , - 0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f , - 0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b , - 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , - 0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 , - 0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb , - 0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff , - 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , - 0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 , - 0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 , - 0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 , - 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , - 0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 , - 0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf , - 0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 , - 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , - 0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d , - 0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 , - 0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 , - 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , - 0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b , - 0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 , - 0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 , - 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , - 0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 , - 0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 , - 0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 , - 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , - 0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f , - 0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce , - 0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe , - 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , - 0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 , - 0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d , - 0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a , - 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , - 0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 , - 0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef , - 0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 , - 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , - 0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 , - 0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 , - 0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca , - 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , - 0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b , - 0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 , - 0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e , - 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , - 0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 , - 0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e , - 0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 , - 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , - 0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 , - 0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f , - 0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf , - 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , - 0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d , - 0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed , - 0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 , - 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , - 0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 , - 0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a , - 0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 , - 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , - 0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 , - 0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 , - 0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f , - 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , - 0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b , - 0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df , - 0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 , - 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , - 0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 , - 0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c , - 0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 , - 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , - 0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 , - 0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 , - 0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 , - 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , - 0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d , - 0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a , - 0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b , - 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , - 0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d , - 0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e , - 0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 , - 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , - 0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 , - 0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c , - 0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b , - 0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 , - 0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 , - 0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 , - 0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 , - 0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e , - 0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa , - 0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 , - 0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 , - 0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b , - 0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 , - 0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c , - 0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 , - 0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca , - 0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee , - 0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 , - 0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 , - 0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 , - 0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 , - 0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 , - 0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab , - 0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 , - 0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db , - 0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef , - 0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 , - 0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 , - 0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 , - 0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b , - 0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 , - 0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a , - 0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d , - 0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d , - 0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b , - 0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 , - 0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c , - 0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 , - 0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 , - 0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe , - 0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 , - 0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce , - 0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 , - 0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f , - 0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a , - 0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 , - 0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 , - 0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 , - 0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf , - 0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 , - 0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 , - 0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 , - 0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 , - 0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 , - 0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 , - 0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 , - 0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e , - 0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 , - 0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 , - 0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b , - 0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 , - 0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 , - 0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd , - 0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 , - 0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 , - 0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 , - 0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa , - 0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d , - 0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda , - 0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 , - 0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 , - 0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 , - 0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b , - 0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf , - 0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc , - 0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 , - 0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 , - 0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 , - 0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd , - 0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 , - 0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d , - 0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 , - 0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 , - 0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 , - 0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb , - 0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec , - 0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 , - 0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff , - 0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 , - 0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb , - 0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 , - 0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 , - 0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc , - 0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 , - 0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 , - 0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b , - 0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 , - 0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f , - 0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 , - 0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d , - 0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c , - 0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 , - 0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 , - 0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 , - 0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 , - 0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 , - 0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 , - 0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd , - 0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 , - 0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 , - 0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab , - 0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 , - 0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 , - 0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b , - 0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 , - 0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 , - 0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e , - 0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 , - 0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 , - 0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 , - 0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff , - 0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 , - 0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 , - 0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef , - 0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 , - 0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 , - 0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 , - 0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 , - 0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 , - 0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a , - 0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 , - 0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 , - 0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 , - 0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb , - 0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a , - 0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 , - 0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c , - 0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 , - 0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 , - 0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e , - 0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 , - 0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e , - 0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 , - 0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 , - 0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 , - 0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c , - 0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 , - 0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 , - 0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c , - 0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d , - 0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b , - 0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 , - 0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 , - 0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 , - 0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee , - 0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 , - 0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 , - 0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 , - 0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 , - 0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 , - 0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b , - 0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 , - 0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf , - 0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 , - 0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e , - 0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 , - 0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 , - 0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e , - 0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 , - 0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 , - 0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 , - 0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b , - 0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e , - 0xc001,0x00c9 ,0xc000,0x0065 }; diff --git a/src/mod/codecs/mod_isac/webrtc_fft_t_rad.c b/src/mod/codecs/mod_isac/webrtc_fft_t_rad.c deleted file mode 100644 index 13fbd9f53e..0000000000 --- a/src/mod/codecs/mod_isac/webrtc_fft_t_rad.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the Q14 radix-2 tables used in ARM9E optimization routines. - * - */ - -extern const unsigned short t_Q14S_rad8[2]; -const unsigned short t_Q14S_rad8[2] = { 0x0000,0x2d41 }; - -//extern const int t_Q30S_rad8[2]; -//const int t_Q30S_rad8[2] = { 0x00000000,0x2d413ccd }; - -extern const unsigned short t_Q14R_rad8[2]; -const unsigned short t_Q14R_rad8[2] = { 0x2d41,0x2d41 }; - -//extern const int t_Q30R_rad8[2]; -//const int t_Q30R_rad8[2] = { 0x2d413ccd,0x2d413ccd }; diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index 3540628eda..e99a1760a6 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -441,14 +441,6 @@ Binaries;Content;Satellites INSTALLFOLDER - - mod_iSAC - {7f1610f1-dd5a-4cf7-8610-30ab12c60add} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_opus {64e99cca-3c6f-4aeb-9fa3-cfac711257bb} From c1f4586e2d4e67ef0d8945de48453bfd75ad0ee6 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 10 Oct 2024 18:37:51 +0300 Subject: [PATCH 189/205] [mod_abstraction] Remove from tree --- Freeswitch.2017.sln | 14 -- build/modules.conf.in | 1 - build/modules.conf.most | 1 - .../autoload_configs/abstraction.conf.xml | 5 - configure.ac | 1 - debian/bootstrap.sh | 3 - debian/control-modules | 5 - freeswitch.spec | 15 +- .../applications/mod_abstraction/Makefile.am | 8 - .../autoload_configs/abstraction.conf.xml | 5 - .../mod_abstraction.2017.vcxproj | 135 -------------- .../mod_abstraction/mod_abstraction.c | 165 ------------------ w32/Setup/Setup.2017.wixproj | 8 - 13 files changed, 1 insertion(+), 365 deletions(-) delete mode 100644 conf/vanilla/autoload_configs/abstraction.conf.xml delete mode 100644 src/mod/applications/mod_abstraction/Makefile.am delete mode 100644 src/mod/applications/mod_abstraction/conf/autoload_configs/abstraction.conf.xml delete mode 100644 src/mod/applications/mod_abstraction/mod_abstraction.2017.vcxproj delete mode 100644 src/mod/applications/mod_abstraction/mod_abstraction.c diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 6fac09141b..3e4451ad7b 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -396,8 +396,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spy", "src\mod\applicat EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_httapi", "src\mod\applications\mod_httapi\mod_httapi.2017.vcxproj", "{4748FF56-CA85-4809-97D6-A94C0FAC1D77}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_abstraction", "src\mod\applications\mod_abstraction\mod_abstraction.2017.vcxproj", "{60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_sms", "src\mod\applications\mod_sms\mod_sms.2017.vcxproj", "{2469B306-B027-4FF2-8815-C9C1EA2CAE79}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "xmlrpc-c", "xmlrpc-c", "{9DE35039-A8F6-4FBF-B1B6-EB527F802411}" @@ -1757,17 +1755,6 @@ Global {4748FF56-CA85-4809-97D6-A94C0FAC1D77}.Release|Win32.Build.0 = Release|Win32 {4748FF56-CA85-4809-97D6-A94C0FAC1D77}.Release|x64.ActiveCfg = Release|x64 {4748FF56-CA85-4809-97D6-A94C0FAC1D77}.Release|x64.Build.0 = Release|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.All|Win32.ActiveCfg = Release|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.All|x64.ActiveCfg = Release|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.All|x64.Build.0 = Release|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Debug|Win32.ActiveCfg = Debug|Win32 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Debug|Win32.Build.0 = Debug|Win32 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Debug|x64.ActiveCfg = Debug|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Debug|x64.Build.0 = Debug|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Release|Win32.ActiveCfg = Release|Win32 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Release|Win32.Build.0 = Release|Win32 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Release|x64.ActiveCfg = Release|x64 - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F}.Release|x64.Build.0 = Release|x64 {2469B306-B027-4FF2-8815-C9C1EA2CAE79}.All|Win32.ActiveCfg = Release|x64 {2469B306-B027-4FF2-8815-C9C1EA2CAE79}.All|x64.ActiveCfg = Release|x64 {2469B306-B027-4FF2-8815-C9C1EA2CAE79}.All|x64.Build.0 = Release|x64 @@ -2588,7 +2575,6 @@ Global {50AAC2CE-BFC9-4912-87CC-C6381850D735} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {A61D7CB4-75A5-4A55-8CA1-BE5AF615D921} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {4748FF56-CA85-4809-97D6-A94C0FAC1D77} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {2469B306-B027-4FF2-8815-C9C1EA2CAE79} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {9DE35039-A8F6-4FBF-B1B6-EB527F802411} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} diff --git a/build/modules.conf.in b/build/modules.conf.in index 16c251f3be..45162bbd38 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -1,4 +1,3 @@ -#applications/mod_abstraction applications/mod_av #applications/mod_avmd #applications/mod_bert diff --git a/build/modules.conf.most b/build/modules.conf.most index 20478c359b..1fbb5c3326 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -1,4 +1,3 @@ -applications/mod_abstraction applications/mod_av applications/mod_avmd applications/mod_bert diff --git a/conf/vanilla/autoload_configs/abstraction.conf.xml b/conf/vanilla/autoload_configs/abstraction.conf.xml deleted file mode 100644 index 7244681374..0000000000 --- a/conf/vanilla/autoload_configs/abstraction.conf.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/configure.ac b/configure.ac index dcd560543c..10fa1a9346 100755 --- a/configure.ac +++ b/configure.ac @@ -2088,7 +2088,6 @@ AC_CONFIG_FILES([Makefile tests/unit/Makefile src/Makefile src/mod/Makefile - src/mod/applications/mod_abstraction/Makefile src/mod/applications/mod_avmd/Makefile src/mod/applications/mod_bert/Makefile src/mod/applications/mod_blacklist/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index e9db3c512c..78845f1899 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -516,7 +516,6 @@ Recommends: freeswitch-meta-codecs (= \${binary:Version}), freeswitch-music, freeswitch-sounds, - freeswitch-mod-abstraction (= \${binary:Version}), freeswitch-mod-avmd (= \${binary:Version}), freeswitch-mod-blacklist (= \${binary:Version}), freeswitch-mod-callcenter (= \${binary:Version}), @@ -601,7 +600,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-meta-mod-say (= \${binary:Version}), freeswitch-music, freeswitch-sounds, - freeswitch-mod-abstraction (= \${binary:Version}), freeswitch-mod-avmd (= \${binary:Version}), freeswitch-mod-av (= \${binary:Version}), freeswitch-mod-blacklist (= \${binary:Version}), @@ -831,7 +829,6 @@ Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-meta-codecs-dbg (= \${binary:Version}), freeswitch-meta-mod-say (= \${binary:Version}), - freeswitch-mod-abstraction-dbg (= \${binary:Version}), freeswitch-mod-avmd-dbg (= \${binary:Version}), freeswitch-mod-av-dbg (= \${binary:Version}), freeswitch-mod-blacklist-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 5e8bd3e56d..fba6b2813e 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -3,11 +3,6 @@ ## mod/applications -Module: applications/mod_abstraction -Description: Abstraction layer for APIs - This module provides a way to create new API functions via regex - rewriting. - Module: applications/mod_av Description: mod_av Adds mod_av. diff --git a/freeswitch.spec b/freeswitch.spec index b87b4802e0..fa79373621 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -227,14 +227,6 @@ FreeSWITCH development files ###################################################################################################################### # FreeSWITCH Application Modules ###################################################################################################################### -%package application-abstraction -Summary: FreeSWITCH mod_abstraction -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description application-abstraction -Provide an abstraction to FreeSWITCH API calls - %package application-avmd Summary: FreeSWITCH voicemail detector Group: System/Libraries @@ -1205,7 +1197,6 @@ The Python ESL module allows for native interaction with FreeSWITCH over the eve Summary: Basic vanilla config set for the FreeSWITCH Open Source telephone platform. Group: System/Libraries Requires: %{name} = %{version}-%{release} -Requires: freeswitch-application-abstraction Requires: freeswitch-application-avmd Requires: freeswitch-application-blacklist Requires: freeswitch-application-callcenter @@ -1299,7 +1290,7 @@ export QA_RPATHS=$[ 0x0001|0x0002 ] # Application Modules # ###################################################################################################################### -APPLICATION_MODULES_AC="applications/mod_abstraction applications/mod_avmd applications/mod_blacklist \ +APPLICATION_MODULES_AC="applications/mod_avmd applications/mod_blacklist \ applications/mod_callcenter applications/mod_cidlookup \ applications/mod_commands applications/mod_conference applications/mod_curl" APPLICATION_MODULES_DE="applications/mod_db applications/mod_directory applications/mod_distributor \ @@ -1758,7 +1749,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/extensions.conf %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/mime.types -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/abstraction.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/acl.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/amr.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/amrwb.conf.xml @@ -1885,9 +1875,6 @@ fi # Application Packages # ###################################################################################################################### -%files application-abstraction -%{MODINSTDIR}/mod_abstraction.so* - %files application-avmd %{MODINSTDIR}/mod_avmd.so* diff --git a/src/mod/applications/mod_abstraction/Makefile.am b/src/mod/applications/mod_abstraction/Makefile.am deleted file mode 100644 index 8ab961eeb2..0000000000 --- a/src/mod/applications/mod_abstraction/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_abstraction - -mod_LTLIBRARIES = mod_abstraction.la -mod_abstraction_la_SOURCES = mod_abstraction.c -mod_abstraction_la_CFLAGS = $(AM_CFLAGS) -mod_abstraction_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_abstraction_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/applications/mod_abstraction/conf/autoload_configs/abstraction.conf.xml b/src/mod/applications/mod_abstraction/conf/autoload_configs/abstraction.conf.xml deleted file mode 100644 index d4b1dfd274..0000000000 --- a/src/mod/applications/mod_abstraction/conf/autoload_configs/abstraction.conf.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/mod/applications/mod_abstraction/mod_abstraction.2017.vcxproj b/src/mod/applications/mod_abstraction/mod_abstraction.2017.vcxproj deleted file mode 100644 index e6a7666b80..0000000000 --- a/src/mod/applications/mod_abstraction/mod_abstraction.2017.vcxproj +++ /dev/null @@ -1,135 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_abstraction - {60C542EE-6882-4EA2-8C21-5AB6DB1BA73F} - mod_abstraction - Win32Proj - - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - - - - - false - - - - - - - X64 - - - - - - - false - - - MachineX64 - - - - - - - - - false - - - - - - - X64 - - - - - - - false - - - MachineX64 - - - - - - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - - - - \ No newline at end of file diff --git a/src/mod/applications/mod_abstraction/mod_abstraction.c b/src/mod/applications/mod_abstraction/mod_abstraction.c deleted file mode 100644 index 11144462ec..0000000000 --- a/src/mod/applications/mod_abstraction/mod_abstraction.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Marc Olivier Chouinard - * - * - * mod_abstraction.c -- Abstraction - * - */ -#include - -/* Prototypes */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_abstraction_shutdown); -SWITCH_MODULE_RUNTIME_FUNCTION(mod_abstraction_runtime); -SWITCH_MODULE_LOAD_FUNCTION(mod_abstraction_load); - -const char *global_cf = "abstraction.conf"; - -/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) - * Defines a switch_loadable_module_function_table_t and a static const char[] modname - */ -SWITCH_MODULE_DEFINITION(mod_abstraction, mod_abstraction_load, mod_abstraction_shutdown, NULL); - -SWITCH_STANDARD_API(api_abstraction_function) -{ - const char *api_name = switch_event_get_header(stream->param_event, "API-Command"); - switch_xml_t cfg, xml, x_apis, x_api; - - if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); - goto end; - } - - if (!(x_apis = switch_xml_child(cfg, "apis"))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No apis group\n"); - goto end; - } - - if ((x_api = switch_xml_find_child_multi(x_apis, "api", "name", api_name , NULL))) { - const char *parse = switch_xml_attr_soft(x_api, "parse"); - const char *destination = switch_xml_attr_soft(x_api, "destination"); - const char *arguments = switch_xml_attr_soft(x_api, "argument"); - - int proceed; - switch_regex_t *re = NULL; - int ovector[30]; - - if ((proceed = switch_regex_perform(cmd, parse, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { - const char *api_args = NULL; - char *substituted = NULL; - - if (cmd && strchr(parse, '(')) { - uint32_t len = (uint32_t) (strlen(cmd) + strlen(arguments) + 10) * proceed; - if (!(substituted = malloc(len))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); - goto end; - } - memset(substituted, 0, len); - switch_perform_substitution(re, proceed, arguments, cmd , substituted, len, ovector); - api_args = substituted; - } else { - api_args = arguments; - } - switch_api_execute(destination, api_args, session, stream); - - switch_safe_free(substituted); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No match for API %s (%s != %s)\n", api_name, parse, cmd); - } - switch_regex_safe_free(re); - - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "API %s doesn't exist inside the xml structure. You might have forgot to reload the module after editing it\n", api_name); - } - -end: - if (xml) - switch_xml_free(xml); - - - return SWITCH_STATUS_SUCCESS; -} - -/* Macro expands to: switch_status_t mod_abstraction_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ -SWITCH_MODULE_LOAD_FUNCTION(mod_abstraction_load) -{ - switch_status_t status = SWITCH_STATUS_TERM; - switch_api_interface_t *api_interface; - switch_xml_t cfg, xml, x_apis, x_api; - int count = 0; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); - goto end; - } - - if (!(x_apis = switch_xml_child(cfg, "apis"))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No apis group\n"); - goto end; - } - - for (x_api = switch_xml_child(x_apis, "api"); x_api; x_api = x_api->next) { - const char *name = switch_xml_attr_soft(x_api, "name"); - const char *description = switch_xml_attr_soft(x_api, "description"); - const char *syntax = switch_xml_attr_soft(x_api, "syntax"); - SWITCH_ADD_API(api_interface, name, description, api_abstraction_function, syntax); - count++; - - } - if (count > 0) { - status = SWITCH_STATUS_SUCCESS; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No API abstraction defined\n"); - } -end: - if (xml) - switch_xml_free(xml); - - return status; -} - -/* - Called when the system shuts down - Macro expands to: switch_status_t mod_abstraction_shutdown() */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_abstraction_shutdown) -{ - /* Cleanup dynamically allocated config settings */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index e99a1760a6..e449a5a55a 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -89,14 +89,6 @@ Binaries;Content;Satellites INSTALLFOLDER - - mod_abstraction - {60c542ee-6882-4ea2-8c21-5ab6db1ba73f} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_avmd {990baa76-89d3-4e38-8479-c7b28784efc8} From 866c235aa38da96f321896166ab17d6403dd3d39 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 14 Nov 2024 00:42:12 +0300 Subject: [PATCH 190/205] [mod_stress] Remove from tree. --- LICENSE | 5 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 1 - debian/bootstrap.sh | 3 - debian/control-modules | 4 - debian/copyright | 5 - freeswitch.spec | 15 +- src/mod/.gitignore | 3 - src/mod/applications/mod_stress/FFTReal.cpp | 615 ------------------ src/mod/applications/mod_stress/FFTReal.h | 133 ---- src/mod/applications/mod_stress/Makefile.am | 8 - .../applications/mod_stress/mod_stress.cpp | 264 -------- 13 files changed, 1 insertion(+), 1057 deletions(-) delete mode 100644 src/mod/applications/mod_stress/FFTReal.cpp delete mode 100644 src/mod/applications/mod_stress/FFTReal.h delete mode 100644 src/mod/applications/mod_stress/Makefile.am delete mode 100644 src/mod/applications/mod_stress/mod_stress.cpp diff --git a/LICENSE b/LICENSE index 0e0935c1db..4465d2d0ca 100644 --- a/LICENSE +++ b/LICENSE @@ -1309,11 +1309,6 @@ Copyright: 2009-2012 10gen Inc. 2001 Unicode, Inc. License: Apache-2.0 -Files: src/mod/applications/mod_stress/FFTReal.h - src/mod/applications/mod_stress/FFTReal.cpp -Copyright: 1999 Laurent de Soras -License: unclear - Files: src/mod/loggers/mod_syslog/mod_syslog.c Copyright: 2005-2010, James Martelletti License: MPL-1.1 diff --git a/build/modules.conf.in b/build/modules.conf.in index 45162bbd38..5efb5c9b0a 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -43,7 +43,6 @@ applications/mod_sms #applications/mod_soundtouch applications/mod_spandsp #applications/mod_spy -#applications/mod_stress applications/mod_test #applications/mod_translate applications/mod_valet_parking diff --git a/build/modules.conf.most b/build/modules.conf.most index 1fbb5c3326..acafb3908a 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -43,7 +43,6 @@ applications/mod_sonar applications/mod_soundtouch applications/mod_spandsp applications/mod_spy -applications/mod_stress applications/mod_test applications/mod_translate applications/mod_valet_parking diff --git a/configure.ac b/configure.ac index 10fa1a9346..0cc99bbac2 100755 --- a/configure.ac +++ b/configure.ac @@ -2135,7 +2135,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_soundtouch/Makefile src/mod/applications/mod_spandsp/Makefile src/mod/applications/mod_spy/Makefile - src/mod/applications/mod_stress/Makefile src/mod/applications/mod_test/Makefile src/mod/applications/mod_translate/Makefile src/mod/applications/mod_valet_parking/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 78845f1899..4587551f4e 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -551,7 +551,6 @@ Recommends: freeswitch-mod-soundtouch (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), - freeswitch-mod-stress (= \${binary:Version}), freeswitch-mod-valet-parking (= \${binary:Version}), freeswitch-mod-vmd (= \${binary:Version}), freeswitch-mod-voicemail (= \${binary:Version}), @@ -641,7 +640,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-soundtouch (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), - freeswitch-mod-stress (= \${binary:Version}), freeswitch-mod-translate (= \${binary:Version}), freeswitch-mod-valet-parking (= \${binary:Version}), freeswitch-mod-video-filter (= \${binary:Version}), @@ -868,7 +866,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-soundtouch-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), freeswitch-mod-spy-dbg (= \${binary:Version}), - freeswitch-mod-stress-dbg (= \${binary:Version}), freeswitch-mod-translate-dbg (= \${binary:Version}), freeswitch-mod-valet-parking-dbg (= \${binary:Version}), freeswitch-mod-video-filter-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index fba6b2813e..6730a6de87 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -223,10 +223,6 @@ Module: applications/mod_spy Description: UserSpy This module adds the ability to monitor the audio of a channel. -Module: applications/mod_stress -Description: Voice stress detection - This module attempts to detect voice stress on an audio channel. - Module: applications/mod_translate Description: Number translation This module implements number translation. diff --git a/debian/copyright b/debian/copyright index 1deeb1869c..deedd66566 100755 --- a/debian/copyright +++ b/debian/copyright @@ -1309,11 +1309,6 @@ Copyright: 2009-2012 10gen Inc. 2001 Unicode, Inc. License: Apache-2.0 -Files: src/mod/applications/mod_stress/FFTReal.h - src/mod/applications/mod_stress/FFTReal.cpp -Copyright: 1999 Laurent de Soras -License: unclear - Files: src/mod/loggers/mod_syslog/mod_syslog.c Copyright: 2005-2010, James Martelletti License: MPL-1.1 diff --git a/freeswitch.spec b/freeswitch.spec index fa79373621..177036acf6 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -535,15 +535,6 @@ Requires: %{name} = %{version}-%{release} Provides FreeSWITCH mod_spy, implements userspy application which provides persistent eavesdrop on all channels bridged to a certain user -%package application-stress -Summary: FreeSWITCH mod_stress -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description application-stress -Provides FreeSWITCH mod_stress. mod_stress attempts to detect stress in a -person's voice and generates FreeSWITCH events based on that data. - %package application-translate Summary: FreeSWITCH mod_translate Group: System/Libraries @@ -1228,7 +1219,6 @@ Requires: freeswitch-application-snapshot Requires: freeswitch-application-snom Requires: freeswitch-application-soundtouch Requires: freeswitch-application-spy -Requires: freeswitch-application-stress Requires: freeswitch-application-valet_parking Requires: freeswitch-application-video_filter Requires: freeswitch-application-voicemail @@ -1307,7 +1297,7 @@ APPLICATION_MODULES_FR="applications/mod_fifo applications/mod_fsk applications/ applications/mod_redis applications/mod_rss " APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot applications/mod_snom applications/mod_soundtouch \ - applications/mod_spandsp applications/mod_spy applications/mod_stress \ + applications/mod_spandsp applications/mod_spy \ applications/mod_valet_parking applications/mod_translate applications/mod_voicemail \ applications/mod_voicemail_ivr applications/mod_video_filter" @@ -1980,9 +1970,6 @@ fi %files application-spy %{MODINSTDIR}/mod_spy.so* -%files application-stress -%{MODINSTDIR}/mod_stress.so* - %files application-translate %{MODINSTDIR}/mod_translate.so* diff --git a/src/mod/.gitignore b/src/mod/.gitignore index 47f1a92e0b..5d2791c825 100644 --- a/src/mod/.gitignore +++ b/src/mod/.gitignore @@ -21,9 +21,6 @@ /applications/mod_spandsp/Makefile /applications/mod_spandsp/Makefile.in /applications/mod_spandsp/mod_spandsp.log -/applications/mod_stress/Makefile -/applications/mod_stress/Makefile.in -/applications/mod_stress/mod_stress.log /applications/mod_translate/Makefile /applications/mod_valet_parking/Makefile /applications/mod_voicemail/Makefile diff --git a/src/mod/applications/mod_stress/FFTReal.cpp b/src/mod/applications/mod_stress/FFTReal.cpp deleted file mode 100644 index fbc268a88d..0000000000 --- a/src/mod/applications/mod_stress/FFTReal.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/***************************************************************************** -* * -* DIGITAL SIGNAL PROCESSING TOOLS * -* Version 1.03, 2001/06/15 * -* (c) 1999 - Laurent de Soras * -* * -* FFTReal.cpp * -* Fourier transformation of real number arrays. * -* Portable ISO C++ * -* * -* Tab = 3 * -*****************************************************************************/ - - - -/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ - -#include "FFTReal.h" - -#include -#include - - - -#if defined (_MSC_VER) -#pragma pack (push, 8) -#endif // _MSC_VER - - - -/*\\\ PUBLIC MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ - - - -/*==========================================================================*/ -/* Name: Constructor */ -/* Input parameters: */ -/* - length: length of the array on which we want to do a FFT. */ -/* Range: power of 2 only, > 0. */ -/* Throws: std::bad_alloc, anything */ -/*==========================================================================*/ - -FFTReal::FFTReal (const long length) -: _length (length) -, _nbr_bits (int (floor (log (length) / log (2) + 0.5))) -, _bit_rev_lut (int (floor (log (length) / log (2) + 0.5))) -, _trigo_lut (int (floor (log (length) / log (2) + 0.5))) -, _sqrt2_2 (flt_t (sqrt (2) * 0.5)) -{ - assert ((1L << _nbr_bits) == length); - - _buffer_ptr = 0; - if (_nbr_bits > 2) - { - _buffer_ptr = new flt_t [_length]; - } -} - - - -/*==========================================================================*/ -/* Name: Destructor */ -/*==========================================================================*/ - -FFTReal::~FFTReal (void) -{ - delete [] _buffer_ptr; - _buffer_ptr = 0; -} - - - -/*==========================================================================*/ -/* Name: do_fft */ -/* Description: Compute the FFT of the array. */ -/* Input parameters: */ -/* - x: pointer on the source array (time). */ -/* Output parameters: */ -/* - f: pointer on the destination array (frequencies). */ -/* f [0...length(x)/2] = real values, */ -/* f [length(x)/2+1...length(x)-1] = imaginary values of */ -/* coefficents 1...length(x)/2-1. */ -/* Throws: Nothing */ -/*==========================================================================*/ - -void FFTReal::do_fft (flt_t f [], const flt_t x []) const -{ - -/*______________________________________________ - * - * General case - *______________________________________________ - */ - - if (_nbr_bits > 2) - { - flt_t * sf; - flt_t * df; - - if (_nbr_bits & 1) - { - df = _buffer_ptr; - sf = f; - } - else - { - df = f; - sf = _buffer_ptr; - } - - /* Do the transformation in several pass */ - { - int pass; - long nbr_coef; - long h_nbr_coef; - long d_nbr_coef; - long coef_index; - - /* First and second pass at once */ - { - const long * const bit_rev_lut_ptr = _bit_rev_lut.get_ptr (); - coef_index = 0; - do - { - const long rev_index_0 = bit_rev_lut_ptr [coef_index]; - const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1]; - const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2]; - const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3]; - - flt_t * const df2 = df + coef_index; - df2 [1] = x [rev_index_0] - x [rev_index_1]; - df2 [3] = x [rev_index_2] - x [rev_index_3]; - - const flt_t sf_0 = x [rev_index_0] + x [rev_index_1]; - const flt_t sf_2 = x [rev_index_2] + x [rev_index_3]; - - df2 [0] = sf_0 + sf_2; - df2 [2] = sf_0 - sf_2; - - coef_index += 4; - } - while (coef_index < _length); - } - - /* Third pass */ - { - coef_index = 0; - const flt_t sqrt2_2 = _sqrt2_2; - do - { - flt_t v; - - sf [coef_index] = df [coef_index] + df [coef_index + 4]; - sf [coef_index + 4] = df [coef_index] - df [coef_index + 4]; - sf [coef_index + 2] = df [coef_index + 2]; - sf [coef_index + 6] = df [coef_index + 6]; - - v = (df [coef_index + 5] - df [coef_index + 7]) * sqrt2_2; - sf [coef_index + 1] = df [coef_index + 1] + v; - sf [coef_index + 3] = df [coef_index + 1] - v; - - v = (df [coef_index + 5] + df [coef_index + 7]) * sqrt2_2; - sf [coef_index + 5] = v + df [coef_index + 3]; - sf [coef_index + 7] = v - df [coef_index + 3]; - - coef_index += 8; - } - while (coef_index < _length); - } - - /* Next pass */ - for (pass = 3; pass < _nbr_bits; ++pass) - { - coef_index = 0; - nbr_coef = 1 << pass; - h_nbr_coef = nbr_coef >> 1; - d_nbr_coef = nbr_coef << 1; - const flt_t * const cos_ptr = _trigo_lut.get_ptr (pass); - do - { - long i; - const flt_t * const sf1r = sf + coef_index; - const flt_t * const sf2r = sf1r + nbr_coef; - flt_t * const dfr = df + coef_index; - flt_t * const dfi = dfr + nbr_coef; - - /* Extreme coefficients are always real */ - dfr [0] = sf1r [0] + sf2r [0]; - dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] = - dfr [h_nbr_coef] = sf1r [h_nbr_coef]; - dfi [h_nbr_coef] = sf2r [h_nbr_coef]; - - /* Others are conjugate complex numbers */ - const flt_t * const sf1i = sf1r + h_nbr_coef; - const flt_t * const sf2i = sf1i + nbr_coef; - for (i = 1; i < h_nbr_coef; ++ i) - { - const flt_t c = cos_ptr [i]; // cos (i*PI/nbr_coef); - const flt_t s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef); - flt_t v; - - v = sf2r [i] * c - sf2i [i] * s; - dfr [i] = sf1r [i] + v; - dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] = - - v = sf2r [i] * s + sf2i [i] * c; - dfi [i] = v + sf1i [i]; - dfi [nbr_coef - i] = v - sf1i [i]; - } - - coef_index += d_nbr_coef; - } - while (coef_index < _length); - - /* Prepare to the next pass */ - { - flt_t * const temp_ptr = df; - df = sf; - sf = temp_ptr; - } - } - } - } - -/*______________________________________________ - * - * Special cases - *______________________________________________ - */ - - /* 4-point FFT */ - else if (_nbr_bits == 2) - { - f [1] = x [0] - x [2]; - f [3] = x [1] - x [3]; - - const flt_t b_0 = x [0] + x [2]; - const flt_t b_2 = x [1] + x [3]; - - f [0] = b_0 + b_2; - f [2] = b_0 - b_2; - } - - /* 2-point FFT */ - else if (_nbr_bits == 1) - { - f [0] = x [0] + x [1]; - f [1] = x [0] - x [1]; - } - - /* 1-point FFT */ - else - { - f [0] = x [0]; - } -} - - - -/*==========================================================================*/ -/* Name: do_ifft */ -/* Description: Compute the inverse FFT of the array. Notice that */ -/* IFFT (FFT (x)) = x * length (x). Data must be */ -/* post-scaled. */ -/* Input parameters: */ -/* - f: pointer on the source array (frequencies). */ -/* f [0...length(x)/2] = real values, */ -/* f [length(x)/2+1...length(x)] = imaginary values of */ -/* coefficents 1...length(x)-1. */ -/* Output parameters: */ -/* - x: pointer on the destination array (time). */ -/* Throws: Nothing */ -/*==========================================================================*/ - -void FFTReal::do_ifft (const flt_t f [], flt_t x []) const -{ - -/*______________________________________________ - * - * General case - *______________________________________________ - */ - - if (_nbr_bits > 2) - { - flt_t * sf = const_cast (f); - flt_t * df; - flt_t * df_temp; - - if (_nbr_bits & 1) - { - df = _buffer_ptr; - df_temp = x; - } - else - { - df = x; - df_temp = _buffer_ptr; - } - - /* Do the transformation in several pass */ - { - int pass; - long nbr_coef; - long h_nbr_coef; - long d_nbr_coef; - long coef_index; - - /* First pass */ - for (pass = _nbr_bits - 1; pass >= 3; --pass) - { - coef_index = 0; - nbr_coef = 1 << pass; - h_nbr_coef = nbr_coef >> 1; - d_nbr_coef = nbr_coef << 1; - const flt_t *const cos_ptr = _trigo_lut.get_ptr (pass); - do - { - long i; - const flt_t * const sfr = sf + coef_index; - const flt_t * const sfi = sfr + nbr_coef; - flt_t * const df1r = df + coef_index; - flt_t * const df2r = df1r + nbr_coef; - - /* Extreme coefficients are always real */ - df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef] - df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef] - df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2; - df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2; - - /* Others are conjugate complex numbers */ - flt_t * const df1i = df1r + h_nbr_coef; - flt_t * const df2i = df1i + nbr_coef; - for (i = 1; i < h_nbr_coef; ++ i) - { - df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i] - df1i [i] = sfi [i] - sfi [nbr_coef - i]; - - const flt_t c = cos_ptr [i]; // cos (i*PI/nbr_coef); - const flt_t s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef); - const flt_t vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i] - const flt_t vi = sfi [i] + sfi [nbr_coef - i]; - - df2r [i] = vr * c + vi * s; - df2i [i] = vi * c - vr * s; - } - - coef_index += d_nbr_coef; - } - while (coef_index < _length); - - /* Prepare to the next pass */ - if (pass < _nbr_bits - 1) - { - flt_t * const temp_ptr = df; - df = sf; - sf = temp_ptr; - } - else - { - sf = df; - df = df_temp; - } - } - - /* Antepenultimate pass */ - { - const flt_t sqrt2_2 = _sqrt2_2; - coef_index = 0; - do - { - df [coef_index] = sf [coef_index] + sf [coef_index + 4]; - df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4]; - df [coef_index + 2] = sf [coef_index + 2] * 2; - df [coef_index + 6] = sf [coef_index + 6] * 2; - - df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3]; - df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7]; - - const flt_t vr = sf [coef_index + 1] - sf [coef_index + 3]; - const flt_t vi = sf [coef_index + 5] + sf [coef_index + 7]; - - df [coef_index + 5] = (vr + vi) * sqrt2_2; - df [coef_index + 7] = (vi - vr) * sqrt2_2; - - coef_index += 8; - } - while (coef_index < _length); - } - - /* Penultimate and last pass at once */ - { - coef_index = 0; - const long * bit_rev_lut_ptr = _bit_rev_lut.get_ptr (); - const flt_t * sf2 = df; - do - { - { - const flt_t b_0 = sf2 [0] + sf2 [2]; - const flt_t b_2 = sf2 [0] - sf2 [2]; - const flt_t b_1 = sf2 [1] * 2; - const flt_t b_3 = sf2 [3] * 2; - - x [bit_rev_lut_ptr [0]] = b_0 + b_1; - x [bit_rev_lut_ptr [1]] = b_0 - b_1; - x [bit_rev_lut_ptr [2]] = b_2 + b_3; - x [bit_rev_lut_ptr [3]] = b_2 - b_3; - } - { - const flt_t b_0 = sf2 [4] + sf2 [6]; - const flt_t b_2 = sf2 [4] - sf2 [6]; - const flt_t b_1 = sf2 [5] * 2; - const flt_t b_3 = sf2 [7] * 2; - - x [bit_rev_lut_ptr [4]] = b_0 + b_1; - x [bit_rev_lut_ptr [5]] = b_0 - b_1; - x [bit_rev_lut_ptr [6]] = b_2 + b_3; - x [bit_rev_lut_ptr [7]] = b_2 - b_3; - } - - sf2 += 8; - coef_index += 8; - bit_rev_lut_ptr += 8; - } - while (coef_index < _length); - } - } - } - -/*______________________________________________ - * - * Special cases - *______________________________________________ - */ - - /* 4-point IFFT */ - else if (_nbr_bits == 2) - { - const flt_t b_0 = f [0] + f [2]; - const flt_t b_2 = f [0] - f [2]; - - x [0] = b_0 + f [1] * 2; - x [2] = b_0 - f [1] * 2; - x [1] = b_2 + f [3] * 2; - x [3] = b_2 - f [3] * 2; - } - - /* 2-point IFFT */ - else if (_nbr_bits == 1) - { - x [0] = f [0] + f [1]; - x [1] = f [0] - f [1]; - } - - /* 1-point IFFT */ - else - { - x [0] = f [0]; - } -} - - - -/*==========================================================================*/ -/* Name: rescale */ -/* Description: Scale an array by divide each element by its length. */ -/* This function should be called after FFT + IFFT. */ -/* Input/Output parameters: */ -/* - x: pointer on array to rescale (time or frequency). */ -/* Throws: Nothing */ -/*==========================================================================*/ - -void FFTReal::rescale (flt_t x []) const -{ - const flt_t mul = flt_t (1.0 / _length); - long i = _length - 1; - - do - { - x [i] *= mul; - --i; - } - while (i >= 0); -} - - - -/*\\\ NESTED CLASS MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ - - - -/*==========================================================================*/ -/* Name: Constructor */ -/* Input parameters: */ -/* - nbr_bits: number of bits of the array on which we want to do a */ -/* FFT. Range: > 0 */ -/* Throws: std::bad_alloc */ -/*==========================================================================*/ - -FFTReal::BitReversedLUT::BitReversedLUT (const int nbr_bits) -{ - long length; - long cnt; - long br_index; - long bit; - - length = 1L << nbr_bits; - _ptr = new long [length]; - - br_index = 0; - _ptr [0] = 0; - for (cnt = 1; cnt < length; ++cnt) - { - /* ++br_index (bit reversed) */ - bit = length >> 1; - while (((br_index ^= bit) & bit) == 0) - { - bit >>= 1; - } - - _ptr [cnt] = br_index; - } -} - - - -/*==========================================================================*/ -/* Name: Destructor */ -/*==========================================================================*/ - -FFTReal::BitReversedLUT::~BitReversedLUT (void) -{ - delete [] _ptr; - _ptr = 0; -} - - - -/*==========================================================================*/ -/* Name: Constructor */ -/* Input parameters: */ -/* - nbr_bits: number of bits of the array on which we want to do a */ -/* FFT. Range: > 0 */ -/* Throws: std::bad_alloc, anything */ -/*==========================================================================*/ - -FFTReal::TrigoLUT::TrigoLUT (const int nbr_bits) -{ - long total_len; - - _ptr = 0; - if (nbr_bits > 3) - { - total_len = (1L << (nbr_bits - 1)) - 4; - _ptr = new flt_t [total_len]; - - const double PI = atan (1) * 4; - for (int level = 3; level < nbr_bits; ++level) - { - const long level_len = 1L << (level - 1); - flt_t * const level_ptr = const_cast (get_ptr (level)); - const double mul = PI / (level_len << 1); - - for (long i = 0; i < level_len; ++ i) - { - level_ptr [i] = (flt_t) cos (i * mul); - } - } - } -} - - - -/*==========================================================================*/ -/* Name: Destructor */ -/*==========================================================================*/ - -FFTReal::TrigoLUT::~TrigoLUT (void) -{ - delete [] _ptr; - _ptr = 0; -} - - - -#if defined (_MSC_VER) -#pragma pack (pop) -#endif // _MSC_VER - - - -/***************************************************************************** - - LEGAL - - Source code may be freely used for any purpose, including commercial - applications. Programs must display in their "About" dialog-box (or - documentation) a text telling they use these routines by Laurent de Soras. - Modified source code can be distributed, but modifications must be clearly - indicated. - - CONTACT - - Laurent de Soras - 92 avenue Albert 1er - 92500 Rueil-Malmaison - France - - ldesoras@club-internet.fr - -*****************************************************************************/ - - - -/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/mod/applications/mod_stress/FFTReal.h b/src/mod/applications/mod_stress/FFTReal.h deleted file mode 100644 index 76d1e0ee00..0000000000 --- a/src/mod/applications/mod_stress/FFTReal.h +++ /dev/null @@ -1,133 +0,0 @@ -/***************************************************************************** -* * -* DIGITAL SIGNAL PROCESSING TOOLS * -* Version 1.03, 2001/06/15 * -* (c) 1999 - Laurent de Soras * -* * -* FFTReal.h * -* Fourier transformation of real number arrays. * -* Portable ISO C++ * -* * -* Tab = 3 * -*****************************************************************************/ - - - -#if defined (FFTReal_CURRENT_HEADER) -#error Recursive inclusion of FFTReal header file. -#endif -#define FFTReal_CURRENT_HEADER - -#if ! defined (FFTReal_HEADER_INCLUDED) -#define FFTReal_HEADER_INCLUDED - - - -#if defined (_MSC_VER) -#pragma pack (push, 8) -#endif // _MSC_VER - - - -class FFTReal { - -/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ - - public: - - /* Change this typedef to use a different floating point type in your FFTs - (i.e. float, double or long double). */ - typedef float flt_t; - - explicit FFTReal(const long length); - ~FFTReal(); - void do_fft(flt_t f[], const flt_t x[]) const; - void do_ifft(const flt_t f[], flt_t x[]) const; - void rescale(flt_t x[]) const; - - - -/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ - - private: - - /* Bit-reversed look-up table nested class */ - class BitReversedLUT { - public: - explicit BitReversedLUT(const int nbr_bits); - ~BitReversedLUT(); - const long *get_ptr() const { - return (_ptr); - } private: - long *_ptr; - }; - - /* Trigonometric look-up table nested class */ - class TrigoLUT { - public: - explicit TrigoLUT(const int nbr_bits); - ~TrigoLUT(); - const flt_t *get_ptr(const int level) const { - return (_ptr + (1L << (level - 1)) - 4); - }; - private: - flt_t *_ptr; - }; - - const BitReversedLUT _bit_rev_lut; - const TrigoLUT _trigo_lut; - const flt_t _sqrt2_2; - const long _length; - const int _nbr_bits; - flt_t *_buffer_ptr; - - - -/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ - - private: - - FFTReal(const FFTReal & other); - const FFTReal & operator =(const FFTReal & other); - int operator ==(const FFTReal & other); - int operator !=(const FFTReal & other); -}; - - - -#if defined (_MSC_VER) -#pragma pack (pop) -#endif // _MSC_VER - - - -#endif // FFTReal_HEADER_INCLUDED - -#undef FFTReal_CURRENT_HEADER - - - -/***************************************************************************** - - LEGAL - - Source code may be freely used for any purpose, including commercial - applications. Programs must display in their "About" dialog-box (or - documentation) a text telling they use these routines by Laurent de Soras. - Modified source code can be distributed, but modifications must be clearly - indicated. - - CONTACT - - Laurent de Soras - 92 avenue Albert 1er - 92500 Rueil-Malmaison - France - - ldesoras@club-internet.fr - -*****************************************************************************/ - - - -/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/mod/applications/mod_stress/Makefile.am b/src/mod/applications/mod_stress/Makefile.am deleted file mode 100644 index 14f7d363c9..0000000000 --- a/src/mod/applications/mod_stress/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_stress - -mod_LTLIBRARIES = mod_stress.la -mod_stress_la_SOURCES = mod_stress.cpp FFTReal.cpp -mod_stress_la_CFLAGS = $(AM_CFLAGS) -mod_stress_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_stress_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/applications/mod_stress/mod_stress.cpp b/src/mod/applications/mod_stress/mod_stress.cpp deleted file mode 100644 index 66da2d26dc..0000000000 --- a/src/mod/applications/mod_stress/mod_stress.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * mod_stress.cpp -- Detect Voice Stress - * - */ - -#include -#include -#include "FFTReal.h" -using namespace std; - -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_stress_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_stress_shutdown); -SWITCH_MODULE_DEFINITION(mod_stress, mod_stress_load, mod_stress_shutdown, NULL); - -struct stress_helper { - switch_core_session_t *session; - int read; - uint32_t frame_size; - FFTReal *fft; - float *data; - float *result; - float *pow_spectrum; - float bind; - int start; - int end; - float avg_tremor_pwr; - float avg_total_pwr; - float total_pwr; - float tremor_ratio; - float stress; - uint32_t rate; - switch_buffer_t *audio_buffer; - int16_t *audio; -}; - -static switch_bool_t stress_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) -{ - struct stress_helper *sth = (struct stress_helper *) user_data; - - switch (type) { - case SWITCH_ABC_TYPE_INIT: - { - switch_codec_t *read_codec = switch_core_session_get_read_codec(sth->session); - - sth->rate = read_codec->implementation->actual_samples_per_second; - - if (sth->rate == 8000) { - sth->frame_size = 8192; - } else if (sth->rate == 16000) { - sth->frame_size = 16384; - } else if (sth->rate == 32000) { - sth->frame_size = 32768; - } else { - return SWITCH_FALSE; - } - - sth->data = (float *) switch_core_session_alloc(sth->session, sizeof(*sth->data) * sth->frame_size); - sth->result = (float *) switch_core_session_alloc(sth->session, sizeof(*sth->result) * sth->frame_size); - sth->pow_spectrum = (float *) switch_core_session_alloc(sth->session, sizeof(*sth->pow_spectrum) * sth->frame_size); - sth->audio = (int16_t *) switch_core_session_alloc(sth->session, sizeof(*sth->audio) * sth->frame_size); - - sth->fft = new FFTReal (sth->frame_size); - switch_buffer_create_dynamic(&sth->audio_buffer, sth->frame_size, sth->frame_size * 3, 0); - - sth->bind = (float) sth->rate / sth->frame_size; - sth->start = (int) (8.0 / sth->bind); - sth->end = (int) (14.0 / sth->bind); - - } - break; - case SWITCH_ABC_TYPE_CLOSE: - { - switch_buffer_destroy(&sth->audio_buffer); - delete sth->fft; - } - break; - case SWITCH_ABC_TYPE_READ: - case SWITCH_ABC_TYPE_WRITE: - break; - case SWITCH_ABC_TYPE_READ_REPLACE: - case SWITCH_ABC_TYPE_WRITE_REPLACE: - { - switch_frame_t *frame; - - if (sth->read) { - frame = switch_core_media_bug_get_read_replace_frame(bug); - } else { - frame = switch_core_media_bug_get_write_replace_frame(bug); - } - - if (!switch_test_flag(frame, SFF_CNG)) { - switch_buffer_write(sth->audio_buffer, frame->data, frame->datalen); - } - - sth->stress = 0.0; - - if (switch_buffer_inuse(sth->audio_buffer) >= sth->frame_size * sizeof(int16_t)) { - switch_size_t bytes; - uint32_t samples, i; - const float threshold = 1.5; - - bytes = switch_buffer_read(sth->audio_buffer, sth->audio, sth->frame_size * sizeof(int16_t)); - samples = bytes / sizeof(int16_t); - - switch_short_to_float(sth->audio, sth->data, samples); - sth->fft->do_fft(sth->result, sth->data); - - for (i = 0; i < samples; ++i) { - sth->pow_spectrum[i] = pow(fabs(sth->result[i]), 2) / (float) samples; - } - - sth->avg_tremor_pwr = 0.0; - sth->avg_total_pwr = 0.0; - sth->total_pwr = 0.0; - - for (i = sth->start; i <= sth->end; ++i) { - sth->avg_tremor_pwr += sth->pow_spectrum[i]; - } - sth->avg_tremor_pwr /= ((sth->end - sth->start) + 1); - - for (i = 0; i < samples; ++i) { - sth->total_pwr += sth->pow_spectrum[i]; - } - sth->avg_total_pwr = sth->total_pwr / samples; - - if (sth->total_pwr < threshold) { - sth->tremor_ratio = 0.0; - } else { - sth->tremor_ratio = sth->avg_tremor_pwr / sth->avg_total_pwr; - } - - if (sth->total_pwr >= 1.0) { - float d = pow(sth->tremor_ratio, 4); - if (d > 0.0) { - sth->stress = (10.0 / d) / 10000; - if (sth->stress >= 20000.0) { - sth->stress = 20000.0; - } - } - } - } - - if (sth->stress) { - switch_event_t *event, *dup; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "Stress %0.2f\n", sth->stress); - - if (switch_event_create(&event, SWITCH_EVENT_DETECTED_SPEECH) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "stress-level"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Stress-Level", "%0.2f", sth->stress); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(sth->session)); - if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { - switch_event_fire(&dup); - } - if (switch_core_session_queue_event(sth->session, &event) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "Event queue failed!\n"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true"); - switch_event_fire(&event); - } - } - } - } - default: - break; - } - - return SWITCH_TRUE; -} - -SWITCH_STANDARD_APP(stress_start_function) -{ - switch_media_bug_t *bug; - switch_channel_t *channel = switch_core_session_get_channel(session); - struct stress_helper *sth; - char *argv[6]; - char *lbuf = NULL; - int x = 0; - - if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_stress_"))) { - if (!zstr(data) && !strcasecmp(data, "stop")) { - switch_channel_set_private(channel, "_stress_", NULL); - switch_core_media_bug_remove(session, &bug); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n"); - } - return; - } - - sth = (struct stress_helper *) switch_core_session_alloc(session, sizeof(*sth)); - assert(sth != NULL); - - - if (data && (lbuf = switch_core_session_strdup(session, data)) - && switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) { - if (!strncasecmp(argv[x], "read", 4)) { - sth->read = 1; - } - } - - sth->session = session; - - if (switch_core_media_bug_add(session, "stress", NULL, stress_callback, sth, 0, sth->read ? SMBF_READ_REPLACE : SMBF_WRITE_REPLACE, &bug) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure!\n"); - return; - } - - switch_channel_set_private(channel, "_stress_", bug); -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_stress_load) -{ - switch_application_interface_t *app_interface; - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "stress", "Analyze the stream for voice stress", "Analyze the stream for voice stress", - stress_start_function, "[read|write|stop]", SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_stress_shutdown) -{ - return SWITCH_STATUS_UNLOAD; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ From b033d27a389c54fac97b0d01a415cb6dc67e2023 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 20 Nov 2024 02:18:43 +0300 Subject: [PATCH 191/205] [mod_unicall] Remove from tree --- .../vanilla/autoload_configs/modules.conf.xml | 1 - .../vanilla/autoload_configs/unicall.conf.xml | 25 - configure.ac | 1 - debian/bootstrap.sh | 1 - debian/control-modules | 4 - freeswitch.spec | 1 - src/mod/.gitignore | 1 - src/mod/endpoints/mod_unicall/Makefile.am | 8 - src/mod/endpoints/mod_unicall/mod_unicall.c | 1900 ----------------- 9 files changed, 1942 deletions(-) delete mode 100644 conf/vanilla/autoload_configs/unicall.conf.xml delete mode 100644 src/mod/endpoints/mod_unicall/Makefile.am delete mode 100644 src/mod/endpoints/mod_unicall/mod_unicall.c diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 0b3b8c4515..8480d8509c 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -41,7 +41,6 @@ - diff --git a/conf/vanilla/autoload_configs/unicall.conf.xml b/conf/vanilla/autoload_configs/unicall.conf.xml deleted file mode 100644 index eeaa0782f7..0000000000 --- a/conf/vanilla/autoload_configs/unicall.conf.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/configure.ac b/configure.ac index 0cc99bbac2..46f25d4652 100755 --- a/configure.ac +++ b/configure.ac @@ -2176,7 +2176,6 @@ AC_CONFIG_FILES([Makefile src/mod/endpoints/mod_rtmp/Makefile src/mod/endpoints/mod_skinny/Makefile src/mod/endpoints/mod_sofia/Makefile - src/mod/endpoints/mod_unicall/Makefile src/mod/endpoints/mod_rtc/Makefile src/mod/endpoints/mod_verto/Makefile src/mod/event_handlers/mod_amqp/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 4587551f4e..db84b2b09c 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -47,7 +47,6 @@ avoid_mods=( endpoints/mod_khomp endpoints/mod_opal endpoints/mod_reference - endpoints/mod_unicall event_handlers/mod_smpp event_handlers/mod_event_zmq formats/mod_webm diff --git a/debian/control-modules b/debian/control-modules index 6730a6de87..0c3149d627 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -420,10 +420,6 @@ Module: endpoints/mod_sofia Description: mod_sofia Adds mod_sofia. -Module: endpoints/mod_unicall -Description: mod_unicall - Adds mod_unicall. - Module: endpoints/mod_verto Description: Adds mod_verto. Adds mod_verto. diff --git a/freeswitch.spec b/freeswitch.spec index 177036acf6..a1f6ff6454 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -1806,7 +1806,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/timezones.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/translate.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/tts_commandline.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/unicall.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/verto.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/voicemail.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/voicemail_ivr.conf.xml diff --git a/src/mod/.gitignore b/src/mod/.gitignore index 5d2791c825..e3298c6125 100644 --- a/src/mod/.gitignore +++ b/src/mod/.gitignore @@ -57,7 +57,6 @@ /say/mod_say_ru/Makefile /timers/mod_posix_timer/Makefile /timers/mod_timerfd/Makefile -/endpoints/mod_unicall/Makefile */*/Makefile.in */*/Makefile */*/mod_*.log diff --git a/src/mod/endpoints/mod_unicall/Makefile.am b/src/mod/endpoints/mod_unicall/Makefile.am deleted file mode 100644 index 1fcfc78b5b..0000000000 --- a/src/mod/endpoints/mod_unicall/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_unicall - -mod_LTLIBRARIES = mod_unicall.la -mod_unicall_la_SOURCES = mod_unicall.c -mod_unicall_la_CFLAGS = $(AM_CFLAGS) -mod_unicall_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_unicall_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/endpoints/mod_unicall/mod_unicall.c b/src/mod/endpoints/mod_unicall/mod_unicall.c deleted file mode 100644 index ee4d65e9ef..0000000000 --- a/src/mod/endpoints/mod_unicall/mod_unicall.c +++ /dev/null @@ -1,1900 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2012, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Steve Underwood 0.0.1 - * - * - * mod_unicall.c -- UniCall endpoint module - * - */ - -/* This is a work in progress. Unfinished. Non-functional */ - -#include -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_unicall_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_unicall_shutdown); -//SWITCH_MODULE_RUNTIME_FUNCTION(mod_unicall_runtime); -SWITCH_MODULE_DEFINITION(mod_unicall, mod_unicall_load, mod_unicall_shutdown, NULL); //mod_unicall_runtime); - -#define MAX_SPANS 128 - -switch_endpoint_interface_t *unicall_endpoint_interface; -static switch_memory_pool_t *module_pool = NULL; -static volatile int running = 1; - -typedef struct { - int span; - const char *id; - const char *protocol_class; - const char *protocol_variant; - int protocol_end; - int outgoing_ok; - char *dialplan; - char *context; - int fd; - uc_t *uc; -} span_data_t; - -span_data_t *span_data[MAX_SPANS]; - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_CODEC = (1 << 7), - TFLAG_BREAK = (1 << 8) -} TFLAGS; - -typedef enum { - GFLAG_MY_CODEC_PREFS = (1 << 0) -} GFLAGS; - - -static struct { - int debug; - /*! Requested frame duration, in ms */ - uint32_t frame_duration; - int dtmf_on; - int dtmf_off; - int suppress_dtmf_tone; - int ignore_dtmf_tone; - char *dialplan; - char *codec_string; - char *codec_order[SWITCH_MAX_CODECS]; - int codec_order_last; - char *codec_rates_string; - char *codec_rates[SWITCH_MAX_CODECS]; - int codec_rates_last; - unsigned int flags; - int calls; - int configured_spans; - switch_hash_t *call_hash; - switch_mutex_t *mutex; - switch_mutex_t *hash_mutex; - switch_mutex_t *channel_mutex; -} globals; - -typedef struct { - unsigned int flags; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_frame_t read_frame; - uint8_t databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_core_session_t *session; - switch_caller_profile_t *caller_profile; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - //switch_thread_cond_t *cond; - uc_t *uc; -} private_t; - - -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); - - - -static switch_status_t unicall_on_init(switch_core_session_t *session); -static switch_status_t unicall_on_routing(switch_core_session_t *session); -static switch_status_t unicall_on_execute(switch_core_session_t *session); -static switch_status_t unicall_on_hangup(switch_core_session_t *session); -static switch_status_t unicall_on_exchange_media(switch_core_session_t *session); -static switch_status_t unicall_on_soft_execute(switch_core_session_t *session); - -static switch_call_cause_t unicall_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, - switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); -static switch_status_t unicall_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t unicall_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); -static switch_status_t unicall_kill_channel(switch_core_session_t *session, int sig); -static switch_status_t unicall_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf); -static switch_status_t unicall_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg); -static switch_status_t unicall_receive_event(switch_core_session_t *session, switch_event_t *event); - -static void unicall_message(int level, const char *s) -{ - int switch_level; - - switch (level) { - case UC_LOG_NONE: - switch_level = SWITCH_LOG_CRIT; - break; - case UC_LOG_ERROR: - switch_level = SWITCH_LOG_ERROR; - break; - case UC_LOG_WARNING: - switch_level = SWITCH_LOG_WARNING; - break; - case UC_LOG_PROTOCOL_ERROR: - switch_level = SWITCH_LOG_ERROR; - break; - case UC_LOG_PROTOCOL_WARNING: - switch_level = SWITCH_LOG_WARNING; - break; - case UC_LOG_INFO: - switch_level = SWITCH_LOG_NOTICE; - //switch_level = SWITCH_LOG_NOTICE; - break; - case UC_LOG_FLOW: - case UC_LOG_FLOW_2: - case UC_LOG_FLOW_3: - case UC_LOG_CAS: - case UC_LOG_TONE: - case UC_LOG_DEBUG_1: - case UC_LOG_DEBUG_2: - case UC_LOG_DEBUG_3: - switch_level = SWITCH_LOG_DEBUG; - break; - default: - switch_level = SWITCH_LOG_CRIT; - break; - } - switch_log_printf(SWITCH_CHANNEL_LOG, switch_level, s); -} - -static void unicall_report(const char *s) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, s); -} - -#if 0 -static switch_call_cause_t unicall_incoming_channel(zap_sigmsg_t *sigmsg, switch_core_session_t **sp) -{ - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - char name[128]; - - *sp = NULL; - - if (!(session = switch_core_session_request_uuid(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL, switch_event_get_header(var_event, "origination_uuid")))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Initialization Error!\n"); - return ZAP_FAIL; - } - - switch_core_session_add_stream(session, NULL); - - tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t)); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Initialization Error!\n"); - switch_core_session_destroy(&session); - return ZAP_FAIL; - } - - *sigmsg->channel->caller_data.collected = '\0'; - - if (sigmsg->channel->caller_data.cid_name[0] == '\0') - switch_set_string(sigmsg->channel->caller_data.cid_name, sigmsg->channel->chan_name); - - if (sigmsg->channel->caller_data.cid_num.digits[0] == '\0') { - if (sigmsg->channel->caller_data.ani.digits[0] != '\0') - switch_set_string(sigmsg->channel->caller_data.cid_num.digits, sigmsg->channel->caller_data.ani.digits); - else - switch_set_string(sigmsg->channel->caller_data.cid_num.digits, sigmsg->channel->chan_number); - } - - tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), - "UniCall", - SPAN_CONFIG[sigmsg->channel->span_id].dialplan, - sigmsg->channel->caller_data.cid_name, - sigmsg->channel->caller_data.cid_num.digits, - NULL, - sigmsg->channel->caller_data.ani.digits, - sigmsg->channel->caller_data.aniII, - sigmsg->channel->caller_data.rdnis.digits, - (char *) modname, - SPAN_CONFIG[sigmsg->channel->span_id].context, sigmsg->channel->caller_data.dnis.digits); - assert(tech_pvt->caller_profile != NULL); - - if (sigmsg->channel->caller_data.screen == 1 || sigmsg->channel->caller_data.screen == 3) - switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN); - - if (sigmsg->channel->caller_data.pres) - switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER); - - snprintf(name, sizeof(name), "UNICALL/%u:%u/%s", sigmsg->channel->span_id, sigmsg->channel->chan_id, tech_pvt->caller_profile->destination_number); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect inbound channel %s\n", name); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Error spawning thread\n"); - switch_core_session_destroy(&session); - return ZAP_FAIL; - } - - if (zap_channel_add_token(sigmsg->channel, switch_core_session_get_uuid(session), 0) != ZAP_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Error adding token\n"); - switch_core_session_destroy(&session); - return ZAP_FAIL; - } - *sp = session; - - return ZAP_SUCCESS; -} -#endif - -static void on_devicefail(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_devicefail\n"); -} - -static void on_protocolfail(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_protocolfail\n"); -} - -static void on_sigchanstatus(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_sigchanstatus\n"); -} - -static void on_detected(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - //struct channel_map *chanmap; - //char name[128]; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_detected\n"); - switch_mutex_lock(globals.channel_mutex); - - //chanmap = spri->private_info; - -#if 0 - if ((session = switch_core_session_locate(chanmap->map[e->offered.channel]))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--Duplicate detected on channel s%dc%d (ignored)\n", spri->span, e->offered.channel); - switch_core_session_rwunlock(session); - switch_mutex_unlock(globals.channel_mutex); - return; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, - "-- Detected on channel s%dc%d (from %s to %s)\n", - spri->span, e->offered.channel, e->offered.parms.originating_number, e->offered.parms.destination_number); - - switch_mutex_unlock(chanmap->mutex); - - //pri_proceeding(spri->pri, e->offered.call, e->offered.channel, 0); - //pri_acknowledge(spri->pri, e->offered.call, e->offered.channel, 0); - - switch_mutex_unlock(chanmap->mutex); - - if ((session = unicall_incoming_channel(sigmsg, &session))) { - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create new inbound channel!\n"); - } -#endif - switch_mutex_unlock(globals.channel_mutex); -} - -static void on_offered(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - //struct channel_map *chanmap; - //char name[128]; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_offered\n"); -} - -static void on_requestmoreinfo(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_requestmoreinfo\n"); -} - -static void on_accepted(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_accepted\n"); -} - -static void on_callinfo(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_callinfo\n"); -} - -static void on_facility(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_facility\n"); -} - -static void on_dialednumber(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_dialednumber\n"); -} - -static void on_dialing(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_dialing\n"); -} - -static void on_sendmoreinfo(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_sendmoreinfo\n"); -} - -static void on_proceeding(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - //struct channel_map *chanmap; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_proceeding\n"); - -#if 0 - chanmap = spri->private_info; - - if ((session = switch_core_session_locate(chanmap->map[e->proceeding.channel]))) { - switch_core_session_message_t *msg; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "-- Proceeding on channel s%dc%d\n", spri->span, e->proceeding.channel); - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_PROGRESS); - switch_channel_mark_pre_answered(channel); - - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, "-- Proceeding on channel s%dc%d but it's not in use?\n", spri->span, e->proceeding.channel); - } -#endif -} - -static void on_alerting(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - //struct channel_map *chanmap; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_alerting\n"); - -#if 0 - chanmap = spri->private_info; - - if ((session = switch_core_session_locate(chanmap->map[e->alerting.channel]))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "-- Ringing on channel s%dc%d\n", spri->span, e->alerting.channel); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_RINGING); - switch_channel_mark_ring_ready(channel); - - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "-- Ringing on channel s%dc%d %s but it's not in use?\n", spri->span, e->alerting.channel, - chanmap->map[e->alerting.channel]); - } -#endif -} - -static void on_connected(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_connected\n"); -} - -static void on_answered(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_answered\n"); -} - -static void on_fardisconnected(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_fardisconnected\n"); -} - -static void on_dropcall(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_dropcall\n"); -} - -static void on_releasecall(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_releasecall\n"); -} - -static void on_farblocked(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_farblocked\n"); -} - -static void on_farunblocked(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_farunblocked\n"); -} - -static void on_localblocked(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_localblocked\n"); -} - -static void on_localunblocked(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - //switch_channel_t *channel; - //private_t *tech_pvt; - - //tech_pvt = switch_core_session_get_private(session); - //assert(tech_pvt != NULL); - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_localunblocked\n"); -} - -static void on_alarm(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_alarm\n"); -} - -static void on_resetlinedev(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_resetlinedev\n"); -} - -static void on_l2frame(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_l2frame\n"); -} - -static void on_l2bufferfull(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_l2bufferfull\n"); -} - -static void on_l2nobuffer(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_l2nobuffer\n"); -} - -static void on_usrinfo(uc_t *uc, switch_core_session_t *session, uc_event_t *e) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_usrinfo\n"); -} - -static void handle_uc_event(uc_t *uc, void *user_data, uc_event_t *e) -{ - switch_core_session_t *session; - - session = (switch_core_session_t *) user_data; - assert(session != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event %s\n", uc_event_to_str(e->e)); - switch (e->e) { - case UC_EVENT_DEVICEFAIL: - on_devicefail(uc, session, e); - break; - case UC_EVENT_PROTOCOLFAIL: - on_protocolfail(uc, session, e); - break; - case UC_EVENT_SIGCHANSTATUS: - on_sigchanstatus(uc, session, e); - break; - case UC_EVENT_DETECTED: - on_detected(uc, session, e); - break; - case UC_EVENT_OFFERED: - on_offered(uc, session, e); - break; - case UC_EVENT_REQUESTMOREINFO: - on_requestmoreinfo(uc, session, e); - break; - case UC_EVENT_ACCEPTED: - on_accepted(uc, session, e); - break; - case UC_EVENT_CALLINFO: - on_callinfo(uc, session, e); - break; - case UC_EVENT_FACILITY: - on_facility(uc, session, e); - break; - case UC_EVENT_DIALEDNUMBER: - on_dialednumber(uc, session, e); - break; - case UC_EVENT_DIALING: - on_dialing(uc, session, e); - break; - case UC_EVENT_SENDMOREINFO: - on_sendmoreinfo(uc, session, e); - break; - case UC_EVENT_PROCEEDING: - on_proceeding(uc, session, e); - break; - case UC_EVENT_ALERTING: - on_alerting(uc, session, e); - break; - case UC_EVENT_CONNECTED: - on_connected(uc, session, e); - break; - case UC_EVENT_ANSWERED: - on_answered(uc, session, e); - break; - case UC_EVENT_FARDISCONNECTED: - on_fardisconnected(uc, session, e); - break; - case UC_EVENT_DROPCALL: - on_dropcall(uc, session, e); - break; - case UC_EVENT_RELEASECALL: - on_releasecall(uc, session, e); - break; - case UC_EVENT_FARBLOCKED: - on_farblocked(uc, session, e); - break; - case UC_EVENT_FARUNBLOCKED: - on_farunblocked(uc, session, e); - break; - case UC_EVENT_LOCALBLOCKED: - on_localblocked(uc, session, e); - break; - case UC_EVENT_LOCALUNBLOCKED: - on_localunblocked(uc, session, e); - break; - case UC_EVENT_ALARM: - on_alarm(uc, session, e); - break; - case UC_EVENT_RESETLINEDEV: - on_resetlinedev(uc, session, e); - break; - case UC_EVENT_L2FRAME: - on_l2frame(uc, session, e); - break; - case UC_EVENT_L2BUFFERFULL: - on_l2bufferfull(uc, session, e); - break; - case UC_EVENT_L2NOBUFFER: - on_l2nobuffer(uc, session, e); - break; - case UC_EVENT_USRINFO: - on_usrinfo(uc, session, e); - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unknown unicall event %d\n", e->e); - break; - } -} - -static void tech_init(private_t *tech_pvt, switch_core_session_t *session) -{ - tech_pvt->read_frame.data = tech_pvt->databuf; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); - switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_core_session_set_private(session, tech_pvt); - tech_pvt->session = session; -} - -/* - State methods. They get called when the state changes to the specified state. - Returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next, - so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. -*/ -static switch_status_t unicall_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_init(%p)\n", (void *) session); - - switch_set_flag_locked(tech_pvt, TFLAG_IO); - - switch_mutex_lock(globals.mutex); - globals.calls++; - switch_mutex_unlock(globals.mutex); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_on_routing(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_routing(%p)\n", (void *) session); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s channel routing\n", switch_channel_get_name(channel)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_on_execute(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_execute(%p)\n", (void *) session); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s channel execute\n", switch_channel_get_name(channel)); - - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_on_destroy(switch_core_session_t *session) -{ - //switch_channel_t *channel; - private_t *tech_pvt; - - //channel = switch_core_session_get_channel(session); - //assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - - if (tech_pvt) { - if (switch_core_codec_ready(&tech_pvt->read_codec)) - switch_core_codec_destroy(&tech_pvt->read_codec); - if (switch_core_codec_ready(&tech_pvt->write_codec)) - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t unicall_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_hangup(%p)\n", (void *) session); - - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); - //switch_thread_cond_signal(tech_pvt->cond); - - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s channel hangup\n", switch_channel_get_name(channel)); - -#if 0 - if ((ret = uc_call_control(uc, UC_OP_DROPCALL, crn, (void *) (intptr_t) switch_channel_get_cause(channel))) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Drop call failed - %s\n", uc_ret_to_str(ret)); - return SWITCH_STATUS_FAILED; - } - /*endif */ -#endif - - switch_mutex_lock(globals.mutex); - if (--globals.calls < 0) - globals.calls = 0; - switch_mutex_unlock(globals.mutex); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_kill_channel(switch_core_session_t *session, int sig) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_kill_channel(%p, %d)\n", (void *) session, sig); - - switch (sig) { - case SWITCH_SIG_KILL: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_kill_channel(%p, %d) SIG_KILL\n", (void *) session, sig); - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - //switch_thread_cond_signal(tech_pvt->cond); - break; - case SWITCH_SIG_BREAK: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_kill_channel(%p, %d) SIG_BREAK\n", (void *) session, sig); - switch_set_flag_locked(tech_pvt, TFLAG_BREAK); - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_kill_channel(%p, %d) DEFAULT\n", (void *) session, sig); - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_on_exchange_media(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_exchange_media(%p)\n", (void *) session); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL LOOPBACK\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_on_soft_execute(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_soft_execute(%p)\n", (void *) session); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL TRANSMIT\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - private_t *tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_send_dtmf(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - //switch_time_t started = switch_time_now(); - //unsigned int elapsed; - switch_byte_t *data; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_read_frame(%p)\n", (void *) session); - - tech_pvt->read_frame.flags = SFF_NONE; - *frame = NULL; - - while (switch_test_flag(tech_pvt, TFLAG_IO)) { - if (switch_test_flag(tech_pvt, TFLAG_BREAK)) { - switch_clear_flag(tech_pvt, TFLAG_BREAK); - data = (switch_byte_t *) tech_pvt->read_frame.data; - data[0] = 65; - data[1] = 0; - tech_pvt->read_frame.datalen = 2; - tech_pvt->read_frame.flags = SFF_CNG; - *frame = &tech_pvt->read_frame; - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) - return SWITCH_STATUS_FALSE; - - if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { - switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); - if (!tech_pvt->read_frame.datalen) - continue; - *frame = &tech_pvt->read_frame; -#if SWITCH_BYTE_ORDER == __BIG_ENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) - switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2); -#endif - return SWITCH_STATUS_SUCCESS; - } - - switch_cond_next(); - } - - return SWITCH_STATUS_FALSE; -} - -static switch_status_t unicall_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - //switch_frame_t *pframe; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_write_frame(%p)\n", (void *) session); - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) - return SWITCH_STATUS_FALSE; -#if SWITCH_BYTE_ORDER == __BIG_ENDIAN - if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) - switch_swap_linear(frame->data, (int) frame->datalen / sizeof(int16_t)); -#endif - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t redirect_audio(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "redirect_audio(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t transmit_text(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "transmit_text(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t answer(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "answer(%p)\n", (void *) session); - -#if 0 - if ((ret = uc_call_control(uc, UC_OP_ANSWERCALL, crn, NULL)) < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Answer call failed - %s\n", uc_ret_to_str(ret)); - return SWITCH_STATUS_FAILED; - } - /*endif */ -#endif - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t progress(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "progress(%p)\n", (void *) session); - -#if 0 - if ((ret = uc_call_control(uc, UC_OP_ACCEPTCALL, crn, NULL)) < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Accept call failed - %s\n", uc_ret_to_str(ret)); - return SWITCH_STATUS_FAILED; - } - /*endif */ -#endif - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t bridge(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "bridge(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unbridge(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "unbridge(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t transfer(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "transfer(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t ringing(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "ringing(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t media(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "media(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t nomedia(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "nomedia(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t hold(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "hold(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unhold(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "unhold(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t redirect(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "redirect(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t respond(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "respond(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t broadcast(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "broadcast(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t media_redirect(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "media_redirect(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t deflect(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "deflect(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t video_refresh_req(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "video_refresh_req(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t display(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uc_t *uc; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - uc = tech_pvt->uc; - assert(uc != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "display(%p)\n", (void *) session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unicall_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch (msg->message_id) { - case SWITCH_MESSAGE_REDIRECT_AUDIO: - return redirect_audio(session, msg); - case SWITCH_MESSAGE_TRANSMIT_TEXT: - return transmit_text(session, msg); - case SWITCH_MESSAGE_INDICATE_ANSWER: - return answer(session, msg); - case SWITCH_MESSAGE_INDICATE_PROGRESS: - return progress(session, msg); - case SWITCH_MESSAGE_INDICATE_BRIDGE: - return bridge(session, msg); - case SWITCH_MESSAGE_INDICATE_UNBRIDGE: - return unbridge(session, msg); - case SWITCH_MESSAGE_INDICATE_TRANSFER: - return transfer(session, msg); - case SWITCH_MESSAGE_INDICATE_RINGING: - return ringing(session, msg); - case SWITCH_MESSAGE_INDICATE_MEDIA: - return media(session, msg); - case SWITCH_MESSAGE_INDICATE_NOMEDIA: - return nomedia(session, msg); - case SWITCH_MESSAGE_INDICATE_HOLD: - return hold(session, msg); - case SWITCH_MESSAGE_INDICATE_UNHOLD: - return unhold(session, msg); - case SWITCH_MESSAGE_INDICATE_REDIRECT: - return redirect(session, msg); - case SWITCH_MESSAGE_INDICATE_RESPOND: - return respond(session, msg); - case SWITCH_MESSAGE_INDICATE_BROADCAST: - return broadcast(session, msg); - case SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT: - return media_redirect(session, msg); - case SWITCH_MESSAGE_INDICATE_DEFLECT: - return deflect(session, msg); - case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: - return video_refresh_req(session, msg); - case SWITCH_MESSAGE_INDICATE_DISPLAY: - return display(session, msg); - default: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "unicall_receive_message(%p) %d\n", (void *) session, msg->message_id); - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines - that allocate memory or you will have 1 channel with memory allocated from another channel's pool! -*/ -static switch_call_cause_t unicall_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, - switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) -{ - private_t *tech_pvt; - switch_channel_t *channel; - switch_caller_profile_t *caller_profile; - uc_t *uc; - uc_makecall_t makecall; - uc_callparms_t *callparms; - int screen; - int hide; - char name[128]; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "unicall_outgoing_channel(%p)\n", (void *) session); - - if ((*new_session = switch_core_session_request(unicall_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) == NULL) { - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - switch_core_session_add_stream(*new_session, NULL); - if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); - switch_core_session_destroy(new_session); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - channel = switch_core_session_get_channel(*new_session); - tech_init(tech_pvt, *new_session); - - if (outbound_profile == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Doh! no caller profile\n"); - switch_core_session_destroy(new_session); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - snprintf(name, sizeof(name), "UNICALL/%s", outbound_profile->destination_number); - switch_channel_set_name(channel, name); - - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - - uc = tech_pvt->uc; - - if ((callparms = uc_new_callparms(NULL)) == NULL) - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - - //uc_callparm_bear_cap_transfer_cap(callparms, cap); - //uc_callparm_bear_cap_transfer_mode(callparms, mode); - //uc_callparm_bear_cap_transfer_rate(callparms, rate); - //uc_callparm_userinfo_layer1_protocol(callparms, prot); - //uc_callparm_user_rate(callparms, rate); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_INFO, "destination '%s'\n", outbound_profile->destination_number); - uc_callparm_set_destination_number(callparms, outbound_profile->destination_number); - uc_callparm_set_destination_ton(callparms, outbound_profile->destination_number_ton); - uc_callparm_set_destination_npi(callparms, outbound_profile->destination_number_numplan); - //uc_callparm_set_destination_sub_addr_number(callparms, num); - //uc_callparm_set_destination_sub_addr_ton(callparms, ton); - //uc_callparm_set_destination_sub_addr_npi(callparms, npi); - - //uc_callparm_set_redirecting_cause(callparms, cause); - //uc_callparm_set_redirecting_presentation(callparms, pres); - uc_callparm_set_redirecting_number(callparms, outbound_profile->rdnis); - uc_callparm_set_redirecting_ton(callparms, outbound_profile->rdnis_ton); - uc_callparm_set_redirecting_npi(callparms, outbound_profile->rdnis_numplan); - //uc_callparm_set_redirecting_subaddr(callparms, num); - //uc_callparm_set_redirecting_subaddr_ton(callparms, ton); - //uc_callparm_set_redirecting_subaddr_npi(callparms, npi); - - //uc_callparm_set_original_called_number(callparms, num); - //uc_callparm_set_original_called_number_ton(callparms, ton); - //uc_callparm_set_original_called_number_npi(callparms, npi); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_INFO, "caller id name '%s'\n", outbound_profile->caller_id_name); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_INFO, "caller id number '%s'\n", outbound_profile->caller_id_number); - uc_callparm_set_originating_name(callparms, outbound_profile->caller_id_name); - uc_callparm_set_originating_number(callparms, outbound_profile->caller_id_number); - screen = switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN); - hide = switch_test_flag(outbound_profile, SWITCH_CPF_HIDE_NUMBER); - if (!screen && !hide) - uc_callparm_set_originating_presentation(callparms, UC_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED); - else if (!screen && hide) - uc_callparm_set_originating_presentation(callparms, UC_PRES_PROHIB_USER_NUMBER_NOT_SCREENED); - else if (screen && !hide) - uc_callparm_set_originating_presentation(callparms, UC_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN); - else - uc_callparm_set_originating_presentation(callparms, UC_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN); - uc_callparm_set_originating_ton(callparms, outbound_profile->caller_ton); - uc_callparm_set_originating_npi(callparms, outbound_profile->caller_numplan); - //uc_callparm_set_originating_sub_addr_number(callparms, num); - //uc_callparm_set_originating_sub_addr_ton(callparms, ton); - //uc_callparm_set_originating_sub_addr_npi(callparms, npi); - - uc_callparm_set_calling_party_category(callparms, UC_CALLER_CATEGORY_NATIONAL_SUBSCRIBER_CALL); - - makecall.callparms = callparms; - makecall.call = NULL; - -#if 0 - if ((ret = uc_call_control(uc, UC_OP_MAKECALL, 0, (void *) &makecall)) < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_INFO, "Make call failed - %s\n", uc_ret_to_str(ret)); - return SWITCH_STATUS_FAILED; - } - /*endif */ -#endif - free(callparms); - - - switch_channel_set_state(channel, CS_INIT); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_INFO, "unicall_outgoing_channel(%p) SUCCESS\n", (void *) session); - return SWITCH_CAUSE_SUCCESS; -} - -static switch_status_t unicall_receive_event(switch_core_session_t *session, switch_event_t *event) -{ - struct private_object *tech_pvt = switch_core_session_get_private(session); - char *body = switch_event_get_body(event); - - switch_assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "unicall_receive_event(%p)\n", (void *) session); - - if (body == NULL) - body = ""; - - return SWITCH_STATUS_SUCCESS; -} - -static void *SWITCH_THREAD_FUNC unicall_thread_run(switch_thread_t *thread, void *obj) -{ - fd_set read; - fd_set write; - fd_set oob; - int fd; - int ret; - switch_event_t *s_event; - uc_t *uc = (uc_t *) obj; - -#if 0 - switch_mutex_init(&chanmap.mutex, SWITCH_MUTEX_NESTED, module_pool); -#endif - - if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_uc._tcp"); - switch_event_fire(&s_event); - } - - uc_get_device_handle(uc, 0, &fd); - if ((ret = uc_call_control(uc, UC_OP_UNBLOCK, 0, (void *) (intptr_t) - 1)) < 0) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Unblock failed - %s\n", uc_ret_to_str(ret)); - /*endif */ - FD_ZERO(&read); - FD_ZERO(&write); - FD_ZERO(&oob); - for (;;) { - FD_SET(fd, &read); - //FD_SET(fd, &write); - //FD_SET(fd, &oob); - - if (select(fd + 1, &read, NULL, NULL, NULL)) { - if (FD_ISSET(fd, &read)) { - uc_check_event(uc); - uc_schedule_run(uc); - } - } - } - - uc_delete(uc); - return NULL; -} - -static void unicall_thread_launch(uc_t *uc) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - - switch_threadattr_create(&thd_attr, module_pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, unicall_thread_run, uc, module_pool); -} - -switch_state_handler_table_t unicall_state_handlers = { - /*.on_init */ unicall_on_init, - /*.on_routing */ unicall_on_routing, - /*.on_execute */ unicall_on_execute, - /*.on_hangup */ unicall_on_hangup, - /*.on_exchange_media */ unicall_on_exchange_media, - /*.on_soft_execute */ unicall_on_soft_execute, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ unicall_on_destroy -}; - -switch_io_routines_t unicall_io_routines = { - /*.outgoing_channel */ unicall_outgoing_channel, - /*.read_frame */ unicall_read_frame, - /*.write_frame */ unicall_write_frame, - /*.kill_channel */ unicall_kill_channel, - /*.send_dtmf */ unicall_send_dtmf, - /*.receive_message */ unicall_receive_message, - /*.receive_event */ unicall_receive_event -}; - -static switch_status_t config_unicall(int reload) -{ - const char *cf = "unicall.conf"; - switch_xml_t cfg; - switch_xml_t xml; - switch_xml_t settings; - switch_xml_t param; - switch_xml_t spans; - switch_xml_t span; - int current_span = 0; - int min_span = 0; - int max_span = 0; - int logging_level; - int i; - char *id; - span_data_t *sp; - - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opening of %s failed\n", cf); - return SWITCH_STATUS_TERM; - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcmp(var, "debug")) { - globals.debug = atoi(val); - } else if (!strcmp(var, "ms-per-frame")) { - globals.frame_duration = atoi(val); - } else if (!strcmp(var, "dtmf-on")) { - globals.dtmf_on = atoi(val); - } else if (!strcmp(var, "dtmf-off")) { - globals.dtmf_off = atoi(val); - } else if (!strcmp(var, "dialplan")) { - set_global_dialplan(val); - } else if (!strcmp(var, "suppress-dtmf-tone")) { - globals.suppress_dtmf_tone = switch_true(val); - } else if (!strcmp(var, "ignore-dtmf-tone")) { - globals.ignore_dtmf_tone = switch_true(val); - } - } - } - spans = switch_xml_child(cfg, "spans"); - id = NULL; - for (span = switch_xml_child(spans, "span"); span; span = span->next) { - id = (char *) switch_xml_attr(span, "id"); - - current_span = 0; - - if (id) { - char *p; - - min_span = atoi(id); - if ((p = strchr(id, '-'))) { - p++; - max_span = atoi(p); - } else { - max_span = min_span; - } - if (min_span < 1 || max_span < min_span) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Span Config! [%s]\n", id); - continue; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing SPAN ID!\n"); - continue; - } - for (i = min_span; i <= max_span; i++) { - current_span = i; - - if (current_span <= 0 || current_span >= MAX_SPANS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid SPAN %d!\n", current_span); - current_span = 0; - continue; - } - if (span_data[current_span] == NULL) { - if ((span_data[current_span] = switch_core_alloc(module_pool, sizeof(*span_data[current_span]))) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "MEMORY ERROR\n"); - break; - } - sp = span_data[current_span]; - memset(sp, 0, sizeof(*sp)); - sp->span = current_span; - sp->protocol_class = NULL; - sp->protocol_variant = NULL; - sp->protocol_end = UC_MODE_CPE; - sp->outgoing_ok = TRUE; - } - sp = span_data[current_span]; - sp->id = strdup(id); - for (param = switch_xml_child(span, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (strcmp(var, "protocol-class") == 0) { - sp->protocol_class = strdup(val); - } else if (strcmp(var, "protocol-variant") == 0) { - sp->protocol_variant = strdup(val); - } else if (strcmp(var, "protocol-end") == 0) { - if (strcasecmp(val, "co") == 0) - sp->protocol_end = UC_MODE_CO; - else if (strcasecmp(val, "cpe") == 0) - sp->protocol_end = UC_MODE_CPE; - else if (strcasecmp(val, "peer") == 0) - sp->protocol_end = UC_MODE_PEER; - else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "UNKNOWN protocol-end TYPE %s\n", val); - } else if (strcmp(var, "outgoing-allowed") == 0) { - sp->outgoing_ok = switch_true(var); - } else if (strcmp(var, "dialplan") == 0) { - sp->dialplan = strdup(val); - } else if (strcmp(var, "context") == 0) { - sp->context = strdup(val); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "UNKNOWN PARAMETER %s\n", var); - } - } - } - } - switch_xml_free(xml); - - if (globals.dialplan == NULL) - set_global_dialplan("XML"); - - globals.configured_spans = 0; - for (current_span = 1; current_span < MAX_SPANS; current_span++) { - if (span_data[current_span]) { - sp = span_data[current_span]; - if ((sp->uc = uc_create(sp->id, sp->protocol_class, sp->protocol_variant, sp->protocol_end, sp->outgoing_ok)) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot launch span %d\n", current_span); - return SWITCH_STATUS_FALSE; - } - uc_get_device_handle(sp->uc, 0, &sp->fd); - uc_set_signaling_callback(sp->uc, handle_uc_event, (void *) (intptr_t) current_span); - logging_level = UC_LOG_SEVERITY_MASK | UC_LOG_SHOW_TAG | UC_LOG_SHOW_PROTOCOL; - uc_set_logging(sp->uc, logging_level, 1, sp->id); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Launched span %d\n", current_span); - unicall_thread_launch(sp->uc); - switch_mutex_lock(globals.hash_mutex); - globals.configured_spans++; - switch_mutex_unlock(globals.hash_mutex); - } - } - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_unicall_load) -{ - int logging_level; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - uc_start(); - uc_set_error_handler(unicall_report); - uc_set_message_handler(unicall_message); - logging_level = UC_LOG_SEVERITY_MASK; - uc_set_logging(NULL, logging_level, 1, NULL); - - memset(span_data, 0, sizeof(span_data)); - - module_pool = pool; - - memset(&globals, 0, sizeof(globals)); - switch_core_hash_init(&globals.call_hash); - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); - switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED, module_pool); - switch_mutex_init(&globals.channel_mutex, SWITCH_MUTEX_NESTED, module_pool); - - if ((status = config_unicall(FALSE)) != SWITCH_STATUS_SUCCESS) - return status; - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - unicall_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - unicall_endpoint_interface->interface_name = "unicall"; - unicall_endpoint_interface->io_routines = &unicall_io_routines; - unicall_endpoint_interface->state_handler = &unicall_state_handlers; - - /* Indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* -SWITCH_MODULE_RUNTIME_FUNCTION(mod_unicall_runtime) -{ - return SWITCH_STATUS_TERM; -} -*/ - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_unicall_shutdown) -{ - int x = 0; - - for (x = 0, running = -1; running && x <= 100; x++) - switch_yield(20000); - uc_end(); - return SWITCH_STATUS_SUCCESS; -} From d912e9fb011298acb790663ca075e845c3740e9d Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 27 Nov 2024 00:29:22 +0300 Subject: [PATCH 192/205] [mod_soundtouch] Remove from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 7 +- debian/bootstrap.sh | 4 - debian/control-modules | 5 - freeswitch.spec | 18 +- libs/.gitignore | 2 - scripts/freeswitch.pkg_deps.sh | 1 - .../applications/mod_soundtouch/Makefile.am | 18 - .../mod_soundtouch/mod_soundtouch.cpp | 472 ------------------ 10 files changed, 2 insertions(+), 527 deletions(-) delete mode 100644 src/mod/applications/mod_soundtouch/Makefile.am delete mode 100644 src/mod/applications/mod_soundtouch/mod_soundtouch.cpp diff --git a/build/modules.conf.in b/build/modules.conf.in index 5efb5c9b0a..eda1524101 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -40,7 +40,6 @@ applications/mod_sms #applications/mod_snapshot #applications/mod_snom #applications/mod_sonar -#applications/mod_soundtouch applications/mod_spandsp #applications/mod_spy applications/mod_test diff --git a/build/modules.conf.most b/build/modules.conf.most index acafb3908a..b07767def9 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -40,7 +40,6 @@ applications/mod_sms applications/mod_snapshot applications/mod_snom applications/mod_sonar -applications/mod_soundtouch applications/mod_spandsp applications/mod_spy applications/mod_test diff --git a/configure.ac b/configure.ac index 46f25d4652..6dc5040250 100755 --- a/configure.ac +++ b/configure.ac @@ -1079,7 +1079,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xclang" ; then fi # Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready -# Untested modules : mod_osp mod_soundtouch mod_opal mod_h323 mod_khomp +# Untested modules : mod_osp mod_opal mod_h323 mod_khomp # mod_erlang_event mod_snmp mod_perl mod_java mod_managed # #saved_CFLAGS="$CFLAGS" @@ -1469,10 +1469,6 @@ PKG_CHECK_MODULES([OPUS], [opus >= 1.1],[ AM_CONDITIONAL([HAVE_OPUS],[true])],[ AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_OPUS],[false])]) -PKG_CHECK_MODULES([SOUNDTOUCH], [soundtouch >= 1.7.0],[ - AM_CONDITIONAL([HAVE_SOUNDTOUCH],[true])],[ - AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SOUNDTOUCH],[false])]) - flite="true" PKG_CHECK_MODULES([FLITE], [flite >= 2],[],[ AC_CHECK_LIB([flite], [flite_init],[ @@ -2132,7 +2128,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_snapshot/Makefile src/mod/applications/mod_snom/Makefile src/mod/applications/mod_sonar/Makefile - src/mod/applications/mod_soundtouch/Makefile src/mod/applications/mod_spandsp/Makefile src/mod/applications/mod_spy/Makefile src/mod/applications/mod_test/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index db84b2b09c..b68ab84b90 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -78,7 +78,6 @@ avoid_mods_wheezy=( applications/mod_hiredis formats/mod_shout applications/mod_sonar - applications/mod_soundtouch formats/mod_vlc ) avoid_mods_trusty=( @@ -547,7 +546,6 @@ Recommends: freeswitch-mod-snapshot (= \${binary:Version}), freeswitch-mod-snom (= \${binary:Version}), freeswitch-mod-sonar (= \${binary:Version}), - freeswitch-mod-soundtouch (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), freeswitch-mod-valet-parking (= \${binary:Version}), @@ -636,7 +634,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-snapshot (= \${binary:Version}), freeswitch-mod-snom (= \${binary:Version}), freeswitch-mod-sonar (= \${binary:Version}), - freeswitch-mod-soundtouch (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), freeswitch-mod-translate (= \${binary:Version}), @@ -862,7 +859,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-snapshot-dbg (= \${binary:Version}), freeswitch-mod-snom-dbg (= \${binary:Version}), freeswitch-mod-sonar-dbg (= \${binary:Version}), - freeswitch-mod-soundtouch-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), freeswitch-mod-spy-dbg (= \${binary:Version}), freeswitch-mod-translate-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 0c3149d627..9970c586a2 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -210,11 +210,6 @@ Description: Sonar ping timer This module measures the latency on an audio link by sending audible audio sonar pings. -Module: applications/mod_soundtouch -Description: Soundtouch - This module implements example media bugs. -Build-Depends: libsoundtouch-dev - Module: applications/mod_spandsp Description: SpanDSP This module implements spandsp fax, dsp, and codec functionality. diff --git a/freeswitch.spec b/freeswitch.spec index a1f6ff6454..128347f8f5 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -514,18 +514,6 @@ Requires: %{name} = %{version}-%{release} Provides FreeSWITCH mod_snom, an application for controlling the functionality and appearance of the programmable softkeys on Snom phones -%package application-soundtouch -Summary: FreeSWITCH mod_soundtouch -Group: System/Libraries -Requires: %{name} = %{version}-%{release} -BuildRequires: soundtouch-devel >= 1.7.1 - -%description application-soundtouch -Provides FreeSWITCH mod_soundtouch, uses the soundtouch library, which can do -pitch shifting and other audio effects, so you can pipe the audio of a call -(or any other channel audio) through this module and achieve those effects. You -can specifically adjust pitch, rate, and tempo. - %package application-spy Summary: FreeSWITCH mod_spy Group: System/Libraries @@ -1217,7 +1205,6 @@ Requires: freeswitch-application-signalwire Requires: freeswitch-application-sms Requires: freeswitch-application-snapshot Requires: freeswitch-application-snom -Requires: freeswitch-application-soundtouch Requires: freeswitch-application-spy Requires: freeswitch-application-valet_parking Requires: freeswitch-application-video_filter @@ -1296,7 +1283,7 @@ APPLICATION_MODULES_FR="applications/mod_fifo applications/mod_fsk applications/ applications/mod_memcache applications/mod_mongo applications/mod_nibblebill applications/mod_rad_auth \ applications/mod_redis applications/mod_rss " -APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot applications/mod_snom applications/mod_soundtouch \ +APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot applications/mod_snom \ applications/mod_spandsp applications/mod_spy \ applications/mod_valet_parking applications/mod_translate applications/mod_voicemail \ applications/mod_voicemail_ivr applications/mod_video_filter" @@ -1963,9 +1950,6 @@ fi %files application-snom %{MODINSTDIR}/mod_snom.so* -%files application-soundtouch -%{MODINSTDIR}/mod_soundtouch.so* - %files application-spy %{MODINSTDIR}/mod_spy.so* diff --git a/libs/.gitignore b/libs/.gitignore index d4d419affc..d2cbc6b7df 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -420,8 +420,6 @@ opal /sofia-sip/win32/Makefile /sofia-sip/win32/Makefile.in /sounds/ -/soundtouch/ -/soundtouch-*/ /sphinxbase-*/ /srtp/aes_tables /srtp/config_in.h diff --git a/scripts/freeswitch.pkg_deps.sh b/scripts/freeswitch.pkg_deps.sh index 77e15f3471..64cdc445a0 100755 --- a/scripts/freeswitch.pkg_deps.sh +++ b/scripts/freeswitch.pkg_deps.sh @@ -6,7 +6,6 @@ wget -c http://svn.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz wget -c http://svn.freeswitch.org/downloads/libs/mpg123.tar.gz wget -c http://svn.freeswitch.org/downloads/libs/openldap-2.4.11.tar.gz wget -c http://svn.freeswitch.org/downloads/libs/pocketsphinx-0.5.99-latest.tar.gz -wget -c http://svn.freeswitch.org/downloads/libs/soundtouch-1.3.1.tar.gz wget -c http://svn.freeswitch.org/downloads/libs/sphinxbase-0.4.99-latest.tar.gz wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-1.0.8.tar.gz wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-1.0.8.tar.gz diff --git a/src/mod/applications/mod_soundtouch/Makefile.am b/src/mod/applications/mod_soundtouch/Makefile.am deleted file mode 100644 index f2883002b7..0000000000 --- a/src/mod/applications/mod_soundtouch/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_soundtouch - -if HAVE_SOUNDTOUCH - -mod_LTLIBRARIES = mod_soundtouch.la -mod_soundtouch_la_SOURCES = mod_soundtouch.cpp -mod_soundtouch_la_CFLAGS = $(AM_CFLAGS) $(SOUNDTOUCH_CFLAGS) -DINTEGER_SAMPLES -mod_soundtouch_la_CXXFLAGS = $(SOUNDTOUCH_CFLAGS) -DINTEGER_SAMPLES -mod_soundtouch_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SOUNDTOUCH_LIBS) -mod_soundtouch_la_LDFLAGS = -avoid-version -module -no-undefined -shared - -else -install: error -all: error -error: - $(error You must install libsoundtouch-dev to build mod_soundtouch) -endif diff --git a/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp b/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp deleted file mode 100644 index 05461bc453..0000000000 --- a/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * mod_soundtouch.cpp -- Example of writeable media bugs - * - */ - -#include -#include -#include -using namespace soundtouch; -using namespace std; - -#include -#define STSTART 1024 * 2 -#define STBLOCK 1024 - -SWITCH_MODULE_LOAD_FUNCTION(mod_soundtouch_load); -SWITCH_MODULE_DEFINITION(mod_soundtouch, mod_soundtouch_load, NULL, NULL); - -static const float ADJUST_AMOUNT = 0.05f; -struct soundtouch_helper { - SoundTouch *st; - switch_core_session_t *session; - bool send_not_recv; - bool hook_dtmf; - float pitch; - float rate; - float tempo; - bool literal; -}; - -/* type is p=>pitch,r=>rate,t=>tempo */ -static float normalize_soundtouch_value(char type, float value) -{ - float min,max; - switch(type) - { - case 'p': - min = 0.01f; - max = 1000.0f; - break; - case 'r': - min = 0.01f; - max = 1000.0f; - break; - case 't': - min = 0.01f; - max = 1000.0f; - break; - } - if (value < min) - value = min; - if (value > max) - value = max; - return value; -} - -/*Computation taken from SoundTouch library for conversion*/ -static float compute_pitch_from_octaves(float octaves) -{ - return (float)exp(0.69314718056f * octaves); -} - -static switch_status_t on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction) -{ - - switch_media_bug_t *bug; - switch_channel_t *channel = switch_core_session_get_channel(session); - if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_soundtouch_"))) { - struct soundtouch_helper *sth = (struct soundtouch_helper *) switch_core_media_bug_get_user_data(bug); - - if (sth) { - if (sth->literal) { - sth->literal = false; - return SWITCH_STATUS_SUCCESS; - } - - - switch (dtmf->digit) { - case '*': - sth->literal=true; - break; - - case '1': - sth->pitch = normalize_soundtouch_value('p',sth->pitch - ADJUST_AMOUNT); - sth->st->setPitch(sth->pitch); - break; - case '2': - sth->pitch = 1.0f; - sth->st->setPitch(sth->pitch); - break; - case '3': - sth->pitch = normalize_soundtouch_value('p',sth->pitch + ADJUST_AMOUNT); - sth->st->setPitch(sth->pitch); - break; - - case '4': - sth->rate = normalize_soundtouch_value('r',sth->rate - ADJUST_AMOUNT); - sth->st->setRate(sth->rate); - break; - case '5': - sth->rate = 1.0f; - sth->st->setRate(sth->rate); - break; - case '6': - sth->rate = normalize_soundtouch_value('r',sth->rate + ADJUST_AMOUNT); - sth->st->setRate(sth->rate); - break; - - case '7': - sth->tempo = normalize_soundtouch_value('t',sth->tempo - ADJUST_AMOUNT); - sth->st->setTempo(sth->tempo); - break; - case '8': - sth->tempo = 1.0f; - sth->st->setTempo(sth->tempo); - break; - case '9': - sth->tempo = normalize_soundtouch_value('t',sth->tempo + ADJUST_AMOUNT); - sth->st->setTempo(sth->tempo); - break; - - case '0': - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "pitch: %f tempo: %f rate: %f\n",sth->pitch,sth->tempo,sth->rate); - } - - } - - - return SWITCH_STATUS_FALSE; - } - return SWITCH_STATUS_SUCCESS; -} -static switch_bool_t soundtouch_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) -{ - struct soundtouch_helper *sth = (struct soundtouch_helper *) user_data; - - switch (type) { - case SWITCH_ABC_TYPE_INIT: - { - switch_codec_t *read_codec = switch_core_session_get_read_codec(sth->session); - sth->st = new SoundTouch(); - sth->st->setSampleRate(read_codec->implementation->samples_per_second); - sth->st->setChannels(read_codec->implementation->number_of_channels); - - sth->st->setSetting(SETTING_USE_QUICKSEEK, 1); - sth->st->setSetting(SETTING_USE_AA_FILTER, 1); - - if (sth->pitch) { - sth->st->setPitch(sth->pitch); - } - - if (sth->rate) { - sth->st->setRate(sth->rate); - } - - if (sth->tempo) { - sth->st->setTempo(sth->tempo); - } - - if (sth->hook_dtmf) - { - if (sth->send_not_recv) { - switch_core_event_hook_add_send_dtmf(sth->session, on_dtmf); - } else { - switch_core_event_hook_add_recv_dtmf(sth->session, on_dtmf); - } - } - } - break; - case SWITCH_ABC_TYPE_CLOSE: - { - delete sth->st; - if (sth->send_not_recv) { - switch_core_event_hook_remove_send_dtmf(sth->session, on_dtmf); - } else { - switch_core_event_hook_remove_recv_dtmf(sth->session, on_dtmf); - } - } - break; - case SWITCH_ABC_TYPE_READ: - case SWITCH_ABC_TYPE_WRITE: - break; - case SWITCH_ABC_TYPE_READ_REPLACE: - case SWITCH_ABC_TYPE_WRITE_REPLACE: - { - switch_frame_t *frame; - - assert(sth != NULL); - assert(sth->st != NULL); - - if (! sth->send_not_recv) { - frame = switch_core_media_bug_get_read_replace_frame(bug); - } else { - frame = switch_core_media_bug_get_write_replace_frame(bug); - } - - sth->st->putSamples((SAMPLETYPE *) frame->data, frame->samples); - - if (sth->st->numSamples() >= frame->samples * 2) { - frame->samples = sth->st->receiveSamples((SAMPLETYPE *) frame->data, frame->samples); - frame->datalen = frame->samples * 2; - } else { - memset(frame->data, 0, frame->datalen); - } - - if (! sth->send_not_recv) { - switch_core_media_bug_set_read_replace_frame(bug, frame); - } else { - switch_core_media_bug_set_write_replace_frame(bug, frame); - } - - } - default: - break; - } - - return SWITCH_TRUE; -} - -SWITCH_STANDARD_APP(soundtouch_start_function) -{ - switch_media_bug_t *bug; - switch_channel_t *channel = switch_core_session_get_channel(session); - struct soundtouch_helper *sth; - char *argv[6]; - int argc; - char *lbuf = NULL; - int x; - int n=0; - - if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_soundtouch_"))) { - if (!zstr(data) && !strcasecmp(data, "stop")) { - switch_channel_set_private(channel, "_soundtouch_", NULL); - switch_core_media_bug_remove(session, &bug); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n"); - } - return; - } - - sth = (struct soundtouch_helper *) switch_core_session_alloc(session, sizeof(*sth)); - assert(sth != NULL); - - - if (data && (lbuf = switch_core_session_strdup(session, data)) - && (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - sth->pitch = 1; - sth->rate = 1; - sth->tempo = 1; - sth->hook_dtmf = false; - sth->send_not_recv = false; - n = 0; - for (x = 0; x < argc; x++) { - if (!strncasecmp(argv[x], "send_leg", 8)) { - sth->send_not_recv = true; - } else if (!strncasecmp(argv[x], "hook_dtmf", 9)) { - sth->hook_dtmf = true; - n++; - } else if (strchr(argv[x], 'p')) { - sth->pitch = normalize_soundtouch_value('p', atof(argv[x])); - n++; - } else if (strchr(argv[x], 'r')) { - sth->rate = normalize_soundtouch_value('r', atof(argv[x])); - n++; - } else if (strchr(argv[x], 'o')) { - sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x])) ); - n++; - } else if (strchr(argv[x], 's')) { - /*12.0f taken from soundtouch conversion to octaves*/ - sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x]) / 12.0f) ); - n++; - } else if (strchr(argv[x], 't')) { - sth->tempo = normalize_soundtouch_value('t', atof(argv[x])); - n++; - } - } - } - - if (n < 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run, no pitch set\n"); - return; - } - - - sth->session = session; - - if (switch_core_media_bug_add(session, "soundtouch", NULL, soundtouch_callback, sth, 0, - sth->send_not_recv ? SMBF_WRITE_REPLACE : SMBF_READ_REPLACE, &bug) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure!\n"); - return; - } - - switch_channel_set_private(channel, "_soundtouch_", bug); -} - -/* API Interface Function */ -#define SOUNDTOUCH_API_SYNTAX " [start|stop] [send_leg] [hook_dtmf] [-]s [-]o p r t" -SWITCH_STANDARD_API(soundtouch_api_function) -{ - switch_core_session_t *rsession = NULL; - switch_channel_t *channel = NULL; - switch_media_bug_t *bug; - struct soundtouch_helper *sth; - char *mycmd = NULL; - int argc = 0; - char *argv[10] = { 0 }; - char *uuid = NULL; - char *action = NULL; - int x, n; - - if (zstr(cmd)) { - goto usage; - } - - if (!(mycmd = strdup(cmd))) { - goto usage; - } - - if ((argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) { - goto usage; - } - - uuid = argv[0]; - action = argv[1]; - - if (!(rsession = switch_core_session_locate(uuid))) { - stream->write_function(stream, "-ERR Cannot locate session!\n"); - goto done; - } - - channel = switch_core_session_get_channel(rsession); - - if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_soundtouch_"))) { - if (!zstr(action) && !strcasecmp(action, "stop")) { - switch_channel_set_private(channel, "_soundtouch_", NULL); - switch_core_media_bug_remove(rsession, &bug); - stream->write_function(stream, "+OK Success\n"); - } else { - stream->write_function(stream, "-ERR Cannot run 2 at once on the same channel!\n"); - } - goto done; - } - - if (!zstr(action) && strcasecmp(action, "start")) { - goto usage; - } - - if (argc < 3) { - goto usage; - } - - sth = (struct soundtouch_helper *) switch_core_session_alloc(rsession, sizeof(*sth)); - assert(sth != NULL); - - - sth->pitch = 1; - sth->rate = 1; - sth->tempo = 1; - sth->hook_dtmf = false; - sth->send_not_recv = false; - n = 0; - for (x = 2; x < argc; x++) { - if (!strncasecmp(argv[x], "send_leg", 8)) { - sth->send_not_recv = true; - } else if (!strncasecmp(argv[x], "hook_dtmf", 9)) { - sth->hook_dtmf = true; - n++; - } else if (strchr(argv[x], 'p')) { - sth->pitch = normalize_soundtouch_value('p', atof(argv[x])); - n++; - } else if (strchr(argv[x], 'r')) { - sth->rate = normalize_soundtouch_value('r', atof(argv[x])); - n++; - } else if (strchr(argv[x], 'o')) { - sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x])) ); - n++; - } else if (strchr(argv[x], 's')) { - /*12.0f taken from soundtouch conversion to octaves*/ - sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x]) / 12.0f) ); - n++; - } else if (strchr(argv[x], 't')) { - sth->tempo = normalize_soundtouch_value('t', atof(argv[x])); - n++; - } - } - - if (n < 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rsession), SWITCH_LOG_WARNING, "Cannot run, no pitch set\n"); - goto usage; - } - - sth->session = rsession; - - if (switch_core_media_bug_add(rsession, "soundtouch", NULL, soundtouch_callback, sth, 0, - sth->send_not_recv ? SMBF_WRITE_REPLACE : SMBF_READ_REPLACE, &bug) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "-ERR Failure!\n"); - goto done; - } else { - switch_channel_set_private(channel, "_soundtouch_", bug); - stream->write_function(stream, "+OK Success\n"); - goto done; - } - - - usage: - stream->write_function(stream, "-USAGE: %s\n", SOUNDTOUCH_API_SYNTAX); - - done: - if (rsession) { - switch_core_session_rwunlock(rsession); - } - - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - - -SWITCH_MODULE_LOAD_FUNCTION(mod_soundtouch_load) -{ - switch_application_interface_t *app_interface; - switch_api_interface_t *api_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "soundtouch", "Alter the audio stream", "Alter the audio stream pitch/rate/tempo", - soundtouch_start_function, "[send_leg] [hook_dtmf] [-]s [-]o p r t", SAF_NONE); - - SWITCH_ADD_API(api_interface, "soundtouch", "soundtouch", soundtouch_api_function, SOUNDTOUCH_API_SYNTAX); - - switch_console_set_complete("add soundtouch ::console::list_uuid ::[start:stop"); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ From f2481690d5e2324e30b64cf77ad5f26c3812d430 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 27 Nov 2024 14:13:35 +0300 Subject: [PATCH 193/205] [mod_sonar] Remove from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 1 - debian/bootstrap.sh | 4 - debian/control-modules | 5 - src/mod/applications/mod_sonar/Makefile.am | 8 - src/mod/applications/mod_sonar/mod_sonar.c | 257 --------------------- 7 files changed, 277 deletions(-) delete mode 100644 src/mod/applications/mod_sonar/Makefile.am delete mode 100644 src/mod/applications/mod_sonar/mod_sonar.c diff --git a/build/modules.conf.in b/build/modules.conf.in index eda1524101..92796371a5 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -39,7 +39,6 @@ applications/mod_signalwire applications/mod_sms #applications/mod_snapshot #applications/mod_snom -#applications/mod_sonar applications/mod_spandsp #applications/mod_spy applications/mod_test diff --git a/build/modules.conf.most b/build/modules.conf.most index b07767def9..4eafa04a8e 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -39,7 +39,6 @@ applications/mod_signalwire applications/mod_sms applications/mod_snapshot applications/mod_snom -applications/mod_sonar applications/mod_spandsp applications/mod_spy applications/mod_test diff --git a/configure.ac b/configure.ac index 6dc5040250..35bc029486 100755 --- a/configure.ac +++ b/configure.ac @@ -2127,7 +2127,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_sms/Makefile src/mod/applications/mod_snapshot/Makefile src/mod/applications/mod_snom/Makefile - src/mod/applications/mod_sonar/Makefile src/mod/applications/mod_spandsp/Makefile src/mod/applications/mod_spy/Makefile src/mod/applications/mod_test/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index b68ab84b90..9a4b746a10 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -77,7 +77,6 @@ avoid_mods_wheezy=( applications/mod_cv applications/mod_hiredis formats/mod_shout - applications/mod_sonar formats/mod_vlc ) avoid_mods_trusty=( @@ -545,7 +544,6 @@ Recommends: freeswitch-mod-sms (= \${binary:Version}), freeswitch-mod-snapshot (= \${binary:Version}), freeswitch-mod-snom (= \${binary:Version}), - freeswitch-mod-sonar (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), freeswitch-mod-valet-parking (= \${binary:Version}), @@ -633,7 +631,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-sms (= \${binary:Version}), freeswitch-mod-snapshot (= \${binary:Version}), freeswitch-mod-snom (= \${binary:Version}), - freeswitch-mod-sonar (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), freeswitch-mod-translate (= \${binary:Version}), @@ -858,7 +855,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-sms-dbg (= \${binary:Version}), freeswitch-mod-snapshot-dbg (= \${binary:Version}), freeswitch-mod-snom-dbg (= \${binary:Version}), - freeswitch-mod-sonar-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), freeswitch-mod-spy-dbg (= \${binary:Version}), freeswitch-mod-translate-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 9970c586a2..2b54b6f7e6 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -205,11 +205,6 @@ Module: applications/mod_snom Description: SNOM specific features This module implements features specific to SNOM phones. -Module: applications/mod_sonar -Description: Sonar ping timer - This module measures the latency on an audio link by sending audible - audio sonar pings. - Module: applications/mod_spandsp Description: SpanDSP This module implements spandsp fax, dsp, and codec functionality. diff --git a/src/mod/applications/mod_sonar/Makefile.am b/src/mod/applications/mod_sonar/Makefile.am deleted file mode 100644 index 4398e3c664..0000000000 --- a/src/mod/applications/mod_sonar/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_sonar - -mod_LTLIBRARIES = mod_sonar.la -mod_sonar_la_SOURCES = mod_sonar.c -mod_sonar_la_CFLAGS = $(AM_CFLAGS) -mod_sonar_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_sonar_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/applications/mod_sonar/mod_sonar.c b/src/mod/applications/mod_sonar/mod_sonar.c deleted file mode 100644 index 52bd5ebf17..0000000000 --- a/src/mod/applications/mod_sonar/mod_sonar.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * William King - * Seven Du - * - * mod_sonar.c -- Sonar ping timer - * - * - */ - -/* - TODO: - 1. Use libteltone directly - 2. Use an energy detection to listen for first set of sound back. Use timestamp of detection of energy as the recv stamp if a tone is eventually detected. - 3. Check for milliwatt pings. Listen for frequency changes, and audio loss - */ - - -#include - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* Prototypes */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sonar_shutdown); -SWITCH_MODULE_RUNTIME_FUNCTION(mod_sonar_runtime); -SWITCH_MODULE_LOAD_FUNCTION(mod_sonar_load); - -/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) - * Defines a switch_loadable_module_function_table_t and a static const char[] modname - */ -SWITCH_MODULE_DEFINITION(mod_sonar, mod_sonar_load, mod_sonar_shutdown, NULL); - - -struct sonar_ping_helper_s { - switch_time_t start, end, diff; - int samples[1024]; - int received; - int sum, min, max; -}; - -typedef struct sonar_ping_helper_s sonar_ping_helper_t; - -switch_bool_t sonar_ping_callback(switch_core_session_t *session, const char *app, const char *app_data){ - switch_channel_t *channel = switch_core_session_get_channel(session); - sonar_ping_helper_t *ph = switch_channel_get_private(channel, "__sonar_ping__"); - int diff; - - if (!ph) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not locate private sonar helper data\n"); - return SWITCH_TRUE; - } - - if ( ph->end ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sonar not yet reset. Likely a repeat detection.\n"); - return SWITCH_TRUE; - } - - ph->end = switch_time_now(); - diff = ph->end - ph->start; - - ph->start = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Sonar ping took %ld milliseconds\n", (long)diff / 1000); - - diff /= 1000; - ph->sum += diff; - ph->max = MAX(ph->max, diff); - ph->min = MIN(ph->min, diff); - ph->samples[ph->received++] = diff; - - return SWITCH_TRUE; -} - -SWITCH_STANDARD_APP(sonar_app) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - char *tone = "%(500,0,1004)"; - const char *arg = (char *) data; - int loops; - int lost = 0; - int x; - int avg = 0, sdev = 0, mdev = 0; - int sum2; - switch_event_t *event; - sonar_ping_helper_t ph = { 0 }; - - if (zstr(arg)) { - loops = 5; - } else { - loops = atoi(data); - } - - if (loops < 0) { - loops = 5; - } else if (loops > 1024) { - loops = 1024; - } - - switch_channel_answer(channel); - switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL); - switch_channel_set_private(channel, "__sonar_ping__", &ph); - - switch_ivr_tone_detect_session(session, - "soar_ping", "1004", - "r", 0, - 1, NULL, NULL, sonar_ping_callback); - - switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL); - - ph.min = 999999; - for( x = 0; x < loops; x++ ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending sonar ping\n"); - ph.end = 0; - ph.start = switch_time_now(); - switch_ivr_gentones(session, tone, 1, NULL); - switch_ivr_sleep(session, 2000, SWITCH_FALSE, NULL); - if ( ph.start ) { - lost++; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost sonar ping\n"); - } - } - - switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL); - switch_ivr_stop_tone_detect_session(session); - - if (loops == lost) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too bad, we lost all!\n"); - return; - } - - if (ph.received + lost != loops) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Race happend %d + %d != %d\n", ph.received, lost, loops); - } - - if (ph.received > 0) avg = ph.sum / ph.received; - - sum2 = 0; - for(x = 0; x < ph.received; x++) { - sum2 += abs(ph.samples[x] - avg); - } - - if (ph.received > 0) { - mdev = sum2 / ph.received; - } - - - sum2 = 0; - for(x = 0; x < ph.received; x++) { - sum2 += (ph.samples[x] - avg) * (ph.samples[x] - avg); - } - - if (ph.received > 1) { - sdev = sqrt(sum2 / (ph.received - 1)); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, - "Sonar Ping (in ms): min:%d max:%d avg:%d sdev:%d mdev:%d sent:%d recv: %d lost:%d lost/send:%2.2f%%\n", - ph.min, ph.max, avg, sdev, mdev, loops, ph.received, lost, lost * 1.0 / loops); - - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "sonar::ping") == SWITCH_STATUS_SUCCESS) { - const char *verbose_event; - - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_min", "%d", ph.min); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_max", "%d", ph.max); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_avg", "%d", avg); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_sdev", "%d", sdev); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_mdev", "%d", mdev); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_sent", "%d", loops); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_recv", "%d", ph.received); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_lost", "%d", lost); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lost_rate", "%2.2f%%", lost * 1.0 / loops); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "destination_number", - switch_channel_get_variable(channel, "ping_destination_number")); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sonar_ping_ref", - switch_channel_get_variable(channel, "sonar_ping_ref")); - - verbose_event = switch_channel_get_variable(channel, "sonar_channel_event"); - - if (verbose_event && switch_true(verbose_event)) { - switch_channel_event_set_data(channel, event); - } - - switch_event_fire(&event); - } - -} - -/* Macro expands to: switch_status_t mod_sonar_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ -SWITCH_MODULE_LOAD_FUNCTION(mod_sonar_load) -{ - switch_application_interface_t *app_interface; - - if (switch_event_reserve_subclass("sonar::ping") != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", "sonar::ping"); - return SWITCH_STATUS_TERM; - } - - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "sonar", "sonar", "sonar", sonar_app, "", SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* - Called when the system shuts down - Macro expands to: switch_status_t mod_sonar_shutdown() */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sonar_shutdown) -{ - - switch_event_free_subclass("sonar::ping"); - - return SWITCH_STATUS_SUCCESS; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ From 4c447a98ede6be14775f27cd478ae6f79d1012b8 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 2 Dec 2024 17:58:09 +0300 Subject: [PATCH 194/205] [mod_snom] Remove from tree. --- Freeswitch.2017.sln | 14 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - .../autoload_configs/modules.conf.xml | 3 - conf/insideout/dialplan/default.xml | 18 -- conf/sbc/dialplan/default.xml | 18 -- .../vanilla/autoload_configs/modules.conf.xml | 3 - conf/vanilla/dialplan/default.xml | 18 -- configure.ac | 1 - debian/bootstrap.sh | 3 - debian/control-modules | 4 - freeswitch.spec | 15 +- src/mod/applications/mod_snom/Makefile.am | 9 - .../mod_snom/conf/dialplan/snom_demo.xml | 16 - .../mod_snom/mod_snom.2017.vcxproj | 146 --------- src/mod/applications/mod_snom/mod_snom.c | 276 ------------------ w32/Setup/Setup.2017.wixproj | 8 - 17 files changed, 1 insertion(+), 553 deletions(-) delete mode 100644 src/mod/applications/mod_snom/Makefile.am delete mode 100644 src/mod/applications/mod_snom/conf/dialplan/snom_demo.xml delete mode 100644 src/mod/applications/mod_snom/mod_snom.2017.vcxproj delete mode 100644 src/mod/applications/mod_snom/mod_snom.c diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 3e4451ad7b..764bd54daa 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -291,8 +291,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shout", "src\mod\format EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libogg", "libs\win32\libogg\libogg.2017.vcxproj", "{0FEEAEC6-4399-4C46-B7DB-62ECE80D15B4}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_snom", "src\mod\applications\mod_snom\mod_snom.2017.vcxproj", "{2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_zh", "src\mod\say\mod_say_zh\mod_say_zh.2017.vcxproj", "{B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_managed", "src\mod\languages\mod_managed\mod_managed.2017.vcxproj", "{7B42BDA1-72C0-4378-A9B6-5C530F8CD61E}" @@ -1216,17 +1214,6 @@ Global {0FEEAEC6-4399-4C46-B7DB-62ECE80D15B4}.Release|Win32.Build.0 = Release|Win32 {0FEEAEC6-4399-4C46-B7DB-62ECE80D15B4}.Release|x64.ActiveCfg = Release|x64 {0FEEAEC6-4399-4C46-B7DB-62ECE80D15B4}.Release|x64.Build.0 = Release|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.All|Win32.ActiveCfg = Release|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.All|x64.ActiveCfg = Release|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.All|x64.Build.0 = Release|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Debug|Win32.ActiveCfg = Debug|Win32 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Debug|Win32.Build.0 = Debug|Win32 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Debug|x64.ActiveCfg = Debug|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Debug|x64.Build.0 = Debug|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Release|Win32.ActiveCfg = Release|Win32 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Release|Win32.Build.0 = Release|Win32 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Release|x64.ActiveCfg = Release|x64 - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03}.Release|x64.Build.0 = Release|x64 {B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E}.All|Win32.ActiveCfg = Release|x64 {B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E}.All|x64.ActiveCfg = Release|x64 {B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E}.All|x64.Build.0 = Release|x64 @@ -2526,7 +2513,6 @@ Global {D3D8B329-20BE-475E-9E83-653CEA0E0EF5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {38FE0559-9910-43A8-9E45-3E5004C27692} = {A5A27244-AD24-46E5-B01B-840CD296C91D} {0FEEAEC6-4399-4C46-B7DB-62ECE80D15B4} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {7B42BDA1-72C0-4378-A9B6-5C530F8CD61E} = {0C808854-54D1-4230-BFF5-77B5FD905000} {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0} = {0C808854-54D1-4230-BFF5-77B5FD905000} diff --git a/build/modules.conf.in b/build/modules.conf.in index 92796371a5..e3d752bdbb 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -38,7 +38,6 @@ applications/mod_httapi applications/mod_signalwire applications/mod_sms #applications/mod_snapshot -#applications/mod_snom applications/mod_spandsp #applications/mod_spy applications/mod_test diff --git a/build/modules.conf.most b/build/modules.conf.most index 4eafa04a8e..9ab256e24a 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -38,7 +38,6 @@ applications/mod_rss applications/mod_signalwire applications/mod_sms applications/mod_snapshot -applications/mod_snom applications/mod_spandsp applications/mod_spy applications/mod_test diff --git a/conf/insideout/autoload_configs/modules.conf.xml b/conf/insideout/autoload_configs/modules.conf.xml index 0e1f60f77d..62d7f31b48 100755 --- a/conf/insideout/autoload_configs/modules.conf.xml +++ b/conf/insideout/autoload_configs/modules.conf.xml @@ -48,9 +48,6 @@ - - - diff --git a/conf/insideout/dialplan/default.xml b/conf/insideout/dialplan/default.xml index 6290dd53b0..6d78a7f3b3 100644 --- a/conf/insideout/dialplan/default.xml +++ b/conf/insideout/dialplan/default.xml @@ -116,24 +116,6 @@ --> - - - - - - - - - - - - - - - - diff --git a/conf/sbc/dialplan/default.xml b/conf/sbc/dialplan/default.xml index bcdd5ddf01..aa3d624033 100644 --- a/conf/sbc/dialplan/default.xml +++ b/conf/sbc/dialplan/default.xml @@ -115,24 +115,6 @@ --> - - - - - - - - - - - - - - - - diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 8480d8509c..8bdf873a76 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -75,9 +75,6 @@ - - - diff --git a/conf/vanilla/dialplan/default.xml b/conf/vanilla/dialplan/default.xml index fb999d54ac..5fd9a079b6 100644 --- a/conf/vanilla/dialplan/default.xml +++ b/conf/vanilla/dialplan/default.xml @@ -179,24 +179,6 @@ --> - - - - - - - - - - - - - - - - diff --git a/configure.ac b/configure.ac index 35bc029486..89ed163568 100755 --- a/configure.ac +++ b/configure.ac @@ -2126,7 +2126,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_signalwire/Makefile src/mod/applications/mod_sms/Makefile src/mod/applications/mod_snapshot/Makefile - src/mod/applications/mod_snom/Makefile src/mod/applications/mod_spandsp/Makefile src/mod/applications/mod_spy/Makefile src/mod/applications/mod_test/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 9a4b746a10..eacc07ce7b 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -543,7 +543,6 @@ Recommends: freeswitch-mod-rss (= \${binary:Version}), freeswitch-mod-sms (= \${binary:Version}), freeswitch-mod-snapshot (= \${binary:Version}), - freeswitch-mod-snom (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), freeswitch-mod-valet-parking (= \${binary:Version}), @@ -630,7 +629,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-shout (= \${binary:Version}), freeswitch-mod-sms (= \${binary:Version}), freeswitch-mod-snapshot (= \${binary:Version}), - freeswitch-mod-snom (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-spy (= \${binary:Version}), freeswitch-mod-translate (= \${binary:Version}), @@ -854,7 +852,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-rss-dbg (= \${binary:Version}), freeswitch-mod-sms-dbg (= \${binary:Version}), freeswitch-mod-snapshot-dbg (= \${binary:Version}), - freeswitch-mod-snom-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), freeswitch-mod-spy-dbg (= \${binary:Version}), freeswitch-mod-translate-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 2b54b6f7e6..b20538ee1c 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -201,10 +201,6 @@ Description: Snapshot This module can record a sliding window of audio and take snapshots to disk. -Module: applications/mod_snom -Description: SNOM specific features - This module implements features specific to SNOM phones. - Module: applications/mod_spandsp Description: SpanDSP This module implements spandsp fax, dsp, and codec functionality. diff --git a/freeswitch.spec b/freeswitch.spec index 128347f8f5..2c0a001677 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -505,15 +505,6 @@ Requires: %{name} = %{version}-%{release} Provides FreeSWITCH mod_snapshot, allows recording a sliding window of audio and taking snapshots to disk. -%package application-snom -Summary: FreeSWITCH mod_snom -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description application-snom -Provides FreeSWITCH mod_snom, an application for controlling the functionality -and appearance of the programmable softkeys on Snom phones - %package application-spy Summary: FreeSWITCH mod_spy Group: System/Libraries @@ -1204,7 +1195,6 @@ Requires: freeswitch-application-rss Requires: freeswitch-application-signalwire Requires: freeswitch-application-sms Requires: freeswitch-application-snapshot -Requires: freeswitch-application-snom Requires: freeswitch-application-spy Requires: freeswitch-application-valet_parking Requires: freeswitch-application-video_filter @@ -1283,7 +1273,7 @@ APPLICATION_MODULES_FR="applications/mod_fifo applications/mod_fsk applications/ applications/mod_memcache applications/mod_mongo applications/mod_nibblebill applications/mod_rad_auth \ applications/mod_redis applications/mod_rss " -APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot applications/mod_snom \ +APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot \ applications/mod_spandsp applications/mod_spy \ applications/mod_valet_parking applications/mod_translate applications/mod_voicemail \ applications/mod_voicemail_ivr applications/mod_video_filter" @@ -1947,9 +1937,6 @@ fi %files application-snapshot %{MODINSTDIR}/mod_snapshot.so* -%files application-snom -%{MODINSTDIR}/mod_snom.so* - %files application-spy %{MODINSTDIR}/mod_spy.so* diff --git a/src/mod/applications/mod_snom/Makefile.am b/src/mod/applications/mod_snom/Makefile.am deleted file mode 100644 index b388f069ec..0000000000 --- a/src/mod/applications/mod_snom/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_snom - -mod_LTLIBRARIES = mod_snom.la -mod_snom_la_SOURCES = mod_snom.c -mod_snom_la_CFLAGS = $(AM_CFLAGS) -mod_snom_la_CPPFLAGS = $(CURL_CFLAGS) $(AM_CPPFLAGS) -mod_snom_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_snom_la_LDFLAGS = $(CURL_LIBS) -avoid-version -module -no-undefined -shared diff --git a/src/mod/applications/mod_snom/conf/dialplan/snom_demo.xml b/src/mod/applications/mod_snom/conf/dialplan/snom_demo.xml deleted file mode 100644 index 5917713471..0000000000 --- a/src/mod/applications/mod_snom/conf/dialplan/snom_demo.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/mod/applications/mod_snom/mod_snom.2017.vcxproj b/src/mod/applications/mod_snom/mod_snom.2017.vcxproj deleted file mode 100644 index c74c9d08c8..0000000000 --- a/src/mod/applications/mod_snom/mod_snom.2017.vcxproj +++ /dev/null @@ -1,146 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_snom - {2A3D00C6-588D-4E86-81AC-9EF5EDE86E03} - mod_snom - Win32Proj - - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) - - - 6385;6340;6246;6011;6387;%(DisableSpecificWarnings) - $(SolutionDir)\src\include;%(AdditionalIncludeDirectories) - - - false - - - - - - - X64 - - - WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) - - - 6385;6340;6246;6011;6387;%(DisableSpecificWarnings) - $(SolutionDir)\src\include;%(AdditionalIncludeDirectories) - - - false - - - MachineX64 - - - - - - - 6385;6340;6246;6011;6387;%(DisableSpecificWarnings) - $(SolutionDir)\src\include;%(AdditionalIncludeDirectories) - - - false - - - - - - - X64 - - - - - 6385;6340;6246;6011;6387;%(DisableSpecificWarnings) - $(SolutionDir)\src\include;%(AdditionalIncludeDirectories) - - - false - - - MachineX64 - - - - - - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - - - - \ No newline at end of file diff --git a/src/mod/applications/mod_snom/mod_snom.c b/src/mod/applications/mod_snom/mod_snom.c deleted file mode 100644 index b3cf2b478e..0000000000 --- a/src/mod/applications/mod_snom/mod_snom.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * mod_snom.c -- SNOM Specific Features - * - */ -#include -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load); -SWITCH_MODULE_DEFINITION(mod_snom, mod_snom_load, NULL, NULL); - -static switch_bool_t snom_bind_key(const char *key, - const char *light, - const char *label, const char *user, const char *host, const char *profile, const char *action_name, const char *action) -{ - switch_event_t *event; - - - if (user && host && profile) { - if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user", user); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "host", host); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile", profile); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "content-type", "application/x-buttons"); - if (action && action_name) { - switch_event_add_body(event, "k=%s\nc=%s\nl=%s\nn=%s\na=%s\n", key, light, label, action, action_name); - } else { - switch_event_add_body(event, "k=%s\nc=%s\nl=%s\n\n", key, light, label); - } - - switch_event_fire(&event); - } - return SWITCH_TRUE; - } - - return SWITCH_FALSE; -} - - -#define URL_SYNTAX "" -SWITCH_STANDARD_API(snom_url_api_function) -{ -#if 0 - char *tmp; - switch_event_serialize(stream->param_event, &tmp, SWITCH_TRUE); - printf("W00t\n%s\n", tmp); - free(tmp); -#endif - - return SWITCH_STATUS_SUCCESS; - -} - -#define KEY_BIND_SYNTAX " - - mod_snom - {2a3d00c6-588d-4e86-81ac-9ef5ede86e03} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_spandsp {1e21afe0-6fdb-41d2-942d-863607c24b91} From 4d7a7f9af6004f6748b45e81db84ad2780e5da8f Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 4 Dec 2024 17:16:02 +0300 Subject: [PATCH 195/205] [mod_rss] Remove from tree --- .gitignore | 1 - Freeswitch.2017.sln | 15 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - conf/curl/autoload_configs/rss.conf.xml | 7 - .../autoload_configs/modules.conf.xml | 1 - conf/insideout/autoload_configs/rss.conf.xml | 7 - .../vanilla/autoload_configs/modules.conf.xml | 1 - conf/vanilla/autoload_configs/rss.conf.xml | 7 - configure.ac | 1 - debian/bootstrap.sh | 3 - debian/control-modules | 4 - freeswitch.spec | 16 +- src/mod/applications/mod_rss/Makefile.am | 8 - .../conf/autoload_configs/rss.conf.xml | 7 - .../mod_rss/conf/dialplan/rss.xml | 7 - .../applications/mod_rss/mod_rss.2017.vcxproj | 141 ---- src/mod/applications/mod_rss/mod_rss.c | 649 ------------------ src/mod/applications/mod_rss/script/news.js | 12 - w32/Setup/Setup.2017.wixproj | 8 - 20 files changed, 1 insertion(+), 896 deletions(-) delete mode 100644 conf/curl/autoload_configs/rss.conf.xml delete mode 100644 conf/insideout/autoload_configs/rss.conf.xml delete mode 100644 conf/vanilla/autoload_configs/rss.conf.xml delete mode 100644 src/mod/applications/mod_rss/Makefile.am delete mode 100644 src/mod/applications/mod_rss/conf/autoload_configs/rss.conf.xml delete mode 100644 src/mod/applications/mod_rss/conf/dialplan/rss.xml delete mode 100644 src/mod/applications/mod_rss/mod_rss.2017.vcxproj delete mode 100644 src/mod/applications/mod_rss/mod_rss.c delete mode 100644 src/mod/applications/mod_rss/script/news.js diff --git a/.gitignore b/.gitignore index 2d0effae96..1df535d36c 100644 --- a/.gitignore +++ b/.gitignore @@ -145,7 +145,6 @@ Release/ /src/mod/applications/mod_nibblebill/Makefile /src/mod/applications/mod_osp/Makefile /src/mod/applications/mod_osp/Makefile.in -/src/mod/applications/mod_rss/Makefile /src/mod/applications/mod_snipe_hunt/Makefile /src/mod/applications/mod_test/test/Makefile /src/mod/applications/mod_test/test/Makefile.in diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 764bd54daa..c021c7c855 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -79,7 +79,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "autoload_configs", "autoloa conf\vanilla\autoload_configs\logfile.conf.xml = conf\vanilla\autoload_configs\logfile.conf.xml conf\vanilla\autoload_configs\modules.conf.xml = conf\vanilla\autoload_configs\modules.conf.xml conf\vanilla\autoload_configs\openmrcp.conf.xml = conf\vanilla\autoload_configs\openmrcp.conf.xml - conf\vanilla\autoload_configs\rss.conf.xml = conf\vanilla\autoload_configs\rss.conf.xml conf\vanilla\autoload_configs\sofia.conf.xml = conf\vanilla\autoload_configs\sofia.conf.xml conf\vanilla\autoload_configs\switch.conf.xml = conf\vanilla\autoload_configs\switch.conf.xml conf\vanilla\autoload_configs\syslog.conf.xml = conf\vanilla\autoload_configs\syslog.conf.xml @@ -199,8 +198,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_rpc", "src\mod\xml_ {BED7539C-0099-4A14-AD5D-30828F15A171} = {BED7539C-0099-4A14-AD5D-30828F15A171} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_rss", "src\mod\applications\mod_rss\mod_rss.2017.vcxproj", "{B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_conference", "src\mod\applications\mod_conference\mod_conference.2017.vcxproj", "{C24FB505-05D7-4319-8485-7540B44C8603}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_dptools", "src\mod\applications\mod_dptools\mod_dptools.2017.vcxproj", "{B5881A85-FE70-4F64-8607-2CAAE52669C6}" @@ -716,17 +713,6 @@ Global {CBEC7225-0C21-4DA8-978E-1F158F8AD950}.Release|Win32.Build.0 = Release|Win32 {CBEC7225-0C21-4DA8-978E-1F158F8AD950}.Release|x64.ActiveCfg = Release|x64 {CBEC7225-0C21-4DA8-978E-1F158F8AD950}.Release|x64.Build.0 = Release|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.All|Win32.ActiveCfg = Release|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.All|x64.ActiveCfg = Release|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.All|x64.Build.0 = Release|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Debug|Win32.ActiveCfg = Debug|Win32 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Debug|Win32.Build.0 = Debug|Win32 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Debug|x64.ActiveCfg = Debug|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Debug|x64.Build.0 = Debug|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Release|Win32.ActiveCfg = Release|Win32 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Release|Win32.Build.0 = Release|Win32 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Release|x64.ActiveCfg = Release|x64 - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}.Release|x64.Build.0 = Release|x64 {C24FB505-05D7-4319-8485-7540B44C8603}.All|Win32.ActiveCfg = Release|x64 {C24FB505-05D7-4319-8485-7540B44C8603}.All|x64.ActiveCfg = Release|x64 {C24FB505-05D7-4319-8485-7540B44C8603}.All|x64.Build.0 = Release|x64 @@ -2467,7 +2453,6 @@ Global {30A5B29C-983E-4580-9FD0-D647CCDCC7EB} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {1C453396-D912-4213-89FD-9B489162B7B5} = {A7AB4405-FDB7-4853-9FBB-1516B1C3D80A} {CBEC7225-0C21-4DA8-978E-1F158F8AD950} = {F69A4A6B-9360-4EBB-A280-22AA3C455AC5} - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {C24FB505-05D7-4319-8485-7540B44C8603} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {B5881A85-FE70-4F64-8607-2CAAE52669C6} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {05515420-16DE-4E63-BE73-85BE85BA5142} = {9ADF1E48-2F5C-4ED7-A893-596259FABFE0} diff --git a/build/modules.conf.in b/build/modules.conf.in index e3d752bdbb..da1ae46552 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -34,7 +34,6 @@ applications/mod_httapi #applications/mod_prefix #applications/mod_rad_auth #applications/mod_redis -#applications/mod_rss applications/mod_signalwire applications/mod_sms #applications/mod_snapshot diff --git a/build/modules.conf.most b/build/modules.conf.most index 9ab256e24a..18823a0386 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -34,7 +34,6 @@ applications/mod_oreka applications/mod_prefix #applications/mod_rad_auth applications/mod_redis -applications/mod_rss applications/mod_signalwire applications/mod_sms applications/mod_snapshot diff --git a/conf/curl/autoload_configs/rss.conf.xml b/conf/curl/autoload_configs/rss.conf.xml deleted file mode 100644 index f8c4f6d2b4..0000000000 --- a/conf/curl/autoload_configs/rss.conf.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/conf/insideout/autoload_configs/modules.conf.xml b/conf/insideout/autoload_configs/modules.conf.xml index 62d7f31b48..9290d072b5 100755 --- a/conf/insideout/autoload_configs/modules.conf.xml +++ b/conf/insideout/autoload_configs/modules.conf.xml @@ -85,7 +85,6 @@ - diff --git a/conf/insideout/autoload_configs/rss.conf.xml b/conf/insideout/autoload_configs/rss.conf.xml deleted file mode 100644 index f8c4f6d2b4..0000000000 --- a/conf/insideout/autoload_configs/rss.conf.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 8bdf873a76..0c3c99c710 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -120,7 +120,6 @@ - diff --git a/conf/vanilla/autoload_configs/rss.conf.xml b/conf/vanilla/autoload_configs/rss.conf.xml deleted file mode 100644 index f8c4f6d2b4..0000000000 --- a/conf/vanilla/autoload_configs/rss.conf.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/configure.ac b/configure.ac index 89ed163568..4b252ce07b 100755 --- a/configure.ac +++ b/configure.ac @@ -2121,7 +2121,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_rad_auth/Makefile src/mod/applications/mod_random/Makefile src/mod/applications/mod_redis/Makefile - src/mod/applications/mod_rss/Makefile src/mod/applications/mod_skel/Makefile src/mod/applications/mod_signalwire/Makefile src/mod/applications/mod_sms/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index eacc07ce7b..6c0ea0b7b7 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -540,7 +540,6 @@ Recommends: freeswitch-mod-oreka (= \${binary:Version}), freeswitch-mod-pgsql (= \${binary:Version}), freeswitch-mod-redis (= \${binary:Version}), - freeswitch-mod-rss (= \${binary:Version}), freeswitch-mod-sms (= \${binary:Version}), freeswitch-mod-snapshot (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), @@ -624,7 +623,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-pgsql (= \${binary:Version}), freeswitch-mod-png (= \${binary:Version}), freeswitch-mod-redis (= \${binary:Version}), - freeswitch-mod-rss (= \${binary:Version}), freeswitch-mod-signalwire (= \${binary:Version}), freeswitch-mod-shout (= \${binary:Version}), freeswitch-mod-sms (= \${binary:Version}), @@ -849,7 +847,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-pgsql-dbg (= \${binary:Version}), freeswitch-mod-png-dbg (= \${binary:Version}), freeswitch-mod-redis-dbg (= \${binary:Version}), - freeswitch-mod-rss-dbg (= \${binary:Version}), freeswitch-mod-sms-dbg (= \${binary:Version}), freeswitch-mod-snapshot-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index b20538ee1c..d44af60e36 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -178,10 +178,6 @@ Description: Redis limit backend This module provides a mechanism to use Redis as a backend data store. -Module: applications/mod_rss -Description: RSS browser - This module provides an RSS browser. - Module: applications/mod_skel Description: Adds mod_skel Adds mod_skel. diff --git a/freeswitch.spec b/freeswitch.spec index 2c0a001677..1844c37ecf 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -468,15 +468,6 @@ Requires: %{name} = %{version}-%{release} Provides FreeSWITCH mod_redis, access to the redis key value pair db system from FreeSWITCH -%package application-rss -Summary: FreeSWITCH mod_rss -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description application-rss -Provides FreeSWITCH mod_rss, edisrse and read an XML based RSS feed, then read -the entries aloud via a TTS engine - %package application-signalwire Summary: FreeSWITCH mod_signalwire Group: System/Libraries @@ -1191,7 +1182,6 @@ Requires: freeswitch-application-limit Requires: freeswitch-application-memcache Requires: freeswitch-application-nibblebill Requires: freeswitch-application-redis -Requires: freeswitch-application-rss Requires: freeswitch-application-signalwire Requires: freeswitch-application-sms Requires: freeswitch-application-snapshot @@ -1271,7 +1261,7 @@ APPLICATION_MODULES_DE+="applications/mod_esl" APPLICATION_MODULES_FR="applications/mod_fifo applications/mod_fsk applications/mod_fsv applications/mod_hash \ applications/mod_httapi applications/mod_http_cache applications/mod_lcr applications/mod_limit \ applications/mod_memcache applications/mod_mongo applications/mod_nibblebill applications/mod_rad_auth \ - applications/mod_redis applications/mod_rss " + applications/mod_redis " APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot \ applications/mod_spandsp applications/mod_spy \ @@ -1769,7 +1759,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/pre_load_modules.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/presence_map.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/redis.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/rss.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/rtmp.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/shout.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/signalwire.conf.xml @@ -1925,9 +1914,6 @@ fi %files application-redis %{MODINSTDIR}/mod_redis.so* -%files application-rss -%{MODINSTDIR}/mod_rss.so* - %files application-signalwire %{MODINSTDIR}/mod_signalwire.so* diff --git a/src/mod/applications/mod_rss/Makefile.am b/src/mod/applications/mod_rss/Makefile.am deleted file mode 100644 index 718ea0d0eb..0000000000 --- a/src/mod/applications/mod_rss/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_rss - -mod_LTLIBRARIES = mod_rss.la -mod_rss_la_SOURCES = mod_rss.c -mod_rss_la_CFLAGS = $(AM_CFLAGS) -mod_rss_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_rss_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/applications/mod_rss/conf/autoload_configs/rss.conf.xml b/src/mod/applications/mod_rss/conf/autoload_configs/rss.conf.xml deleted file mode 100644 index f8c4f6d2b4..0000000000 --- a/src/mod/applications/mod_rss/conf/autoload_configs/rss.conf.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/mod/applications/mod_rss/conf/dialplan/rss.xml b/src/mod/applications/mod_rss/conf/dialplan/rss.xml deleted file mode 100644 index 3cd2b17567..0000000000 --- a/src/mod/applications/mod_rss/conf/dialplan/rss.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/mod/applications/mod_rss/mod_rss.2017.vcxproj b/src/mod/applications/mod_rss/mod_rss.2017.vcxproj deleted file mode 100644 index 5e121057c2..0000000000 --- a/src/mod/applications/mod_rss/mod_rss.2017.vcxproj +++ /dev/null @@ -1,141 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_rss - {B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4} - mod_rss - Win32Proj - - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) - - - - - false - - - - - - - X64 - - - WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) - - - - - false - - - MachineX64 - - - - - - - - - false - - - - - - - X64 - - - - - - - false - - - MachineX64 - - - - - - - - {f6c55d93-b927-4483-bb69-15aef3dd2dff} - false - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - - - - \ No newline at end of file diff --git a/src/mod/applications/mod_rss/mod_rss.c b/src/mod/applications/mod_rss/mod_rss.c deleted file mode 100644 index 16cd35412b..0000000000 --- a/src/mod/applications/mod_rss/mod_rss.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Bret McDanel - * - * - * mod_rss.c -- RSS Browser - * - */ -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_rss_load); -SWITCH_MODULE_DEFINITION(mod_rss, mod_rss_load, NULL, NULL); - -typedef enum { - SFLAG_INSTRUCT = (1 << 0), - SFLAG_INFO = (1 << 1), - SFLAG_MAIN = (1 << 2) -} SFLAGS; - -/* helper object */ -struct dtmf_buffer { - int32_t index; - uint32_t flags; - int32_t speed; - char voice[80]; - switch_speech_handle_t *sh; -}; - -#define TTS_MEAN_SPEED 170 -#define TTS_MAX_ENTRIES 99 -#define TTS_DEFAULT_ENGINE "flite" -#define TTS_DEFAULT_VOICE "slt" - -#define MATCH_COUNT - -struct rss_entry { - uint8_t inuse; - char *title_txt; - char *description_txt; - char *subject_txt; - char *dept_txt; -}; - -#ifdef MATCH_COUNT -static uint32_t match_count(char *str, uint32_t max) -{ - char tstr[80] = ""; - uint32_t matches = 0, x = 0; - uint32_t len = (uint32_t) strlen(str); - - for (x = 0; x < max; x++) { - switch_snprintf(tstr, sizeof(tstr), "%u", x); - if (!strncasecmp(str, tstr, len)) { - matches++; - } - } - return matches; -} -#endif - - -/* - dtmf handler function you can hook up to be executed when a digit is dialed during playback - if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. -*/ -static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) -{ - switch (itype) { - case SWITCH_INPUT_TYPE_DTMF:{ - switch_dtmf_t *dtmf = (switch_dtmf_t *) input; - struct dtmf_buffer *dtb; - dtb = (struct dtmf_buffer *) buf; - - switch (dtmf->digit) { - case '#': - switch_set_flag(dtb, SFLAG_MAIN); - return SWITCH_STATUS_BREAK; - case '6': - dtb->index++; - return SWITCH_STATUS_BREAK; - case '4': - dtb->index--; - return SWITCH_STATUS_BREAK; - case '*': - if (switch_test_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE)) { - switch_clear_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE); - } else { - switch_set_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE); - } - break; - case '5': - switch_core_speech_text_param_tts(dtb->sh, "voice", "next"); - switch_set_flag(dtb, SFLAG_INFO); - return SWITCH_STATUS_BREAK; - case '9': - switch_core_speech_text_param_tts(dtb->sh, "voice", dtb->voice); - switch_set_flag(dtb, SFLAG_INFO); - return SWITCH_STATUS_BREAK; - case '2': - if (dtb->speed < 260) { - dtb->speed += 30; - switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed); - switch_set_flag(dtb, SFLAG_INFO); - return SWITCH_STATUS_BREAK; - } - break; - case '7': - dtb->speed = TTS_MEAN_SPEED; - switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed); - switch_set_flag(dtb, SFLAG_INFO); - return SWITCH_STATUS_BREAK; - case '8': - if (dtb->speed > 80) { - dtb->speed -= 30; - switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed); - switch_set_flag(dtb, SFLAG_INFO); - return SWITCH_STATUS_BREAK; - } - break; - case '0': - switch_set_flag(dtb, SFLAG_INSTRUCT); - return SWITCH_STATUS_BREAK; - } - } - break; - default: - break; - } - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_APP(rss_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status; - const char *err = NULL; - struct dtmf_buffer dtb = { 0 }; - switch_xml_t xml = NULL, item, xchannel = NULL; - struct rss_entry entries[TTS_MAX_ENTRIES] = { {0} }; - uint32_t i = 0; - char *title_txt = "", *description_txt = "", *rights_txt = ""; - switch_codec_t speech_codec; - char *engine = TTS_DEFAULT_ENGINE; - char *voice = TTS_DEFAULT_VOICE; - char *timer_name = NULL; - switch_speech_handle_t sh; - switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; - switch_timer_t timer = { 0 }, *timerp = NULL; - uint32_t last; - char *mydata = NULL; - char *filename = NULL; - char *argv[3], *feed_list[TTS_MAX_ENTRIES] = { 0 }, *feed_names[TTS_MAX_ENTRIES] = { - 0}; - int feed_index = 0; - const char *cf = "rss.conf"; - switch_xml_t cfg, cxml, feeds, feed; - char buf[1024] = ""; - int32_t jumpto = -1; - uint32_t matches = 0; - switch_input_args_t args = { 0 }; - const char *vcf = NULL; - char *chanvars = switch_channel_build_param_string(channel, NULL, NULL); - switch_codec_implementation_t read_impl = { 0 }; - uint32_t rate, interval, channels; - switch_core_session_get_read_impl(session, &read_impl); - interval = read_impl.microseconds_per_packet / 1000; - - if ((vcf = switch_channel_get_variable(channel, "rss_alt_config"))) { - cf = vcf; - } - - if (!(cxml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of %s failed\n", cf); - return; - } - switch_safe_free(chanvars); - - if ((feeds = switch_xml_child(cfg, "feeds"))) { - for (feed = switch_xml_child(feeds, "feed"); feed; feed = feed->next) { - char *name = (char *) switch_xml_attr_soft(feed, "name"); - char *expanded = NULL; - char *idx = feed->txt; - - if ((expanded = switch_channel_expand_variables(channel, idx)) == idx) { - expanded = NULL; - } else { - idx = expanded; - } - - if (!name) { - name = "Error No Name."; - } - - feed_list[feed_index] = switch_core_session_strdup(session, idx); - switch_safe_free(expanded); - - if ((expanded = switch_channel_expand_variables(channel, name)) == name) { - expanded = NULL; - } else { - name = expanded; - } - feed_names[feed_index] = switch_core_session_strdup(session, name); - switch_safe_free(expanded); - feed_index++; - - } - } - - switch_xml_free(cxml); - - switch_channel_answer(channel); - - if (!zstr(data)) { - if ((mydata = switch_core_session_strdup(session, data))) { - switch_separate_string(mydata, ' ', argv, sizeof(argv) / sizeof(argv[0])); - - if (argv[0]) { - engine = argv[0]; - if (argv[1]) { - voice = argv[1]; - if (argv[2]) { - jumpto = atoi(argv[2]); - } - } - } - } - } - - if (!feed_index) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No Feeds Specified!\n"); - return; - } - - if (switch_channel_media_ready(channel)) { - rate = read_impl.actual_samples_per_second; - channels = read_impl.number_of_channels; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Codec Error!\n"); - return; - } - - memset(&sh, 0, sizeof(sh)); - if (switch_core_speech_open(&sh, engine, voice, rate, interval, channels, &flags, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid TTS module!\n"); - return; - } - - if (switch_core_codec_init(&speech_codec, - "L16", - NULL, - NULL, - (int) rate, - interval, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, - switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", rate, interval); - flags = 0; - switch_core_speech_close(&sh, &flags); - return; - } - - if (timer_name) { - if (switch_core_timer_init(&timer, timer_name, interval, (int) (rate / 50), switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n"); - switch_core_codec_destroy(&speech_codec); - flags = 0; - switch_core_speech_close(&sh, &flags); - return; - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", (rate / 50) * 2, interval); - - /* start a thread to absorb incoming audio */ - switch_core_service_session(session); - timerp = &timer; - } - - while (switch_channel_ready(channel)) { - int32_t len = 0, idx = 0; - char cmd[3]; - main_menu: - filename = NULL; - len = 0; - *cmd = '\0'; - title_txt = description_txt = rights_txt = ""; - - if (jumpto > -1) { - switch_snprintf(cmd, sizeof(cmd), "%d", jumpto); - jumpto = -1; - } else { - switch_core_speech_flush_tts(&sh); - switch_ivr_sleep(session, 500, SWITCH_FALSE, NULL); - -#ifdef MATCH_COUNT - switch_snprintf(buf + len, sizeof(buf) - len, "%s", - ", Main Menu." - "Select one of the following news sources, or press 0 to exit. "); -#else - switch_snprintf(buf + len, sizeof(buf) - len, "%s", - ",Main Menu. " - "Select one of the following news sources, followed by the pound key or press 0 to exit. "); -#endif - len = (int32_t) strlen(buf); - - for (idx = 0; idx < feed_index; idx++) { - switch_snprintf(buf + len, sizeof(buf) - len, "%d: %s. />", idx + 1, feed_names[idx]); - len = (int32_t) strlen(buf); - } - - args.input_callback = NULL; - args.buf = cmd; - args.buflen = sizeof(cmd); - status = switch_ivr_speak_text_handle(session, &sh, &speech_codec, timerp, buf, &args); - if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { - goto finished; - } - } - if (*cmd != '\0') { - int32_t x; - char *p; - - if (strchr(cmd, '0')) { - break; - } - - if ((p = strchr(cmd, '#'))) { - *p = '\0'; -#ifdef MATCH_COUNT - /* Hmmm... I know there are no more matches so I don't *need* them to press pound but - I already told them to press it. Will this confuse people or not? Let's make em press - pound unless this define is enabled for now. - */ - } else if (match_count(cmd, feed_index) > 1) { -#else - } else { -#endif - char term; - char *cp; - switch_size_t blen = sizeof(cmd) - strlen(cmd); - - cp = cmd + blen; - switch_ivr_collect_digits_count(session, cp, blen, blen, "#", &term, 5000, 0, 0); - } - - x = atoi(cmd) - 1; - - if (x > -1 && x < feed_index) { - filename = feed_list[x]; - } else if (matches > 1) { - - } else { - args.input_callback = NULL; - args.buf = NULL; - args.buflen = 0; - status = switch_ivr_speak_text_handle(session, &sh, &speech_codec, timerp, "I'm sorry. That is an Invalid Selection. ", &args); - if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { - goto finished; - } - } - } - - if (!filename) { - continue; - } - - if (!(xml = switch_xml_parse_file(filename))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of %s failed\n", filename); - goto finished; - } - - err = switch_xml_error(xml); - - if (!zstr(err)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Error [%s]\n", err); - goto finished; - } - - if ((xchannel = switch_xml_child(xml, "channel"))) { - switch_xml_t title, description, rights; - - if ((title = switch_xml_child(xchannel, "title"))) { - title_txt = title->txt; - } - - if ((description = switch_xml_child(xchannel, "description"))) { - description_txt = description->txt; - } - - if ((rights = switch_xml_child(xchannel, "dc:rights"))) { - rights_txt = rights->txt; - } - } - - - if (!(item = switch_xml_child(xml, "item"))) { - if (xchannel) { - item = switch_xml_child(xchannel, "item"); - } - } - - memset(entries, 0, sizeof(entries)); - - for (i = 0; item; item = item->next) { - switch_xml_t title, description, subject, dept; - char *p; - - entries[i].inuse = 1; - entries[i].title_txt = NULL; - entries[i].description_txt = NULL; - entries[i].subject_txt = NULL; - entries[i].dept_txt = NULL; - - if ((title = switch_xml_child(item, "title"))) { - entries[i].title_txt = title->txt; - } - - if ((description = switch_xml_child(item, "description"))) { - char *t, *e; - entries[i].description_txt = description->txt; - for (;;) { - if (!(t = strchr(entries[i].description_txt, '<'))) { - break; - } - if (!(e = strchr(t, '>'))) { - break; - } - - memset(t, 32, ++e - t); - } - } - - if ((subject = switch_xml_child(item, "dc:subject"))) { - entries[i].subject_txt = subject->txt; - } - - if ((dept = switch_xml_child(item, "slash:department"))) { - entries[i].dept_txt = dept->txt; - } - - if (entries[i].description_txt && (p = strchr(entries[i].description_txt, '<'))) { - *p = '\0'; - } -#ifdef _STRIP_SOME_CHARS_ - for (p = entries[i].description_txt; *p; p++) { - if (*p == '\'' || *p == '"' || *p == ':') { - *p = ' '; - } - } -#endif - i++; - } - - if (switch_channel_ready(channel)) { - switch_time_exp_t tm; - char date[80] = ""; - switch_size_t retsize; - char dtmf[5] = ""; - - switch_time_exp_lt(&tm, switch_micro_time_now()); - switch_strftime_nocheck(date, &retsize, sizeof(date), "%I:%M %p", &tm); - - switch_ivr_sleep(session, 500, SWITCH_FALSE, NULL); - - switch_snprintf(buf, sizeof(buf), - ",%s. %s. %s. local time: %s, Press 0 for options, 5 to change voice, or pound to return to the main menu. ", - title_txt, description_txt, rights_txt, date); - args.input_callback = NULL; - args.buf = dtmf; - args.buflen = sizeof(dtmf); - status = switch_ivr_speak_text_handle(session, &sh, &speech_codec, timerp, buf, &args); - if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { - goto finished; - } - if (*dtmf != '\0') { - switch (*dtmf) { - case '0': - switch_set_flag(&dtb, SFLAG_INSTRUCT); - break; - case '#': - goto main_menu; - } - } - } - - for (last = 0; last < TTS_MAX_ENTRIES; last++) { - if (!entries[last].inuse) { - last--; - break; - } - } - - dtb.index = 0; - dtb.sh = &sh; - dtb.speed = TTS_MEAN_SPEED; - //switch_set_flag(&dtb, SFLAG_INFO); - switch_copy_string(dtb.voice, voice, sizeof(dtb.voice)); - while (entries[0].inuse && switch_channel_ready(channel)) { - while (switch_channel_ready(channel)) { - uint8_t cont = 0; - - if (dtb.index >= TTS_MAX_ENTRIES) { - dtb.index = 0; - } - if (dtb.index < 0) { - dtb.index = last; - } - - if (!entries[dtb.index].inuse) { - dtb.index = 0; - continue; - } - if (switch_channel_ready(channel)) { - char tmpbuf[1024] = ""; - uint32_t tmplen = 0; - - if (switch_test_flag(&dtb, SFLAG_MAIN)) { - switch_clear_flag(&dtb, SFLAG_MAIN); - goto main_menu; - } - if (switch_test_flag(&dtb, SFLAG_INFO)) { - switch_clear_flag(&dtb, SFLAG_INFO); - switch_snprintf(tmpbuf + tmplen, sizeof(tmpbuf) - tmplen, "%s %s. I am speaking at %u words per minute. ", sh.engine, sh.voice, - dtb.speed); - tmplen = (uint32_t) strlen(tmpbuf); - } - - if (switch_test_flag(&dtb, SFLAG_INSTRUCT)) { - switch_clear_flag(&dtb, SFLAG_INSTRUCT); - cont = 1; - switch_snprintf(tmpbuf + tmplen, sizeof(tmpbuf) - tmplen, "%s", - "Press star to pause or resume speech. " - "To go to the next item, press six. " - "To go back, press 4. " - "Press two to go faster, eight to slow down, or 7 to resume normal speed. " - "To change voices, press five. To restore the original voice press 9. " - "To hear these options again, press zero or press pound to return to the main menu. "); - } else { - switch_snprintf(tmpbuf + tmplen, sizeof(tmpbuf) - tmplen, "Story %d. ", dtb.index + 1); - tmplen = (uint32_t) strlen(tmpbuf); - - if (entries[dtb.index].subject_txt) { - switch_snprintf(tmpbuf + tmplen, sizeof(tmpbuf) - tmplen, "Subject: %s. ", entries[dtb.index].subject_txt); - tmplen = (uint32_t) strlen(tmpbuf); - } - - if (entries[dtb.index].dept_txt) { - switch_snprintf(tmpbuf + tmplen, sizeof(tmpbuf) - tmplen, "From the %s department. ", entries[dtb.index].dept_txt); - tmplen = (uint32_t) strlen(tmpbuf); - } - - if (entries[dtb.index].title_txt) { - switch_snprintf(tmpbuf + tmplen, sizeof(tmpbuf) - tmplen, "%s", entries[dtb.index].title_txt); - } - } - switch_core_speech_flush_tts(&sh); - args.input_callback = on_dtmf; - args.buf = &dtb; - args.buflen = sizeof(dtb); - status = switch_ivr_speak_text_handle(session, &sh, &speech_codec, timerp, tmpbuf, &args); - if (status == SWITCH_STATUS_BREAK) { - continue; - } else if (status != SWITCH_STATUS_SUCCESS) { - goto finished; - } - - if (cont) { - continue; - } - - if (entries[dtb.index].description_txt) { - args.input_callback = on_dtmf; - args.buf = &dtb; - args.buflen = sizeof(dtb); - status = switch_ivr_speak_text_handle(session, &sh, &speech_codec, timerp, entries[dtb.index].description_txt, &args); - } - if (status == SWITCH_STATUS_BREAK) { - continue; - } else if (status != SWITCH_STATUS_SUCCESS) { - goto finished; - } - } - - dtb.index++; - } - } - } - - finished: - switch_core_speech_close(&sh, &flags); - switch_core_codec_destroy(&speech_codec); - - if (timerp) { - /* End the audio absorbing thread */ - switch_core_thread_session_end(session); - switch_core_timer_destroy(&timer); - } - - switch_xml_free(xml); - switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); -} - - -SWITCH_MODULE_LOAD_FUNCTION(mod_rss_load) -{ - switch_application_interface_t *app_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - SWITCH_ADD_APP(app_interface, "rss", NULL, NULL, rss_function, NULL, SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/applications/mod_rss/script/news.js b/src/mod/applications/mod_rss/script/news.js deleted file mode 100644 index d6dea0dc29..0000000000 --- a/src/mod/applications/mod_rss/script/news.js +++ /dev/null @@ -1,12 +0,0 @@ -if (session.ready()) { - session.answer(); - session.speak("cepstral","David","Please wait while we refresh the RSS feeds.") - - fetchURLFile("http://weather.yahooapis.com/forecastrss?p=60610","rss/weather.rss"); - fetchURLFile("http://rss.news.yahoo.com/rss/topstories","rss/yahootop.rss"); - fetchURLFile("http://rss.news.yahoo.com/rss/science","rss/yahoosci.rss"); - fetchURLFile("http://rss.news.yahoo.com/rss/business","rss/yahoobus.rss"); - fetchURLFile("http://rss.news.yahoo.com/rss/entertainment","rss/yahooent.rss"); - fetchURLFile("http://rss.slashdot.org/Slashdot/slashdot","rss/slashdot.rss"); - fetchURLFile("http://www.freeswitch.org/xml.php","rss/freeswitch.rss"); -} diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index 0dfef658bb..fe6522bbc1 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -289,14 +289,6 @@ Binaries;Content;Satellites INSTALLFOLDER - - mod_rss - {b69247fa-ecd6-40ed-8e44-5ca6c3baf9a4} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_signalwire {b19ae6fc-bfff-428d-b483-3bbeaeccc618} From e9023d124c2e6c23090b23099783b9913c09cfa5 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 5 Dec 2024 23:58:16 +0300 Subject: [PATCH 196/205] [mod_raven] Remove from tree --- build/modules.conf.in | 1 - configure.ac | 1 - debian/bootstrap.sh | 3 - src/mod/loggers/mod_raven/Makefile.am | 8 - .../conf/autoload_configs/raven.conf.xml | 11 - src/mod/loggers/mod_raven/mod_raven.c | 320 ------------------ 6 files changed, 344 deletions(-) delete mode 100644 src/mod/loggers/mod_raven/Makefile.am delete mode 100644 src/mod/loggers/mod_raven/conf/autoload_configs/raven.conf.xml delete mode 100644 src/mod/loggers/mod_raven/mod_raven.c diff --git a/build/modules.conf.in b/build/modules.conf.in index da1ae46552..798984ffc2 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -119,7 +119,6 @@ loggers/mod_console #loggers/mod_graylog2 loggers/mod_logfile loggers/mod_syslog -#loggers/mod_raven #say/mod_say_de say/mod_say_en #say/mod_say_es diff --git a/configure.ac b/configure.ac index 4b252ce07b..be9ce948f8 100755 --- a/configure.ac +++ b/configure.ac @@ -2210,7 +2210,6 @@ AC_CONFIG_FILES([Makefile src/mod/loggers/mod_graylog2/Makefile src/mod/loggers/mod_logfile/Makefile src/mod/loggers/mod_syslog/Makefile - src/mod/loggers/mod_raven/Makefile src/mod/say/mod_say_de/Makefile src/mod/say/mod_say_en/Makefile src/mod/say/mod_say_es/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 6c0ea0b7b7..a21364d3fa 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -81,17 +81,14 @@ avoid_mods_wheezy=( ) avoid_mods_trusty=( event_handlers/mod_amqp - loggers/mod_raven ) avoid_mods_utopic=( directories/mod_ldap - loggers/mod_raven ) avoid_mods_xenial=( event_handlers/mod_ldap event_handlers/mod_amqp asr_tts/mod_flite - loggers/mod_raven ) manual_pkgs=( freeswitch-all diff --git a/src/mod/loggers/mod_raven/Makefile.am b/src/mod/loggers/mod_raven/Makefile.am deleted file mode 100644 index f62beb9081..0000000000 --- a/src/mod/loggers/mod_raven/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_raven - -mod_LTLIBRARIES = mod_raven.la -mod_raven_la_SOURCES = mod_raven.c -mod_raven_la_CFLAGS = $(AM_CFLAGS) -mod_raven_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_raven_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/loggers/mod_raven/conf/autoload_configs/raven.conf.xml b/src/mod/loggers/mod_raven/conf/autoload_configs/raven.conf.xml deleted file mode 100644 index 95125e9e85..0000000000 --- a/src/mod/loggers/mod_raven/conf/autoload_configs/raven.conf.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/mod/loggers/mod_raven/mod_raven.c b/src/mod/loggers/mod_raven/mod_raven.c deleted file mode 100644 index 335294673c..0000000000 --- a/src/mod/loggers/mod_raven/mod_raven.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, James Martelletti - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * James Martelletti - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Tamas Cseke - * - * mod_raven.c -- Raven Logging - * - */ -#include -#include -#include - -#define RAVEN_ZLIB_CHUNK 16384 -#define RAVEN_VERSION "5" -#define RAVEN_UA "freeswitch-raven/1.0" - -SWITCH_MODULE_LOAD_FUNCTION(mod_raven_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_raven_shutdown); -SWITCH_MODULE_DEFINITION(mod_raven, mod_raven_load, mod_raven_shutdown, NULL); - -static switch_status_t load_config(void); - -static struct { - char *uri; - char *key; - char *secret; - char *project; - switch_bool_t log_uuid; - switch_log_level_t log_level; -} globals; - -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_uri, globals.uri); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_key, globals.key); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_secret, globals.secret); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_project, globals.project); - -static switch_loadable_module_interface_t raven_module_interface = { - /*.module_name */ modname, - /*.endpoint_interface */ NULL, - /*.timer_interface */ NULL, - /*.dialplan_interface */ NULL, - /*.codec_interface */ NULL, - /*.application_interface */ NULL, - /*.api_interface */ NULL, - /*.file_interface */ NULL, - /*.speech_interface */ NULL, - /*.directory_interface */ NULL -}; - -static switch_status_t encode(const char *raw, int raw_len, char **encoded_out) -{ - z_stream stream; - unsigned char *encoded = NULL, *compressed = NULL; - int ret; - switch_size_t compressed_size = 0, compressed_len = 0, need_bytes; - - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - ret = deflateInit(&stream, Z_DEFAULT_COMPRESSION); - if (ret != Z_OK) { - return SWITCH_STATUS_FALSE; - } - - stream.next_in = (unsigned char *)raw; - stream.avail_in = raw_len; - - do { - compressed_size += RAVEN_ZLIB_CHUNK; - compressed = realloc(compressed, compressed_size + 1); - switch_assert(compressed != NULL); - - stream.avail_out = compressed_size - compressed_len; - stream.next_out = compressed + compressed_len; - - ret = deflate(&stream, Z_FINISH); - assert(ret != Z_STREAM_ERROR); - compressed_len = compressed_size - stream.avail_out; - } while (stream.avail_in != 0); - - deflateEnd(&stream); - - need_bytes = compressed_len * 3 + 1; - encoded = malloc(need_bytes); - switch_assert(encoded); - memset(encoded, 0, need_bytes); - switch_b64_encode(compressed, compressed_len, encoded, need_bytes); - - switch_safe_free(compressed); - - *encoded_out = (char *)encoded; - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t raven_capture(const char *userdata, const char *message, const char *level, const char *file, const char *func, int line) -{ - cJSON* json, *fingerprint; - char *raw_body; - char *encoded_body = NULL; - switch_time_t timestamp = switch_micro_time_now(); - switch_status_t status = SWITCH_STATUS_SUCCESS; - char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - switch_uuid_str(uuid, sizeof(uuid)); - json = cJSON_CreateObject(); - cJSON_AddStringToObject(json, "event_id", (const char *)uuid); - cJSON_AddNumberToObject(json, "timestamp", timestamp); - cJSON_AddStringToObject(json, "platform", RAVEN_UA); - cJSON_AddStringToObject(json, "project", globals.project); - cJSON_AddStringToObject(json, "server_name", switch_core_get_hostname()); - cJSON_AddStringToObject(json, "level", level); - - if (globals.log_uuid && !zstr(userdata)) { - cJSON_AddItemToObject(json, "message", cJSON_CreateStringPrintf("%s %s", userdata, message)); - } else { - cJSON_AddStringToObject(json, "message", message); - } - - fingerprint = cJSON_CreateArray(); - cJSON_AddItemToArray(fingerprint, cJSON_CreateString(file)); - cJSON_AddItemToArray(fingerprint, cJSON_CreateString(func)); - cJSON_AddItemToArray(fingerprint, cJSON_CreateNumber(line)); - cJSON_AddItemToObject(json, "fingerprint", fingerprint); - - raw_body = cJSON_PrintUnformatted(json); - - if ((status = encode(raw_body, strlen(raw_body), &encoded_body)) == SWITCH_STATUS_SUCCESS) { - int response; - CURL *curl_handle = switch_curl_easy_init(); - switch_curl_slist_t * list = NULL; - char *auth_header = switch_mprintf("X-Sentry-Auth: Sentry sentry_version=%s," - " sentry_client=%s," - " sentry_timestamp=%d," - " sentry_key=%s," - " sentry_secret=%s", - RAVEN_VERSION, RAVEN_UA, - timestamp, globals.key, globals.secret); - - char *url = switch_mprintf( "%s/api/%s/store/", globals.uri, globals.project); - switch_curl_easy_setopt(curl_handle, CURLOPT_URL,url); - switch_curl_easy_setopt(curl_handle, CURLOPT_POST, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, encoded_body); - switch_curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(encoded_body)); - - switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, RAVEN_UA); - - list = switch_curl_slist_append(list, auth_header); - list = switch_curl_slist_append(list, "Content-Type: application/octet-stream"); - switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, list); - - if (!strncasecmp(globals.uri, "https", 5)) { - switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); - switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0); - } - - switch_curl_easy_perform(curl_handle); - switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &response); - - if (response != 200) { - status = SWITCH_STATUS_FALSE; - } - - switch_curl_easy_cleanup(curl_handle); - switch_curl_slist_free_all(list); - switch_safe_free(url); - switch_safe_free(auth_header); - } - - switch_safe_free(raw_body); - switch_safe_free(encoded_body); - cJSON_Delete(json); - - return status; -} - - -static switch_status_t mod_raven_logger(const switch_log_node_t *node, switch_log_level_t level) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (level != SWITCH_LOG_CONSOLE && !zstr(node->data)) { - const char * raven_level; - - switch (level) { - case SWITCH_LOG_DEBUG: - raven_level = "debug"; - break; - case SWITCH_LOG_INFO: - raven_level = "info"; - break; - case SWITCH_LOG_NOTICE: - case SWITCH_LOG_WARNING: - raven_level = "warning"; - break; - case SWITCH_LOG_ERROR: - raven_level = "error"; - break; - case SWITCH_LOG_CRIT: - case SWITCH_LOG_ALERT: - raven_level = "fatal"; - break; - default: - raven_level = "debug"; - break; - } - - status = raven_capture(node->userdata, node->data, raven_level, node->file, node->func, node->line); - } - - return status; -} - -static switch_status_t load_config(void) -{ - char *cf = "raven.conf"; - switch_xml_t cfg, xml, settings, param; - - globals.log_level = SWITCH_LOG_WARNING; - globals.log_uuid = SWITCH_TRUE; - - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); - return SWITCH_STATUS_FALSE; - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcmp(var, "uri")) { - set_global_uri(val); - } else if (!strcmp(var, "key")) { - set_global_key(val); - } else if (!strcmp(var, "secret")) { - set_global_secret(val); - } else if (!strcmp(var, "project")) { - set_global_project(val); - } else if (!strcasecmp(var, "loglevel") && !zstr(val)) { - globals.log_level = switch_log_str2level(val); - if (globals.log_level == SWITCH_LOG_INVALID) { - globals.log_level = SWITCH_LOG_WARNING; - } - } else if (!strcasecmp(var, "uuid")) { - globals.log_uuid = switch_true(val); - } - } - } - switch_xml_free(xml); - - if (zstr(globals.uri) || zstr(globals.project) || zstr(globals.key) || zstr(globals.secret)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing parameter\n"); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_raven_load) -{ - switch_status_t status; - *module_interface = &raven_module_interface; - - memset(&globals, 0, sizeof(globals)); - - if ((status = load_config()) != SWITCH_STATUS_SUCCESS) { - return status; - } - - switch_log_bind_logger(mod_raven_logger, globals.log_level, SWITCH_FALSE); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_raven_shutdown) -{ - switch_safe_free(globals.uri); - switch_safe_free(globals.key); - switch_safe_free(globals.secret); - switch_safe_free(globals.project); - - switch_log_unbind_logger(mod_raven_logger); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ From 94df749a610edf8b6d2aae4783424fc77ad7f97c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 12 Dec 2024 01:01:12 +0300 Subject: [PATCH 197/205] [mod_radius_cdr] Remove from tree --- LICENSE | 4 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 1 - debian/control-modules | 4 - debian/copyright | 4 - freeswitch.spec | 13 +- .../event_handlers/mod_radius_cdr/Makefile.am | 30 - src/mod/event_handlers/mod_radius_cdr/README | 98 -- .../mod_radius_cdr/mod_radius_cdr.c | 892 ------------------ .../mod_radius_cdr/mod_radius_cdr.conf.xml | 35 - .../mod_radius_cdr/mod_radius_cdr.h | 65 -- .../mod_radius_cdr/radius/dictionary | 353 ------- 13 files changed, 1 insertion(+), 1500 deletions(-) delete mode 100644 src/mod/event_handlers/mod_radius_cdr/Makefile.am delete mode 100644 src/mod/event_handlers/mod_radius_cdr/README delete mode 100644 src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c delete mode 100644 src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.conf.xml delete mode 100644 src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h delete mode 100644 src/mod/event_handlers/mod_radius_cdr/radius/dictionary diff --git a/LICENSE b/LICENSE index 4465d2d0ca..e3c1b831e3 100644 --- a/LICENSE +++ b/LICENSE @@ -1321,10 +1321,6 @@ Files: src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.[ch] Copyright: 1999, 2000, 2002 Aladdin Enterprises. License: zlib/libpng -Files: src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h -Copyright: 2006, Author: Yossi Neiman of Cartis Solutions, Inc. -License: MPL-1.1 - Files: src/mod/say/mod_say_??/mod_say_??.c scripts/c/socket2me/socket2me.c src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl diff --git a/build/modules.conf.in b/build/modules.conf.in index 798984ffc2..08f1711c37 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -91,7 +91,6 @@ event_handlers/mod_event_socket #event_handlers/mod_fail2ban #event_handlers/mod_format_cdr #event_handlers/mod_json_cdr -#event_handlers/mod_radius_cdr #event_handlers/mod_odbc_cdr #event_handlers/mod_smpp #event_handlers/mod_snmp diff --git a/build/modules.conf.most b/build/modules.conf.most index 18823a0386..e53d58b9ec 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -89,7 +89,6 @@ event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_format_cdr event_handlers/mod_json_cdr -#event_handlers/mod_radius_cdr event_handlers/mod_odbc_cdr event_handlers/mod_snmp #event_handlers/mod_event_zmq diff --git a/configure.ac b/configure.ac index be9ce948f8..b71e691434 100755 --- a/configure.ac +++ b/configure.ac @@ -2182,7 +2182,6 @@ AC_CONFIG_FILES([Makefile src/mod/event_handlers/mod_fail2ban/Makefile src/mod/event_handlers/mod_format_cdr/Makefile src/mod/event_handlers/mod_json_cdr/Makefile - src/mod/event_handlers/mod_radius_cdr/Makefile src/mod/event_handlers/mod_odbc_cdr/Makefile src/mod/event_handlers/mod_smpp/Makefile src/mod/event_handlers/mod_snmp/Makefile diff --git a/debian/control-modules b/debian/control-modules index d44af60e36..4522649527 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -468,10 +468,6 @@ Module: event_handlers/mod_odbc_cdr Description: mod_odbc_cdr Adds mod_odbc_cdr. -Module: event_handlers/mod_radius_cdr -Description: mod_radius_cdr - Adds mod_radius_cdr. - Module: event_handlers/mod_smpp Description: mod_snmp Adds mod_snmp. diff --git a/debian/copyright b/debian/copyright index deedd66566..61669a3e06 100755 --- a/debian/copyright +++ b/debian/copyright @@ -1321,10 +1321,6 @@ Files: src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.[ch] Copyright: 1999, 2000, 2002 Aladdin Enterprises. License: zlib/libpng -Files: src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h -Copyright: 2006, Author: Yossi Neiman of Cartis Solutions, Inc. -License: MPL-1.1 - Files: src/mod/say/mod_say_??/mod_say_??.c scripts/c/socket2me/socket2me.c src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl diff --git a/freeswitch.spec b/freeswitch.spec index 1844c37ecf..5d02a33adb 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -871,14 +871,6 @@ Requires: %{name} = %{version}-%{release} %description event-json-cdr JSON CDR Logger for FreeSWITCH. -%package event-radius-cdr -Summary: RADIUS Logger for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description event-radius-cdr -RADIUS Logger for the FreeSWITCH open source telephony platform - %package event-snmp Summary: SNMP stats reporter for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1326,7 +1318,7 @@ ENDPOINTS_MODULES=" \ ###################################################################################################################### EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_sqlite \ event_handlers/mod_cdr_mongodb event_handlers/mod_format_cdr event_handlers/mod_erlang_event event_handlers/mod_event_multicast \ - event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_radius_cdr \ + event_handlers/mod_event_socket event_handlers/mod_json_cdr \ event_handlers/mod_snmp" #### BUILD ISSUES NET RESOLVED FOR RELEASE event_handlers/mod_event_zmq @@ -2075,9 +2067,6 @@ fi %files event-json-cdr %{MODINSTDIR}/mod_json_cdr.so* -%files event-radius-cdr -%{MODINSTDIR}/mod_radius_cdr.so* - %files event-snmp %{MODINSTDIR}/mod_snmp.so* diff --git a/src/mod/event_handlers/mod_radius_cdr/Makefile.am b/src/mod/event_handlers/mod_radius_cdr/Makefile.am deleted file mode 100644 index b8a09eebdc..0000000000 --- a/src/mod/event_handlers/mod_radius_cdr/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_radius_cdr - -RADCLIENT_VERSION=1.1.7 -RADCLIENT=freeradius-client-$(RADCLIENT_VERSION) -RADCLIENT_DIR=$(switch_srcdir)/libs/$(RADCLIENT) -RADCLIENT_BUILDDIR=$(switch_builddir)/libs/$(RADCLIENT) -RADCLIENT_LIBDIR=$(RADCLIENT_BUILDDIR)/lib -RADCLIENT_LA=${RADCLIENT_LIBDIR}/libfreeradius-client.la - -mod_LTLIBRARIES = mod_radius_cdr.la -mod_radius_cdr_la_SOURCES = mod_radius_cdr.c -mod_radius_cdr_la_CFLAGS = $(AM_CFLAGS) -I$(RADCLIENT_DIR)/include -mod_radius_cdr_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(RADCLIENT_LA) -mod_radius_cdr_la_LDFLAGS = -avoid-version -module -no-undefined -shared -BUILT_SOURCES=$(RADCLIENT_LA) - -$(RADCLIENT_DIR): - $(GETLIB) $(RADCLIENT).tar.gz - -$(RADCLIENT_BUILDDIR)/Makefile: $(RADCLIENT_DIR) - mkdir -p $(RADCLIENT_BUILDDIR) - cd $(RADCLIENT_BUILDDIR) && $(DEFAULT_VARS) $(RADCLIENT_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(RADCLIENT_DIR) - $(TOUCH_TARGET) - -$(RADCLIENT_LA): $(RADCLIENT_BUILDDIR)/Makefile - cd $(RADCLIENT_BUILDDIR) && CFLAGS="$(CFLAGS)" $(MAKE) - $(TOUCH_TARGET) - - diff --git a/src/mod/event_handlers/mod_radius_cdr/README b/src/mod/event_handlers/mod_radius_cdr/README deleted file mode 100644 index 1734d6b8fa..0000000000 --- a/src/mod/event_handlers/mod_radius_cdr/README +++ /dev/null @@ -1,98 +0,0 @@ -mod_radius_cdr - A cdr Accounting module for FreeSWITCH. - -cparker at segv dot org - -========================================================================================= - -Currently, this is in it's infancy, and is still being worked on. It is not -yet enabled by default in building. - -Comments, code, patches are always welcome. :) - -========================================================================================= - -Pre-reqs: - -In order to use this module you will need to have the CVS head of the freeradius-client -library installed. - -CVS version as of June 14, 2007 or later will be sufficient. - -Instructions on how to retrieve and install this can be found here: - - http://wiki.freeradius.org/Radiusclient - -========================================================================================= - -Building: - -1) Compile and install freeradius-client library. - -2) Edit the top level 'configure.in'. At approx line 336 you need to add: - ---- -AC_CONFIG_FILES([Makefile - src/Makefile - src/mod/Makefile - src/mod/event_handlers/mod_cdr/Makefile -+ src/mod/event_handlers/mod_radius_cdr/Makefile - src/mod/endpoints/mod_sofia/Makefile - src/include/switch_am_config.h - build/getlib.sh - build/modmake.rules]) ---- - -3) Rerun bootstrap, re-run configure - -4) Edit the top-level 'modules.conf'. Add the following entry: - -... -event_handlers/mod_radius_cdr -... - -5) Run make, and make install. Make sure the module is built and installed. - -6) Configure FreeSWITCH to load mod_radius_cdr - - - Copy the 'mod_radius_cdr.conf.xml' file to the FreeSWITCH conf directory - - Copy the 'radius/' directory to the FreeSWITCH conf directory - - Edit 'conf/modules.conf' to load mod_radius_cdr - - Edit 'conf/freeswitch.xml' to include 'mod_radius_cdr.conf.xml' - -========================================================================================= - -Here's a sample RADIUS transaction ( logged to a detail file via FreeRADIUS server ): - -Fri Jun 8 08:23:10 2007 - Acct-Status-Type = Start - Acct-Session-Id = "d734ff5e-bf04-4045-8cb3-f5744574808b" - Freeswitch-Src = "8478797989" - Freeswitch-CLID = "Chris Parker" - Freeswitch-Dst = "888" - Freeswitch-Dialplan = "XML" - NAS-Port = 0 - Acct-Delay-Time = 0 - NAS-IP-Address = 127.0.0.1 - Client-IP-Address = 127.0.0.1 - Acct-Unique-Session-Id = "4b7754541b5902fa" - Timestamp = 1181308990 - -Fri Jun 8 08:23:31 2007 - Acct-Status-Type = Stop - Acct-Session-Id = "d734ff5e-bf04-4045-8cb3-f5744574808b" - Freeswitch-Hangupcause = Normal-Clearing - Freeswitch-Src = "8478797989" - Freeswitch-CLID = "Chris Parker" - Freeswitch-Dst = "888" - Freeswitch-Dialplan = "XML" - Freeswitch-Lastapp = "bridge" - Freeswitch-Billusec = 21460442 - NAS-Port = 0 - Acct-Delay-Time = 0 - NAS-IP-Address = 127.0.0.1 - Client-IP-Address = 127.0.0.1 - Acct-Unique-Session-Id = "4b7754541b5902fa" - Timestamp = 1181309011 - - - diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c deleted file mode 100644 index 153ec6252d..0000000000 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Chris Parker - * Mathieu Rene - * - * - * mod_radius_cdr.c -- RADIUS CDR Module - * - */ - -#include -#include -#include -#include "mod_radius_cdr.h" - -SWITCH_MODULE_LOAD_FUNCTION(mod_radius_cdr_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_radius_cdr_shutdown); -SWITCH_MODULE_DEFINITION(mod_radius_cdr, mod_radius_cdr_load, mod_radius_cdr_shutdown, NULL); - -static struct { - int shutdown; - switch_thread_rwlock_t *rwlock; -} globals = { -0}; - -static char cf[] = "mod_radius_cdr.conf"; -static char my_dictionary[PATH_MAX]; -static char my_seqfile[PATH_MAX]; -static char *my_deadtime; /* 0 */ -static char *my_timeout; /* 5 */ -static char *my_retries; /* 3 */ -static char my_servers[SERVER_MAX][255]; -static const char *my_timezone=""; /* Asia/Tokyo */ - -static rc_handle *my_radius_init(void) -{ - int i = 0; - rc_handle *rad_config; - - rad_config = rc_new(); - - if (rad_config == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing rc_handle!\n"); - return NULL; - } - - rad_config = rc_config_init(rad_config); - - if (rad_config == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error initializing radius config!\n"); - rc_destroy(rad_config); - return NULL; - } - - /* Some hardcoded ( for now ) defaults needed to initialize radius */ - if (rc_add_config(rad_config, "auth_order", "radius", "mod_radius_cdr.c", 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting auth_order = radius failed\n"); - rc_destroy(rad_config); - return NULL; - } - - if (rc_add_config(rad_config, "seqfile", my_seqfile, "mod_radius_cdr.c", 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting seqfile = %s failed\n", my_seqfile); - rc_destroy(rad_config); - return NULL; - } - - - /* Add the module configs to initialize rad_config */ - - for (i = 0; i < SERVER_MAX && my_servers[i][0] != '\0'; i++) { - if (rc_add_config(rad_config, "acctserver", my_servers[i], cf, 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting acctserver = %s failed\n", my_servers[i]); - rc_destroy(rad_config); - return NULL; - } - } - - if (rc_add_config(rad_config, "dictionary", my_dictionary, cf, 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed setting dictionary = %s failed\n", my_dictionary); - rc_destroy(rad_config); - return NULL; - } - - if (rc_add_config(rad_config, "radius_deadtime", my_deadtime, cf, 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting radius_deadtime = %s failed\n", my_deadtime); - rc_destroy(rad_config); - return NULL; - } - - if (rc_add_config(rad_config, "radius_timeout", my_timeout, cf, 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting radius_timeout = %s failed\n", my_timeout); - rc_destroy(rad_config); - return NULL; - } - - if (rc_add_config(rad_config, "radius_retries", my_retries, cf, 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting radius_retries = %s failed\n", my_retries); - rc_destroy(rad_config); - return NULL; - } - - /* Read the dictionary file(s) */ - if (rc_read_dictionary(rad_config, rc_conf_str(rad_config, "dictionary")) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "reading dictionary file(s): %s\n", my_dictionary); - rc_destroy(rad_config); - return NULL; - } - - return rad_config; -} - -static switch_status_t my_on_routing(switch_core_session_t *session) -{ - switch_xml_t cdr = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - rc_handle *rad_config; - switch_status_t retval = SWITCH_STATUS_TERM; - VALUE_PAIR *send = NULL; - uint32_t client_port = 0; - uint32_t framed_addr = 0; - uint32_t status_type = PW_STATUS_START; - switch_time_t callstartdate = 0; - switch_time_t callanswerdate = 0; - switch_time_t callenddate = 0; - switch_time_t calltransferdate = 0; - const char *signal_bond = NULL; - - char *uuid_str; - - switch_time_exp_t tm; - switch_time_exp_t requested_tm; - char buffer[32]; - - char *radius_avpair_data; - char *delim; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_routing\n"); - - if (globals.shutdown) { - return SWITCH_STATUS_FALSE; - } - - if (channel) { - const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_start"); - - if (switch_true(disable_flag)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Start\n"); - - return SWITCH_STATUS_SUCCESS; - } - } - - switch_thread_rwlock_rdlock(globals.rwlock); - - rad_config = my_radius_init(); - - if (rad_config == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, Start packet not logged.\n"); - goto end; - } - - if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { - uuid_str = switch_core_session_get_uuid(session); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); - goto end; - } - - /* GMT offset may change according daylight saving rules. Evaluating GMT offset each time */ - if (zstr(my_timezone)) { - switch_time_exp_lt(&requested_tm, switch_micro_time_now()); - } else { - switch_time_exp_tz_name(my_timezone, &requested_tm, switch_micro_time_now()); - } - - /* Create the radius packet */ - - /* Set Status Type */ - if (rc_avpair_add(rad_config, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed setting Acct-Status-Type: Start\n"); - rc_destroy(rad_config); - goto end; - } - - if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_ID, uuid_str, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed adding Acct-Session-ID: %s\n", uuid_str); - rc_destroy(rad_config); - goto end; - } - - /* Add VSAs */ - - if (channel) { - /*switch_call_cause_t cause; */ - switch_caller_profile_t *profile; - const char *radius_avpair = switch_channel_get_variable(channel, "radius_avpair"); - - /* - cause = switch_channel_get_cause(channel); - if (rc_avpair_add(rad_config, &send, PW_FS_HANGUPCAUSE, &cause, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); - rc_destroy(rad_config); - return SWITCH_STATUS_TERM; - } - */ - - if ((signal_bond = switch_channel_get_partner_uuid(channel)) && !zstr(signal_bond)) { - if (rc_avpair_add(rad_config, &send, PW_FS_OTHER_LEG_ID, (void*) signal_bond, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed adding Freeswitch-Other-Leg-Id: %s\n", uuid_str); - rc_destroy(rad_config); - goto end; - } - } - - profile = switch_channel_get_caller_profile(channel); - - if (profile) { - - callstartdate = profile->times->created; - callanswerdate = profile->times->answered; - calltransferdate = profile->times->transferred; - callenddate = profile->times->hungup; - - if (profile->username) { - if (rc_avpair_add(rad_config, &send, PW_USER_NAME, (void *) profile->username, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->caller_id_number) { - if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->caller_id_name) { - if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->destination_number) { - if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->dialplan) { - if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->network_addr) { - inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr); - framed_addr = htonl(framed_addr); - if (rc_avpair_add(rad_config, &send, PW_FRAMED_IP_ADDRESS, &framed_addr, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->rdnis) { - if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->context) { - if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->ani) { - if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->aniii) { - if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->source) { - if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); - rc_destroy(rad_config); - goto end; - } - } - - if (callstartdate > 0) { - switch_time_exp_tz(&tm, callstartdate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLSTARTDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (callanswerdate > 0) { - switch_time_exp_tz(&tm, callanswerdate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLANSWERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (calltransferdate > 0) { - switch_time_exp_tz(&tm, calltransferdate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLTRANSFERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (callenddate > 0) { - switch_time_exp_tz(&tm, callenddate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLENDDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) { - if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP, - (void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); - rc_destroy(rad_config); - goto end; - } - } - - if (radius_avpair) { - char *radius_avpair_data_tmp = NULL; - - radius_avpair_data = strdup(radius_avpair + (strncmp(radius_avpair, "ARRAY::", 7) ? 0 : 7)); - radius_avpair_data_tmp = radius_avpair_data; - - do { - delim = strstr(radius_avpair_data_tmp, "|:"); - - if (delim) { - *delim = '\0'; - } - - if (rc_avpair_add(rad_config, &send, PW_FS_AVPAIR, (void *)radius_avpair_data_tmp, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-AVPair: %s\n", radius_avpair_data_tmp); - rc_destroy(rad_config); - switch_safe_free(radius_avpair_data); - goto end; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "added Freeswitch-AVPair: %s\n", radius_avpair_data_tmp); - - if (delim) { - radius_avpair_data_tmp = delim + 2; - } - } while (delim); - - switch_safe_free(radius_avpair_data); - } - - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "profile == NULL\n"); - } - } - - if (rc_acct(rad_config, client_port, send) == OK_RC) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] RADIUS Accounting OK\n"); - retval = SWITCH_STATUS_SUCCESS; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] RADIUS Accounting Failed\n"); - retval = SWITCH_STATUS_TERM; - } - - rc_avpair_free(send); - rc_destroy(rad_config); - end: - switch_xml_free(cdr); - switch_thread_rwlock_unlock(globals.rwlock); - - return (retval); -} - -static switch_status_t my_on_reporting(switch_core_session_t *session) -{ - switch_xml_t cdr = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - rc_handle *rad_config; - switch_status_t retval = SWITCH_STATUS_TERM; - VALUE_PAIR *send = NULL; - uint32_t client_port = 0; - uint32_t framed_addr = 0; - uint32_t status_type = PW_STATUS_STOP; - switch_time_t callstartdate = 0; - switch_time_t callanswerdate = 0; - switch_time_t callenddate = 0; - switch_time_t calltransferdate = 0; - switch_time_t billusec = 0; - uint32_t billsec = 0; - char *uuid_str; - - switch_time_exp_t tm; - switch_time_exp_t requested_tm; - - char buffer[32] = ""; - - char *radius_avpair_data; - char *delim; - - if (globals.shutdown) { - return SWITCH_STATUS_FALSE; - } - - - if (channel) { - const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_stop"); - if (switch_true(disable_flag)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Stop\n"); - return SWITCH_STATUS_SUCCESS; - } - } - - switch_thread_rwlock_rdlock(globals.rwlock); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_reporting\n"); - - rad_config = my_radius_init(); - - if (rad_config == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, session not logged.\n"); - goto end; - } - - if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { - uuid_str = switch_core_session_get_uuid(session); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); - goto end; - } - - /* GMT offset may change according daylight saving rules. Evaluating GMT offset each time */ - if (zstr(my_timezone)) { - switch_time_exp_lt(&requested_tm, time(NULL)); - } else { - switch_time_exp_tz_name(my_timezone, &requested_tm, time(NULL)); - } - - /* Create the radius packet */ - - /* Set Status Type */ - if (rc_avpair_add(rad_config, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); - rc_destroy(rad_config); - goto end; - } - - if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_ID, uuid_str, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); - rc_destroy(rad_config); - goto end; - } - - /* Add VSAs */ - - if (channel) { - switch_call_cause_t cause; - switch_caller_profile_t *profile; - const char *radius_avpair = switch_channel_get_variable(channel, "radius_avpair"); - - cause = switch_channel_get_cause(channel); - if (rc_avpair_add(rad_config, &send, PW_FS_HANGUPCAUSE, &cause, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); - rc_destroy(rad_config); - goto end; - } - - profile = switch_channel_get_caller_profile(channel); - - if (profile) { - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Calculating billable time\n"); - - /* calculate billable time */ - callstartdate = profile->times->created; - callanswerdate = profile->times->answered; - calltransferdate = profile->times->transferred; - callenddate = profile->times->hungup; - - if (switch_channel_test_flag(channel, CF_ANSWERED)) { - if (callstartdate && callanswerdate) { - if (callenddate) - billusec = callenddate - callanswerdate; - else if (calltransferdate) - billusec = calltransferdate - callanswerdate; - } - } else if (switch_channel_test_flag(channel, CF_TRANSFER)) { - if (callanswerdate && calltransferdate) - billusec = calltransferdate - callanswerdate; - } - billsec = (billusec / 1000000); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Finished calculating billable time\n"); - - if (profile->username) { - if (rc_avpair_add(rad_config, &send, PW_USER_NAME, (void *) profile->username, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); - rc_destroy(rad_config); - goto end; - } - } - if (profile->caller_id_number) { - if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); - rc_destroy(rad_config); - goto end; - } - } - if (profile->caller_id_name) { - if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); - rc_destroy(rad_config); - goto end; - } - } - if (profile->destination_number) { - if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); - rc_destroy(rad_config); - goto end; - } - } - if (profile->dialplan) { - if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); - rc_destroy(rad_config); - goto end; - } - } - if (profile->network_addr) { - inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr); - framed_addr = htonl(framed_addr); - if (rc_avpair_add(rad_config, &send, PW_FRAMED_IP_ADDRESS, &framed_addr, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); - rc_destroy(rad_config); - goto end; - } - } - if (profile->rdnis) { - if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); - rc_destroy(rad_config); - goto end; - } - } - if (profile->context) { - if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); - rc_destroy(rad_config); - goto end; - } - } - if (profile->ani) { - if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); - rc_destroy(rad_config); - goto end; - } - } - if (profile->aniii) { - if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); - rc_destroy(rad_config); - goto end; - } - } - if (profile->source) { - if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); - rc_destroy(rad_config); - goto end; - } - } - if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) { - if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP, - (void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); - rc_destroy(rad_config); - goto end; - } - } - if (rc_avpair_add(rad_config, &send, PW_FS_BILLUSEC, &billusec, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Billusec: %u\n", (uint32_t) billusec); - rc_destroy(rad_config); - goto end; - } - - if (callstartdate > 0) { - switch_time_exp_tz(&tm, callstartdate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLSTARTDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (callanswerdate > 0) { - switch_time_exp_tz(&tm, callanswerdate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLANSWERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (calltransferdate > 0) { - switch_time_exp_tz(&tm, calltransferdate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLTRANSFERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (callenddate > 0) { - switch_time_exp_tz(&tm, callenddate, requested_tm.tm_gmtoff); - switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - if (rc_avpair_add(rad_config, &send, PW_FS_CALLENDDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); - rc_destroy(rad_config); - goto end; - } - } - - if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_TIME, &billsec, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-Time: %u\n", billsec); - rc_destroy(rad_config); - goto end; - } - - { - const char *direction_str = profile->direction == SWITCH_CALL_DIRECTION_INBOUND ? "inbound" : "outbound"; - - if (rc_avpair_add(rad_config, &send, PW_FS_DIRECTION, (void *) direction_str, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Direction: %s\n", direction_str); - rc_destroy(rad_config); - goto end; - } - } - - if (radius_avpair) { - radius_avpair_data = strdup(radius_avpair + (strncmp(radius_avpair, "ARRAY::", 7) ? 0 : 7)); - do { - delim = strstr(radius_avpair_data, "|:"); - - if (delim) { - *delim = '\0'; - } - - if (rc_avpair_add(rad_config, &send, PW_FS_AVPAIR, (void *) radius_avpair_data, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-AVPair: %s\n", radius_avpair_data); - rc_destroy(rad_config); - goto end; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "added Freeswitch-AVPair: %s\n", radius_avpair_data); - - if (delim) { - radius_avpair_data = delim + 2; - } - } while (delim); - } - - } else { /* no profile, can't create data to send */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "profile == NULL\n"); - } - } - - if (rc_acct(rad_config, client_port, send) == OK_RC) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RADIUS Accounting OK\n"); - retval = SWITCH_STATUS_SUCCESS; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RADIUS Accounting Failed\n"); - retval = SWITCH_STATUS_TERM; - } - rc_avpair_free(send); - rc_destroy(rad_config); - - end: - switch_xml_free(cdr); - switch_thread_rwlock_unlock(globals.rwlock); - return (retval); -} - -static switch_status_t load_config(void) -{ - switch_xml_t cfg, xml, settings, param; - - int num_servers = 0; - int i = 0; - static char *tz_name; - - my_timeout = "5"; - my_retries = "3"; - my_deadtime = "0"; - strncpy(my_seqfile, "/var/run/radius.seq", PATH_MAX - 1); - strncpy(my_dictionary, "/usr/local/freeswitch/conf/radius/dictionary", PATH_MAX - 1); - - for (i = 0; i < SERVER_MAX; i++) { - my_servers[i][0] = '\0'; - } - - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); - return SWITCH_STATUS_TERM; - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcmp(var, "acctserver")) { - if (num_servers < SERVER_MAX) { - strncpy(my_servers[num_servers], val, 255 - 1); - num_servers++; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "you can only specify %d radius servers, ignoring excess server entry\n", SERVER_MAX); - } - } else if (!strcmp(var, "dictionary")) { - strncpy(my_dictionary, val, PATH_MAX - 1); - } else if (!strcmp(var, "seqfile")) { - strncpy(my_seqfile, val, PATH_MAX - 1); - } else if (!strcmp(var, "radius_timeout")) { - my_timeout = strdup(val); - } else if (!strcmp(var, "radius_retries")) { - my_retries = strdup(val); - } else if (!strcmp(var, "radius_deadtime")) { - my_deadtime = strdup(val); - } else if (!strcmp(var, "timezone")) { - tz_name = strdup(val); - } - } - } - - switch_xml_free(xml); - - if (num_servers < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you must specify at least 1 radius server\n"); - return SWITCH_STATUS_TERM; - } - - if (!zstr(tz_name)) { - if (switch_lookup_timezone(tz_name)) { - my_timezone= tz_name; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find timezone %s\n, Setting timezone to GMT", tz_name); - my_timezone= "GMT"; - } - } - - /* If we made it this far, we succeeded */ - return SWITCH_STATUS_SUCCESS; -} - -static const switch_state_handler_table_t state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ my_on_routing, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ my_on_reporting -}; - -SWITCH_MODULE_LOAD_FUNCTION(mod_radius_cdr_load) -{ - - switch_thread_rwlock_create(&globals.rwlock, pool); - - if (load_config() != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - - /* test global state handlers */ - switch_core_add_state_handler(&state_handlers); - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_radius_cdr_shutdown) -{ - - globals.shutdown = 1; - switch_core_remove_state_handler(&state_handlers); - switch_thread_rwlock_wrlock(globals.rwlock); - switch_thread_rwlock_unlock(globals.rwlock); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.conf.xml b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.conf.xml deleted file mode 100644 index fea5194b81..0000000000 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.conf.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h deleted file mode 100644 index 0257f61303..0000000000 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application Call Detail Recorder module - * Copyright 2006, Author: Yossi Neiman of Cartis Solutions, Inc. - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application Call Detail Recorder module - * - * The Initial Developer of the Original Code is - * Chris Parker - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Chris Parker - * - * Description: Contains definitions and structs used by the radius cdr module. - * - * mod_radius_cdr.h - * - */ - -#ifndef MODRADIUSCDR -#define MODRADIUSCDR - -#define PW_FS_PEC 27880 - -#define PW_FS_AVPAIR 1 -#define PW_FS_CLID 2 -#define PW_FS_DIALPLAN 3 -#define PW_FS_SRC 4 -#define PW_FS_DST 5 -#define PW_FS_SRC_CHANNEL 6 -#define PW_FS_DST_CHANNEL 7 -#define PW_FS_ANI 8 -#define PW_FS_ANIII 9 -#define PW_FS_LASTAPP 10 -#define PW_FS_LASTDATA 11 -#define PW_FS_DISPOSITION 12 -#define PW_FS_HANGUPCAUSE 13 -#define PW_FS_BILLUSEC 15 -#define PW_FS_AMAFLAGS 16 -#define PW_FS_RDNIS 17 -#define PW_FS_CONTEXT 18 -#define PW_FS_SOURCE 19 -#define PW_FS_CALLSTARTDATE 20 -#define PW_FS_CALLANSWERDATE 21 -#define PW_FS_CALLTRANSFERDATE 22 -#define PW_FS_CALLENDDATE 23 -#define PW_FS_DIRECTION 24 -#define PW_FS_OTHER_LEG_ID 25 - - -#endif diff --git a/src/mod/event_handlers/mod_radius_cdr/radius/dictionary b/src/mod/event_handlers/mod_radius_cdr/radius/dictionary deleted file mode 100644 index c126e685d4..0000000000 --- a/src/mod/event_handlers/mod_radius_cdr/radius/dictionary +++ /dev/null @@ -1,353 +0,0 @@ -# -# Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl -# -# This file contains dictionary translations for parsing -# requests and generating responses. All transactions are -# composed of Attribute/Value Pairs. The value of each attribute -# is specified as one of 4 data types. Valid data types are: -# -# string - 0-253 octets -# ipaddr - 4 octets in network byte order -# integer - 32 bit value in big endian order (high byte first) -# date - 32 bit value in big endian order - seconds since -# 00:00:00 GMT, Jan. 1, 1970 -# -# Enumerated values are stored in the user file with dictionary -# VALUE translations for easy administration. -# -# Example: -# -# ATTRIBUTE VALUE -# --------------- ----- -# Framed-Protocol = PPP -# 7 = 1 (integer encoding) -# - -# -# Following are the proper new names. Use these. -# -ATTRIBUTE User-Name 1 string -ATTRIBUTE Password 2 string -ATTRIBUTE CHAP-Password 3 string -ATTRIBUTE NAS-IP-Address 4 ipaddr -ATTRIBUTE NAS-Port-Id 5 integer -ATTRIBUTE Service-Type 6 integer -ATTRIBUTE Framed-Protocol 7 integer -ATTRIBUTE Framed-IP-Address 8 ipaddr -ATTRIBUTE Framed-IP-Netmask 9 ipaddr -ATTRIBUTE Framed-Routing 10 integer -ATTRIBUTE Filter-Id 11 string -ATTRIBUTE Framed-MTU 12 integer -ATTRIBUTE Framed-Compression 13 integer -ATTRIBUTE Login-IP-Host 14 ipaddr -ATTRIBUTE Login-Service 15 integer -ATTRIBUTE Login-TCP-Port 16 integer -ATTRIBUTE Reply-Message 18 string -ATTRIBUTE Callback-Number 19 string -ATTRIBUTE Callback-Id 20 string -ATTRIBUTE Framed-Route 22 string -ATTRIBUTE Framed-IPX-Network 23 ipaddr -ATTRIBUTE State 24 string -ATTRIBUTE Class 25 string -ATTRIBUTE Vendor-Specific 26 string -ATTRIBUTE Session-Timeout 27 integer -ATTRIBUTE Idle-Timeout 28 integer -ATTRIBUTE Termination-Action 29 integer -ATTRIBUTE Called-Station-Id 30 string -ATTRIBUTE Calling-Station-Id 31 string -ATTRIBUTE NAS-Identifier 32 string -ATTRIBUTE Proxy-State 33 string -ATTRIBUTE Login-LAT-Service 34 string -ATTRIBUTE Login-LAT-Node 35 string -ATTRIBUTE Login-LAT-Group 36 string -ATTRIBUTE Framed-AppleTalk-Link 37 integer -ATTRIBUTE Framed-AppleTalk-Network 38 integer -ATTRIBUTE Framed-AppleTalk-Zone 39 string -ATTRIBUTE Acct-Status-Type 40 integer -ATTRIBUTE Acct-Delay-Time 41 integer -ATTRIBUTE Acct-Input-Octets 42 integer -ATTRIBUTE Acct-Output-Octets 43 integer -ATTRIBUTE Acct-Session-Id 44 string -ATTRIBUTE Acct-Authentic 45 integer -ATTRIBUTE Acct-Session-Time 46 integer -ATTRIBUTE Acct-Input-Packets 47 integer -ATTRIBUTE Acct-Output-Packets 48 integer -ATTRIBUTE Acct-Terminate-Cause 49 integer -ATTRIBUTE Acct-Multi-Session-Id 50 string -ATTRIBUTE Acct-Link-Count 51 integer -ATTRIBUTE Event-Timestamp 55 integer -ATTRIBUTE CHAP-Challenge 60 string -ATTRIBUTE NAS-Port-Type 61 integer -ATTRIBUTE Port-Limit 62 integer -ATTRIBUTE Login-LAT-Port 63 integer -ATTRIBUTE Connect-Info 77 string - -# -# RFC3162 IPv6 attributes -# -ATTRIBUTE NAS-IPv6-Address 95 string -ATTRIBUTE Framed-Interface-Id 96 string -ATTRIBUTE Framed-IPv6-Prefix 97 string -ATTRIBUTE Login-IPv6-Host 98 string -ATTRIBUTE Framed-IPv6-Route 99 string -ATTRIBUTE Framed-IPv6-Pool 100 string - -# -# Experimental Non Protocol Attributes used by Cistron-Radiusd -# -ATTRIBUTE Huntgroup-Name 221 string -ATTRIBUTE User-Category 1029 string -ATTRIBUTE Group-Name 1030 string -ATTRIBUTE Simultaneous-Use 1034 integer -ATTRIBUTE Strip-User-Name 1035 integer -ATTRIBUTE Fall-Through 1036 integer -ATTRIBUTE Add-Port-To-IP-Address 1037 integer -ATTRIBUTE Exec-Program 1038 string -ATTRIBUTE Exec-Program-Wait 1039 string -ATTRIBUTE Hint 1040 string - -# -# Non-Protocol Attributes -# These attributes are used internally by the server -# -ATTRIBUTE Expiration 21 date -ATTRIBUTE Auth-Type 1000 integer -ATTRIBUTE Menu 1001 string -ATTRIBUTE Termination-Menu 1002 string -ATTRIBUTE Prefix 1003 string -ATTRIBUTE Suffix 1004 string -ATTRIBUTE Group 1005 string -ATTRIBUTE Crypt-Password 1006 string -ATTRIBUTE Connect-Rate 1007 integer - -# -# Integer Translations -# - -# User Types - -VALUE Service-Type Login-User 1 -VALUE Service-Type Framed-User 2 -VALUE Service-Type Callback-Login-User 3 -VALUE Service-Type Callback-Framed-User 4 -VALUE Service-Type Outbound-User 5 -VALUE Service-Type Administrative-User 6 -VALUE Service-Type NAS-Prompt-User 7 - -# Framed Protocols - -VALUE Framed-Protocol PPP 1 -VALUE Framed-Protocol SLIP 2 - -# Framed Routing Values - -VALUE Framed-Routing None 0 -VALUE Framed-Routing Broadcast 1 -VALUE Framed-Routing Listen 2 -VALUE Framed-Routing Broadcast-Listen 3 - -# Framed Compression Types - -VALUE Framed-Compression None 0 -VALUE Framed-Compression Van-Jacobson-TCP-IP 1 - -# Login Services - -VALUE Login-Service Telnet 0 -VALUE Login-Service Rlogin 1 -VALUE Login-Service TCP-Clear 2 -VALUE Login-Service PortMaster 3 - -# Status Types - -VALUE Acct-Status-Type Start 1 -VALUE Acct-Status-Type Stop 2 -VALUE Acct-Status-Type Alive 3 -VALUE Acct-Status-Type Accounting-On 7 -VALUE Acct-Status-Type Accounting-Off 8 - -# Authentication Types - -VALUE Acct-Authentic RADIUS 1 -VALUE Acct-Authentic Local 2 -VALUE Acct-Authentic PowerLink128 100 - -# Termination Options - -VALUE Termination-Action Default 0 -VALUE Termination-Action RADIUS-Request 1 - -# NAS Port Types, available in 3.3.1 and later - -VALUE NAS-Port-Type Async 0 -VALUE NAS-Port-Type Sync 1 -VALUE NAS-Port-Type ISDN 2 -VALUE NAS-Port-Type ISDN-V120 3 -VALUE NAS-Port-Type ISDN-V110 4 - -# Acct Terminate Causes, available in 3.3.2 and later - -VALUE Acct-Terminate-Cause User-Request 1 -VALUE Acct-Terminate-Cause Lost-Carrier 2 -VALUE Acct-Terminate-Cause Lost-Service 3 -VALUE Acct-Terminate-Cause Idle-Timeout 4 -VALUE Acct-Terminate-Cause Session-Timeout 5 -VALUE Acct-Terminate-Cause Admin-Reset 6 -VALUE Acct-Terminate-Cause Admin-Reboot 7 -VALUE Acct-Terminate-Cause Port-Error 8 -VALUE Acct-Terminate-Cause NAS-Error 9 -VALUE Acct-Terminate-Cause NAS-Request 10 -VALUE Acct-Terminate-Cause NAS-Reboot 11 -VALUE Acct-Terminate-Cause Port-Unneeded 12 -VALUE Acct-Terminate-Cause Port-Preempted 13 -VALUE Acct-Terminate-Cause Port-Suspended 14 -VALUE Acct-Terminate-Cause Service-Unavailable 15 -VALUE Acct-Terminate-Cause Callback 16 -VALUE Acct-Terminate-Cause User-Error 17 -VALUE Acct-Terminate-Cause Host-Request 18 - -# -# Non-Protocol Integer Translations -# - -VALUE Auth-Type Local 0 -VALUE Auth-Type System 1 -VALUE Auth-Type SecurID 2 -VALUE Auth-Type Crypt-Local 3 -VALUE Auth-Type Reject 4 - -# -# Cistron extensions -# -VALUE Auth-Type Pam 253 -VALUE Auth-Type Accept 254 - -# -# Experimental Non-Protocol Integer Translations for Cistron-Radiusd -# -VALUE Fall-Through No 0 -VALUE Fall-Through Yes 1 -VALUE Add-Port-To-IP-Address No 0 -VALUE Add-Port-To-IP-Address Yes 1 - -# -# Configuration Values -# uncomment these two lines to turn account expiration on -# - -#VALUE Server-Config Password-Expiration 30 -#VALUE Server-Config Password-Warning 5 - -# -*- text -*- -# -# dictionary.freeswitch -# -# cparker@segv.org -# -# Version: $Id: $ -# - -VENDOR Freeswitch 27880 - -# -# Standard attribute -# -BEGIN-VENDOR Freeswitch - -ATTRIBUTE Freeswitch-AVPair 1 string Freeswitch -ATTRIBUTE Freeswitch-CLID 2 string Freeswitch -ATTRIBUTE Freeswitch-Dialplan 3 string Freeswitch -ATTRIBUTE Freeswitch-Src 4 string Freeswitch -ATTRIBUTE Freeswitch-Dst 5 string Freeswitch -ATTRIBUTE Freeswitch-Src-Channel 6 string Freeswitch -ATTRIBUTE Freeswitch-Dst-Channel 7 string Freeswitch -ATTRIBUTE Freeswitch-Ani 8 string Freeswitch -ATTRIBUTE Freeswitch-Aniii 9 string Freeswitch -ATTRIBUTE Freeswitch-Lastapp 10 string Freeswitch -ATTRIBUTE Freeswitch-Lastdata 11 string Freeswitch -ATTRIBUTE Freeswitch-Disposition 12 string Freeswitch -ATTRIBUTE Freeswitch-Hangupcause 13 integer Freeswitch -ATTRIBUTE Freeswitch-Billusec 15 integer Freeswitch -ATTRIBUTE Freeswitch-AMAFlags 16 integer Freeswitch -ATTRIBUTE Freeswitch-RDNIS 17 string Freeswitch -ATTRIBUTE Freeswitch-Context 18 string Freeswitch -ATTRIBUTE Freeswitch-Source 19 string Freeswitch -ATTRIBUTE Freeswitch-Callstartdate 20 string Freeswitch -ATTRIBUTE Freeswitch-Callanswerdate 21 string Freeswitch -ATTRIBUTE Freeswitch-Calltransferdate 22 string Freeswitch -ATTRIBUTE Freeswitch-Callenddate 23 string Freeswitch -ATTRIBUTE Freeswitch-Direction 24 string Freeswitch -ATTRIBUTE Freeswitch-Other-Leg-Id 25 string Freeswitch - -# -# Freeswitch-Hangupcause -# -VALUE Freeswitch-Hangupcause None 0 -VALUE Freeswitch-Hangupcause Unallocated-Number 1 -VALUE Freeswitch-Hangupcause No-Route-Transit-Net 2 -VALUE Freeswitch-Hangupcause No-Route-Destination 3 -VALUE Freeswitch-Hangupcause Channel-Unacceptable 6 -VALUE Freeswitch-Hangupcause Call-Awarded-Delivery 7 -VALUE Freeswitch-Hangupcause Normal-Clearing 16 -VALUE Freeswitch-Hangupcause User-Busy 17 -VALUE Freeswitch-Hangupcause No-User-Response 18 -VALUE Freeswitch-Hangupcause No-Answer 19 -VALUE Freeswitch-Hangupcause Subscriber-Absent 20 -VALUE Freeswitch-Hangupcause Call-Rejected 21 -VALUE Freeswitch-Hangupcause Number-Changed 22 -VALUE Freeswitch-Hangupcause Redirecto-To-New-Destination 23 -VALUE Freeswitch-Hangupcause Exchange-Routing-Error 25 -VALUE Freeswitch-Hangupcause Destination-Out-Of-Order 27 -VALUE Freeswitch-Hangupcause Invalid-Number-Format 28 -VALUE Freeswitch-Hangupcause Facility-Rejected 29 -VALUE Freeswitch-Hangupcause Response-To-Status-Enquiry 30 -VALUE Freeswitch-Hangupcause Normal-Unspecified 31 -VALUE Freeswitch-Hangupcause Normal-Circuit-Congestion 34 -VALUE Freeswitch-Hangupcause Network-Out-Of-Order 38 -VALUE Freeswitch-Hangupcause Normal-Temporary-Failure 41 -VALUE Freeswitch-Hangupcause Switch-Congestion 42 -VALUE Freeswitch-Hangupcause Access-Info-Discarded 43 -VALUE Freeswitch-Hangupcause Requested-Chan-Unavail 44 -VALUE Freeswitch-Hangupcause Pre-Empted 45 -VALUE Freeswitch-Hangupcause Facility-Not-Subscribed 50 -VALUE Freeswitch-Hangupcause Outgoing-Call-Barred 52 -VALUE Freeswitch-Hangupcause Incoming-Call-Barred 54 -VALUE Freeswitch-Hangupcause Bearercapability-Notauth 57 -VALUE Freeswitch-Hangupcause Bearercapability-Notavail 58 -VALUE Freeswitch-Hangupcause Service-Unavailable 63 -VALUE Freeswitch-Hangupcause Bearercapability-Notimpl 65 -VALUE Freeswitch-Hangupcause Chan-Not-Implemented 66 -VALUE Freeswitch-Hangupcause Facility-Not-Implemented 69 -VALUE Freeswitch-Hangupcause Service-Not-Implemented 79 -VALUE Freeswitch-Hangupcause Invalid-Call-Reference 81 -VALUE Freeswitch-Hangupcause Incompatible-Destination 88 -VALUE Freeswitch-Hangupcause Invalid-Msg-Unspecified 95 -VALUE Freeswitch-Hangupcause Mandatory-IE-Missing 96 -VALUE Freeswitch-Hangupcause Message-Type-Nonexist 97 -VALUE Freeswitch-Hangupcause Wrong-Message 98 -VALUE Freeswitch-Hangupcause IE-Nonexist 99 -VALUE Freeswitch-Hangupcause Invalid-IE-Contents 100 -VALUE Freeswitch-Hangupcause Wrong-Call-State 101 -VALUE Freeswitch-Hangupcause Recovery-On-Timer-Expire 102 -VALUE Freeswitch-Hangupcause Mandatory-IE-Length-Error 103 -VALUE Freeswitch-Hangupcause Protocol-Error 111 -VALUE Freeswitch-Hangupcause Interworking 127 -VALUE Freeswitch-Hangupcause Success 142 -VALUE Freeswitch-Hangupcause Originator-Cancel 487 -VALUE Freeswitch-Hangupcause Crash 500 -VALUE Freeswitch-Hangupcause System-Shutdown 501 -VALUE Freeswitch-Hangupcause Lose-Race 502 -VALUE Freeswitch-Hangupcause Manager-Request 503 -VALUE Freeswitch-Hangupcause Blind-Transfer 600 -VALUE Freeswitch-Hangupcause Attended-Transfer 601 -VALUE Freeswitch-Hangupcause Allotted-Timeout 602 -VALUE Freeswitch-Hangupcause User-Challenge 603 -VALUE Freeswitch-Hangupcause Media-Timeout 604 -VALUE Freeswitch-Hangupcause Picked-Off 605 -VALUE Freeswitch-Hangupcause User-Not-Registered 606 - -# -# -# - -END-VENDOR Freeswitch From 285df0b0262de79dc29ca3f0fc919e76831e84ec Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 12 Dec 2024 13:52:55 +0300 Subject: [PATCH 198/205] [mod_xml_radius] Remove from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - .../vanilla/autoload_configs/modules.conf.xml | 1 - configure.ac | 1 - debian/bootstrap.sh | 1 - debian/control-modules | 4 - src/mod/xml_int/mod_xml_radius/.gitignore | 1 - .../mod_xml_radius/00_dialplan_auth.xml | 27 - src/mod/xml_int/mod_xml_radius/Makefile.am | 31 - src/mod/xml_int/mod_xml_radius/config.c.diff | 50 - .../mod_xml_radius/dictionaries/dictionary | 244 ---- .../dictionaries/dictionary.cisco | 161 --- .../dictionaries/dictionary.rfc5090 | 27 - .../xml_int/mod_xml_radius/mod_xml_radius.c | 1237 ----------------- .../mod_xml_radius/xml_radius.conf.xml | 167 --- 15 files changed, 1954 deletions(-) delete mode 100644 src/mod/xml_int/mod_xml_radius/.gitignore delete mode 100644 src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml delete mode 100644 src/mod/xml_int/mod_xml_radius/Makefile.am delete mode 100644 src/mod/xml_int/mod_xml_radius/config.c.diff delete mode 100644 src/mod/xml_int/mod_xml_radius/dictionaries/dictionary delete mode 100644 src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.cisco delete mode 100644 src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.rfc5090 delete mode 100644 src/mod/xml_int/mod_xml_radius/mod_xml_radius.c delete mode 100644 src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml diff --git a/build/modules.conf.in b/build/modules.conf.in index 08f1711c37..8a0a687199 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -141,7 +141,6 @@ say/mod_say_en xml_int/mod_xml_cdr #xml_int/mod_xml_curl #xml_int/mod_xml_ldap -#xml_int/mod_xml_radius xml_int/mod_xml_rpc xml_int/mod_xml_scgi diff --git a/build/modules.conf.most b/build/modules.conf.most index e53d58b9ec..93327ff7c2 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -136,6 +136,5 @@ timers/mod_timerfd xml_int/mod_xml_cdr xml_int/mod_xml_curl xml_int/mod_xml_ldap -#xml_int/mod_xml_radius xml_int/mod_xml_rpc xml_int/mod_xml_scgi diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 0c3c99c710..8f7fa9285f 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -16,7 +16,6 @@ - diff --git a/configure.ac b/configure.ac index b71e691434..ac4fdca0b5 100755 --- a/configure.ac +++ b/configure.ac @@ -2232,7 +2232,6 @@ AC_CONFIG_FILES([Makefile src/mod/xml_int/mod_xml_cdr/Makefile src/mod/xml_int/mod_xml_curl/Makefile src/mod/xml_int/mod_xml_ldap/Makefile - src/mod/xml_int/mod_xml_radius/Makefile src/mod/xml_int/mod_xml_rpc/Makefile src/mod/xml_int/mod_xml_scgi/Makefile src/mod/applications/mod_av/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index a21364d3fa..cf7ac11a69 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -52,7 +52,6 @@ avoid_mods=( formats/mod_webm sdk/autotools xml_int/mod_xml_ldap - xml_int/mod_xml_radius ) avoid_mods_armhf=( languages/mod_v8 diff --git a/debian/control-modules b/debian/control-modules index 4522649527..c63a93e7d2 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -706,10 +706,6 @@ Description: mod_xml_ldap Adds mod_xml_ldap. Build-Depends: libldap2-dev, libsasl2-dev -Module: xml_int/mod_xml_radius -Description: mod_xml_radius - Adds mod_xml_radius - Module: xml_int/mod_xml_rpc Description: mod_xml_rpc Adds mod_xml_rpc. diff --git a/src/mod/xml_int/mod_xml_radius/.gitignore b/src/mod/xml_int/mod_xml_radius/.gitignore deleted file mode 100644 index bb7ad3d288..0000000000 --- a/src/mod/xml_int/mod_xml_radius/.gitignore +++ /dev/null @@ -1 +0,0 @@ -freeradius-client* \ No newline at end of file diff --git a/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml b/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml deleted file mode 100644 index 2e17abbfdd..0000000000 --- a/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/xml_int/mod_xml_radius/Makefile.am b/src/mod/xml_int/mod_xml_radius/Makefile.am deleted file mode 100644 index bfac0040c1..0000000000 --- a/src/mod/xml_int/mod_xml_radius/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_xml_radius - -RADCLIENT_VERSION=1.1.7 -RADCLIENT=freeradius-client-$(RADCLIENT_VERSION) -RADCLIENT_DIR=$(switch_srcdir)/libs/$(RADCLIENT) -RADCLIENT_BUILDDIR=$(switch_builddir)/libs/$(RADCLIENT) -RADCLIENT_LIBDIR=$(RADCLIENT_BUILDDIR)/lib -RADCLIENT_LA=${RADCLIENT_LIBDIR}/libfreeradius-client.la - -mod_LTLIBRARIES = mod_xml_radius.la -mod_xml_radius_la_SOURCES = mod_xml_radius.c -mod_xml_radius_la_CFLAGS = $(AM_CFLAGS) -I$(RADCLIENT_DIR)/include -mod_xml_radius_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(RADCLIENT_LA) -mod_xml_radius_la_LDFLAGS = -avoid-version -module -no-undefined -shared - -BUILT_SOURCES=$(RADCLIENT_LA) - -$(RADCLIENT_DIR): - $(GETLIB) $(RADCLIENT).tar.gz - -$(RADCLIENT_BUILDDIR)/Makefile: $(RADCLIENT_DIR) - mkdir -p $(RADCLIENT_BUILDDIR) - cd $(RADCLIENT_BUILDDIR) && $(DEFAULT_VARS) $(RADCLIENT_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(RADCLIENT_DIR) - $(TOUCH_TARGET) - -$(RADCLIENT_LA): $(RADCLIENT_BUILDDIR)/Makefile - cd $(RADCLIENT_BUILDDIR) && CFLAGS="$(CFLAGS)" $(MAKE) - $(TOUCH_TARGET) - - diff --git a/src/mod/xml_int/mod_xml_radius/config.c.diff b/src/mod/xml_int/mod_xml_radius/config.c.diff deleted file mode 100644 index 962c1e5844..0000000000 --- a/src/mod/xml_int/mod_xml_radius/config.c.diff +++ /dev/null @@ -1,50 +0,0 @@ ---- ../../../../libs/freeradius-client-1.1.6/lib/config.c 2012-08-18 22:13:13.000000000 -0700 -+++ ./config.c 2012-08-18 22:14:08.000000000 -0700 -@@ -301,6 +301,8 @@ - int i; - SERVER *authservers; - SERVER *acctservers; -+ OPTION *acct; -+ OPTION *auth; - - rh->config_options = malloc(sizeof(config_options_default)); - if (rh->config_options == NULL) -@@ -311,8 +313,8 @@ - } - memcpy(rh->config_options, &config_options_default, sizeof(config_options_default)); - -- authservers = rc_conf_srv(rh, "authserver"); -- acctservers = rc_conf_srv(rh, "acctserver"); -+ acct = find_option(rh, "acctserver", OT_ANY); -+ auth = find_option(rh, "authserver", OT_ANY); - authservers = malloc(sizeof(SERVER)); - acctservers = malloc(sizeof(SERVER)); - -@@ -334,6 +336,8 @@ - acctservers->name[i] = NULL; - acctservers->secret[i] = NULL; - } -+ acct->val = acctservers; -+ auth->val = authservers; - return rh; - } - -@@ -894,11 +898,15 @@ - continue; - if (rh->config_options[i].type == OT_SRV) { - serv = (SERVER *)rh->config_options[i].val; -- for (j = 0; j < serv->max; j++) -+ for (j = 0; j < serv->max; j++) { - free(serv->name[j]); -- free(serv); -- } else { -+ free(serv->secret[j]); -+ } - free(rh->config_options[i].val); -+ rh->config_options[i].val = NULL; -+ -+ } else { -+ free(rh->config_options[i].val); - } - } - free(rh->config_options); diff --git a/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary b/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary deleted file mode 100644 index 431d92c544..0000000000 --- a/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary +++ /dev/null @@ -1,244 +0,0 @@ -# -# Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl -# -# This file contains dictionary translations for parsing -# requests and generating responses. All transactions are -# composed of Attribute/Value Pairs. The value of each attribute -# is specified as one of 4 data types. Valid data types are: -# -# string - 0-253 octets -# ipaddr - 4 octets in network byte order -# integer - 32 bit value in big endian order (high byte first) -# date - 32 bit value in big endian order - seconds since -# 00:00:00 GMT, Jan. 1, 1970 -# -# Enumerated values are stored in the user file with dictionary -# VALUE translations for easy administration. -# -# Example: -# -# ATTRIBUTE VALUE -# --------------- ----- -# Framed-Protocol = PPP -# 7 = 1 (integer encoding) -# - -# -# Following are the proper new names. Use these. -# -$INCLUDE /usr/local/src/freeswitch/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.cisco -$INCLUDE /usr/local/src/freeswitch/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.rfc5090 - -ATTRIBUTE User-Name 1 string -ATTRIBUTE Password 2 string -ATTRIBUTE CHAP-Password 3 string -ATTRIBUTE NAS-IP-Address 4 ipaddr -ATTRIBUTE NAS-Port-Id 5 integer -ATTRIBUTE Service-Type 6 integer -ATTRIBUTE Framed-Protocol 7 integer -ATTRIBUTE Framed-IP-Address 8 ipaddr -ATTRIBUTE Framed-IP-Netmask 9 ipaddr -ATTRIBUTE Framed-Routing 10 integer -ATTRIBUTE Filter-Id 11 string -ATTRIBUTE Framed-MTU 12 integer -ATTRIBUTE Framed-Compression 13 integer -ATTRIBUTE Login-IP-Host 14 ipaddr -ATTRIBUTE Login-Service 15 integer -ATTRIBUTE Login-TCP-Port 16 integer -ATTRIBUTE Reply-Message 18 string -ATTRIBUTE Callback-Number 19 string -ATTRIBUTE Callback-Id 20 string -ATTRIBUTE Framed-Route 22 string -ATTRIBUTE Framed-IPX-Network 23 ipaddr -ATTRIBUTE State 24 string -ATTRIBUTE Class 25 string -ATTRIBUTE Vendor-Specific 26 string -ATTRIBUTE Session-Timeout 27 integer -ATTRIBUTE Idle-Timeout 28 integer -ATTRIBUTE Termination-Action 29 integer -ATTRIBUTE Called-Station-Id 30 string -ATTRIBUTE Calling-Station-Id 31 string -ATTRIBUTE NAS-Identifier 32 string -ATTRIBUTE Proxy-State 33 string -ATTRIBUTE Login-LAT-Service 34 string -ATTRIBUTE Login-LAT-Node 35 string -ATTRIBUTE Login-LAT-Group 36 string -ATTRIBUTE Framed-AppleTalk-Link 37 integer -ATTRIBUTE Framed-AppleTalk-Network 38 integer -ATTRIBUTE Framed-AppleTalk-Zone 39 string -ATTRIBUTE Acct-Status-Type 40 integer -ATTRIBUTE Acct-Delay-Time 41 integer -ATTRIBUTE Acct-Input-Octets 42 integer -ATTRIBUTE Acct-Output-Octets 43 integer -ATTRIBUTE Acct-Session-Id 44 string -ATTRIBUTE Acct-Authentic 45 integer -ATTRIBUTE Acct-Session-Time 46 integer -ATTRIBUTE Acct-Input-Packets 47 integer -ATTRIBUTE Acct-Output-Packets 48 integer -ATTRIBUTE Acct-Terminate-Cause 49 integer -ATTRIBUTE Acct-Multi-Session-Id 50 string -ATTRIBUTE Acct-Link-Count 51 integer -ATTRIBUTE Event-Timestamp 55 integer -ATTRIBUTE CHAP-Challenge 60 string -ATTRIBUTE NAS-Port-Type 61 integer -ATTRIBUTE Port-Limit 62 integer -ATTRIBUTE Login-LAT-Port 63 integer -ATTRIBUTE Connect-Info 77 string - -# -# RFC3162 IPv6 attributes -# -ATTRIBUTE NAS-IPv6-Address 95 string -ATTRIBUTE Framed-Interface-Id 96 string -ATTRIBUTE Framed-IPv6-Prefix 97 string -ATTRIBUTE Login-IPv6-Host 98 string -ATTRIBUTE Framed-IPv6-Route 99 string -ATTRIBUTE Framed-IPv6-Pool 100 string - -# -# Experimental Non Protocol Attributes used by Cistron-Radiusd -# -ATTRIBUTE Huntgroup-Name 221 string -ATTRIBUTE User-Category 1029 string -ATTRIBUTE Group-Name 1030 string -ATTRIBUTE Simultaneous-Use 1034 integer -ATTRIBUTE Strip-User-Name 1035 integer -ATTRIBUTE Fall-Through 1036 integer -ATTRIBUTE Add-Port-To-IP-Address 1037 integer -ATTRIBUTE Exec-Program 1038 string -ATTRIBUTE Exec-Program-Wait 1039 string -ATTRIBUTE Hint 1040 string - -# -# Non-Protocol Attributes -# These attributes are used internally by the server -# -ATTRIBUTE Expiration 21 date -ATTRIBUTE Auth-Type 1000 integer -ATTRIBUTE Menu 1001 string -ATTRIBUTE Termination-Menu 1002 string -ATTRIBUTE Prefix 1003 string -ATTRIBUTE Suffix 1004 string -ATTRIBUTE Group 1005 string -ATTRIBUTE Crypt-Password 1006 string -ATTRIBUTE Connect-Rate 1007 integer - -# -# Integer Translations -# - -# User Types - -VALUE Service-Type Login-User 1 -VALUE Service-Type Framed-User 2 -VALUE Service-Type Callback-Login-User 3 -VALUE Service-Type Callback-Framed-User 4 -VALUE Service-Type Outbound-User 5 -VALUE Service-Type Administrative-User 6 -VALUE Service-Type NAS-Prompt-User 7 - -# Framed Protocols - -VALUE Framed-Protocol PPP 1 -VALUE Framed-Protocol SLIP 2 - -# Framed Routing Values - -VALUE Framed-Routing None 0 -VALUE Framed-Routing Broadcast 1 -VALUE Framed-Routing Listen 2 -VALUE Framed-Routing Broadcast-Listen 3 - -# Framed Compression Types - -VALUE Framed-Compression None 0 -VALUE Framed-Compression Van-Jacobson-TCP-IP 1 - -# Login Services - -VALUE Login-Service Telnet 0 -VALUE Login-Service Rlogin 1 -VALUE Login-Service TCP-Clear 2 -VALUE Login-Service PortMaster 3 - -# Status Types - -VALUE Acct-Status-Type Start 1 -VALUE Acct-Status-Type Stop 2 -VALUE Acct-Status-Type Alive 3 -VALUE Acct-Status-Type Accounting-On 7 -VALUE Acct-Status-Type Accounting-Off 8 - -# Authentication Types - -VALUE Acct-Authentic RADIUS 1 -VALUE Acct-Authentic Local 2 -VALUE Acct-Authentic PowerLink128 100 - -# Termination Options - -VALUE Termination-Action Default 0 -VALUE Termination-Action RADIUS-Request 1 - -# NAS Port Types, available in 3.3.1 and later - -VALUE NAS-Port-Type Async 0 -VALUE NAS-Port-Type Sync 1 -VALUE NAS-Port-Type ISDN 2 -VALUE NAS-Port-Type ISDN-V120 3 -VALUE NAS-Port-Type ISDN-V110 4 - -# Acct Terminate Causes, available in 3.3.2 and later - -VALUE Acct-Terminate-Cause User-Request 1 -VALUE Acct-Terminate-Cause Lost-Carrier 2 -VALUE Acct-Terminate-Cause Lost-Service 3 -VALUE Acct-Terminate-Cause Idle-Timeout 4 -VALUE Acct-Terminate-Cause Session-Timeout 5 -VALUE Acct-Terminate-Cause Admin-Reset 6 -VALUE Acct-Terminate-Cause Admin-Reboot 7 -VALUE Acct-Terminate-Cause Port-Error 8 -VALUE Acct-Terminate-Cause NAS-Error 9 -VALUE Acct-Terminate-Cause NAS-Request 10 -VALUE Acct-Terminate-Cause NAS-Reboot 11 -VALUE Acct-Terminate-Cause Port-Unneeded 12 -VALUE Acct-Terminate-Cause Port-Preempted 13 -VALUE Acct-Terminate-Cause Port-Suspended 14 -VALUE Acct-Terminate-Cause Service-Unavailable 15 -VALUE Acct-Terminate-Cause Callback 16 -VALUE Acct-Terminate-Cause User-Error 17 -VALUE Acct-Terminate-Cause Host-Request 18 - -# -# Non-Protocol Integer Translations -# - -VALUE Auth-Type Local 0 -VALUE Auth-Type System 1 -VALUE Auth-Type SecurID 2 -VALUE Auth-Type Crypt-Local 3 -VALUE Auth-Type Reject 4 - -# -# Cistron extensions -# -VALUE Auth-Type Pam 253 -VALUE Auth-Type Accept 254 - -# -# Experimental Non-Protocol Integer Translations for Cistron-Radiusd -# -VALUE Fall-Through No 0 -VALUE Fall-Through Yes 1 -VALUE Add-Port-To-IP-Address No 0 -VALUE Add-Port-To-IP-Address Yes 1 - -# -# Configuration Values -# uncomment these two lines to turn account expiration on -# - -#VALUE Server-Config Password-Expiration 30 -#VALUE Server-Config Password-Warning 5 - - diff --git a/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.cisco b/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.cisco deleted file mode 100644 index b61c9d27cc..0000000000 --- a/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.cisco +++ /dev/null @@ -1,161 +0,0 @@ -# -*- text -*- -# -# dictionary.cisco -# -# Accounting VSAs originally by -# "Marcelo M. Sosa Lugones" -# -# Version: $Id$ -# -# For documentation on Cisco RADIUS attributes, see: -# -# http://www.cisco.com/univercd/cc/td/doc/product/access/acs_serv/vapp_dev/vsaig3.htm -# -# For general documentation on Cisco RADIUS configuration, see: -# -# http://www.cisco.com/en/US/partner/tech/tk583/tk547/tsd_technology_support_sub-protocol_home.html -# - -VENDOR Cisco 9 - -# -# Standard attribute -# -#BEGIN-VENDOR Cisco - -ATTRIBUTE Cisco-AVPair 1 string vendor=Cisco -ATTRIBUTE Cisco-NAS-Port 2 string vendor=Cisco - -# -# T.37 Store-and-Forward attributes. -# -ATTRIBUTE Cisco-Fax-Account-Id-Origin 3 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Msg-Id 4 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Pages 5 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Coverpage-Flag 6 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Modem-Time 7 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Connect-Speed 8 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Recipient-Count 9 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Process-Abort-Flag 10 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Dsn-Address 11 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Dsn-Flag 12 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Mdn-Address 13 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Mdn-Flag 14 string vendor=Cisco -ATTRIBUTE Cisco-Fax-Auth-Status 15 string vendor=Cisco -ATTRIBUTE Cisco-Email-Server-Address 16 string vendor=Cisco -ATTRIBUTE Cisco-Email-Server-Ack-Flag 17 string vendor=Cisco -ATTRIBUTE Cisco-Gateway-Id 18 string vendor=Cisco -ATTRIBUTE Cisco-Call-Type 19 string vendor=Cisco -ATTRIBUTE Cisco-Port-Used 20 string vendor=Cisco -ATTRIBUTE Cisco-Abort-Cause 21 string vendor=Cisco - -# -# Voice over IP attributes. -# -ATTRIBUTE h323-remote-address 23 string vendor=Cisco -ATTRIBUTE h323-conf-id 24 string vendor=Cisco -ATTRIBUTE h323-setup-time 25 string vendor=Cisco -ATTRIBUTE h323-call-origin 26 string vendor=Cisco -ATTRIBUTE h323-call-type 27 string vendor=Cisco -ATTRIBUTE h323-connect-time 28 string vendor=Cisco -ATTRIBUTE h323-disconnect-time 29 string vendor=Cisco -ATTRIBUTE h323-disconnect-cause 30 string vendor=Cisco -ATTRIBUTE h323-voice-quality 31 string vendor=Cisco -ATTRIBUTE h323-gw-id 33 string vendor=Cisco -ATTRIBUTE h323-incoming-conf-id 35 string vendor=Cisco - -ATTRIBUTE Cisco-Policy-Up 37 string vendor=Cisco -ATTRIBUTE Cisco-Policy-Down 38 string vendor=Cisco - -ATTRIBUTE sip-conf-id 100 string vendor=Cisco -ATTRIBUTE h323-credit-amount 101 string vendor=Cisco -ATTRIBUTE h323-credit-time 102 string vendor=Cisco -ATTRIBUTE h323-return-code 103 string vendor=Cisco -ATTRIBUTE h323-prompt-id 104 string vendor=Cisco -ATTRIBUTE h323-time-and-day 105 string vendor=Cisco -ATTRIBUTE h323-redirect-number 106 string vendor=Cisco -ATTRIBUTE h323-preferred-lang 107 string vendor=Cisco -ATTRIBUTE h323-redirect-ip-address 108 string vendor=Cisco -ATTRIBUTE h323-billing-model 109 string vendor=Cisco -ATTRIBUTE h323-currency 110 string vendor=Cisco -ATTRIBUTE subscriber 111 string vendor=Cisco -ATTRIBUTE gw-rxd-cdn 112 string vendor=Cisco -ATTRIBUTE gw-final-xlated-cdn 113 string vendor=Cisco -ATTRIBUTE remote-media-address 114 string vendor=Cisco -ATTRIBUTE release-source 115 string vendor=Cisco -ATTRIBUTE gw-rxd-cgn 116 string vendor=Cisco -ATTRIBUTE gw-final-xlated-cgn 117 string vendor=Cisco - -# SIP Attributes -ATTRIBUTE call-id 141 string vendor=Cisco -ATTRIBUTE session-protocol 142 string vendor=Cisco -ATTRIBUTE method 143 string vendor=Cisco -ATTRIBUTE prev-hop-via 144 string vendor=Cisco -ATTRIBUTE prev-hop-ip 145 string vendor=Cisco -ATTRIBUTE incoming-req-uri 146 string vendor=Cisco -ATTRIBUTE outgoing-req-uri 147 string vendor=Cisco -ATTRIBUTE next-hop-ip 148 string vendor=Cisco -ATTRIBUTE next-hop-dn 149 string vendor=Cisco -ATTRIBUTE sip-hdr 150 string vendor=Cisco - -# -# Extra attributes sent by the Cisco, if you configure -# "radius-server vsa accounting" (requires IOS11.2+). -# -ATTRIBUTE Cisco-Multilink-ID 187 integer vendor=Cisco -ATTRIBUTE Cisco-Num-In-Multilink 188 integer vendor=Cisco -ATTRIBUTE Cisco-Pre-Input-Octets 190 integer vendor=Cisco -ATTRIBUTE Cisco-Pre-Output-Octets 191 integer vendor=Cisco -ATTRIBUTE Cisco-Pre-Input-Packets 192 integer vendor=Cisco -ATTRIBUTE Cisco-Pre-Output-Packets 193 integer vendor=Cisco -ATTRIBUTE Cisco-Maximum-Time 194 integer vendor=Cisco -ATTRIBUTE Cisco-Disconnect-Cause 195 integer vendor=Cisco -ATTRIBUTE Cisco-Data-Rate 197 integer vendor=Cisco -ATTRIBUTE Cisco-PreSession-Time 198 integer vendor=Cisco -ATTRIBUTE Cisco-PW-Lifetime 208 integer vendor=Cisco -ATTRIBUTE Cisco-IP-Direct 209 integer vendor=Cisco -ATTRIBUTE Cisco-PPP-VJ-Slot-Comp 210 integer vendor=Cisco -ATTRIBUTE Cisco-PPP-Async-Map 212 integer vendor=Cisco -ATTRIBUTE Cisco-IP-Pool-Definition 217 string vendor=Cisco -ATTRIBUTE Cisco-Assign-IP-Pool 218 integer vendor=Cisco -ATTRIBUTE Cisco-Route-IP 228 integer vendor=Cisco -ATTRIBUTE Cisco-Link-Compression 233 integer vendor=Cisco -ATTRIBUTE Cisco-Target-Util 234 integer vendor=Cisco -ATTRIBUTE Cisco-Maximum-Channels 235 integer vendor=Cisco -ATTRIBUTE Cisco-Data-Filter 242 integer vendor=Cisco -ATTRIBUTE Cisco-Call-Filter 243 integer vendor=Cisco -ATTRIBUTE Cisco-Idle-Limit 244 integer vendor=Cisco -ATTRIBUTE Cisco-Subscriber-Password 249 string vendor=Cisco -ATTRIBUTE Cisco-Account-Info 250 string vendor=Cisco -ATTRIBUTE Cisco-Service-Info 251 string vendor=Cisco -ATTRIBUTE Cisco-Command-Code 252 string vendor=Cisco -ATTRIBUTE Cisco-Control-Info 253 string vendor=Cisco -ATTRIBUTE Cisco-Xmit-Rate 255 integer vendor=Cisco - -VALUE Cisco-Disconnect-Cause Unknown 2 -VALUE Cisco-Disconnect-Cause CLID-Authentication-Failure 4 -VALUE Cisco-Disconnect-Cause No-Carrier 10 -VALUE Cisco-Disconnect-Cause Lost-Carrier 11 -VALUE Cisco-Disconnect-Cause No-Detected-Result-Codes 12 -VALUE Cisco-Disconnect-Cause User-Ends-Session 20 -VALUE Cisco-Disconnect-Cause Idle-Timeout 21 -VALUE Cisco-Disconnect-Cause Exit-Telnet-Session 22 -VALUE Cisco-Disconnect-Cause No-Remote-IP-Addr 23 -VALUE Cisco-Disconnect-Cause Exit-Raw-TCP 24 -VALUE Cisco-Disconnect-Cause Password-Fail 25 -VALUE Cisco-Disconnect-Cause Raw-TCP-Disabled 26 -VALUE Cisco-Disconnect-Cause Control-C-Detected 27 -VALUE Cisco-Disconnect-Cause EXEC-Program-Destroyed 28 -VALUE Cisco-Disconnect-Cause Timeout-PPP-LCP 40 -VALUE Cisco-Disconnect-Cause Failed-PPP-LCP-Negotiation 41 -VALUE Cisco-Disconnect-Cause Failed-PPP-PAP-Auth-Fail 42 -VALUE Cisco-Disconnect-Cause Failed-PPP-CHAP-Auth 43 -VALUE Cisco-Disconnect-Cause Failed-PPP-Remote-Auth 44 -VALUE Cisco-Disconnect-Cause PPP-Remote-Terminate 45 -VALUE Cisco-Disconnect-Cause PPP-Closed-Event 46 -VALUE Cisco-Disconnect-Cause Session-Timeout 100 -VALUE Cisco-Disconnect-Cause Session-Failed-Security 101 -VALUE Cisco-Disconnect-Cause Session-End-Callback 102 -VALUE Cisco-Disconnect-Cause Invalid-Protocol 120 - -#END-VENDOR Cisco diff --git a/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.rfc5090 b/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.rfc5090 deleted file mode 100644 index 4feda43628..0000000000 --- a/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary.rfc5090 +++ /dev/null @@ -1,27 +0,0 @@ -# -*- text -*- -# -# Attributes and values defined in RFC 5090. -# http://www.ietf.org/rfc/rfc5090.txt -# -# $Id$ -# -ATTRIBUTE Digest-Response 103 string -ATTRIBUTE Digest-Realm 104 string -ATTRIBUTE Digest-Nonce 105 string -ATTRIBUTE Digest-Response-Auth 106 string -ATTRIBUTE Digest-Nextnonce 107 string -ATTRIBUTE Digest-Method 108 string -ATTRIBUTE Digest-URI 109 string -ATTRIBUTE Digest-Qop 110 string -ATTRIBUTE Digest-Algorithm 111 string -ATTRIBUTE Digest-Entity-Body-Hash 112 string -ATTRIBUTE Digest-CNonce 113 string -ATTRIBUTE Digest-Nonce-Count 114 string -ATTRIBUTE Digest-Username 115 string -ATTRIBUTE Digest-Opaque 116 string -ATTRIBUTE Digest-Auth-Param 117 string -ATTRIBUTE Digest-AKA-Auts 118 string -ATTRIBUTE Digest-Domain 119 string -ATTRIBUTE Digest-Stale 120 string -ATTRIBUTE Digest-HA1 121 string -ATTRIBUTE SIP-AOR 122 string diff --git a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c deleted file mode 100644 index f35966145f..0000000000 --- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c +++ /dev/null @@ -1,1237 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * 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. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * William King - * - * mod_xml_radius.c -- Radius authentication and authorization - * - */ -#include -#include - -static struct { - switch_memory_pool_t *pool; - switch_xml_t auth_invite_configs; - switch_xml_t auth_reg_configs; - switch_xml_t auth_app_configs; - switch_xml_t acct_start_configs; - switch_xml_t acct_end_configs; - /* xml read write lock */ -} globals = {0}; - -SWITCH_MODULE_LOAD_FUNCTION(mod_xml_radius_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_radius_shutdown); -SWITCH_MODULE_DEFINITION(mod_xml_radius, mod_xml_radius_load, mod_xml_radius_shutdown, NULL); - -int GLOBAL_DEBUG = 0; -/* - * Time format 0: - * 20:16:33.479 UTC Thu May 02 2013 - * - * Time format 1: - * 2013-05-03T00:53:26.139798+0400 - * - */ -int GLOBAL_TIME_FORMAT = 0; -char *GLOBAL_TIME_ZONE = "UTC"; -static char radattrdays[7][4] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; -static char radattrmonths[12][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -switch_status_t mod_xml_radius_new_handle(rc_handle **new_handle, switch_xml_t xml) { - switch_xml_t server, param; - - if ( (*new_handle = rc_new()) == NULL ) { - goto err; - } - - if ( rc_config_init(*new_handle) == NULL ) { - *new_handle = NULL; - goto err; - } - - if (rc_add_config(*new_handle, "auth_order", "radius", "mod_radius_cdr.c", 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error adding auth_order\n"); - goto err; - } - - if ((server = switch_xml_child(xml, "connection")) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section in config file.\n"); - goto err; - } - - for (param = switch_xml_child(server, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Attempting to add param '%s' with value '%s' \n", var, val); - } - - if (strncmp(var, "dictionary", 10) == 0) { - if ( rc_read_dictionary(*new_handle, val) != 0) { - goto err; - } - } else if (rc_add_config(*new_handle, var, val, "mod_xml_radius", 0) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error adding param '%s' with value '%s' \n", var, val); - goto err; - } - } - - return SWITCH_STATUS_SUCCESS; - - err: - if ( *new_handle ) { - rc_destroy( *new_handle ); - *new_handle = NULL; - } - return SWITCH_STATUS_GENERR; -} - -switch_status_t do_config() -{ - char *conf = "xml_radius.conf"; - switch_xml_t xml, cfg, tmp, server, param; - int serv, timeout, deadtime, retries, dict, seq; - - /* TODO: - 1. Fix read/write lock on configs - a. read new configs - b. Create replacement xml and vas objects - c. Get the write lock. - d. Replace xml and vas objects - e. unlock and return. - 2. Don't manually check for proper configs. Use the function in the client library - 3. Add api that would reload configs - */ - - if (!(xml = switch_xml_open_cfg(conf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", conf); - goto err; - } - - serv = timeout = deadtime = retries = dict = seq = 0; - if ((tmp = switch_xml_dup(switch_xml_child(cfg, "auth_invite"))) != NULL ) { - if ( (server = switch_xml_child(tmp, "connection")) != NULL) { - for (param = switch_xml_child(server, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - if ( strncmp(var, "authserver", 10) == 0 ) { - serv = 1; - } else if ( strncmp(var, "radius_timeout", 14) == 0 ) { - timeout = 1; - } else if ( strncmp(var, "radius_deadtime", 15) == 0 ) { - deadtime = 1; - } else if ( strncmp(var, "radius_retries", 14) == 0 ) { - retries = 1; - } else if ( strncmp(var, "dictionary", 10) == 0 ) { - dict = 1; - } else if ( strncmp(var, "seqfile", 7) == 0 ) { - seq = 1; - } - } - - if ( serv && timeout && deadtime && retries && dict && seq ) { - globals.auth_invite_configs = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing a require section for radius connections\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section for auth_invite\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'auth_invite' section in config file.\n"); - } - - serv = timeout = deadtime = retries = dict = seq = 0; - if ((tmp = switch_xml_dup(switch_xml_child(cfg, "auth_reg"))) != NULL ) { - if ( (server = switch_xml_child(tmp, "connection")) != NULL) { - for (param = switch_xml_child(server, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - if ( strncmp(var, "authserver", 10) == 0 ) { - serv = 1; - } else if ( strncmp(var, "radius_timeout", 14) == 0 ) { - timeout = 1; - } else if ( strncmp(var, "radius_deadtime", 15) == 0 ) { - deadtime = 1; - } else if ( strncmp(var, "radius_retries", 14) == 0 ) { - retries = 1; - } else if ( strncmp(var, "dictionary", 10) == 0 ) { - dict = 1; - } else if ( strncmp(var, "seqfile", 7) == 0 ) { - seq = 1; - } - } - - if ( serv && timeout && deadtime && retries && dict && seq ) { - globals.auth_reg_configs = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing a require section for radius connections\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section for auth_invite\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'auth_reg' section in config file.\n"); - } - - if ((tmp = switch_xml_child(cfg, "global")) != NULL ) { - for (param = switch_xml_child(tmp, "param"); param; param = param->next) { - char *name = (char *) switch_xml_attr_soft(param, "name"); - char *value = (char *) switch_xml_attr_soft(param, "value"); - if ( strncmp(name, "time_format", 11) == 0 && value != NULL ) { - GLOBAL_TIME_FORMAT = atoi(value); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Time format changed to %d\n", GLOBAL_TIME_FORMAT); - } - if ( strncmp(name, "time_zone", 9) == 0 && value != NULL ) { - GLOBAL_TIME_ZONE = value; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Time zone changed to %s\n", GLOBAL_TIME_ZONE); - } - if ( strncmp(name, "debug", 5) == 0 && value != NULL ) { - GLOBAL_DEBUG = atoi(value); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Debug changed to %d\n", GLOBAL_DEBUG); - } - } - } - - serv = timeout = deadtime = retries = dict = seq = 0; - if ((tmp = switch_xml_dup(switch_xml_child(cfg, "auth_app"))) != NULL ) { - if ( (server = switch_xml_child(tmp, "connection")) != NULL) { - for (param = switch_xml_child(server, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - if ( strncmp(var, "authserver", 10) == 0 ) { - serv = 1; - } else if ( strncmp(var, "radius_timeout", 14) == 0 ) { - timeout = 1; - } else if ( strncmp(var, "radius_deadtime", 15) == 0 ) { - deadtime = 1; - } else if ( strncmp(var, "radius_retries", 14) == 0 ) { - retries = 1; - } else if ( strncmp(var, "dictionary", 10) == 0 ) { - dict = 1; - } else if ( strncmp(var, "seqfile", 7) == 0 ) { - seq = 1; - } - } - - if ( serv && timeout && deadtime && retries && dict && seq ) { - globals.auth_app_configs = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing a require section for radius connections\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section for auth_app\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'auth_app' section in config file.\n"); - } - - serv = timeout = deadtime = retries = dict = seq = 0; - if (( tmp = switch_xml_dup(switch_xml_child(cfg, "acct_start"))) != NULL ) { - if ( (server = switch_xml_child(tmp, "connection")) != NULL) { - for (param = switch_xml_child(server, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - if ( strncmp(var, "acctserver", 10) == 0 ) { - serv = 1; - } else if ( strncmp(var, "radius_timeout", 14) == 0 ) { - timeout = 1; - } else if ( strncmp(var, "radius_deadtime", 15) == 0 ) { - deadtime = 1; - } else if ( strncmp(var, "radius_retries", 14) == 0 ) { - retries = 1; - } else if ( strncmp(var, "dictionary", 10) == 0 ) { - dict = 1; - } else if ( strncmp(var, "seqfile", 7) == 0 ) { - seq = 1; - } - } - - if ( serv && timeout && deadtime && retries && dict && seq ) { - globals.acct_start_configs = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing a require section for radius connections\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section for acct_start\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'acct_start' section in config file.\n"); - } - - serv = timeout = deadtime = retries = dict = seq = 0; - if (( tmp = switch_xml_dup(switch_xml_child(cfg, "acct_end"))) != NULL ) { - if ( (server = switch_xml_child(tmp, "connection")) != NULL) { - for (param = switch_xml_child(server, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - if ( strncmp(var, "acctserver", 10) == 0 ) { - serv = 1; - } else if ( strncmp(var, "radius_timeout", 14) == 0 ) { - timeout = 1; - } else if ( strncmp(var, "radius_deadtime", 15) == 0 ) { - deadtime = 1; - } else if ( strncmp(var, "radius_retries", 14) == 0 ) { - retries = 1; - } else if ( strncmp(var, "dictionary", 10) == 0 ) { - dict = 1; - } else if ( strncmp(var, "seqfile", 7) == 0 ) { - seq = 1; - } - } - - if ( serv && timeout && deadtime && retries && dict && seq ) { - globals.acct_end_configs = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing a require section for radius connections\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section for acct_end\n"); - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'acct_end' section in config file.\n"); - } - - if ( xml ) { - switch_xml_free(xml); - xml = NULL; - } - - return SWITCH_STATUS_SUCCESS; - - err: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Configuration error\n"); - if ( xml ) { - switch_xml_free(xml); - xml = NULL; - } - - return SWITCH_STATUS_GENERR; -} - -switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch_event_t *params, rc_handle *handle, VALUE_PAIR **send, switch_xml_t fields) -{ - switch_xml_t param; - void *av_value = NULL; - - if ( (param = switch_xml_child(fields, "param")) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under the fields section\n"); - goto err; - } - - for (; param; param = param->next) { - DICT_ATTR *attribute = NULL; - DICT_VENDOR *vendor = NULL; - int attr_num = 0, vend_num = 0; - - char *var = (char *) switch_xml_attr(param, "name"); - char *vend = (char *) switch_xml_attr(param, "vendor"); - char *variable = (char *) switch_xml_attr(param, "variable"); - char *variable_secondary = (char *) switch_xml_attr(param, "variable_secondary"); - char *val_default = (char *) switch_xml_attr(param, "default"); - char *skip_if_set = (char *) switch_xml_attr(param, "skip_if_set"); - char *format = (char *) switch_xml_attr(param, "format"); - char *other_leg = (char *) switch_xml_attr(param, "other_leg"); - char *regex = (char *) switch_xml_attr(param, "regex"); - - attribute = rc_dict_findattr(handle, var); - - if ( attribute == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate attribute '%s' in the configured dictionary\n", var); - goto err; - } - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict attr '%s' value '%d' type '%d'\n", - attribute->name, attribute->value, attribute->type); - } - - attr_num = attribute->value; - - if ( vend ) { - vendor = rc_dict_findvend(handle, vend); - - if ( vendor == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate vendor '%s' in the configured dictionary %p\n", - vend, vend); - goto err; - } - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict vend name '%s' vendorpec '%d'\n", - vendor->vendorname, vendor->vendorpec); - } - - vend_num = vendor->vendorpec; - } - - if ( var ) { - if ( session ) { - switch_channel_t *channel = switch_core_session_get_channel(session); - if ( skip_if_set && switch_channel_get_variable(channel, skip_if_set) ) { - goto end_loop; - } - - /* Accounting only */ - if ( strncmp( var, "h323-setup-time", 15) == 0 ) { - switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); - switch_time_t time = profile->times->created; - switch_time_exp_t tm; - - if ( !time ) { - goto end_loop; - } - - switch_time_exp_lt(&tm, time); - - if ( GLOBAL_TIME_FORMAT == 1 ) { - av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, - GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], - tm.tm_mday, tm.tm_year + 1900); - } else { - av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, - tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - } - - if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); - } - } else if ( strncmp( var, "h323-connect-time", 17) == 0 ) { - switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); - switch_time_t time = profile->times->answered; - switch_time_exp_t tm; - - if ( !time ) { - goto end_loop; - } - - switch_time_exp_lt(&tm, time); - - if ( GLOBAL_TIME_FORMAT == 1 ) { - av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, - GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], - tm.tm_mday, tm.tm_year + 1900); - } else { - av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, - tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - } - - if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); - } - } else if ( strncmp( var, "h323-disconnect-time", 20) == 0 ) { - switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); - switch_time_t time = profile->times->hungup; - switch_time_exp_t tm; - - if ( !time ) { - if ( variable_secondary != NULL && strncmp(variable_secondary, "now", 3) == 0 ) { - time = switch_time_now(); - } else { - goto end_loop; - } - } - - switch_time_exp_lt(&tm, time); - - if ( GLOBAL_TIME_FORMAT == 1 ) { - av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, - GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], - tm.tm_mday, tm.tm_year + 1900); - } else { - av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, - tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); - } - - if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); - } - } else if ( strncmp( var, "h323-disconnect-cause", 21) == 0 ) { - switch_call_cause_t cause = switch_channel_get_cause(channel); - av_value = switch_mprintf("h323-disconnect-cause=%x", cause); - if (rc_avpair_add(handle, send, 30, av_value, -1, 9) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add disconnect cause \n"); - goto err; - } - - } else { - if ( format == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing format attribute for %s variable\n", variable); - goto err; - } - - if ( attribute->type == 0 ) { - const char *val = NULL; - - if ( other_leg ) { - val = switch_channel_get_variable_partner(channel, variable); - if ( val == NULL && variable_secondary != NULL) { - val = switch_channel_get_variable_partner(channel, variable_secondary); - } - } else { - val = switch_channel_get_variable(channel, variable); - if ( val == NULL && variable_secondary != NULL) { - val = switch_channel_get_variable(channel, variable_secondary); - } - } - - if ( regex && val ) { - switch_regex_t *re = NULL; - int ovector[30]; - int proceed; - char replace[1024] = ""; - proceed = 0; - proceed = switch_regex_perform(val, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - if ( proceed > 0 ) { - switch_regex_copy_substring(val, ovector, proceed, proceed - 1, replace, sizeof(replace)); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "original value: %s, regex: %s, result: %s\n", val, regex, replace); - val = replace; - } - else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "original value: %s, regex: %s, result: nomatch, value left intact\n", val, regex); - } - switch_regex_safe_free(re); - } - - if ( val == NULL && val_default != NULL) { - av_value = switch_mprintf(format, val_default); - } else { - av_value = switch_mprintf(format, val); - } - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); - } - - if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "mod_xml_radius: failed to add option with val '%s' to handle\n", (char *) av_value); - goto err; - } - } else if ( attribute->type == 1 ) { - const char *data = switch_channel_get_variable(channel, variable); - int number = 0; - - if ( data ) { - number = atoi(data); - } - - if (rc_avpair_add(handle, send, attr_num, &number, -1, vend_num) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "mod_xml_radius: failed to add option with value '%d' to handle\n", number); - goto err; - } - } - } - } else if ( params ) { - /* Auth only */ - char *tmp = switch_event_get_header(params, variable); - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: param var '%s' val: %s\n", variable, tmp); - } - - if ( tmp == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Unable to locate '%s' on the event\n", variable); - goto err; - } - - av_value = switch_mprintf(format, tmp); - if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - } else { - goto err; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: all params must have a name attribute\n"); - goto err; - } - - end_loop: - if ( av_value != NULL ) { - free(av_value); - av_value = NULL; - } - } - - return SWITCH_STATUS_SUCCESS; - err: - if ( av_value != NULL ) { - free(av_value); - av_value = NULL; - } - return SWITCH_STATUS_GENERR; - -} - -/* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */ -SWITCH_STANDARD_API(mod_xml_radius_debug_api) -{ - if ( !strncmp(cmd, "on", 2) ) { - GLOBAL_DEBUG = 1; - } else if ( !strncmp(cmd, "off", 3)){ - GLOBAL_DEBUG = 0; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Valid options are [yes|no]\n" ); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "debug is %s\n", (GLOBAL_DEBUG ? "on" : "off") ); - return SWITCH_STATUS_SUCCESS; -} - -switch_xml_t mod_xml_radius_auth_invite(switch_event_t *params) { - int result = 0, param_idx = 0; - VALUE_PAIR *send = NULL, *recv = NULL, *service_vp = NULL; - char msg[512 * 10 + 1] = {0}; - uint32_t service = PW_AUTHENTICATE_ONLY; - rc_handle *new_handle = NULL; - switch_xml_t fields, xml, dir, dom, usr, vars, var; - char name[512], value[512], *strtmp; - - if (GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting invite authentication\n"); - } - - if ( mod_xml_radius_new_handle(&new_handle, globals.auth_invite_configs) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle for digest invite authentication\n"); - goto err; - } - - if ( new_handle == NULL ) { - goto err; - } - - if ((fields = switch_xml_child(globals.auth_invite_configs, "fields")) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); - goto err; - } - - if ( mod_xml_radius_add_params(NULL, params, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); - goto err; - } - - if (rc_avpair_add(new_handle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - - result = rc_auth(new_handle, 0, send, &recv, msg); - - if ( GLOBAL_DEBUG ){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: result(RC=%d) %s \n", result, msg); - } - - if ( result != 0 ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to authenticate\n"); - goto err; - } - - xml = switch_xml_new("document"); - switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); - dir = switch_xml_add_child_d(xml, "section", 0); - switch_xml_set_attr_d(dir, "name", "directory"); - dom = switch_xml_add_child_d(dir, "domain", 0); - switch_xml_set_attr_d(dom, "name", switch_event_get_header(params, "domain")); - usr = switch_xml_add_child_d(dom, "user", 0); - vars = switch_xml_add_child_d(usr, "variables", 0); - - switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user")); - - var = switch_xml_add_child_d(vars, "variable", param_idx++); - switch_xml_set_attr_d(var, "name", "radius_auth_result"); - switch_xml_set_attr_d(var, "value", "0"); - - service_vp = recv; - while (service_vp != NULL) { - rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512); - if ( GLOBAL_DEBUG ) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\tattribute (%s)[%s] found in radius packet\n", name, value); - var = switch_xml_add_child_d(vars, "variable", param_idx++); - strtmp = strdup(name); - switch_xml_set_attr_d(var, "name", strtmp); - free(strtmp); - strtmp = strdup(value); - switch_xml_set_attr_d(var, "value", strtmp); - free(strtmp); - service_vp = service_vp->next; - } - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML: %s \n", switch_xml_toxml(xml, 1)); - } - - if ( recv ) { - rc_avpair_free(recv); - recv = NULL; - } - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - return xml; - err: - if ( recv ) { - rc_avpair_free(recv); - recv = NULL; - } - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - - return NULL; -} - -switch_xml_t mod_xml_radius_auth_reg(switch_event_t *params) { - int result = 0, param_idx = 0; - VALUE_PAIR *send = NULL, *recv = NULL, *service_vp = NULL; - char msg[512 * 10 + 1] = {0}; - uint32_t service = PW_AUTHENTICATE_ONLY; - rc_handle *new_handle = NULL; - switch_xml_t fields, xml, dir, dom, usr, vars, var; - char name[512], value[512], *strtmp; - - if (GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting registration authentication\n"); - } - - if ( mod_xml_radius_new_handle(&new_handle, globals.auth_reg_configs) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle for registration authentication\n"); - goto err; - } - - if ( new_handle == NULL ) { - goto err; - } - - if ((fields = switch_xml_child(globals.auth_reg_configs, "fields")) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); - goto err; - } - - if ( mod_xml_radius_add_params(NULL, params, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); - goto err; - } - - if (rc_avpair_add(new_handle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - - result = rc_auth(new_handle, 0, send, &recv, msg); - - if ( GLOBAL_DEBUG ){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: result(RC=%d) %s \n", result, msg); - } - - if ( result != 0 ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to authenticate\n"); - goto err; - } - - xml = switch_xml_new("document"); - switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); - dir = switch_xml_add_child_d(xml, "section", 0); - switch_xml_set_attr_d(dir, "name", "directory"); - dom = switch_xml_add_child_d(dir, "domain", 0); - switch_xml_set_attr_d(dom, "name", switch_event_get_header(params, "domain")); - usr = switch_xml_add_child_d(dom, "user", 0); - vars = switch_xml_add_child_d(usr, "variables", 0); - - switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user")); - - service_vp = recv; - while (service_vp != NULL) { - rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512); - if ( GLOBAL_DEBUG ) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\tattribute (%s)[%s] found in radius packet\n", name, value); - var = switch_xml_add_child_d(vars, "variable", param_idx++); - strtmp = strdup(name); - switch_xml_set_attr_d(var, "name", strtmp); - free(strtmp); - strtmp = strdup(value); - switch_xml_set_attr_d(var, "value", strtmp); - free(strtmp); - service_vp = service_vp->next; - } - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML: %s \n", switch_xml_toxml(xml, 1)); - } - - if ( recv ) { - rc_avpair_free(recv); - recv = NULL; - } - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - - return xml; - err: - if ( recv ) { - rc_avpair_free(recv); - recv = NULL; - } - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - - return NULL; -} - -static switch_xml_t mod_xml_radius_directory_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, - switch_event_t *params, void *user_data) -{ - char *event_buf = NULL; - switch_xml_t xml = NULL; - char *auth_method = switch_event_get_header(params,"sip_auth_method"); - - - if ( GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting authentication\n"); - switch_event_serialize(params, &event_buf, SWITCH_TRUE); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Event: %s \n", event_buf); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\nSection: %s \nTag: %s\nKey_name: %s\nKey_value: %s\n", - section, tag_name, key_name, key_value); - } - - if ( auth_method == NULL) { - return NULL; - } - - if ( strncmp( "INVITE", auth_method, 6) == 0) { - xml = mod_xml_radius_auth_invite(params); - } else if ( strncmp( "REGISTER", auth_method, 8) == 0) { - xml = mod_xml_radius_auth_reg(params); - } else { - xml = NULL; - } - - return xml; -} - -switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switch_xml_t conditions) { - switch_xml_t condition, param; - char *channel_var = NULL; - const char *channel_val = NULL; - char *regex = NULL; - char *anti = NULL; - int all_matched = 1; - int result = 0; - - if ( (condition = switch_xml_child(conditions, "condition")) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a condition under the conditions section\n"); - return SWITCH_STATUS_FALSE; - } - - for (; condition; condition = condition->next) { - - if ( (param = switch_xml_child(condition, "param")) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under this condition\n"); - return SWITCH_STATUS_FALSE; - } - - all_matched = 1; - for (; param && all_matched; param = param->next) { - channel_var = (char *) switch_xml_attr(param, "var"); - regex = (char *) switch_xml_attr(param, "regex"); - anti = (char *) switch_xml_attr(param, "anti"); - - if ( channel_var == NULL || regex == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition: %s %s\n", channel_var, regex); - continue; - } - - if ( ( channel_val = switch_channel_get_variable(channel, channel_var) ) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Improperly constructed mod_radius condition, no such channel variable: %s %s\n", channel_var, regex); - continue; - } - - result = ( switch_regex_match( channel_val, regex) != SWITCH_STATUS_SUCCESS); - if (( anti == NULL && result ) || ( anti != NULL && !result ) ){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Didn't match: %s == %s \n", switch_channel_get_variable(channel, channel_var), regex); - all_matched = 0; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Result of %s match: %s == %s \n", - anti, switch_channel_get_variable(channel, channel_var), regex); - } - } - - if ( all_matched ) { - return SWITCH_STATUS_SUCCESS; - } - } - - return SWITCH_STATUS_FALSE; -} - -switch_status_t mod_xml_radius_accounting_start(switch_core_session_t *session){ - VALUE_PAIR *send = NULL; - uint32_t service = PW_STATUS_START; - rc_handle *new_handle = NULL; - switch_xml_t fields, conditions; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting accounting start\n"); - switch_core_session_execute_application(session, "info", NULL); - } - - /* If there are conditions defined, and none of them pass, then skip this accounting */ - if ((conditions = switch_xml_child(globals.acct_start_configs, "conditions")) != NULL && - mod_xml_radius_check_conditions(channel, conditions) != SWITCH_STATUS_SUCCESS ) { - goto end; - } - - if ( mod_xml_radius_new_handle(&new_handle, globals.acct_start_configs) != SWITCH_STATUS_SUCCESS || new_handle == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new accounting_start handle for call: %s\n", - switch_channel_get_variable(channel, "uuid")); - goto end; - } - - if ((fields = switch_xml_child(globals.acct_start_configs, "fields")) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); - goto end; - } - - if ( mod_xml_radius_add_params(session, NULL, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); - goto end; - } - - if (rc_avpair_add(new_handle, &send, PW_ACCT_STATUS_TYPE, &service, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto end; - } - - if (rc_acct(new_handle, 0, send) == OK_RC) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "mod_xml_radius: Accounting Start success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Accounting Start failed\n"); - } - - end: - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t mod_xml_radius_accounting_end(switch_core_session_t *session){ - VALUE_PAIR *send = NULL; - uint32_t service = PW_STATUS_STOP; - rc_handle *new_handle = NULL; - switch_xml_t fields = NULL, conditions = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting accounting stop\n"); - switch_core_session_execute_application(session, "info", NULL); - } - - /* If there are conditions defined, and none of them pass, then skip this accounting */ - if ((conditions = switch_xml_child(globals.acct_end_configs, "conditions")) != NULL && - mod_xml_radius_check_conditions(channel, conditions) != SWITCH_STATUS_SUCCESS ) { - goto end; - } - - if ( mod_xml_radius_new_handle(&new_handle, globals.acct_end_configs) != SWITCH_STATUS_SUCCESS || new_handle == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new accounting_end handle for call: %s\n", - switch_channel_get_variable(channel, "uuid")); - goto end; - } - - if ((fields = switch_xml_child(globals.acct_end_configs, "fields")) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); - goto end; - } - - if ( mod_xml_radius_add_params(session, NULL, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); - goto end; - } - - if (rc_avpair_add(new_handle, &send, PW_ACCT_STATUS_TYPE, &service, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto end; - } - - if (rc_acct(new_handle, 0, send) == OK_RC) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "mod_xml_radius: Accounting Stop success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Accounting Stop failed\n"); - } - - end: - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle) { - rc_destroy(new_handle); - new_handle = NULL; - } - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_APP(radius_auth_handle) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - int result = 0; - VALUE_PAIR *send = NULL, *recv = NULL, *service_vp = NULL; - char msg[512 * 10 + 1] = {0}; - uint32_t service = PW_AUTHENTICATE_ONLY; - rc_handle *new_handle = NULL; - switch_xml_t fields; - char name[512], value[512], *temp = NULL; - - if (GLOBAL_DEBUG ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting app authentication\n"); - } - - if ( mod_xml_radius_new_handle(&new_handle, globals.auth_app_configs) != SWITCH_STATUS_SUCCESS || new_handle == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new authentication handle for call: %s\n", - switch_channel_get_variable(channel, "uuid")); - goto err; - } - - if ((fields = switch_xml_child(globals.auth_app_configs, "fields")) == NULL ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); - goto err; - } - - if ( mod_xml_radius_add_params(session, NULL, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); - goto err; - } - - if (rc_avpair_add(new_handle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); - goto err; - } - - result = rc_auth(new_handle, 0, send, &recv, msg); - - if ( GLOBAL_DEBUG ){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: result(RC=%d) %s \n", result, msg); - } - temp = switch_mprintf("%d",result); - switch_channel_set_variable(channel, "radius_auth_result", temp); - free(temp); - temp = NULL; - - if ( result != 0 ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to authenticate, authentication result: %d \n", result); - goto err; - } - - - service_vp = recv; - while (service_vp != NULL) { - rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512); - if ( GLOBAL_DEBUG ) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\tattribute (%s)[%s] found in radius packet\n", name, value); - - switch_channel_set_variable(channel, name, value); - service_vp = service_vp->next; - } - - if ( recv ) { - rc_avpair_free(recv); - recv = NULL; - } - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - - return; - err: - if ( recv ) { - rc_avpair_free(recv); - recv = NULL; - } - if ( send ) { - rc_avpair_free(send); - send = NULL; - } - if ( new_handle ) { - rc_destroy(new_handle); - new_handle = NULL; - } - return; -} - -static const switch_state_handler_table_t state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ mod_xml_radius_accounting_start, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ mod_xml_radius_accounting_end -}; - - -/* switch_status_t name (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ -SWITCH_MODULE_LOAD_FUNCTION(mod_xml_radius_load) -{ - switch_api_interface_t *mod_xml_radius_api_interface; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_application_interface_t *app_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - memset(&globals, 0, sizeof(globals)); - globals.pool = pool; - - if ( GLOBAL_DEBUG != 0 ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: loading\n"); - } - - if ( (status = do_config()) != SWITCH_STATUS_SUCCESS ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to load configs\n"); - return SWITCH_STATUS_TERM; - } - - if ( globals.auth_invite_configs && globals.auth_reg_configs ) { - status = switch_xml_bind_search_function(mod_xml_radius_directory_search, switch_xml_parse_section_string("directory"), NULL); - } - - SWITCH_ADD_API(mod_xml_radius_api_interface, "xml_radius_debug", "mod_xml_radius toggle debug", mod_xml_radius_debug_api, NULL); - - switch_core_add_state_handler(&state_handlers); - - SWITCH_ADD_APP(app_interface, "radius_auth", NULL, NULL, radius_auth_handle, "radius_auth", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_radius_shutdown) -{ - switch_core_remove_state_handler(&state_handlers); - switch_xml_unbind_search_function_ptr(mod_xml_radius_directory_search); - - if ( globals.auth_invite_configs ) { - switch_xml_free(globals.auth_invite_configs); - } - if ( globals.auth_reg_configs ) { - switch_xml_free(globals.auth_reg_configs); - } - if ( globals.auth_app_configs ) { - switch_xml_free(globals.auth_app_configs); - } - if ( globals.acct_start_configs ) { - switch_xml_free(globals.acct_start_configs); - } - if ( globals.acct_end_configs ) { - switch_xml_free(globals.acct_end_configs); - } - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml b/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml deleted file mode 100644 index 028ace286a..0000000000 --- a/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 443a1ca790130f3944ff28e53b6e26b10770851d Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 12 Dec 2024 15:11:34 +0300 Subject: [PATCH 199/205] [mod_rad_auth] Remove from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 1 - debian/bootstrap.sh | 1 - debian/control-modules | 4 - debian/util.sh | 1 - freeswitch.spec | 20 +- libs/.gitignore | 1 - src/mod/applications/mod_rad_auth/Makefile.am | 29 - .../applications/mod_rad_auth/mod_rad_auth.c | 936 ------------------ 10 files changed, 4 insertions(+), 991 deletions(-) delete mode 100644 src/mod/applications/mod_rad_auth/Makefile.am delete mode 100644 src/mod/applications/mod_rad_auth/mod_rad_auth.c diff --git a/build/modules.conf.in b/build/modules.conf.in index 8a0a687199..dd5a6a88ff 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -32,7 +32,6 @@ applications/mod_httapi #applications/mod_oreka #applications/mod_osp #applications/mod_prefix -#applications/mod_rad_auth #applications/mod_redis applications/mod_signalwire applications/mod_sms diff --git a/build/modules.conf.most b/build/modules.conf.most index 93327ff7c2..a8e2cde1d0 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -32,7 +32,6 @@ applications/mod_nibblebill applications/mod_oreka #applications/mod_osp applications/mod_prefix -#applications/mod_rad_auth applications/mod_redis applications/mod_signalwire applications/mod_sms diff --git a/configure.ac b/configure.ac index ac4fdca0b5..1b6a435ae2 100755 --- a/configure.ac +++ b/configure.ac @@ -2118,7 +2118,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_oreka/Makefile src/mod/applications/mod_osp/Makefile src/mod/applications/mod_prefix/Makefile - src/mod/applications/mod_rad_auth/Makefile src/mod/applications/mod_random/Makefile src/mod/applications/mod_redis/Makefile src/mod/applications/mod_skel/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index cf7ac11a69..e59092b9f3 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -36,7 +36,6 @@ avoid_mods=( applications/mod_limit applications/mod_mongo applications/mod_osp - applications/mod_rad_auth applications/mod_skel applications/mod_cluechoo codecs/mod_com_g729 diff --git a/debian/control-modules b/debian/control-modules index c63a93e7d2..27361516e8 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -164,10 +164,6 @@ Description: Longest prefix match search This module provides a data store with fast lookups by the longest prefix match (LPM) rule. -Module: applications/mod_rad_auth -Description: RADIUS AA - This module implements RADIUS Authentication and Authorization. - Module: applications/mod_random Description: Entropy extraction This module extracts entropy from FreeSWITCH and feeds it into diff --git a/debian/util.sh b/debian/util.sh index dab53b1d47..c82e681d23 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -105,7 +105,6 @@ getlibs () { getlib http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz #getlib http://download.zeromq.org/zeromq-2.1.9.tar.gz \ # || getlib http://download.zeromq.org/historic/zeromq-2.1.9.tar.gz - getlib http://files.freeswitch.org/downloads/libs/freeradius-client-1.1.7.tar.gz #getlib http://files.freeswitch.org/downloads/libs/v8-3.24.14.tar.bz2 } diff --git a/freeswitch.spec b/freeswitch.spec index 5d02a33adb..75ad292bd2 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -110,10 +110,9 @@ Vendor: http://www.freeswitch.org/ # ###################################################################################################################### Source0: http://files.freeswitch.org/%{name}-%{nonparsedversion}.tar.bz2 -Source1: http://files.freeswitch.org/downloads/libs/freeradius-client-1.1.7.tar.gz -Source2: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz -Source3: http://files.freeswitch.org/downloads/libs/pocketsphinx-0.8.tar.gz -Source4: http://files.freeswitch.org/downloads/libs/sphinxbase-0.8.tar.gz +Source1: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz +Source2: http://files.freeswitch.org/downloads/libs/pocketsphinx-0.8.tar.gz +Source3: http://files.freeswitch.org/downloads/libs/sphinxbase-0.8.tar.gz Prefix: %{prefix} @@ -451,14 +450,6 @@ Provides FreeSWITCH mod_nibblebill, provides a credit/debit module for FreeSWITCH to allow real-time debiting of credit or cash from a database while calls are in progress. -%package application-rad_auth -Summary: FreeSWITCH mod_rad_auth -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description application-rad_auth -Provides FreeSWITCH mod_rad_auth, authentication via RADIUS protocol from FreeSWITCH dialplan - %package application-redis Summary: FreeSWITCH mod_redis Group: System/Libraries @@ -1252,7 +1243,7 @@ APPLICATION_MODULES_DE+="applications/mod_esl" APPLICATION_MODULES_FR="applications/mod_fifo applications/mod_fsk applications/mod_fsv applications/mod_hash \ applications/mod_httapi applications/mod_http_cache applications/mod_lcr applications/mod_limit \ - applications/mod_memcache applications/mod_mongo applications/mod_nibblebill applications/mod_rad_auth \ + applications/mod_memcache applications/mod_mongo applications/mod_nibblebill \ applications/mod_redis " APPLICATION_MODULES_SZ="applications/mod_signalwire applications/mod_sms applications/mod_snapshot \ @@ -1900,9 +1891,6 @@ fi %files application-nibblebill %{MODINSTDIR}/mod_nibblebill.so* -%files application-rad_auth -%{MODINSTDIR}/mod_rad_auth.so* - %files application-redis %{MODINSTDIR}/mod_redis.so* diff --git a/libs/.gitignore b/libs/.gitignore index d2cbc6b7df..def72ad13e 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -57,7 +57,6 @@ opal /esl/Debug/ /esl/Release/ /flite-*/ -/freeradius-client-*/ /ilbc/config-h.in /ilbc/doc/Makefile /ilbc/doc/Makefile.in diff --git a/src/mod/applications/mod_rad_auth/Makefile.am b/src/mod/applications/mod_rad_auth/Makefile.am deleted file mode 100644 index 05f7155a80..0000000000 --- a/src/mod/applications/mod_rad_auth/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_rad_auth - -RADCLIENT_VERSION=1.1.7 -RADCLIENT=freeradius-client-$(RADCLIENT_VERSION) -RADCLIENT_DIR=$(switch_srcdir)/libs/$(RADCLIENT) -RADCLIENT_BUILDDIR=$(switch_builddir)/libs/$(RADCLIENT) -RADCLIENT_LIBDIR=$(RADCLIENT_BUILDDIR)/lib -RADCLIENT_LA=${RADCLIENT_LIBDIR}/libfreeradius-client.la - -mod_LTLIBRARIES = mod_rad_auth.la -mod_rad_auth_la_SOURCES = mod_rad_auth.c -mod_rad_auth_la_CFLAGS = $(AM_CFLAGS) -I$(RADCLIENT_DIR)/include -mod_rad_auth_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(RADCLIENT_LA) -mod_rad_auth_la_LDFLAGS = -avoid-version -module -no-undefined -shared - -BUILT_SOURCES=$(RADCLIENT_LA) - -$(RADCLIENT_DIR): - $(GETLIB) $(RADCLIENT).tar.gz - -$(RADCLIENT_BUILDDIR)/Makefile: $(RADCLIENT_DIR) - mkdir -p $(RADCLIENT_BUILDDIR) - cd $(RADCLIENT_BUILDDIR) && $(DEFAULT_VARS) $(RADCLIENT_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(RADCLIENT_DIR) - $(TOUCH_TARGET) - -$(RADCLIENT_LA): $(RADCLIENT_BUILDDIR)/Makefile - cd $(RADCLIENT_BUILDDIR) && CFLAGS="$(CFLAGS)" $(MAKE) - $(TOUCH_TARGET) diff --git a/src/mod/applications/mod_rad_auth/mod_rad_auth.c b/src/mod/applications/mod_rad_auth/mod_rad_auth.c deleted file mode 100644 index a4d43d545d..0000000000 --- a/src/mod/applications/mod_rad_auth/mod_rad_auth.c +++ /dev/null @@ -1,936 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2014, Anthony Minessale II -* -* 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. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Contributor(s): -* -* Anthony Minessale II -* Neal Horman -* Tihomir Culjaga -* -* mod_rad_auth.c -- module for radius authorization/authentication -* -*/ -#include -#include - -#define RC_CONFIG_FILE "/usr/local/etc/radiusclient/radiusclient.conf" -#define EMBENDED_CONFIG 1 - -#define STR_LENGTH 512 -char* rc_config_file = NULL; - -struct config_vsas -{ - char* name; - int id; - char* value; - int pec; - int expr; - int direction; - - struct config_vsas *pNext; -}; - -struct config_client -{ - char* name; - char* value; - - struct config_client *pNext; -}; - -typedef struct config_vsas CONFIG_VSAS; -typedef struct config_client CONFIG_CLIENT; - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rad_authshutdown); -SWITCH_MODULE_RUNTIME_FUNCTION(mod_rad_authruntime); -SWITCH_MODULE_LOAD_FUNCTION(mod_rad_authload); -SWITCH_MODULE_DEFINITION(mod_rad_auth, mod_rad_authload, mod_rad_authshutdown, NULL /*mod_rad_authruntime*/); - -CONFIG_VSAS* CONFIGVSAS; -CONFIG_CLIENT* CONFIGCLIENT; - -void free_radius_auth_value_pair(VALUE_PAIR *send, VALUE_PAIR *received, rc_handle *rh) -{ - if (send) - rc_avpair_free(send); - - if (received) - rc_avpair_free(received); - - if (rh) - rc_destroy(rh); - rh = NULL; -} - -char* extract_in_variable(char* invar) -{ - char *var = NULL; - if (strlen(invar) < 4) - return NULL; - - while (invar[0] == ' ') - invar++; - - if (invar[0] != 'i' && invar[0] != 'I' && invar[1] != 'n' && invar[1] - != 'N' && invar[2] != ' ' && invar[2] != ' ') - { - return NULL; - } - - var = strchr(invar, ' '); - - while (var[0] == ' ') - var++; - - return var; -} - -char* extract_out_variable(char* outvar) -{ - char *var = NULL; - if (strlen(outvar) < 5) - return NULL; - - while (outvar[0] == ' ') - outvar++; - - if (outvar[0] != 'o' && outvar[0] != 'O' && outvar[1] != 'u' && outvar[1] - != 'U' && outvar[2] != 't' && outvar[2] != 'T' && outvar[3] != ' ' - && outvar[3] != ' ') - { - return NULL; - } - - var = strchr(outvar, ' '); - - while (var[0] == ' ') - { - var++; - } - - return var; -} - - -CONFIG_VSAS* GetVSAS(char* key) -{ - CONFIG_VSAS* PCONFIGVSAS = CONFIGVSAS; - - while(PCONFIGVSAS) - { - if (strcmp(key, PCONFIGVSAS->name) == 0) - { - return PCONFIGVSAS; - } - - PCONFIGVSAS = PCONFIGVSAS->pNext; - } - - return NULL; -} - -char* GetValue(switch_channel_t *channel, CONFIG_VSAS* VSAS, char* value) -{ - if (VSAS == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal Error : VSAS is null object.\n"); - return ""; - } - - if (VSAS->value == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal Error : VSAS->value is null object.\n"); - return ""; - } - - if (VSAS->expr == 1) - { - const char* v = switch_channel_get_variable(channel, VSAS->value); - - if (v != NULL) - { - strcpy(value, v); - return value; - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Undefined channel variable: %s.\n", VSAS->value); - strcpy(value, ""); - return value; - } - } - else - { - strcpy(value, VSAS->value); - return value; - } -} - -int radius_auth_test(switch_channel_t *channel, char* username1, char* passwd1, char* auth_result, char* biling_model, char* credit_amount, char* currency, char* preffered_lang) -{ - int result; - char username[128]; - char passwd[AUTH_PASS_LEN + 1]; - VALUE_PAIR *send, *received; - uint32_t service; - char msg[4096], username_realm[256]; - char *default_realm; - rc_handle *rh; - - strcpy(username, "123"); - strcpy(passwd, "123"); - - if ((rh = rc_read_config(RC_CONFIG_FILE)) == NULL) - return ERROR_RC; - - if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) - return ERROR_RC; - - default_realm = rc_conf_str(rh, "default_realm"); - - - send = NULL; - - /* - * Fill in User-Name - */ - - strncpy(username_realm, username, sizeof(username_realm)); - - /* Append default realm */ - if ((strchr(username_realm, '@') == NULL) && default_realm && - (*default_realm != '\0')) - { - strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1); - strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1); - } - - if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0) == NULL) - return ERROR_RC; - - /* - * Fill in User-Password - */ - - if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL) - return ERROR_RC; - - /* - * Fill in Service-Type - */ - - service = PW_AUTHENTICATE_ONLY; - if (rc_avpair_add(rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) - return ERROR_RC; - - result = rc_auth(rh, 0, send, &received, msg); - - if (result == OK_RC) - { - fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username); - } - else - { - fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result); - } - - return result; - -} - -int radius_auth(switch_channel_t *channel, char* called_number, char* username, char* password , char* auth_result/*, char* biling_model, char* credit_amount, char* currency, char* preffered_lang*/) -{ - int result = OK_RC; - VALUE_PAIR *send = NULL; - VALUE_PAIR *received = NULL; - VALUE_PAIR *service_vp; - DICT_ATTR *pda; - CONFIG_VSAS* PCONFIGVSAS = NULL; - char *default_realm = NULL; - rc_handle *rh = NULL; - int attrid =0; - - char msg[STR_LENGTH * 10 + 1]; - char username_realm[STR_LENGTH + 1]; - char value[STR_LENGTH + 1]; - int integer; - - memset(msg, 0, STR_LENGTH * 10); - memset(username_realm, 0, STR_LENGTH); - - send = NULL; - - - - do - { - -#if EMBENDED_CONFIG - - CONFIG_CLIENT* PCONFIGCLIENT = CONFIGCLIENT; - - rh = rc_new(); - if (rh == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Failed to allocate initial structure.\n"); - result = ERROR_RC; - break; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "allocate initial structure.\n"); - - /* Initialize the config structure */ - - rh = rc_config_init(rh); - if (rh == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"ERROR: Failed to initialze configuration.\n"); - result = ERROR_RC; - break; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"initialzed configuration.\n"); - - while(PCONFIGCLIENT) - { - //if (rc_add_config(rh, "auth_order", "radius", "config", 0) != 0) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value); - if (rc_add_config(rh, PCONFIGCLIENT->name, PCONFIGCLIENT->value, "config", 0) != 0) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Unable to set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value); - - result = ERROR_RC; - break; - } - - PCONFIGCLIENT = PCONFIGCLIENT->pNext; - } - - if (result == ERROR_RC) - break; - - -#else - if ((rh = rc_read_config(!rc_config_file ? RC_CONFIG_FILE : rc_config_file)) == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius config file\n"); - - result = ERROR_RC; - break; - } - -#endif - - if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius dictionary\n"); - - result = ERROR_RC; - break; - } - - default_realm = rc_conf_str(rh, "default_realm"); - if (default_realm == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "default_realm is null object.\n"); - result = ERROR_RC; - break; - } - - strncpy(username_realm, username, sizeof(username_realm)); - - if ((strchr(username_realm, '@') == NULL) && default_realm && - (*default_realm != '\0')) - { - strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1); - strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1); - } - - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "... radius: User-Name: %s\n", username); - if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0)== NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : username\n"); - result = ERROR_RC; - break; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "... radius: User-Password: %s\n", password); - if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, password, -1, 0) == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : password\n"); - result = ERROR_RC; - break; - } - - if (!called_number || strcmp(called_number, "") == 0) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "... radius: Called-station-Id is empty, ignoring...\n"); - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "... radius: Called-station-Id: %s\n", called_number); - if (rc_avpair_add(rh, &send, 30, called_number, -1, 0) == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : Called-station-Id\n"); - result = ERROR_RC; - break; - } - } - - - PCONFIGVSAS = CONFIGVSAS; - - while(PCONFIGVSAS) - { - if (PCONFIGVSAS->direction == 1) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name ); - - memset(value, 0, STR_LENGTH); - GetValue(channel, PCONFIGVSAS, value); - - if (PCONFIGVSAS->pec != 0) - attrid = PCONFIGVSAS->id | (PCONFIGVSAS->pec << 16); - else - attrid = PCONFIGVSAS->id ; - - pda = rc_dict_getattr(rh, attrid); - - if (pda == NULL) - { - result = ERROR_RC; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute: key:%s, not found in dictionary\n", PCONFIGVSAS->name); - break; - } - - if (PCONFIGVSAS->pec != 0 && rc_dict_getvend(rh, PCONFIGVSAS->pec) == NULL) - { - result = ERROR_RC; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown vendor specific id: key:%s, id:%dnot found in dictionary\n", PCONFIGVSAS->name, PCONFIGVSAS->pec); - break; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... dictionary data: id:%d, vendor id:%d, attr type:%d, attr name:%s (%d)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, pda->type, pda->name, attrid); - - switch(pda->type) - { - case PW_TYPE_STRING: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%s) as string\n", PCONFIGVSAS->name, PCONFIGVSAS->value, value); - if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, value, -1, PCONFIGVSAS->pec) == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name); - result = ERROR_RC; - break; - } - break; - - //case PW_TYPE_DATE: - case PW_TYPE_INTEGER: - integer = atoi(value); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as integer\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer); - - - if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name); - result = ERROR_RC; - break; - } - break; - case PW_TYPE_IPADDR: - integer = rc_get_ipaddr(value); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as ipaddr\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer); - - - if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name); - result = ERROR_RC; - break; - } - break; - - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute type: key:%s, type %d\n", PCONFIGVSAS->name, pda->type); - break; - } - } - - PCONFIGVSAS = PCONFIGVSAS->pNext; - } - - - if (result != ERROR_RC) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending radius packet ...\n" ); - result = rc_auth(rh, 0, send, &received, msg); - - - if (result == OK_RC) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "RADIUS Authentication OK\n"); - - strcpy(auth_result, "OK"); - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - " RADIUS Authentication failure (RC=%d)\n", - result); - - strcpy(auth_result, "NOK"); - } - - - - PCONFIGVSAS = CONFIGVSAS; - - while(PCONFIGVSAS) - { - if (PCONFIGVSAS->direction == 0) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name ); - if ((service_vp = rc_avpair_get(received, PCONFIGVSAS->id, PCONFIGVSAS->pec)) != NULL) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tattribute (%s) found in radius packet\n", PCONFIGVSAS->name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tset variable %s := %s\n", PCONFIGVSAS->value, service_vp->strvalue); - - switch_channel_set_variable(channel, PCONFIGVSAS->value, service_vp->strvalue); - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tNo found out attribute id: %d, pec:%d, (%s)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, PCONFIGVSAS->name ); - } - } - - PCONFIGVSAS = PCONFIGVSAS->pNext; - } - } - else - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "abort sending radius packet.\n" ); - break; - } - - } while(1 == 0); - - if (result == ERROR_RC) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "An error occured during RADIUS Authentication(RC=%d)\n", - result); - } - - free_radius_auth_value_pair(send, received, rh); - - return result; -} - -SWITCH_STANDARD_APP(auth_function) -{ - char* in_called_number = NULL; - char *in_username = NULL; - char *in_password = NULL; - - char *out_auth_result = NULL; - /*char *out_biling_model = NULL; - char *out_credit_amount = NULL; - char *out_currency = NULL; - char *out_preffered_lang = NULL;*/ - - char auth_result[STR_LENGTH + 1]; - /*char biling_model[STR_LENGTH + 1]; - char credit_amount[STR_LENGTH + 1]; - char currency[STR_LENGTH + 1]; - char preffered_lang[STR_LENGTH + 1];*/ - - switch_channel_t *channel = switch_core_session_get_channel(session); - - memset(auth_result, 0, STR_LENGTH); - /*memset(biling_model, 0, STR_LENGTH); - memset(credit_amount, 0, STR_LENGTH); - memset(currency, 0, STR_LENGTH); - memset(preffered_lang, 0, STR_LENGTH);*/ - - if (switch_strlen_zero(data)) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "No variable name specified.\n"); - } - else - { - - char *in_called_number_expanded = NULL; - char *in_username_expanded = NULL; - char *in_password_expanded = NULL; - - - in_called_number = switch_core_session_strdup(session, data); - - in_username = strchr(in_called_number, ','); - - if (in_username) - { - *in_username++ = '\0'; - if (switch_strlen_zero(in_username)) - { - in_username = NULL; - } - } - - in_password = strchr(in_username, ','); - - if (in_password) - { - *in_password++ = '\0'; - if (switch_strlen_zero(in_password)) - { - in_password = NULL; - } - } - - out_auth_result = strchr(in_password, ','); - - if (out_auth_result) - { - *out_auth_result++ = '\0'; - if (switch_strlen_zero(out_auth_result)) - { - out_auth_result = NULL; - } - } - - /*out_biling_model = strchr(out_auth_result, ','); - - if (out_biling_model) - { - *out_biling_model++ = '\0'; - if (switch_strlen_zero(out_biling_model)) - { - out_biling_model = NULL; - } - } - - out_credit_amount = strchr(out_biling_model, ','); - - if (out_credit_amount) - { - *out_credit_amount++ = '\0'; - if (switch_strlen_zero(out_credit_amount)) - { - out_credit_amount = NULL; - } - } - - out_currency = strchr(out_credit_amount, ','); - - if (out_currency) - { - *out_currency++ = '\0'; - if (switch_strlen_zero(out_currency)) - { - out_currency = NULL; - } - } - - out_preffered_lang = strchr(out_currency, ','); - - if (out_preffered_lang) - { - *out_preffered_lang++ = '\0'; - if (switch_strlen_zero(out_preffered_lang)) - { - out_preffered_lang = NULL; - } - }*/ - - if (in_called_number) - in_called_number = extract_in_variable(in_called_number); - - in_username = extract_in_variable(in_username); - in_password = extract_in_variable(in_password); - out_auth_result = extract_out_variable(out_auth_result); - /*out_biling_model = extract_out_variable(out_biling_model); - out_credit_amount = extract_out_variable(out_credit_amount); - out_currency = extract_out_variable(out_currency); - out_preffered_lang = extract_out_variable(out_preffered_lang);*/ - - if (!in_username || !in_password) - { - //todo: throw Exception - switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Syntax error.\n" ); - return; - } - - if (in_called_number) - in_called_number_expanded = switch_channel_expand_variables(channel, in_called_number); - - in_username_expanded = switch_channel_expand_variables(channel, in_username); - in_password_expanded = switch_channel_expand_variables(channel, in_password); - - - if (radius_auth(channel, in_called_number_expanded, in_username_expanded, in_password_expanded , - auth_result/*, biling_model, credit_amount, currency, preffered_lang*/) != OK_RC) - { - switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "An error occured during radius authorization.\n"); - } - - - switch_channel_set_variable(channel, out_auth_result, auth_result); - - /*switch_channel_set_variable(channel, out_biling_model, biling_model); - switch_channel_set_variable(channel, out_credit_amount, credit_amount); - switch_channel_set_variable(channel, out_currency, currency); - switch_channel_set_variable(channel, out_preffered_lang, preffered_lang);*/ - - if (in_called_number && in_called_number_expanded && in_called_number_expanded != in_called_number) - { - switch_safe_free(in_called_number_expanded); - } - - if (in_username_expanded && in_username_expanded != in_username) - { - switch_safe_free(in_username_expanded); - } - - if (in_password_expanded && in_password_expanded != in_password) - { - switch_safe_free(in_password_expanded); - } - } -} - - - - -switch_status_t load_config() -{ - CONFIG_VSAS* PCONFIGVSAS = NULL; - CONFIG_CLIENT* PCONFIGCLIENT = NULL; - - char *cf = "rad_auth.conf"; - switch_xml_t cfg, xml, settings, param; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_event_t *params = NULL; - - char *name; - char *id; - char *value; - char *pec; - char *expr; - char* direction; - - CONFIGVSAS = NULL; - CONFIGCLIENT = NULL; - - switch_event_create(¶ms, SWITCH_EVENT_MESSAGE); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", - "profile_rad_auth"); - - //vsas - - if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "open of %s failed\n", cf); - status = SWITCH_STATUS_FALSE; - return status; - } - - if ((settings = switch_xml_child(cfg, "settings"))) - { - for (param = switch_xml_child(settings, "param"); param; param - = param->next) - { - name = (char *) switch_xml_attr_soft(param, "name"); - value = (char *) switch_xml_attr_soft(param, "value"); - - if (strcmp(name, "radius_config") == 0) - { - if (rc_config_file == NULL) - rc_config_file = malloc(STR_LENGTH + 1); - strcpy(rc_config_file, value); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "radius config: %s\n", value); - } - } - } - - if ((settings = switch_xml_child(cfg, "vsas"))) - { - for (param = switch_xml_child(settings, "param"); param; param - = param->next) - { - if (CONFIGVSAS == NULL) - { - CONFIGVSAS = malloc(sizeof(CONFIG_VSAS)); - PCONFIGVSAS = CONFIGVSAS; - } - else - { - PCONFIGVSAS->pNext = malloc(sizeof(CONFIG_VSAS)); - PCONFIGVSAS = PCONFIGVSAS->pNext; - } - - name = (char *) switch_xml_attr_soft(param, "name"); - id = (char *) switch_xml_attr_soft(param, "id"); - value = (char *) switch_xml_attr_soft(param, "value"); - pec = (char *) switch_xml_attr_soft(param, "pec"); - expr = (char *) switch_xml_attr_soft(param, "expr"); - direction = (char *) switch_xml_attr_soft(param, "direction"); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "config attr: %s, %s, %s, %s, %s, %s\n", name, id, value, pec, expr, direction); - - PCONFIGVSAS->name = (char*) malloc(STR_LENGTH + 1); - PCONFIGVSAS->value = (char*) malloc(STR_LENGTH + 1); - - strncpy(PCONFIGVSAS->name, name, STR_LENGTH); - strncpy(PCONFIGVSAS->value, value, STR_LENGTH); - PCONFIGVSAS->id = atoi(id); - PCONFIGVSAS->pec = atoi(pec); - PCONFIGVSAS->expr = atoi(expr); - if(strcmp(direction, "in") == 0) - PCONFIGVSAS->direction = 1; - else - PCONFIGVSAS->direction = 0; - PCONFIGVSAS->pNext = NULL; - } - } - - - if ((settings = switch_xml_child(cfg, "client"))) - { - for (param = switch_xml_child(settings, "param"); param; param - = param->next) - { - if (CONFIGCLIENT == NULL) - { - CONFIGCLIENT = malloc(sizeof(CONFIG_CLIENT)); - PCONFIGCLIENT = CONFIGCLIENT; - } - else - { - PCONFIGCLIENT->pNext = malloc(sizeof(CONFIG_CLIENT)); - PCONFIGCLIENT = PCONFIGCLIENT->pNext; - } - - name = (char *) switch_xml_attr_soft(param, "name"); - value = (char *) switch_xml_attr_soft(param, "value"); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "config client: %s, %s\n", name, value); - - PCONFIGCLIENT->name = (char*) malloc(STR_LENGTH + 1); - PCONFIGCLIENT->value = (char*) malloc(STR_LENGTH + 1); - - strncpy(PCONFIGCLIENT->name, name, STR_LENGTH); - strncpy(PCONFIGCLIENT->value, value, STR_LENGTH); - - PCONFIGCLIENT->pNext = NULL; - } - } - - switch_xml_free(xml); - return status; -} - - - - -SWITCH_MODULE_LOAD_FUNCTION(mod_rad_authload) -{ - switch_application_interface_t *app_interface; - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "auth_function", NULL, NULL, auth_function, "in , in , out , out , out , out , out ", SAF_SUPPORT_NOMEDIA); - - load_config(); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "mod rad_auth services is loaded.\n"); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_RUNTIME_FUNCTION(mod_rad_authruntime) -{ - return SWITCH_STATUS_TERM; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rad_authshutdown) -{ - CONFIG_VSAS* PCONFIGVSAS = CONFIGVSAS; - CONFIG_CLIENT* PCONFIGCLIENT = CONFIGCLIENT; - - CONFIG_VSAS* tmpVSAS = NULL; - CONFIG_CLIENT* tmpCLIENT = NULL; - - while(PCONFIGVSAS) - { - if (PCONFIGVSAS->name) - free(PCONFIGVSAS->name); - PCONFIGVSAS->name = NULL; - - if (PCONFIGVSAS->value) - free(PCONFIGVSAS->value); - PCONFIGVSAS->value = NULL; - - tmpVSAS = PCONFIGVSAS; - PCONFIGVSAS = PCONFIGVSAS->pNext; - - free(tmpVSAS); - } - - CONFIGVSAS = NULL; - - - while(PCONFIGCLIENT) - { - if (PCONFIGCLIENT->name) - free(PCONFIGCLIENT->name); - PCONFIGCLIENT->name = NULL; - - if (PCONFIGCLIENT->value) - free(PCONFIGCLIENT->value); - PCONFIGCLIENT->value = NULL; - - tmpCLIENT = PCONFIGCLIENT; - PCONFIGCLIENT = PCONFIGCLIENT->pNext; - - free(tmpCLIENT); - } - - CONFIGCLIENT = NULL; - - return SWITCH_STATUS_SUCCESS; -} - - From 2b52002e7564f1ecbe85f1e0cc306ebf4ceb6c19 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 13 Dec 2024 19:49:44 +0300 Subject: [PATCH 200/205] [mod_khomp] Remove from tree --- LICENSE | 12 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - .../vanilla/autoload_configs/modules.conf.xml | 1 - configure.ac | 3 +- debian/bootstrap.sh | 1 - debian/control-modules | 4 - debian/copyright | 12 - debian/license-reconcile.yml | 12 - freeswitch.spec | 13 +- .../mod_khomp/Install/files/khomp.conf.xml | 511 --- src/mod/endpoints/mod_khomp/Makefile.am | 51 - .../mod_khomp/commons/base/atomic.hpp | 203 - .../mod_khomp/commons/base/config_commons.hpp | 74 - .../mod_khomp/commons/base/config_options.cpp | 302 -- .../mod_khomp/commons/base/config_options.hpp | 798 ---- .../commons/base/configurator/configfile.cpp | 240 -- .../commons/base/configurator/configfile.hpp | 90 - .../commons/base/configurator/option.cpp | 186 - .../commons/base/configurator/option.hpp | 128 - .../commons/base/configurator/restriction.cpp | 358 -- .../commons/base/configurator/restriction.hpp | 269 -- .../commons/base/configurator/section.cpp | 136 - .../commons/base/configurator/section.hpp | 260 -- .../mod_khomp/commons/base/const_this.hpp | 15 - .../mod_khomp/commons/base/flagger.hpp | 102 - .../mod_khomp/commons/base/format.cpp | 337 -- .../mod_khomp/commons/base/format.hpp | 561 --- .../mod_khomp/commons/base/function.hpp | 429 -- .../mod_khomp/commons/base/initializer.hpp | 80 - .../mod_khomp/commons/base/k3lapi.cpp | 318 -- .../mod_khomp/commons/base/k3lapi.hpp | 494 --- .../mod_khomp/commons/base/k3lutil.cpp | 206 - .../mod_khomp/commons/base/k3lutil.hpp | 80 - .../mod_khomp/commons/base/logger.hpp | 557 --- .../mod_khomp/commons/base/noncopyable.hpp | 54 - .../mod_khomp/commons/base/refcounter.hpp | 268 -- .../mod_khomp/commons/base/regex.cpp | 149 - .../mod_khomp/commons/base/regex.hpp | 243 -- .../mod_khomp/commons/base/ringbuffer.cpp | 485 --- .../mod_khomp/commons/base/ringbuffer.hpp | 448 -- .../commons/base/saved_condition.cpp | 46 - .../commons/base/saved_condition.hpp | 61 - .../mod_khomp/commons/base/scoped_lock.hpp | 95 - .../mod_khomp/commons/base/simple_lock.hpp | 104 - .../mod_khomp/commons/base/strings.cpp | 267 -- .../mod_khomp/commons/base/strings.hpp | 113 - .../system/freeswitch/saved_condition.cpp | 62 - .../system/freeswitch/saved_condition.hpp | 136 - .../base/system/freeswitch/simple_lock.hpp | 177 - .../commons/base/system/freeswitch/thread.hpp | 330 -- .../mod_khomp/commons/base/tagged_union.hpp | 313 -- .../mod_khomp/commons/base/thread.hpp | 103 - .../mod_khomp/commons/base/timer.cpp | 366 -- .../mod_khomp/commons/base/timer.hpp | 231 -- .../mod_khomp/commons/base/types.hpp | 99 - .../mod_khomp/commons/base/variable.hpp | 124 - .../mod_khomp/commons/base/verbose.cpp | 2992 -------------- .../mod_khomp/commons/base/verbose.hpp | 303 -- .../commons/tools/generate-verbose-headers.sh | 183 - src/mod/endpoints/mod_khomp/docs/Manual.html | 1091 ----- src/mod/endpoints/mod_khomp/docs/Manual.pdf | Bin 470577 -> 0 bytes src/mod/endpoints/mod_khomp/docs/README.html | 39 - src/mod/endpoints/mod_khomp/docs/README.pdf | Bin 399111 -> 0 bytes .../endpoints/mod_khomp/docs/README_en.html | 39 - .../endpoints/mod_khomp/docs/README_en.pdf | Bin 314423 -> 0 bytes .../endpoints/mod_khomp/docs/User_Guide.html | 1093 ----- .../endpoints/mod_khomp/docs/User_Guide.pdf | Bin 464991 -> 0 bytes .../mod_khomp/examples/intercept.xml | 26 - .../endpoints/mod_khomp/examples/transfer.xml | 43 - .../mod_khomp/include/applications.h | 1037 ----- src/mod/endpoints/mod_khomp/include/cli.h | 1273 ------ src/mod/endpoints/mod_khomp/include/defs.h | 210 - src/mod/endpoints/mod_khomp/include/frame.h | 160 - src/mod/endpoints/mod_khomp/include/globals.h | 121 - src/mod/endpoints/mod_khomp/include/k3l.h | 2009 --------- .../endpoints/mod_khomp/include/khomp_pvt.h | 1349 ------- .../mod_khomp/include/khomp_pvt_fxo.h | 395 -- .../mod_khomp/include/khomp_pvt_gsm.h | 333 -- .../mod_khomp/include/khomp_pvt_kxe1.h | 1198 ------ .../mod_khomp/include/khomp_pvt_passive.h | 305 -- src/mod/endpoints/mod_khomp/include/lock.h | 86 - src/mod/endpoints/mod_khomp/include/logger.h | 141 - src/mod/endpoints/mod_khomp/include/opt.h | 266 -- .../endpoints/mod_khomp/include/revision.h | 1 - src/mod/endpoints/mod_khomp/include/spec.h | 91 - src/mod/endpoints/mod_khomp/include/utils.h | 783 ---- src/mod/endpoints/mod_khomp/mod_khomp.cpp | 1524 ------- .../endpoints/mod_khomp/src/applications.cpp | 976 ----- src/mod/endpoints/mod_khomp/src/cli.cpp | 3141 -------------- src/mod/endpoints/mod_khomp/src/frame.cpp | 124 - src/mod/endpoints/mod_khomp/src/globals.cpp | 68 - src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp | 2607 ------------ .../endpoints/mod_khomp/src/khomp_pvt_fxo.cpp | 821 ---- .../endpoints/mod_khomp/src/khomp_pvt_gsm.cpp | 572 --- .../mod_khomp/src/khomp_pvt_kxe1.cpp | 3590 ----------------- .../mod_khomp/src/khomp_pvt_passive.cpp | 295 -- src/mod/endpoints/mod_khomp/src/lock.cpp | 138 - src/mod/endpoints/mod_khomp/src/logger.cpp | 437 -- src/mod/endpoints/mod_khomp/src/opt.cpp | 694 ---- src/mod/endpoints/mod_khomp/src/spec.cpp | 893 ---- src/mod/endpoints/mod_khomp/src/utils.cpp | 682 ---- .../mod_khomp/support/config_defaults.cpp | 50 - .../mod_khomp/support/config_defaults.hpp | 75 - .../mod_khomp/support/klog-config.cpp | 126 - .../mod_khomp/support/klog-config.hpp | 75 - .../mod_khomp/support/klog-options.cpp | 158 - .../mod_khomp/support/klog-options.hpp | 81 - src/mod/endpoints/mod_khomp/tools/getk3l.sh | 116 - .../endpoints/mod_khomp/tools/getversion.sh | 51 - 110 files changed, 2 insertions(+), 43978 deletions(-) delete mode 100644 src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml delete mode 100644 src/mod/endpoints/mod_khomp/Makefile.am delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/atomic.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/config_options.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/config_options.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/option.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/option.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/section.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/configurator/section.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/const_this.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/flagger.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/format.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/format.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/function.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/initializer.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/k3lapi.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/k3lapi.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/k3lutil.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/k3lutil.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/logger.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/noncopyable.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/refcounter.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/regex.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/regex.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/ringbuffer.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/ringbuffer.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/saved_condition.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/saved_condition.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/scoped_lock.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/simple_lock.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/strings.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/strings.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/simple_lock.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/tagged_union.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/thread.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/timer.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/timer.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/types.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/variable.hpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/verbose.cpp delete mode 100644 src/mod/endpoints/mod_khomp/commons/base/verbose.hpp delete mode 100755 src/mod/endpoints/mod_khomp/commons/tools/generate-verbose-headers.sh delete mode 100644 src/mod/endpoints/mod_khomp/docs/Manual.html delete mode 100644 src/mod/endpoints/mod_khomp/docs/Manual.pdf delete mode 100644 src/mod/endpoints/mod_khomp/docs/README.html delete mode 100644 src/mod/endpoints/mod_khomp/docs/README.pdf delete mode 100644 src/mod/endpoints/mod_khomp/docs/README_en.html delete mode 100644 src/mod/endpoints/mod_khomp/docs/README_en.pdf delete mode 100644 src/mod/endpoints/mod_khomp/docs/User_Guide.html delete mode 100644 src/mod/endpoints/mod_khomp/docs/User_Guide.pdf delete mode 100644 src/mod/endpoints/mod_khomp/examples/intercept.xml delete mode 100644 src/mod/endpoints/mod_khomp/examples/transfer.xml delete mode 100644 src/mod/endpoints/mod_khomp/include/applications.h delete mode 100644 src/mod/endpoints/mod_khomp/include/cli.h delete mode 100644 src/mod/endpoints/mod_khomp/include/defs.h delete mode 100644 src/mod/endpoints/mod_khomp/include/frame.h delete mode 100644 src/mod/endpoints/mod_khomp/include/globals.h delete mode 100644 src/mod/endpoints/mod_khomp/include/k3l.h delete mode 100644 src/mod/endpoints/mod_khomp/include/khomp_pvt.h delete mode 100644 src/mod/endpoints/mod_khomp/include/khomp_pvt_fxo.h delete mode 100644 src/mod/endpoints/mod_khomp/include/khomp_pvt_gsm.h delete mode 100644 src/mod/endpoints/mod_khomp/include/khomp_pvt_kxe1.h delete mode 100644 src/mod/endpoints/mod_khomp/include/khomp_pvt_passive.h delete mode 100644 src/mod/endpoints/mod_khomp/include/lock.h delete mode 100644 src/mod/endpoints/mod_khomp/include/logger.h delete mode 100644 src/mod/endpoints/mod_khomp/include/opt.h delete mode 100644 src/mod/endpoints/mod_khomp/include/revision.h delete mode 100644 src/mod/endpoints/mod_khomp/include/spec.h delete mode 100644 src/mod/endpoints/mod_khomp/include/utils.h delete mode 100644 src/mod/endpoints/mod_khomp/mod_khomp.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/applications.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/cli.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/frame.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/globals.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/khomp_pvt_fxo.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/khomp_pvt_gsm.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/khomp_pvt_kxe1.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/khomp_pvt_passive.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/lock.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/logger.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/opt.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/spec.cpp delete mode 100644 src/mod/endpoints/mod_khomp/src/utils.cpp delete mode 100644 src/mod/endpoints/mod_khomp/support/config_defaults.cpp delete mode 100644 src/mod/endpoints/mod_khomp/support/config_defaults.hpp delete mode 100644 src/mod/endpoints/mod_khomp/support/klog-config.cpp delete mode 100644 src/mod/endpoints/mod_khomp/support/klog-config.hpp delete mode 100644 src/mod/endpoints/mod_khomp/support/klog-options.cpp delete mode 100644 src/mod/endpoints/mod_khomp/support/klog-options.hpp delete mode 100755 src/mod/endpoints/mod_khomp/tools/getk3l.sh delete mode 100755 src/mod/endpoints/mod_khomp/tools/getversion.sh diff --git a/LICENSE b/LICENSE index e3c1b831e3..2fb4682ad0 100644 --- a/LICENSE +++ b/LICENSE @@ -1484,18 +1484,6 @@ Copyright: 2010 Ilnitskiy Mixim (max.h323@gmail.com) 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru) License: MPL-1.1 -Files: src/mod/endpoints/mod_khomp/* -Copyright: 2007-2010 Khomp Ind. & Com. -License: MPL-1.1 or LGPL-2.1+ - -Files: src/mod/endpoints/mod_khomp/mod_khomp.cpp -Copyright: 2005-2014, Anthony Minessale II -License: MPL-1.1 - -Files: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp -Copyright: 1998 Doug Rabson -License: BSD-2-clause - Files: src/mod/languages/mod_java/modjava.c Copyright: 2007, Damjan Jovanovic License: MPL-1.1 diff --git a/build/modules.conf.in b/build/modules.conf.in index dd5a6a88ff..95d47294d0 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -71,7 +71,6 @@ dialplans/mod_dialplan_xml #directories/mod_ldap #endpoints/mod_alsa #endpoints/mod_h323 -#endpoints/mod_khomp endpoints/mod_loopback #endpoints/mod_opal endpoints/mod_rtc diff --git a/build/modules.conf.most b/build/modules.conf.most index a8e2cde1d0..fdf5d61ac9 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -70,7 +70,6 @@ dialplans/mod_dialplan_xml directories/mod_ldap #endpoints/mod_alsa #endpoints/mod_h323 -#endpoints/mod_khomp endpoints/mod_loopback #endpoints/mod_opal endpoints/mod_rtc diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 8f7fa9285f..3e48242643 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -41,7 +41,6 @@ - diff --git a/configure.ac b/configure.ac index 1b6a435ae2..cced754c5f 100755 --- a/configure.ac +++ b/configure.ac @@ -1079,7 +1079,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xclang" ; then fi # Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready -# Untested modules : mod_osp mod_opal mod_h323 mod_khomp +# Untested modules : mod_osp mod_opal mod_h323 # mod_erlang_event mod_snmp mod_perl mod_java mod_managed # #saved_CFLAGS="$CFLAGS" @@ -2160,7 +2160,6 @@ AC_CONFIG_FILES([Makefile src/mod/directories/mod_ldap/Makefile src/mod/endpoints/mod_alsa/Makefile src/mod/endpoints/mod_h323/Makefile - src/mod/endpoints/mod_khomp/Makefile src/mod/endpoints/mod_loopback/Makefile src/mod/endpoints/mod_opal/Makefile src/mod/endpoints/mod_reference/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index e59092b9f3..429110e2f6 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -43,7 +43,6 @@ avoid_mods=( codecs/mod_siren codecs/mod_skel_codec endpoints/mod_h323 - endpoints/mod_khomp endpoints/mod_opal endpoints/mod_reference event_handlers/mod_smpp diff --git a/debian/control-modules b/debian/control-modules index 27361516e8..813247deba 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -365,10 +365,6 @@ Description: mod_h323 Adds mod_h323. Build-Depends: libopenh323-dev | libh323plus-dev, libpt-dev -Module: endpoints/mod_khomp -Description: mod_khomp - Adds mod_khomp. - Module: endpoints/mod_loopback Description: mod_loopback Adds mod_loopback. diff --git a/debian/copyright b/debian/copyright index 61669a3e06..c39ceefb99 100755 --- a/debian/copyright +++ b/debian/copyright @@ -1484,18 +1484,6 @@ Copyright: 2010 Ilnitskiy Mixim (max.h323@gmail.com) 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru) License: MPL-1.1 -Files: src/mod/endpoints/mod_khomp/* -Copyright: 2007-2010 Khomp Ind. & Com. -License: MPL-1.1 or LGPL-2.1+ - -Files: src/mod/endpoints/mod_khomp/mod_khomp.cpp -Copyright: 2005-2014, Anthony Minessale II -License: MPL-1.1 - -Files: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp -Copyright: 1998 Doug Rabson -License: BSD-2-clause - Files: src/mod/languages/mod_java/modjava.c Copyright: 2007, Damjan Jovanovic License: MPL-1.1 diff --git a/debian/license-reconcile.yml b/debian/license-reconcile.yml index 22fdb40a19..d547556a3c 100644 --- a/debian/license-reconcile.yml +++ b/debian/license-reconcile.yml @@ -149,18 +149,6 @@ Rules: Matches: const\schar\s\*\scopyright\s; Copyright: 1999-2009 Erik de Castro Lopo Justification: prevent false-psitive copyright detection - - - Glob: src/mod/endpoints/mod_khomp/* - Matches: The\scontents\sof\sthis\sfile\sare\ssubject\sto\sthe\sMozilla\sPublic\sLicense\sVersion\s1.1 - Matches: Alternatively,\sthe\scontents\sof\sthis\sfile\smay\sbe\sused\sunder\sthe\sterms\sof\sthe - Matches: GNU\sLesser\sGeneral\sPublic\sLicense\s2\.1.\slicense\s\(the\s.LGPL.\sLicense\),\sin\swhich - Matches: version\s2\.1\sof\sthe\sLicense,\sor\s\(at\syour\soption\)\sany\slater\sversion. - License: MPL-1.1 or LGPL-2.1+ - - - Glob: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp - Matches: Original\scopyright\sfollows[:] - Matches: Copyright\s\(c\)\s1998\sDoug\sRabson - Copyright: 1998 Doug Rabson - Glob: libs/esl/getopt/getopt_long.c Matches: This\scode\sis\sderived\sfrom\ssoftware\scontributed\sto\sThe\sNetBSD\sFoundation diff --git a/freeswitch.spec b/freeswitch.spec index 75ad292bd2..1864521459 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -747,14 +747,6 @@ PostgreSQL native support for FreeSWITCH. #%description endpoint-h323 #H.323 endpoint support for FreeSWITCH open source telephony platform -#%package endpoint-khomp -#Summary: khomp endpoint support for FreeSWITCH open source telephony platform -#Group: System/Libraries -#Requires: %{name} = %{version}-%{release} -# -#%description endpoint-khomp -#Khomp hardware endpoint support for FreeSWITCH open source telephony platform. - %package endpoint-rtmp Summary: RTPM Endpoint support for FreeSWITCH open source telephony platform Group: System/Libraries @@ -1300,7 +1292,7 @@ ENDPOINTS_MODULES=" \ endpoints/mod_loopback endpoints/mod_rtmp \ endpoints/mod_skinny endpoints/mod_verto endpoints/mod_rtc endpoints/mod_sofia" -## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_h323 endpoints/mod_khomp +## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_h323 ###################################################################################################################### # @@ -2009,9 +2001,6 @@ fi #%files endpoint-h323 #%{MODINSTDIR}/mod_h323.so* -#%files endpoint-khomp -#%{MODINSTDIR}/mod_khomp.so* - %files endpoint-rtmp %{MODINSTDIR}/mod_rtmp.so* diff --git a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml deleted file mode 100644 index 6778ef7cb2..0000000000 --- a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml +++ /dev/null @@ -1,511 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_khomp/Makefile.am b/src/mod/endpoints/mod_khomp/Makefile.am deleted file mode 100644 index 43e803d073..0000000000 --- a/src/mod/endpoints/mod_khomp/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_khomp -mod_LTLIBRARIES = mod_khomp.la -mod_khomp_la_SOURCES = mod_khomp.cpp -mod_khomp_la_CFLAGS = $(AM_CFLAGS) -mod_khomp_la_CFLAGS += -I./ -I./include -I./commons -I./commons/base -I./support -mod_khomp_la_CFLAGS += -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM -DCOMMONS_LIBRARY_USING_FREESWITCH -mod_khomp_la_CFLAGS += -DFS_VERSION_MAJOR=`./tools/getversion.sh "SWITCH_VERSION_MAJOR" $(switch_srcdir)` -mod_khomp_la_CFLAGS += -DFS_VERSION_MINOR=`./tools/getversion.sh "SWITCH_VERSION_MINOR" $(switch_srcdir)` -mod_khomp_la_CFLAGS += -DFS_VERSION_MICRO=`./tools/getversion.sh "SWITCH_VERSION_MICRO" $(switch_srcdir)` -mod_khomp_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_khomp_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lk3l -KHOMP_MODDIR=$(switch_srcdir)/src/mod/endpoints/mod_khomp -TOOLS_DIR=$(KHOMP_MODDIR)/commons/tools - -mod_khomp_la_SOURCES += ./commons/base/k3lapi.cpp ./commons/base/k3lutil.cpp ./commons/base/config_options.cpp ./commons/base/format.cpp ./commons/base/strings.cpp ./commons/base/ringbuffer.cpp ./commons/base/verbose.cpp ./commons/base/saved_condition.cpp ./commons/base/regex.cpp ./commons/base/timer.cpp ./commons/base/configurator/configfile.cpp ./commons/base/configurator/option.cpp ./commons/base/configurator/section.cpp ./commons/base/configurator/restriction.cpp ./commons/base/verbose_traits.cpp -mod_khomp_la_SOURCES += ./support/klog-config.cpp ./support/klog-options.cpp ./support/config_defaults.cpp -mod_khomp_la_SOURCES += ./src/globals.cpp ./src/opt.cpp ./src/frame.cpp ./src/utils.cpp ./src/lock.cpp ./src/spec.cpp ./src/applications.cpp ./src/khomp_pvt_fxo.cpp ./src/khomp_pvt_gsm.cpp ./src/khomp_pvt_kxe1.cpp ./src/khomp_pvt_passive.cpp ./src/khomp_pvt.cpp ./src/logger.cpp ./src/cli.cpp - -conf_file_name = khomp.conf.xml -conf_file_dir = ./Install/files -conf_file_dir_alt = ./conf -conf_file_install = $(sysconfdir)/autoload_configs - -BUILT_SOURCES=verbose_traits.hpp verbose_traits.cpp - -verbose_traits.hpp verbose_traits.cpp: - @if test ! -f $(KHOMP_MODDIR)/commons/base/verbose_traits.hpp || test ! -f $(KHOMP_MODDIR)/commons/base/verbose_traits.cpp ; then \ - echo "Generating verbose_traits" ;\ - bash $(TOOLS_DIR)/generate-verbose-headers.sh $(KHOMP_MODDIR)/commons/base/ include/k3l.h ;\ - fi; - -install-data-local: - @if test "w`kserver --version 2>/dev/null | grep 2.1`" == "w" ; then \ - echo "###############################################################################" ;\ - echo "Install k3l from KHOMP." ;\ - echo "Run: ./tools/getk3l.sh" ;\ - echo "###############################################################################" ;\ - exit 1;\ - fi; - @echo "Copy $(conf_file_name)" - @if test -d $(conf_file_install) ; then \ - if test -f $(conf_file_dir)/$(conf_file_name) ; then \ - cp $(conf_file_dir)/$(conf_file_name) $(conf_file_install)/$(conf_file_name).new ;\ - else \ - cp $(conf_file_dir_alt)/$(conf_file_name) $(conf_file_install)/$(conf_file_name).new ;\ - fi; \ - if test ! -f "$(conf_file_install)/$(conf_file_name)" ; then \ - mv $(conf_file_install)/$(conf_file_name).new $(conf_file_install)/$(conf_file_name) ;\ - fi; \ - fi; diff --git a/src/mod/endpoints/mod_khomp/commons/base/atomic.hpp b/src/mod/endpoints/mod_khomp/commons/base/atomic.hpp deleted file mode 100644 index 02278b390c..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/atomic.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - - This code was based on FreeBSD 7.X SVN (sys/i386/include/atomic.h), - with changes regarding optimizations and generalizations, and a - remake of the interface to fit use C++ features. - - Code is distributed under original license. - Original copyright follows: - - * Copyright (c) 1998 Doug Rabson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - -*/ - -#ifndef _ATOMIC_HPP_ -#define _ATOMIC_HPP_ - -namespace Atomic -{ - // Macros used to insert compare and exchange instructions easily into functions. - - #define MAKE_CMPXCHG_FUNCTION(INS, PTR, EXP, VAL, TYPE) \ - PunnedType pexp; pexp.valtype = EXP; \ - PunnedType pval; pval.valtype = VAL; \ - TYPE vexp = *(pexp.podtype); \ - TYPE vval = *(pval.podtype); \ - TYPE res; \ - unsigned char chg = 0; \ - asm volatile("lock;" INS "sete %1;" \ - : "=a" (res), /* 0 */ \ - "=q" (chg), /* 1 */ \ - "=m" (*(unsigned char **)(PTR)) /* 2 */ \ - : "r" (vval), /* 3 */ \ - "a" (vexp), /* 4 */ \ - "m" (*(unsigned char **)(PTR)) /* 5 */ \ - : "memory"); \ - *(pexp.podtype) = res; \ - return (chg != 0 ? true : false); - - #define MAKE_CMPXCHG8B_FUNCTION(PTR,EXP,VAL) \ - PunnedType pexp; pexp.valtype = EXP; \ - PunnedType pval; pval.valtype = VAL; \ - unsigned long long vexp = *(pexp.podtype); \ - unsigned long long vval = *(pval.podtype); \ - unsigned long vval32 = (unsigned long)vval; \ - unsigned char chg = 0; \ - asm volatile( \ - "xchgl %%ebx, %4;" \ - "lock; cmpxchg8b %2; sete %1;" \ - "movl %4, %%ebx; " \ - : "+A" (vexp), /* 0 (result) */ \ - "=c" (chg) /* 1 */ \ - : "m" (*(unsigned char**)(PTR)), /* 2 */ \ - "c" ((unsigned long)(vval >> 32)), \ - "m" (vval32)); \ - *(pexp.podtype) = vexp; \ - return (chg != 0 ? true : false); - -// "movl %%ecx, %4;" -// -// "m" (*((unsigned long*)(*(pval.podtype)))), -// "m" ((unsigned long)(vval >> 32)) -// -// "m" (*((unsigned long*)(&vval))), -// "m" ((unsigned long)(vval >> 32)) -// -// unsigned long long vval = *(pval.podtype); -// unsigned long long res = (unsigned long long)exp; -// - // Types used for making CMPXCHG instructions independent from base type. - - template < typename ValType, typename PodType > - union PunnedTypeTemplate - { - ValType * valtype; - PodType * podtype; - }; - - template < int SizeOfType, typename ReturnType > - struct HelperCreateCAS; - - template < typename ValType > - struct HelperCreateCAS<4, ValType> - { - #if !defined(__LP64__) && !defined(__LP64) - typedef unsigned long BaseType; - #else - typedef unsigned int BaseType; - #endif - - typedef PunnedTypeTemplate< ValType, BaseType > PunnedType; - - inline static bool apply(volatile void *p, ValType * exp, ValType now) - { - #if !defined(__LP64__) && !defined(__LP64) - MAKE_CMPXCHG_FUNCTION("cmpxchgl %3,%5;", p, exp, &now, BaseType); - #else - MAKE_CMPXCHG_FUNCTION("cmpxchgl %k3,%5;", p, exp, &now, BaseType); - #endif - } - }; - - template < typename ValType > - struct HelperCreateCAS<8, ValType> - { - #if !defined(__LP64__) && !defined(__LP64) - typedef unsigned long long BaseType; - #else - typedef unsigned long BaseType; - #endif - - typedef PunnedTypeTemplate< ValType, BaseType > PunnedType; - - inline static volatile ValType apply(volatile void *p, ValType * exp, ValType now) - { - #if !defined(__LP64__) && !defined(__LP64) - MAKE_CMPXCHG8B_FUNCTION(p, exp, &now); - #else - MAKE_CMPXCHG_FUNCTION("cmpxchgq %3,%5;", p, exp, &now, BaseType); - #endif - } - - }; - - // The CAS function itself. - - template < typename ValType > - inline bool doCAS(volatile ValType * p, ValType * o, ValType n) - { - return HelperCreateCAS::apply(static_cast(p), o, n); - }; - - template < typename ValType > - inline bool doCAS(volatile ValType * p, ValType o, ValType n) - { - return HelperCreateCAS::apply(static_cast(p), &o, n); - }; - - #undef MAKE_CMPXCHG_32_FUNCTION - #undef MAKE_CMPXCHG_64_FUNCTION - - #define MAKE_LOCKED_TEMPLATE(NAME) \ - template < typename ValType > inline void do##NAME(volatile ValType * p, ValType v); \ - template < typename ValType > inline void do##NAME(volatile ValType * p); - - #define MAKE_LOCKED_FUNCTION(NAME, TYPE, INS, CONS, VAL) \ - template < > inline void do##NAME < TYPE > (volatile TYPE * p, TYPE v){ asm volatile("lock;" INS : "=m" (*p) : CONS (VAL), "m" (*p)); } \ - template < > inline void do##NAME < TYPE > (volatile TYPE * p) { asm volatile("lock;" INS : "=m" (*p) : CONS (1), "m" (*p)); } - - #define MAKE_LOCKED_FUNCTIONS(NAME, TYPE, INS, CONS, VAL) \ - MAKE_LOCKED_FUNCTION(NAME, TYPE, INS, CONS, VAL) \ - MAKE_LOCKED_FUNCTION(NAME, unsigned TYPE, INS, CONS, VAL) - - MAKE_LOCKED_TEMPLATE(Add); - MAKE_LOCKED_TEMPLATE(Sub); - MAKE_LOCKED_TEMPLATE(SetBits); - MAKE_LOCKED_TEMPLATE(ClearBits); - - MAKE_LOCKED_FUNCTIONS(Add, int, "addl %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(Sub, int, "subl %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(SetBits, int, "orl %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(ClearBits, int, "andl %1,%0", "ir", ~v); - - #if !defined(__LP64__) && !defined(__LP64) - - MAKE_LOCKED_FUNCTIONS(Add, long, "addl %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(Sub, long, "subl %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(SetBits, long, "orl %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(ClearBits, long, "andl %1,%0", "ir", ~v); - - #else - - MAKE_LOCKED_FUNCTIONS(Add, long, "addq %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(Sub, long, "subq %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(SetBits, long, "orq %1,%0", "ir", v); - MAKE_LOCKED_FUNCTIONS(ClearBits, long, "andq %1,%0", "ir", ~v); - - #endif -}; - -#endif /* _ATOMIC_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp b/src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp deleted file mode 100644 index 14f8a19d2c..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _CONFIG_COMMONS_HPP_ -#define _CONFIG_COMMONS_HPP_ - -/****************************************************************************/ -/* ASTERISK */ -#if defined(COMMONS_LIBRARY_USING_ASTERISK) - #define COMMONS_IMPLEMENTATION asterisk -/****************************************************************************/ -/* CALLWEAVER */ -#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) - #define COMMONS_IMPLEMENTATION callweaver -/****************************************************************************/ -/* FREESWITCH */ -#elif defined(COMMONS_LIBRARY_USING_FREESWITCH) - #define COMMONS_IMPLEMENTATION freeswitch -/****************************************************************************/ -/* GNU/LINUX (generic) */ -#elif defined(COMMONS_LIBRARY_USING_GNU_LINUX) - #define COMMONS_IMPLEMENTATION gnulinux -/****************************************************************************/ -#else - #error Unknown implementation selected. Please define COMMONS_LIBRARY_USING_* correctly. -#endif - -#define COMMONS_INCLUDE(file) - -#define COMMONS_VERSION_MAJOR 1 -#define COMMONS_VERSION_MINOR 1 - -#define COMMONS_AT_LEAST(x,y) \ - ((COMMONS_VERSION_MAJOR > x) || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y)) - -#endif /* _CONFIG_COMMONS_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/config_options.cpp b/src/mod/endpoints/mod_khomp/commons/base/config_options.cpp deleted file mode 100644 index 7412b4b1a0..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/config_options.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -void Config::Restriction::checkRange(const std::string & name, const SIntType value, const Range < SIntType > & range) -{ - if (value < range.minimum) - throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % name)); - - if (value > range.maximum) - throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % name)); - - if (((value - range.minimum) % range.step) != 0) - throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % name)); -} - -void Config::Restriction::checkRange(const std::string & name, const UIntType value, const Range < UIntType > & range) -{ - if (value < range.minimum) - throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % name)); - - if (value > range.maximum) - throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % name)); - - if (((value - range.minimum) % range.step) != 0) - throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % name)); -} - -void Config::Restriction::checkStringSet(const std::string & name, const StringType & value, const StringSet & allowed) -{ - if (allowed.empty()) - return; - - if (allowed.find(value) != allowed.end()) - return; - - std::string strlist; - - for (StringSet::const_iterator i = allowed.begin(); i != allowed.end(); i++) - { - strlist += " '"; - strlist += (*i); - strlist += "'"; - } - - throw Failure(STG(FMT("value '%s' not allowed for option '%s' (allowed values:%s)") - % value % name % strlist)); -} - -Config::Option::Option(std::string name, Config::Option::StringMemberType value, const StringType defvalue, StringSet & allowed, bool listme) -: _myname(name), _option(InnerStringType(name, value, defvalue, allowed)), _listme(listme), _values(NULL) -{}; - -Config::Option::Option(std::string name, Config::Option::StringMemberType value, const StringType defvalue, bool listme) -: _myname(name), _option(InnerStringType(name, value, defvalue)), _listme(listme), _values(NULL) -{}; - -Config::Option::Option(std::string name, Config::Option::BooleanMemberType value, const BooleanType defvalue, bool listme) -: _myname(name), _option(InnerBooleanType(name, value, defvalue)), _listme(listme), _values(NULL) -{}; - -Config::Option::Option(std::string name, Config::Option::SIntMemberType value, const SIntType defvalue, - SIntType min, SIntType max, SIntType step, bool listme) -: _myname(name), _option(InnerSIntType(name, value, defvalue, min, max, step)), _listme(listme), _values(NULL) -{}; - -Config::Option::Option(std::string name, Config::Option::UIntMemberType value, const UIntType defvalue, - UIntType min, UIntType max, UIntType step, bool listme) -: _myname(name), _option(InnerUIntType(name, value, defvalue, min, max, step)), _listme(listme), _values(NULL) -{}; - -Config::Option::Option(const Config::Option & o) -: _myname(o._myname), _option(o._option), _listme(o._listme), _values(o._values) -{}; - -Config::Option::Option(std::string name, Config::Option::FunctionMemberType value, const StringType defvalue, StringSet & allowed, bool listme) -: _myname(name), _option(InnerFunctionType(name, value, defvalue, allowed)), _listme(listme), _values(NULL) -{}; - -Config::Option::Option(std::string name, Config::Option::FunctionMemberType value, const StringType defvalue, bool listme) -: _myname(name), _option(InnerFunctionType(name, value, defvalue)), _listme(listme), _values(NULL) -{}; - -Config::Option::~Option(void) -{ - if (_values) - { - for (unsigned int i = 0; _values[i] != NULL; i++) - delete _values[i]; - - delete[] _values; - _values = NULL; - } -}; - -const char ** Config::Option::values(void) -{ - if (_values != NULL) - return _values; - - /**/ if (_option.check()) - { - _values = new const char*[3]; - - _values[0] = strdup("yes"); - _values[1] = strdup("no"); - _values[2] = NULL; - - } - else if (_option.check()) - { - const InnerSIntType & tmp = _option.get(); - - unsigned int count = ((tmp._range.maximum - tmp._range.minimum) / tmp._range.step) + 1; - unsigned int index = 0; - - _values = new const char*[count + 1]; - - for (SIntType i = tmp._range.minimum; i <= tmp._range.maximum; i += tmp._range.step, ++index) - _values[index] = strdup(STG(FMT("%d") % i).c_str()); - - _values[index] = NULL; - } - else if (_option.check()) - { - const InnerUIntType & tmp = _option.get(); - - unsigned int count = ((tmp._range.maximum - tmp._range.minimum) / tmp._range.step) + 1; - unsigned int index = 0; - - _values = new const char*[count + 1]; - - for (UIntType i = tmp._range.minimum; i <= tmp._range.maximum; i += tmp._range.step, ++index) - _values[index] = strdup(STG(FMT("%d") % i).c_str()); - - _values[index] = NULL; - } - else if (_option.check()) - { - const InnerStringType & tmp = _option.get(); - - _values = new const char*[ tmp._allowed.size() + 1 ]; - - unsigned int index = 0; - - for (StringSet::iterator i = tmp._allowed.begin(); i != tmp._allowed.end(); ++i, ++index) - _values[index] = strdup((*i).c_str()); - - _values[index] = NULL; - } - else if (_option.check()) - { - const InnerFunctionType & tmp = _option.get(); - - _values = new const char*[ tmp._allowed.size() + 1 ]; - - unsigned int index = 0; - - for (StringSet::iterator i = tmp._allowed.begin(); i != tmp._allowed.end(); ++i, ++index) - _values[index] = strdup((*i).c_str()); - - _values[index] = NULL; - } - else - { - throw Failure(STG(FMT("values() not implemented for type used in option '%s'") % _myname)); - } - - return _values; -}; - -/*********************************/ - -Config::Options::Options(void) -: _values(NULL) -{}; - -Config::Options::~Options() -{ - if (_values) - { - for (unsigned int i = 0; _values[i] != NULL; i++) - free((void*)(_values[i])); - - delete[] _values; - _values = NULL; - } -}; - -bool Config::Options::add(Config::Option option) -{ - std::pair ret = _map.insert(OptionPair(option.name(), option)); - - return ret.second; -} - -bool Config::Options::synonym(std::string equiv_opt, std::string main_opt) -{ - std::pair ret = _syn_map.insert(SynOptionPair(equiv_opt, main_opt)); - - return ret.second; -} - -Config::StringSet Config::Options::options(void) -{ - StringSet res; - - for (OptionMap::iterator i = _map.begin(); i != _map.end(); i++) - res.insert(i->first); - - return res; -} - -const char ** Config::Options::values(const char * name) -{ - OptionMap::iterator iter = find_option(name); - - if (iter == _map.end()) - throw Failure(STG(FMT("unknown option '%s'") % name)); - - return iter->second.values(); -} - -const char ** Config::Options::values(void) -{ - if (_values != NULL) - return _values; - - unsigned int count = 0; - - for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i) - if (i->second.listme()) - ++count; - - _values = new const char*[ count + 1 ]; - - unsigned int index = 0; - - for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i) - { - if (i->second.listme()) - { - _values[index] = strdup(i->first.c_str()); - ++index; - } - } - - _values[index] = NULL; - - return _values; -} - -Config::Options::OptionMap::iterator Config::Options::find_option(std::string name) -{ - SynOptionMap::iterator syn_iter = _syn_map.find(name); - - if (syn_iter != _syn_map.end()) - name = syn_iter->second; - - OptionMap::iterator iter = _map.find(name); - - return iter; -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/config_options.hpp b/src/mod/endpoints/mod_khomp/commons/base/config_options.hpp deleted file mode 100644 index 9196f3b5a8..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/config_options.hpp +++ /dev/null @@ -1,798 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _CONFIG_OPTIONS_HPP_ -#define _CONFIG_OPTIONS_HPP_ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace Config -{ - /* exceptions */ - - struct Failure: public std::runtime_error - { - Failure(const std::string & msg) : std::runtime_error(msg) {}; - }; - - struct EmptyValue: public std::runtime_error - { - EmptyValue(): std::runtime_error("accessed option still not loaded from configuration") {}; - }; - - /* types */ - - typedef int SIntType; - typedef unsigned int UIntType; - typedef bool BooleanType; - typedef std::string StringType; - - template < typename Type > - struct Value; - - template < typename Type > - struct InnerOptionBase; - - template < typename Type > - struct InnerOption; - - struct Option; - - /* here we go! */ - - template < typename Type > - struct Range - { - Range(const Type _minimum, const Type _maximum, const Type _step) - : minimum(_minimum), maximum(_maximum), step(_step) {}; - - const Type minimum, maximum, step; - }; - - typedef std::set < std::string > StringSet; - - template < typename Type > - struct Value: COUNTER_SUPER(Value < Type >) - { - friend class COUNTER_CLASS(Value < Type >); - friend class InnerOptionBase< Type >; - friend class InnerOption < Type >; - friend class Option; - - Value() - : _tmpval(0), _stored(0), _loaded(false), _inited(false) - {}; - - Value(const Value & o) - : COUNTER_REFER(o, Value < Type >), - _tmpval(o._tmpval), _stored(o._stored), - _loaded(o._loaded), _inited(o._inited) - {}; - - const Type & operator()(void) const - { - if (!_inited) - throw EmptyValue(); - - if (!_stored) - return *_tmpval; - - return *_stored; - }; - - const Type & get(void) const { return operator()(); }; - bool loaded(void) const { return _loaded; }; - - void store(const Type val) - { - if (_tmpval) - { - delete _tmpval; - _tmpval = 0; - } - - _tmpval = new Type(val); - - _loaded = true; - _inited = true; - } - - protected: - void unreference(void) - { - _inited = false; - _loaded = false; - - if (_tmpval) - { - delete _tmpval; - _tmpval = 0; - } - - if (_stored) - { - delete _stored; - _stored = 0; - } - }; - - protected: - void commit(Type def) - { - if (_tmpval) - { - { - delete _stored; - _stored = 0; - } - - _stored = _tmpval; - _tmpval = 0; - } - else - { - if (!_stored) - _stored = new Type(def); - } - - _loaded = true; - _inited = true; - }; - - void reset(void) - { - _loaded = false; - } - - protected: - const Type * _tmpval; - const Type * _stored; - bool _loaded; - bool _inited; - }; - - struct FunctionValue - { - friend class InnerFunctionType; - friend class Option; - - FunctionValue() - : _loaded(false), _inited(false) {}; - - virtual ~FunctionValue() {}; - - public: - virtual void operator()(const StringType & val) - { - throw Failure("undefined operator() for value"); - } - - const StringType & get(void) const - { - if (!_inited) - throw EmptyValue(); - - return _stored; - }; - - bool loaded(void) const { return _loaded; }; - - protected: - void commit(const StringType def) - { - if (_tmpval.empty()) - { - _stored = def; - } - else - { - _stored = _tmpval; - _tmpval.clear(); - } - - operator()(_stored); - - _loaded = true; - _inited = true; - }; - - void store(const StringType val) - { - _tmpval = val; - _loaded = true; - _inited = true; - } - - void reset(void) - { - _loaded = false; - } - - private: - StringType _tmpval; - StringType _stored; - bool _loaded; - bool _inited; - }; - - /* NOTE: we use a non-templated classe to place this functions inside the .cpp */ - struct Restriction - { - static void checkRange(const std::string & name, const SIntType value, const Range < SIntType > & range); - static void checkRange(const std::string & name, const UIntType value, const Range < UIntType > & range); - static void checkStringSet(const std::string & name, const StringType & value, const StringSet & allowed); - }; - - template < typename Type > - struct InnerOptionBase - { - typedef Variable < Value < Type > > MemberValue; - - InnerOptionBase(const std::string name, MemberValue option, const Type defvalue) - : _name(name), _option(option), _default(defvalue) {}; - - template < typename Object > - void reset(Object * const obj) const - { - _option(obj).reset(); - } - - template < typename Object > - const Type & get(const Object * const obj) const - { - return _option(obj).get(); - } - - template < typename Object > - bool loaded(const Object * const obj) const - { - return _option(obj).loaded(); - } - - protected: - const std::string _name; - MemberValue _option; - const Type _default; - }; - - template < > - struct InnerOption < SIntType >: public InnerOptionBase < SIntType > - { - typedef InnerOptionBase < SIntType > Super; - typedef Super::MemberValue MemberValue; - - InnerOption(const std::string name, MemberValue option, const SIntType defval, - const SIntType min, const SIntType max, const SIntType step) - : Super(name, option, defval), _range(min, max, step) {}; - - template < typename Object > - void commit(Object * const obj) const - { - Restriction::checkRange(_name, _default, _range); - _option(obj).commit(_default); - }; - - template < typename Object > - void store(Object * const obj, const SIntType stored) const - { - Restriction::checkRange(_name, _default, _range); - _option(obj).store(stored); - } - - using Super::reset; - using Super::get; - - const Range< SIntType > _range; - }; - - template < > - struct InnerOption < UIntType >: public InnerOptionBase < UIntType > - { - typedef InnerOptionBase < UIntType > Super; - typedef Super::MemberValue MemberValue; - - InnerOption(const std::string name, MemberValue option, const UIntType defval, - const UIntType min, const UIntType max, const UIntType step) - : Super(name, option, defval), _range(min, max, step) {}; - - template < typename Object > - void commit(Object * const obj) const - { - Restriction::checkRange(_name, _default, _range); - _option(obj).commit(_default); - }; - - template < typename Object > - void store(Object * const obj, const UIntType stored) const - { - Restriction::checkRange(_name, _default, _range); - _option(obj).store(stored); - } - - using Super::reset; - using Super::get; - - const Range< UIntType > _range; - }; - - template < > - struct InnerOption < BooleanType >: public InnerOptionBase < BooleanType > - { - typedef InnerOptionBase < BooleanType > Super; - typedef Super::MemberValue MemberValue; - - InnerOption(std::string name, MemberValue option, BooleanType defval) - : Super(name, option, defval) {}; - - template < typename Object > - void commit(Object * obj) const - { - _option(obj).commit(_default); - }; - - template < typename Object > - void store(Object * obj, BooleanType stored) const - { - _option(obj).store(stored); - } - - using Super::reset; - using Super::get; - }; - - template < > - struct InnerOption < StringType >: public InnerOptionBase < StringType > - { - typedef InnerOptionBase < StringType > Super; - typedef Super::MemberValue MemberValue; - - InnerOption(const std::string name, MemberValue option, const StringType defval, const StringSet & allowed) - : Super(name, option, defval), _allowed(allowed) {}; - - InnerOption(const std::string name, MemberValue option, const StringType defval) - : Super(name, option, defval) {}; - - template < typename Object > - void commit(Object * const obj) const - { - Restriction::checkStringSet(_name, _default, _allowed); - _option(obj).commit(_default); - }; - - template < typename Object > - void store(Object * const obj, const StringType stored) const - { - Restriction::checkStringSet(_name, _default, _allowed); - _option(obj).store(stored); - } - - using Super::reset; - using Super::get; - - const StringSet _allowed; - }; - - struct InnerFunctionType - { - typedef Variable < FunctionValue > MemberValue; - - InnerFunctionType(const std::string name, MemberValue option, const StringType defval, const StringSet & allowed) - : _name(name), _option(option), _default(defval), _allowed(allowed) {}; - - InnerFunctionType(const std::string name, MemberValue option, const StringType defval) - : _name(name), _option(option), _default(defval) {}; - - template < typename Object > - const StringType & get(const Object * const obj) const - { - return _option(obj).get(); - } - - template < typename Object > - bool loaded(const Object * const obj) const - { - return _option(obj).loaded(); - } - - template < typename Object > - void reset(Object * const obj) const - { - _option(obj).reset(); - } - - template < typename Object > - void commit(Object * const obj) const - { - Restriction::checkStringSet(_name, _default, _allowed); - _option(obj).commit(_default); - }; - - template < typename Object > - void store(Object * const obj, const StringType stored) const - { - Restriction::checkStringSet(_name, _default, _allowed); - _option(obj).store(stored); - } - - protected: - const std::string _name; - MemberValue _option; - const StringType _default; - - public: - const StringSet _allowed; - }; - - struct Option - { - typedef InnerOption < SIntType > InnerSIntType; - typedef InnerOption < UIntType > InnerUIntType; - typedef InnerOption < BooleanType > InnerBooleanType; - typedef InnerOption < StringType > InnerStringType; - - typedef Variable < Value < SIntType > > SIntMemberType; - typedef Variable < Value < UIntType > > UIntMemberType; - typedef Variable < Value < BooleanType > > BooleanMemberType; - typedef Variable < Value < StringType > > StringMemberType; - - typedef Variable < FunctionValue > FunctionMemberType; - - typedef Tagged::Union < InnerStringType, - Tagged::Union < InnerBooleanType, - Tagged::Union < InnerSIntType , - Tagged::Union < InnerUIntType, - Tagged::Union < InnerFunctionType > > > > > - InnerType; - - explicit Option(std::string, StringMemberType, const StringType, StringSet & allowed, bool listme = true); - explicit Option(std::string, StringMemberType, const StringType = "", bool listme = true); - explicit Option(std::string, SIntMemberType, const SIntType = 0, SIntType min = INT_MIN, SIntType max = INT_MAX, SIntType step = 1, bool listme = true); - explicit Option(std::string, UIntMemberType, const UIntType = 0, UIntType min = 0, UIntType max = UINT_MAX, UIntType step = 1, bool listme = true); - explicit Option(std::string, BooleanMemberType, const BooleanType = false, bool listme = true); - - explicit Option(std::string, FunctionMemberType, const StringType, StringSet & allowed, bool listme = true); - explicit Option(std::string, FunctionMemberType, const StringType = "", bool listme = true); - - Option(const Option & o); - - ~Option(void); - - template < typename Object > - void set(Object * object, std::string value) - { - try - { - /**/ if (_option.check()) _option.get().store(object, value); - else if (_option.check()) _option.get().store(object, value); - else if (_option.check()) _option.get().store(object, Strings::toboolean(value)); - else if (_option.check()) _option.get().store(object, Strings::tolong(value)); - else if (_option.check()) _option.get().store(object, Strings::toulong(value)); - else - { - throw Failure(STG(FMT("set() not implemented for type used in option '%s'") % _myname)); - } - } - catch (Strings::invalid_value & e) - { - throw Failure(STG(FMT("got invalid value '%s' for option '%s'") % value % _myname)); - } - catch (EmptyVariable & e) - { - throw Failure(STG(FMT("uninitialized variable while setting value '%s' for option '%s'") % value % _myname)); - } - } - - template < typename Object > - std::string get(const Object * const object) const - { - try - { - /**/ if (_option.check()) return _option.get().get(object); - else if (_option.check()) return _option.get().get(object); - else if (_option.check()) return (_option.get().get(object) ? "yes" : "no"); - else if (_option.check()) return STG(FMT("%d") % _option.get().get(object)); - else if (_option.check()) return STG(FMT("%u") % _option.get().get(object)); - else - { - throw Failure(STG(FMT("get() not implemented for type used in option '%s'") % _myname)); - } - } - catch (EmptyVariable & e) - { - throw Failure(STG(FMT("uninitialized variable while getting value for option '%s'") % _myname)); - } - } - - template < typename Object > - bool loaded(const Object * const object) const - { - try - { - /**/ if (_option.check()) return _option.get().loaded(object); - else if (_option.check()) return _option.get().loaded(object); - else if (_option.check()) return _option.get().loaded(object); - else if (_option.check()) return _option.get().loaded(object); - else if (_option.check()) return _option.get().loaded(object); - else - { - throw Failure(STG(FMT("loaded() not implemented for type used in option '%s'") % _myname)); - } - } - catch (EmptyVariable & e) - { - throw Failure(STG(FMT("uninitialized variable while checking load status for option '%s'") % _myname)); - } - } - - template < typename Object > - void reset(Object * const object) - { - try - { - /**/ if (_option.check()) _option.get().reset(object); - else if (_option.check()) _option.get().reset(object); - else if (_option.check()) _option.get().reset(object); - else if (_option.check()) _option.get().reset(object); - else if (_option.check()) _option.get().reset(object); - else - { - throw Failure(STG(FMT("reset() not implemented for type used in option '%s'") % _myname)); - } - } - catch (EmptyVariable & e) - { - throw Failure(STG(FMT("uninitialized variable while reseting status for option '%s'") % _myname)); - } - } - - template < typename Object > - void commit(Object * const object) - { - try - { - /**/ if (_option.check()) _option.get().commit(object); - else if (_option.check()) _option.get().commit(object); - else if (_option.check()) _option.get().commit(object); - else if (_option.check()) _option.get().commit(object); - else if (_option.check()) _option.get().commit(object); - else - { - throw Failure(STG(FMT("commit() not implemented for type used in option '%s'") % _myname)); - } - } - catch (EmptyVariable & e) - { - throw Failure(STG(FMT("uninitialized variable while commiting option '%s'") % _myname)); - } - } - - const std::string & name(void) const { return _myname; } - bool listme(void) const { return _listme; }; - - const char ** values(void); - - template < typename Object > - void copyFrom(const Object * const srcobj, Object * const dstobj, bool force = false) - { - if (loaded(dstobj) && !force) - return; - - if (loaded(srcobj)) - set(dstobj, get(srcobj)); - else - reset(dstobj); - } - - protected: - const std::string _myname; - InnerType _option; - const bool _listme; - const char ** _values; - }; - - struct Options - { - typedef std::vector < std::string > Messages; - - Options(); - ~Options(); - - typedef std::set < std::string > StringSet; - - typedef std::map < std::string, Option > OptionMap; - typedef std::pair < std::string, Option > OptionPair; - - typedef std::map < std::string, std::string > SynOptionMap; - typedef std::pair < std::string, std::string > SynOptionPair; - - bool add(Option option); - - /* only valid in "process" (for backwards compatibility config files) */ - bool synonym(std::string, std::string); - - template < typename Type > - void set(const std::string & name, Type value) - { - OptionMap::iterator iter = find_option(name); - - if (iter == _map.end()) - throw Failure(STG(FMT("unknown option: %s") % name)); - - iter->second.set(value); - } - - template < typename Object > - std::string get(const Object * const object, const std::string & name) - { - OptionMap::iterator iter = find_option(name); - - if (iter == _map.end()) - throw Failure(STG(FMT("unknown option: %s") % name)); - - return iter->second.get(object); - } - - template < typename Object > - void process(Object * const object, const char * name, const char * value) - { - OptionMap::iterator iter = find_option(name); - - if (iter == _map.end()) - throw Failure(STG(FMT("unknown option '%s'") % name)); - - iter->second.set(object, value); - } - - template < typename Object > - Messages commit(Object * const object, const std::string & name) - { - Messages msgs; - - OptionMap::iterator i = _map.find(name); - - if (i != _map.end()) - { - try - { - i->second.commit(object); - } - catch (Failure & e) - { - msgs.push_back(e.what()); - } - } - else - { - msgs.push_back(STG(FMT("unable to find option: %s") % name)); - }; - - return msgs; - } - - template < typename Object > - Messages commit(Object * const object) - { - Messages msgs; - - for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i) - { - try - { - i->second.commit(object); - } - catch (Failure & e) - { - msgs.push_back(e.what()); - } - } - - return msgs; - } - - template < typename Object > - void reset(Object * object) - { - for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i) - i->second.reset(object); - } - - template < typename Object > - bool loaded(Object * object, const std::string & name) - { - OptionMap::iterator iter = find_option(name); - - if (iter == _map.end()) - return false; - - return iter->second.loaded(object); - } - - bool exists(const std::string & name) - { - OptionMap::iterator iter = find_option(name); - - return (iter != _map.end()); - } - - StringSet options(void); - - const char ** values(const char *); /* option value */ - const char ** values(void); /* values from options */ - - template < typename Object > - void copyFrom(const std::string & name, const Object * const src_obj, Object * const dst_obj, bool force = false) - { - OptionMap::iterator iter = find_option(name); - - if (iter == _map.end()) - throw Failure(STG(FMT("unknown option '%s'") % name)); - - iter->second.copyFrom(src_obj, dst_obj, force); - } - - template < typename Object > - void copyFrom(Object * src_obj, Object * dst_obj, bool force = false) - { - for (OptionMap::iterator iter = _map.begin(); iter != _map.end(); ++iter) - iter->second.copyFrom(src_obj, dst_obj, force); - } - - protected: - OptionMap::iterator find_option(std::string); - - protected: - OptionMap _map; - SynOptionMap _syn_map; - - const char ** _values; - }; -}; - -#endif /* _CONFIG_OPTIONS_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.cpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.cpp deleted file mode 100644 index 02e43df120..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ -#include - -#include - -#if _MSC_VER >= 1400 -#undef close -#endif - -void Configfile::ignore(const std::string & str) -{ - _ignores.insert(str); -}; - -bool Configfile::select(Section **ptr, const std::string & str) -{ - /* default section == this! */ - *ptr = this; - - /* always success by default */ - return true; -}; - -bool Configfile::adjust(Section * section, const std::string & opt, const std::string & val) -{ - return section->load(opt, val); -}; - -bool Configfile::deserialize(std::ifstream & fd) -{ - Section * section = NULL; - - /* default selection! */ - if (!select(§ion)) - { - _errors.push_back("default selection has failed!"); - return false; - } - - size_t count = 0; - - while (fd.good()) - { - std::string str; - - /* read one line! */ - std::getline(fd, str); - - size_t lst = str.size() - 1; - - if (str.size() >= 1 && str[lst] == '\r') //cuida das quebras de linha do tipo \r\n - { - str.erase(lst,1); - --lst; - } - - /* empty line! */ - if (str.size() == 0) - continue; - - /* comment! */ - if (str[0] == '#') - continue; - - ++count; - - if (str[0] == '[' && str[lst] == ']') - { - str.erase(0,1); --lst; - str.erase(lst,1); --lst; - - if (!select(§ion, str)) - { - _errors.push_back(STG(FMT("erroneous section '%s'") % str)); - - /* ignore this section */ - section = NULL; - continue; - } - } - else - { - std::string::size_type pos = str.find('='); - - if (pos == std::string::npos) - { - _errors.push_back(STG(FMT("erroneous separator '%s'") % str)); - continue; - }; - - if (section == NULL) - { - _errors.push_back(STG(FMT("no section for option '%s'") % str)); - continue; - } - - std::string opt(str.substr(0,pos)); - std::string val(str.substr(pos+1)); - - if (_ignores.find(opt) != _ignores.end()) - continue; - - if (val == "@") val = ""; - - if (adjust(section, opt, val)) - continue; - - _errors.push_back(STG(FMT("option '%s' does not exist or '%s' is not " - "a valid value (at section '%s')") % opt % val % section->name())); - } - } - - // retorna 'true' se arquivo tinha alguma coisa valida. - return (count != 0); -} - -bool Configfile::obtain() -{ - std::ifstream fd(_filename.c_str()); - - if (!fd.is_open()) - { - _errors.push_back(STG(FMT("unable to open file '%s': %s") - % _filename % strerror(errno))); - return false; - }; - - if (!deserialize(fd)) - { - fd.close(); - return false; - } - - fd.close(); - return true; -}; - -void Configfile::recurse(std::ofstream & fd, Section * section) -{ - typedef Section::SectionMap::const_iterator SectionIter; - typedef Section::OptionMap::const_iterator OptionIter; - - for (OptionIter i = section->option_begin(); i != section->option_end(); i++) - { - std::string res; - - if ((*i).second.store(res)) - { - if (res == "") res = "@"; - fd << (*i).first << "=" << res << std::endl; - } - } - - if (!section->recursive()) - return; - - for (SectionIter j = section->section_begin(); j != section->section_end(); j++) - recurse(fd, (*j).second); -} - -bool Configfile::serialize(std::ofstream & fd) -{ - recurse(fd, this); - return true; -} - -bool Configfile::provide() -{ - std::string tmp(_filename); - tmp += ".new"; - - std::ofstream fd(tmp.c_str()); - - if (!fd.good()) - { - _errors.push_back(STG(FMT("unable to open file '%s': %s") - % tmp % strerror(errno))); - return false; - } - - if (!serialize(fd)) - { - fd.close(); - return false; - } - - fd.close(); - - if (rename(tmp.c_str(), _filename.c_str()) != 0) - { - _errors.push_back(STG(FMT("unable to replace config file '%s': %s") - % _filename % strerror(errno))); - return false; - } - - return true; -} - -#if _MSC_VER >= 1400 -#define close _close -#endif diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.hpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.hpp deleted file mode 100644 index e725c09964..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/configfile.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include -#include -#include - -#include - -#include - -#ifndef _CONFIG_CONFIGFILE_HPP_ -#define _CONFIG_CONFIGFILE_HPP_ - -struct Configfile: public Section -{ - typedef std::list < std::string > ErrorVector; - typedef std::set < std::string > NameSet; - - Configfile(const std::string & name, const std::string & desc) - : Section(name, desc), _good(false) {}; - - virtual ~Configfile() {}; - - bool good() const { return _good; }; - const std::string & filename() const { return _filename; }; - - const ErrorVector & errors() const { return _errors; }; - - void ignore(const std::string &); - - virtual bool obtain(); - virtual bool provide(); - - protected: - virtual bool select(Section **, const std::string & str = ""); - virtual bool adjust(Section *, const std::string & opt, const std::string & val); - - virtual bool deserialize(std::ifstream &); - virtual bool serialize(std::ofstream &); - - void recurse(std::ofstream &, Section *); - - protected: - bool _good; - ErrorVector _errors; - NameSet _ignores; - std::string _filename; -}; - -#endif /* _CONFIG_CONFIGFILE_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/option.cpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/option.cpp deleted file mode 100644 index 6de9212bf3..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/option.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -bool Option::equals(const std::string & value) const -{ - switch (_restriction.numeral()) - { - case Restriction::N_UNIQUE: - { - Restriction::Value my_value; - - if (!_restriction.get(Restriction::F_USER, my_value)) - return false; - - return (my_value == value); - } - case Restriction::N_MULTIPLE: - { - Restriction::Vector my_values; - - if (!_restriction.get(Restriction::F_USER, my_values)) - return false; - - for (Restriction::Vector::iterator i = my_values.begin(); i != my_values.end(); i++) - { - if ((*i) == value) - return true; - } - - return false; - } - } - - return false; -} - -bool Option::load(const std::string & value) -{ - bool ret = _restriction.set( (const Restriction::Format)Restriction::F_FILE, value); - - if (ret) _modified = false; - - return ret; -} - -bool Option::change(const std::string & value) -{ - bool ret = _restriction.set(Restriction::F_FILE, value); - - if (ret) _modified = true; - - return ret; -} - -bool Option::store(std::string & value) const -{ - switch (_restriction.numeral()) - { - case Restriction::N_UNIQUE: - return _restriction.get(Restriction::F_FILE, value); - - case Restriction::N_MULTIPLE: - { - Restriction::Vector values; - - if (!_restriction.get(Restriction::F_FILE, values)) - return false; - - Strings::Merger strs; - - for (Restriction::Vector::iterator i = values.begin(); i != values.end(); i++) - strs.add(*i); - - value = strs.merge(","); - - return true; - } - - default: - return false; - } -} - -/* -Option::Flags Option::set(const char * value) -{ - std::string str_value(value); - return set(str_value); -} -*/ - -Option::Flags Option::set(const Restriction::Value & value) -{ - Restriction::Value last_value, curr_value; - Flags flags; - - bool ret1 = _restriction.get(Restriction::F_USER, last_value); - - if (!_restriction.set(Restriction::F_USER, value)) - return flags; - - flags[F_ADJUSTED] = true; - - bool ret2 = _restriction.get(Restriction::F_USER, curr_value); - - if (!ret1 || (ret2 && (last_value != curr_value))) - { - flags[F_MODIFIED] = true; - _modified = true; - } - - return flags; -} - -Option::Flags Option::set(const Restriction::Vector & values) -{ - Restriction::Vector last_values, curr_values; - Flags flags; - - bool ret1 = _restriction.get(Restriction::F_USER, last_values); - - if (!_restriction.set(Restriction::F_USER, values)) - return flags; - - flags[F_ADJUSTED] = true; - - bool ret2 = _restriction.get(Restriction::F_USER, curr_values); - - if (!ret1 || (ret2 && (last_values != curr_values))) - { - flags[F_MODIFIED] = true; - _modified = true; - } - - return flags; -} - -bool Option::get(Restriction::Value & value) const -{ - return _restriction.get(Restriction::F_USER, value); -} - -bool Option::get(Restriction::Vector & values) const -{ - return _restriction.get(Restriction::F_USER, values); -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/option.hpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/option.hpp deleted file mode 100644 index e46ab75902..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/option.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#include -#include -#include - -#include -#include - -#include - -#ifndef _CONFIG_OPTION_HPP_ -#define _CONFIG_OPTION_HPP_ - -struct Option -{ - enum FlagTypes - { - F_MODIFIED = 0x0, /* if option was modified */ - F_ADJUSTED = 0x1, /* if option was correctly formated */ - }; - - struct Flags: public std::vector - { - Flags(): std::vector(2) {}; - }; - - typedef Restriction::Value Value; - typedef Restriction::Vector Vector; - - /* exception */ - struct InvalidDefaultValue: public std::runtime_error - { - InvalidDefaultValue(const std::string & name, const std::string & value) - : std::runtime_error(STG(FMT("invalid default value '%s' for option '%s'") % value % name)), - _name(name), _value(value) - {}; - - ~InvalidDefaultValue() throw () - {}; - - const std::string & name() const { return _name; }; - const std::string & value() const { return _value; }; - - protected: - const std::string _name; - const std::string _value; - }; - - Option(const std::string & name, const std::string & desc, const std::string & defvalue, const Restriction & restriction) - : _name(name), _description(desc), _restriction(restriction), _modified(true) - { -// std::string value(defvalue); - - if (!(set(defvalue)[F_ADJUSTED])) - throw InvalidDefaultValue(name, defvalue); - } - - const std::string & name() const { return _name; }; - const std::string & description() const { return _description; }; - - const Restriction & restriction() const { return _restriction; }; - bool modified() const { return _modified; }; - - public: - bool load(const std::string &); - bool change(const std::string &); - bool store(std::string &) const; - -// Flags set(const char *); - Flags set(const Value &); - Flags set(const Vector &); - - bool get(Value &) const; - bool get(Vector &) const; - - bool equals(const std::string &) const; - - protected: - const std::string _name; - const std::string _description; - - Restriction _restriction; - bool _modified; -}; - -#endif /* _CONFIG_OPTION_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.cpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.cpp deleted file mode 100644 index 52be1ea881..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include - -#include -#include - -#include - -/* internal helper! */ -bool Restriction::equalNumber(const double a, const double b) -{ - char tmp1[64]; - char tmp2[64]; - - snprintf(tmp1, sizeof(tmp1), "%.3f", a); - snprintf(tmp2, sizeof(tmp2), "%.3f", b); - - if (strncmp(tmp1, tmp2, sizeof(tmp1))) - return false; - - return true; -} - -/* process value to our internal representation */ - -bool Restriction::process(Restriction::Format fmt, - const Restriction::Value & value, Restriction::Value & final) const -{ - switch (_bounds) - { - case B_RANGE: - { - if (_kind != K_NUMBER) - return false; - - std::string tmpvalue; - - Restriction::Value::const_iterator itr = value.begin(); - Restriction::Value::const_iterator end = value.end(); - - tmpvalue.reserve(value.size()); - - // f*cking dot/comma notation! - for (; itr != end; ++itr) - tmpvalue += ((*itr) != ',' ? (*itr) : '.'); - - try - { - double newvalue = Strings::todouble(tmpvalue); - - if (newvalue < _init && newvalue > _fini) - return false; - - double res = (newvalue - _init) / _step; - - if (!Restriction::equalNumber(res, rint(res))) - return false; - - final = value; - return true; - } - catch (...) - { - return false; - } - } - - case B_LIST: - for (List::const_iterator i = _list.begin(); i != _list.end(); i++) - { - const Value & tmp = (*i); - - if (tmp == value) - { - final = value; - return true; - } - } - return false; - - case B_MAPS: - switch (fmt) - { - case F_USER: - { - Map::const_iterator i = _map_from_usr.find(value); - - if (i == _map_from_usr.end()) - return false; - - const Value & tmp = (*i).second; - - final = tmp; - return true; - } - - case F_FILE: - { - Map::const_iterator i = _map_from_cfg.find(value); - - if (i == _map_from_cfg.end()) - return false; - - final = value; - return true; - } - - default: - break; - } - return false; - - case B_FREE: - final = value; - return true; - - default: - break; - } - - return false; -} - -/* unprocess the value (outputs the external representation) */ - -bool Restriction::unprocess(Restriction::Format fmt, - const Restriction::Value & value, Restriction::Value & final) const -{ - switch (_bounds) - { - case B_MAPS: - - switch (fmt) - { - case F_USER: - { - Map::const_iterator i = _map_from_cfg.find(value); - - if (i == _map_from_cfg.end()) - return false; - - final = (*i).second; - return true; - } - default: - break; - } - - default: - final = value; - return true; - } -} - -/***************************** *****************************/ - -bool Restriction::get(Restriction::Format fmt, Restriction::Value & value) const -{ - if (_numeral != N_UNIQUE) - return false; - - if (!unprocess(fmt, _value._unique, value)) - return false; - - return true; -} - -bool Restriction::get(Restriction::Format fmt, Restriction::Vector & values) const -{ - if (_numeral != N_MULTIPLE) - return false; - - const List & my_values = _value._multiple; - - for (List::const_iterator i = my_values.begin(); i != my_values.end(); i++) - { - const Value & value = (*i); - - Value final; - - if (!unprocess(fmt, value, final)) - return false; - - values.push_back(final); - }; - - return true; -} - -/***************************** *****************************/ - -bool Restriction::set(Restriction::Format fmt, const Restriction::Value & value) -{ - switch (_numeral) - { - case N_UNIQUE: - { - Value final; - - if (!constThis().process(fmt, value, final)) - return false; - - _value._unique = final; - return true; - } - - case N_MULTIPLE: - { - if (value == "@" || value == "#" || value == "") - { - _value._multiple.clear(); - return true; - } - - Strings::vector_type values; - Strings::tokenize(value, values, ","); - - return set(fmt, values); - } - - default: - return false; - } -} - -bool Restriction::set(Restriction::Format fmt, const Restriction::Vector & values) -{ - if (_numeral != N_MULTIPLE) - return false; - - if (values.empty()) - { - _value._multiple.clear(); - } - else - { - /* list needed to store temporary values */ - List finals; - - for (Vector::const_iterator i = values.begin(); i != values.end(); i++) - { - const Value & value = (*i); - - Value final; - - if (!constThis().process(fmt, value, final)) - return false; - - finals.push_back(final); - } - - List & lst = _value._multiple; - - /* need to clear values set before */ - lst.clear(); - - for (List::iterator i = finals.begin(); i != finals.end(); i++) - { - Value value = (*i); - lst.push_back(value); - } - }; - - return true; -} - -/***************************** *****************************/ - -void Restriction::allowed(Restriction::Vector & vals) const -{ - switch (_bounds) - { - case B_FREE: - return; - - case B_LIST: - for (List::const_iterator i = _list.begin(); i != _list.end(); i++) - vals.push_back(*i); - break; - - case B_MAPS: - for (Map::const_iterator i = _map_from_usr.begin(); i != _map_from_usr.end(); i++) - vals.push_back(i->first); - break; - - case B_RANGE: - { - if (_kind != K_NUMBER) - return; - - // is there any fraction? - bool has_fraction = - (!Restriction::equalNumber(_init, rint(_init))) || - (!Restriction::equalNumber(_fini, rint(_fini))) || - (!Restriction::equalNumber(_step, rint(_step))); - - const char * format = (has_fraction ? "%.2f" : "%02.0f"); - - for (double i = _init; i <= _fini; i += _step) - { - char tmp[32]; - snprintf(tmp, sizeof(tmp), format, i); - vals.push_back(std::string(tmp)); - } - break; - } - - default: - break; - } -} - -void Restriction::init_class() -{ - _value._unique.clear(); - _value._multiple.clear(); -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.hpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.hpp deleted file mode 100644 index 576560dbd4..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/restriction.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#include -#include -#include -#include - -#include - -#ifndef _CONFIG_RESTRICTION_HPP_ -#define _CONFIG_RESTRICTION_HPP_ - -struct Restriction: public ConstThis < Restriction > -{ - /* generic types */ - - // TODO: change this type name for something different - // to avoid conflicting with "format.hpp". - enum Format - { - F_USER, - F_FILE - }; - - enum Kind - { - K_STRING, - K_NUMBER // = K_INTEGER // compatibility - }; - - enum Bounds - { - B_FREE, - B_RANGE, - B_LIST, - B_MAPS - }; - - enum Numeral - { - N_UNIQUE, - N_MULTIPLE - }; - - typedef std::string Value; - - /* types used for data input */ - struct Pair - { - const char *pretty; - const char *value; - }; - - typedef std::pair < Value, Value > PairMap; - typedef std::list < PairMap > ListMap; - - /* types used internally */ - typedef std::map < Value, Value > Map; - typedef std::vector < Value > Vector; - - typedef std::list < Value > List; - typedef std::pair < Value, Value > MapPair; - - struct Generic - { - Value _unique; - List _multiple; - }; - - Restriction(Kind kind, Numeral num) - : _kind(kind), _bounds(B_FREE), _numeral(num), _unit(""), - _init(-1), _fini(-1), _step(-1) - { - init_class(); - } - - Restriction(Kind kind, Numeral num, - double init, double fini, double step = 1) - : _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(""), - _init(init), _fini(fini), _step(step) - { - init_class(); - } - - Restriction(Kind kind, Numeral num, - const char *unit, double init, double fini, double step = 1.0) - : _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit), - _init(init), _fini(fini), _step(step) - { - init_class(); - } - - Restriction(Kind kind, Numeral num, - std::string unit, double init, double fini, double step = 1.0) - : _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit), - _init(init), _fini(fini), _step(step) - { - init_class(); - } - - Restriction(Kind kind, Numeral num, - const char *first, ...) - : _kind(kind), _bounds(B_LIST), _numeral(num), _unit(""), - _init(-1), _fini(-1), _step(-1) - { - _list.push_back(std::string(first)); - - va_list ap; - va_start(ap, first); - - while (true) - { - const char *arg = va_arg(ap, const char *); - - if (arg == NULL) break; - - _list.push_back(std::string(arg)); - } - - init_class(); - } - - Restriction(Kind kind, const char *unit, Numeral num, - const char *first, ...) - : _kind(kind), _bounds(B_LIST), _numeral(num), _unit(unit), - _init(-1), _fini(-1), _step(-1) - { - _list.push_back(std::string(first)); - - va_list ap; - va_start(ap, first); - - while (true) - { - const char *arg = va_arg(ap, const char *); - - if (arg == NULL) break; - - _list.push_back(std::string(arg)); - } - - init_class(); - } - - Restriction(Kind kind, Numeral num, - const struct Pair first, ...) - : _kind(kind), _bounds(B_MAPS), _numeral(num), _unit(""), - _init(-1), _fini(-1), _step(-1) - { - _map_from_usr.insert(MapPair(Value(first.pretty), Value(first.value))); - _map_from_cfg.insert(MapPair(Value(first.value), Value(first.pretty))); - - va_list ap; - va_start(ap, first); - - while (true) - { - Pair arg = va_arg(ap, Pair); - - if (arg.pretty == NULL) break; - - _map_from_usr.insert(MapPair(Value(arg.pretty), Value(arg.value))); - _map_from_cfg.insert(MapPair(Value(arg.value), Value(arg.pretty))); - } - - init_class(); - } - - Restriction(Kind kind, Numeral num, List list) - : _kind(kind), _bounds(B_LIST), _numeral(num), _unit(""), - _init(-1), _fini(-1), _step(-1), _list(list) - { - init_class(); - } - - Restriction(Kind kind, Numeral num, ListMap map) - : _kind(kind), _bounds(B_MAPS), _numeral(num), _unit(""), - _init(-1), _fini(-1), _step(-1) - { - for (ListMap::iterator i = map.begin(); i != map.end(); i++) - { - _map_from_usr.insert(MapPair(Value((*i).first), Value((*i).second))); - _map_from_cfg.insert(MapPair(Value((*i).second), Value((*i).first))); - } - - init_class(); - } - - const Kind kind() const { return _kind; }; - const Bounds bounds() const { return _bounds; }; - const Numeral numeral() const { return _numeral; }; - - const std::string & unit() const { return _unit; }; - - bool set(Format, const Vector &); - bool set(Format, const Value &); - - bool get(Format, Vector &) const; - bool get(Format, Value &) const; - - void allowed(Vector &) const; - - private: - bool process(const Format, const Value &, Value &) const; - bool unprocess(const Format, const Value &, Value &) const; - - void init_class(); - - static bool equalNumber(const double, const double); - - protected: - const Kind _kind; - const Bounds _bounds; - const Numeral _numeral; - - Value _unit; - - const double _init, _fini, _step; - - Map _map_from_usr, - _map_from_cfg; - - List _list; - - Generic _value; -}; - -#endif /* _CONFIG_RESTRICTION_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/section.cpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/section.cpp deleted file mode 100644 index 9ed775b044..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/section.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -void Section::options(Section::OptionVector & vec) const -{ - for (OptionMap::const_iterator it = _options.begin(); it != _options.end();) - { - vec.push_back(const_cast< Option * >(&(it->second))); - ++it; - } -} - -void Section::sections(Section::SectionVector & vec) const -{ - for (SectionMap::const_iterator it = _sections.begin(); it != _sections.end();) - { - vec.push_back(const_cast< Section * >(it->second)); - ++it; - } -} - -/*********/ - -Option * Section::option_find(const std::string & str, bool recurse) const -{ - OptionMap::const_iterator i = _options.find(str); - - if (i == _options.end()) - { - if (!recurse) - throw OptionNotFound(str, _name); -// throw not_found(); - - for (SectionMap::const_iterator i = _sections.begin(); i != _sections.end(); i++) - { - try - { - return i->second->option_find(str, recurse); - } - catch (NotFound & e) - { - /* keep looping! */ - }; - } - -// throw not_found(); - throw OptionNotFound(str, _name); - } - - return const_cast< Option * >(&(i->second)); -} - -/* -Option * Section::option_find(const char * str, bool recurse) -{ - std::string sstr(str); - return option_find(sstr, recurse); -} -*/ - -/*********/ - -Section * Section::section_find(const std::string & str, bool recurse) const -{ - SectionMap::const_iterator i = _sections.find(str); - - if (i == _sections.end()) - { - if (!recurse) - throw SectionNotFound(str, _name); - - for (SectionMap::const_iterator i = _sections.begin(); i != _sections.end(); i++) - { - try - { - return i->second->section_find(str, recurse); - } - catch (NotFound & e) - { - /* keep looping! */ - }; - } - - throw SectionNotFound(str, _name); - } - - return const_cast< Section * >(i->second); -} - -/* -Section * Section::section_find(const char * str, bool recurse) -{ - std::string sstr(str); - return section_find(sstr, recurse); -} -*/ diff --git a/src/mod/endpoints/mod_khomp/commons/base/configurator/section.hpp b/src/mod/endpoints/mod_khomp/commons/base/configurator/section.hpp deleted file mode 100644 index d5a8c95688..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/configurator/section.hpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _CONFIG_SECTION_HPP_ -#define _CONFIG_SECTION_HPP_ - -#include -#include -#include -#include -#include - -#include - -#include - -struct Section -{ - typedef std::map < std::string, Option > OptionMap; - typedef std::vector< Option * > OptionVector; - - typedef std::map < std::string, Section * > SectionMap; - typedef std::vector < Section * > SectionVector; - - struct NotFound: public std::runtime_error - { - NotFound(const std::string & type, const std::string & name, const std::string & me) - : std::runtime_error(STG(FMT("%s '%s' not found on section '%s'") % type % name % me)) {}; - }; - - struct OptionNotFound: public NotFound - { - OptionNotFound(const std::string & name, const std::string & me) - : NotFound("option", name, me) {}; - }; - - struct SectionNotFound: public NotFound - { - SectionNotFound(const std::string & name, const std::string & me) - : NotFound("section", name, me) {}; - }; - - typedef NotFound not_found; /* backward compatibility */ - -// protected: - Section(const std::string & name, const std::string & desc, bool recursive = true) - : _name(name), _description(desc), _recursive(recursive) {}; - - void add(const Option & o) - { - _options.insert(std::pair(o.name(), o)); - }; - - void del(const std::string & name) - { - _options.erase(name); - }; - - void add(Section * s) - { - _sections.insert(std::pair< std::string, Section * >(s->name(), s)); - }; - - public: - const std::string & name() const { return _name; }; - const std::string & description() const { return _description; }; - - const bool recursive() const { return _recursive; }; - - OptionMap::const_iterator option_begin() const { return _options.begin(); }; - OptionMap::const_iterator option_end() const { return _options.end(); }; - - SectionMap::const_iterator section_begin() const { return _sections.begin(); }; - SectionMap::const_iterator section_end() const { return _sections.end(); }; - - /**/ - -// Option * option_find(const char *, bool recurse = false) const; -// Section * section_find(const char *, bool recurse = false) const; - - Option * option_find(const std::string &, bool recurse = false) const; - Section * section_find(const std::string &, bool recurse = false) const; - - /**/ - - void options(OptionVector &) const; - void sections(SectionVector &) const; - - /**/ - - template < typename T, typename F > - bool search_and_apply(const std::string & key, T & value, F f) - { - OptionMap::iterator i = _options.find(key); - - if (i != _options.end()) - return f(i->second); - - if (!_recursive) - return false; - - return (find_if(_sections.begin(), _sections.end(), f) != _sections.end()); - } - - private: - struct ConstKeyValue - { - ConstKeyValue(const std::string & k, const std::string &v) - : _k(k), _v(v) {}; - - const std::string & _k; - const std::string & _v; - }; - - struct KeyValue - { - KeyValue(const std::string & k, std::string &v) - : _k(k), _v(v) {}; - - const std::string & _k; - std::string & _v; - }; - - struct load_section: protected ConstKeyValue - { - load_section(const std::string & k, const std::string & v): ConstKeyValue(k,v) {}; - - bool operator()(Option & o) { return o.load(_v); }; - bool operator()(SectionMap::value_type & v) { return v.second->load(_k,_v); }; - }; - - struct change_section: protected ConstKeyValue - { - change_section(const std::string & k, const std::string & v): ConstKeyValue(k,v) {}; - - bool operator()(Option & o) { return o.change(_v); }; - bool operator()(SectionMap::value_type & v) { return v.second->change(_k,_v); }; - }; - - struct store_section: protected KeyValue - { - store_section(const std::string & k, std::string & v): KeyValue(k,v) {}; - - bool operator()(Option & o) { return o.store(_v); }; - bool operator()(SectionMap::value_type & v) { return v.second->store(_k,_v); }; - }; - - struct set_section: protected ConstKeyValue - { - set_section(const std::string & k, const std::string & v): ConstKeyValue(k,v) {}; - - bool operator()(Option & o) { return (o.set(_v))[Option::F_ADJUSTED]; }; - bool operator()(SectionMap::value_type & v) { return v.second->set(_k,_v); }; - }; - - struct get_section: protected KeyValue - { - get_section(const std::string & k, std::string & v): KeyValue(k,v) {}; - - bool operator()(Option & o) { return o.get(_v); }; - bool operator()(SectionMap::value_type & v) { return v.second->get(_k,_v); }; - }; - - struct modified_section - { - bool operator()(const OptionMap::value_type & v) { return v.second.modified(); }; - bool operator()(const SectionMap::value_type & v) { return v.second->modified(); }; - }; - - public: -/* - bool load(const char * key, const std::string value) - { - std::string skey(key); - return search_and_apply(skey, value, load_section(skey, value)); - } -*/ - bool load(const std::string & key, const std::string & value) - { - return search_and_apply(key, value, load_section(key, value)); - } - - bool change(const std::string & key, const std::string & value) - { - return search_and_apply(key, value, change_section(key, value)); - } - - bool store(const std::string & key, std::string & value) - { - return search_and_apply(key, value, store_section(key, value)); - } - - bool set(const std::string & key, const std::string & value) - { - return search_and_apply(key, value, set_section(key, value)); - } - - bool get(const std::string & key, std::string & value) - { - return search_and_apply(key, value, get_section(key, value)); - } - - bool modified() const - { - return ((find_if(_options.begin(), _options.end(), modified_section()) != _options.end()) || - (find_if(_sections.begin(), _sections.end(), modified_section()) != _sections.end())); - } - - private: - Section(): _name(""), _description(""), _recursive(false) {}; - - protected: - const std::string _name; - const std::string _description; - - OptionMap _options; - SectionMap _sections; - - const bool _recursive; -}; - -#endif /* _CONFIG_SECTION_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/const_this.hpp b/src/mod/endpoints/mod_khomp/commons/base/const_this.hpp deleted file mode 100644 index 48e3c1e32f..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/const_this.hpp +++ /dev/null @@ -1,15 +0,0 @@ - -#ifndef _CONST_THIS_H_ -#define _CONST_THIS_H_ - -template < typename T > -struct ConstThis -{ - T const & constThis() const - { - // TODO: will this return the right reference? - return static_cast(*this); - } -}; - -#endif /* _CONST_THIS_H_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/flagger.hpp b/src/mod/endpoints/mod_khomp/commons/base/flagger.hpp deleted file mode 100644 index 49a4adda0f..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/flagger.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#include - -#ifndef _FLAGGER_HPP_ -#define _FLAGGER_HPP_ - -template < typename Flag > -struct Flagger -{ - protected: - struct Bool - { - Bool(): value(false) {}; - Bool(bool &v): value(v) {}; - - bool value; - }; - - typedef std::map< Flag, Bool > Map; - - public: - typedef Initializer< Flag > InitFlags; - - Flagger() {}; - - Flagger(InitFlags flags) - { - for (typename InitFlags::iterator i = flags.begin(); i != flags.end(); i++) - { - Flag & flag = (*i); - _map[flag].value = true; - }; - }; - - void set(Flag elt, bool value = true) - { - _map[elt].value = value; - } - - bool is_set(Flag elt) - { - return _map[elt].value; - } - - Flagger & operator&(Flag elt) - { - set(elt); - return *this; - }; - - bool operator[](Flag elt) - { - return is_set(elt); - }; - - protected: - Map _map; -}; - -#endif /* _FLAGGER_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/format.cpp b/src/mod/endpoints/mod_khomp/commons/base/format.cpp deleted file mode 100644 index 74223cc406..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/format.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include "format.hpp" -//#include - -void FormatTraits::initialize(const char * format_string) -{ - std::string txt; - - const char * ptr = format_string; - - while (*ptr != '\0') - { - if (*ptr != '%') - { - txt += *ptr; - ++ptr; - continue; - } - - const char * ptr2 = ptr+1; - - if (*ptr2 == '%') - { - txt += *ptr; - ptr += 2; - continue; - } - - if (!txt.empty()) - push_argument(txt, T_LITERAL); - - std::string arg(1, *ptr); - - ++ptr; - - bool finished = false; - - short long_count = 0; - short short_count = 0; - - while(*ptr != '\0' && !finished) - { - switch (*ptr) - { - case ' ': - // uncomplete format with ' ', make it a literal. - arg += *ptr; - push_argument(arg, T_LITERAL); - finished = true; - break; - - case '%': - // uncomplete format with '%', make it a literal and start a new format. - push_argument(arg, T_LITERAL); - arg += *ptr; - break; - - case 'h': - short_count = std::min(short_count+1, 2); - long_count = 0; - arg += *ptr; - break; - - case 'l': - long_count = std::min(long_count+1, 2); - short_count = 0; - arg += *ptr; - break; - - case 'd': - case 'i': - arg += *ptr; - switch (long_count - short_count) - { - case 2: - push_argument(arg, T_SIGNED_LONG_LONG); - break; - case 1: - push_argument(arg, T_SIGNED_LONG); - break; - case 0: - push_argument(arg, T_SIGNED_INT); - break; - case -1: - push_argument(arg, T_SIGNED_SHORT); - break; - case -2: - push_argument(arg, T_SIGNED_SHORT_SHORT); - break; - default: - break; - } - finished = true; - break; - - case 'o': - case 'u': - case 'x': - case 'X': - arg += *ptr; - switch (long_count - short_count) - { - case 2: - push_argument(arg, T_UNSIGNED_LONG_LONG); - break; - case 1: - push_argument(arg, T_UNSIGNED_LONG); - break; - case 0: - push_argument(arg, T_UNSIGNED_INT); - break; - case -1: - push_argument(arg, T_UNSIGNED_SHORT); - break; - case -2: - push_argument(arg, T_UNSIGNED_SHORT_SHORT); - break; - default: - break; - } - finished = true; - break; - - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'a': - case 'A': - arg += *ptr; - push_argument(arg, T_FLOAT); - finished = true; - break; - - case 'c': - arg += *ptr; - push_argument(arg, T_CHAR); - finished = true; - break; - - case 's': - arg += *ptr; - push_argument(arg, T_STRING); - finished = true; - break; - - case 'p': - arg += *ptr; - push_argument(arg, T_POINTER); - finished = true; - break; - - case 'C': - case 'S': - case 'm': - case 'n': // unsupported for now. - arg += *ptr; - push_argument(arg, T_ANYTHING); - finished = true; - break; - - default: - arg += *ptr; - break; - } - - ++ptr; - } - - if (!arg.empty()) - push_argument(arg, T_LITERAL); - } - - if (!txt.empty()) - push_argument(txt, T_LITERAL); -} - -void FormatTraits::push_argument(std::string & data, FormatTraits::Type type) -{ -// std::cerr << "pushing type (" << type << ") with format (" << data << ")" << std::endl; - - _args.push(Argument(data, type)); - data.clear(); -} - -void FormatTraits::pop_argument(void) -{ - _args.pop(); -} - -const FormatTraits::Argument * FormatTraits::next_argument(void) -{ -// std::cerr << "size: " << _args.size() << std::endl; - - while (true) - { -// std::cerr << "loop size: " << _args.size() << std::endl; - - if (_args.empty()) - return NULL; // throw NoArgumentLeft(); - - const Argument & top = _args.front(); - - if (top.type() == T_LITERAL) - { -// std::cerr << "top type == LITERAL, looping..." << std::endl; - _result += top.fmts(); - pop_argument(); - } - else - { -// std::cerr << "top type: " << top.type() << std::endl; - return ⊤ - } - } -} - -/******************************************************************/ - -#if 0 -Format::Format(const char * format_string, bool raise_exception) -: _format(format_string), _valid(true), _raise(raise_exception) -{ - FormatTraits::initialize(format_string); -} - -Format::Format(std::string format_string, bool raise_exception) -: _format(format_string), _valid(true), _raise(raise_exception) -{ - FormatTraits::initialize(format_string.c_str()); -} - -/* -Format::Format(std::string & format_string, bool raise_exception) -: _format(NULL), _valid(true), _raise(raise_exception) -{ - initialize(format_string.c_str()); -} -*/ - -void Format::mark_invalid(std::string & msg) -{ - if (_valid) - { - _valid = false; - - _result = "** INVALID FORMAT: "; - _result += msg; - _result += " **"; - } -} - -void Format::raise(void) const -{ - if (!_valid) - { - // call specialized class - FormatException::raise(_result); - } -} - -bool Format::valid(void) const -{ -// raise(); - return _valid; -} - -std::string Format::str() -{ - if (!valid()) - return _result; - -// try -// { - if (next_argument() != NULL) - { - std::string msg; - - msg += "too few arguments passed for format '"; - msg += _format; - msg += "' ("; - msg += _format; - msg += ")"; - - mark_invalid(msg); - - return _result; - } -// catch (NoArgumentLeft e) -// { -// return _result; -// } -} - -#endif diff --git a/src/mod/endpoints/mod_khomp/commons/base/format.hpp b/src/mod/endpoints/mod_khomp/commons/base/format.hpp deleted file mode 100644 index 0469e4fdf9..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/format.hpp +++ /dev/null @@ -1,561 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _FORMAT_H_ -#define _FORMAT_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 // WINDOWS -# include -#endif - -struct InvalidFormat -{ - InvalidFormat(std::string _msg) : msg(_msg) {} - const std::string msg; -}; - -template < bool E > -struct FormatException -{ - void raise(const std::string & msg) const - { - /* DO NOTHING */ - }; -}; - -template < > -struct FormatException < true > -{ - void raise(const std::string & msg) const - { - throw InvalidFormat(msg); - }; -}; - -struct FormatTraits -{ - enum Type - { - T_ANYTHING = 1, - - T_SIGNED_SHORT, - T_SIGNED_SHORT_SHORT, - T_SIGNED_INT, - T_SIGNED_LONG, - T_SIGNED_LONG_LONG, - - T_UNSIGNED_SHORT, - T_UNSIGNED_SHORT_SHORT, - T_UNSIGNED_INT, - T_UNSIGNED_LONG, - T_UNSIGNED_LONG_LONG, - - T_FLOAT, - T_CHAR, - - T_POINTER, - T_STRING, - - T_LITERAL - }; - - struct Argument - { - Argument(std::string fmts, Type type) - : _fmts(fmts), _type(type) {}; - - const Type type(void) const { return _type; } - const std::string & fmts(void) const { return _fmts; } - - protected: - const std::string _fmts; - const Type _type; - }; - - typedef std::queue < Argument > ArgumentQueue; - - ////////////////////////////////// - - template < typename V > - bool number_verify_signed_short( V value ) const - { - return - ((typeid(V) == typeid(short int) || - typeid(V) == typeid(short) || - typeid(V) == typeid(const short int) || - typeid(V) == typeid(const short) || - typeid(V) == typeid(volatile short int) || - typeid(V) == typeid(volatile short)) && - sizeof(V) == sizeof(short)); - } - - template < typename V > - bool number_verify_unsigned_short( V value ) const - { - return - ((typeid(V) == typeid(unsigned short int) || - typeid(V) == typeid(unsigned short) || - typeid(V) == typeid(const unsigned short int) || - typeid(V) == typeid(const unsigned short) || - typeid(V) == typeid(volatile unsigned short int) || - typeid(V) == typeid(volatile unsigned short)) && - sizeof(V) == sizeof(unsigned short)); - } - - template < typename V > - bool number_verify_signed_long( V value ) const - { - return - ((typeid(V) == typeid(long int) || - typeid(V) == typeid(long) || - typeid(V) == typeid(const long int) || - typeid(V) == typeid(const long) || - typeid(V) == typeid(volatile long int) || - typeid(V) == typeid(volatile long)) && - sizeof(V) == sizeof(long)); - } - - template < typename V > - bool number_verify_unsigned_long( V value ) const - { - return - ((typeid(V) == typeid(unsigned long int) || - typeid(V) == typeid(unsigned long) || - typeid(V) == typeid(const unsigned long int) || - typeid(V) == typeid(const unsigned long) || - typeid(V) == typeid(volatile unsigned long int) || - typeid(V) == typeid(volatile unsigned long)) && - sizeof(V) == sizeof(long long)); - } - - template < typename V > - bool number_verify_signed_long_long( V value ) const - { - return - ((typeid(V) == typeid(long long int) || - typeid(V) == typeid(long long) || - typeid(V) == typeid(const long long int) || - typeid(V) == typeid(const long long) || - typeid(V) == typeid(volatile long long) || - typeid(V) == typeid(volatile long long int)) && - sizeof(V) == sizeof(long long)); - } - - template < typename V > - bool number_verify_unsigned_long_long( V value ) const - { - return - ((typeid(V) == typeid(unsigned long long int) || - typeid(V) == typeid(unsigned long long) || - typeid(V) == typeid(const unsigned long long int) || - typeid(V) == typeid(const unsigned long long) || - typeid(V) == typeid(volatile unsigned long long) || - typeid(V) == typeid(volatile unsigned long long int)) && - sizeof(V) == sizeof(unsigned long long)); - } - - template < typename V > - bool number_verify_signed_int( V value ) const - { - return - (sizeof(V) <= sizeof(int) || - typeid(V) == typeid(int) || - typeid(V) == typeid(const int) || - typeid(V) == typeid(volatile int)); - } - - template < typename V > - bool number_verify_unsigned_int( V value ) const - { - return - (sizeof(V) <= sizeof(unsigned int) || - typeid(V) == typeid(unsigned int) || - typeid(V) == typeid(const unsigned int) || - typeid(V) == typeid(volatile unsigned int)); - } - - template < typename V > - bool generic_verify( V value, const Type type ) const - { - switch (type) - { - /* EXCEPTION: consider any number an valid input. */ - case T_SIGNED_INT: - case T_UNSIGNED_INT: - return - (number_verify_signed_int(value) || - number_verify_unsigned_int(value) || - number_verify_signed_long(value) || - number_verify_unsigned_long(value) || - number_verify_signed_short(value) || - number_verify_unsigned_short(value)); - - case T_SIGNED_SHORT_SHORT: - return (typeid(V) == typeid(char) || typeid(V) == typeid(const char)); - - case T_SIGNED_SHORT: - return number_verify_signed_short(value); - - case T_SIGNED_LONG: - return number_verify_signed_long(value); - - case T_SIGNED_LONG_LONG: - return number_verify_signed_long_long(value); - - case T_UNSIGNED_SHORT_SHORT: - return (typeid(V) == typeid(unsigned char) || typeid(V) == typeid(unsigned char)); - - case T_UNSIGNED_SHORT: - return number_verify_unsigned_short(value); - - case T_UNSIGNED_LONG: - return number_verify_unsigned_long(value); - - case T_UNSIGNED_LONG_LONG: - return number_verify_unsigned_long_long(value); - - case T_FLOAT: - return (typeid(V) == typeid(float)) || (typeid(V) == typeid(double) || - typeid(V) == typeid(const float)) || (typeid(V) == typeid(const double)); - - case T_CHAR: - return (typeid(V) == typeid(char)) || (typeid(V) == typeid(unsigned char) || - typeid(V) == typeid(const char)) || (typeid(V) == typeid(const unsigned char)); - - case T_POINTER: - case T_STRING: - return false; - - case T_ANYTHING: - return true; - - case T_LITERAL: - return false; - } - - return false; - }; - - const Argument * next_argument(void); - - void push_argument(std::string & data, const Type type); - void pop_argument(void); - - void initialize(const char *); - - protected: - ArgumentQueue _args; - std::string _result; - -}; - -template < bool E = false > -struct FormatBase: protected FormatTraits, protected FormatException < E > -{ - static const unsigned int strings_base_length = 64; - static const unsigned int generic_base_length = 64; - - explicit FormatBase(const char * format_string) - : _format(format_string), _valid(true) - { - FormatTraits::initialize(format_string); - }; - - explicit FormatBase(std::string format_string) - : _format(format_string), _valid(true) - { - FormatTraits::initialize(format_string.c_str()); - }; - - bool valid(void) const - { - return _valid; - } - - const std::string str() - { - if (valid() && (next_argument() != NULL)) - { - std::string msg; - - // TODO: why format appears two times? - msg += "too few arguments passed for format '"; - msg += _format; - msg += "' ("; - msg += _format; - msg += ")"; - - mark_invalid(msg); - } - - raise(); - return _result; - }; - - //////////////////////////////////////////////////////////// - - template < typename V > - FormatBase & operator%( V value ) - { - if (!valid()) - return *this; - - const Argument * top = next_argument(); - - if (top == NULL) - { - std::string msg; - - msg += "too many arguments passed for format '"; - msg += _format; - msg += "'"; - - mark_invalid(msg); - } - else - { - char temp[generic_base_length]; - - if (!FormatTraits::generic_verify(value, top->type())) - { - std::string msg; - - msg += "type mismatch: got type '"; - msg += typeid(value).name(); - msg += "' in format '"; - msg += top->fmts(); - msg += "' ("; - msg += _format; - msg += ")"; - - mark_invalid(msg); - return *this; - } - - snprintf(temp, sizeof(temp), top->fmts().c_str(), value); - _result += temp; - - pop_argument(); - } - - raise(); - return *this; - } - - template < typename V > - FormatBase & operator%( V * value ) - { - if (!valid()) - return *this; - - const Argument * top = next_argument(); - - if (top == NULL) - { - std::string msg; - - msg += "too many arguments passed for format '"; - msg += _format; - msg += "'"; - - mark_invalid(msg); - } - else - { - switch (top->type()) - { - case T_POINTER: - { - char temp[generic_base_length]; - snprintf(temp, sizeof(temp), top->fmts().c_str(), value); - _result += temp; - break; - } - - case T_STRING: - { - if ((typeid(const char) == typeid(V)) || - (typeid(char) == typeid(V)) || - (typeid(const unsigned char) == typeid(V)) || - (typeid(unsigned char) == typeid(V)) || - (typeid(const void) == typeid(V)) || - (typeid(void) == typeid(V))) - { - int len = strlen((const char*)value)+strings_base_length+1; - - char * temp = new char[len]; - - snprintf(temp, len, top->fmts().c_str(), value); - _result += temp; - - delete[] temp; - } - else - { - std::string msg; - - msg += "type mismatch: got type '"; - msg += typeid(value).name(); - msg += "' in string format ("; - msg += _format; - msg += ")"; - - mark_invalid(msg); - } - break; - } - - default: - { - std::string msg; - - msg += "type mismatch: got pointer/string type in format '"; - msg += top->fmts(); - msg += "' ("; - msg += _format; - msg += ")"; - - mark_invalid(msg); - break; - } - } - - pop_argument(); - } - - raise(); - return *this; - } - - FormatBase & operator%( const std::string value ) - { - if (!valid()) - return *this; - - const Argument * top = next_argument(); - - if (top == NULL) - { - std::string msg; - - msg += "too many arguments passed for format '"; - msg += _format; - msg += "'"; - - mark_invalid(msg); - } - else - { - if (top->type() == T_STRING) - { - int len = value.length()+strings_base_length+1; - - char * temp = new char[len]; - - snprintf(temp, len, top->fmts().c_str(), value.c_str()); - _result += temp; - - delete[] temp; - } - else - { - std::string msg; - - msg += "type mismatch: got string type in format '"; - msg += top->fmts(); - msg += "' ("; - msg += _format; - msg += ")"; - - mark_invalid(msg); - } - - pop_argument(); - } - - raise(); - return *this; - } - - protected: - void mark_invalid(std::string & msg) - { - if (_valid) - { - _valid = false; - - _result = "** INVALID FORMAT: "; - _result += msg; - _result += " **"; - } - } - - void raise(void) const - { - if (!_valid) - { - // call specialized class - FormatException< E >::raise(_result); - } - } - - private: - const std::string _format; - bool _valid; -}; - -/* useful typedef for general usage (not generating exceptions) */ -typedef FormatBase<> Format; - -/* macros used for shortening lines and making the code clearer */ -#define STG(x) (x).str() -#define FMT(x) Format(x) - -#endif /* _FORMAT_H_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/function.hpp b/src/mod/endpoints/mod_khomp/commons/base/function.hpp deleted file mode 100644 index 7470bf245d..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/function.hpp +++ /dev/null @@ -1,429 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the "LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#ifndef _FUNCTION_HPP_ -#define _FUNCTION_HPP_ - -namespace Function -{ - struct EmptyFunction {}; - struct NonMemberFunction {}; - - /**/ - - template < typename FunctionTraits > - struct StorageBase: COUNTER_SUPER(StorageBase < FunctionTraits >) - { - typedef typename FunctionTraits::BaseType BaseType; - - typedef typename FunctionTraits::FunType FunType; - typedef typename FunctionTraits::ObjType ObjType; - - template < typename Functor > - StorageBase(const Functor f) - : _object(reinterpret_cast< ObjType >(new Functor(f))), - _function(reinterpret_cast< FunType >(&Functor::operator())), - _malloced(true) - {}; - - template < typename Functor > - StorageBase(Functor & f, bool malloced) - : _object(reinterpret_cast< ObjType >((malloced ? new Functor(f) : &f))), - _function(reinterpret_cast< FunType >(&Functor::operator())), - _malloced(malloced) - {}; - - StorageBase(FunType const * member) - : _object(reinterpret_cast< ObjType >(0)), - _function(reinterpret_cast< FunType >(member)), - _malloced(false) - {}; - - StorageBase() - : _object(reinterpret_cast< ObjType >(0)), - _function(reinterpret_cast< FunType >(0)), - _malloced(false) - {}; - - StorageBase(const StorageBase & o) - : COUNTER_REFER(o, StorageBase < FunctionTraits >), - _object(o._object), _function(o._function), _malloced(o._malloced) - {}; - - virtual ~StorageBase() {}; - - void unreference() - { - // TODO: will this work if we delete a different type? // - if (_malloced) - delete _object; - }; - - template < typename Functor > - void operator=(Functor f) - { - _object = reinterpret_cast< ObjType >(new Functor(f)), - _function = reinterpret_cast< FunType >(&Functor::operator()); - _malloced = true; - } - - protected: - ObjType _object; - FunType _function; - bool _malloced; - }; - - /**/ - - template < typename R > - struct VTable0 - { - R operator()(void) { return R(); }; - }; - - template < > - struct VTable0< void > - { - void operator()(void) { return; }; - }; - - template < typename R > - struct Function0Traits - { - typedef VTable0 BaseType; - - typedef R (BaseType::* FunType)(void); - typedef BaseType * ObjType; - }; - - /**/ - - template < typename R, typename A0 > - struct VTable1 - { - R operator()(A0 a0) { return R(); }; - }; - - template < typename A0 > - struct VTable1< void, A0 > - { - void operator()(A0 a0) { return; }; - }; - - template < typename R, typename A0 > - struct Function1Traits - { - typedef VTable1 BaseType; - - typedef R (BaseType::* FunType)(A0); - typedef BaseType * ObjType; - }; - - /**/ - - template < typename R, typename A0, typename A1 > - struct VTable2 - { - R operator()(A0 a0, A1) { return R(); }; - }; - - template < typename A0, typename A1 > - struct VTable2< void, A0, A1 > - { - void operator()(A0 a0, A1 a1) { return; }; - }; - - template < typename R, typename A0, typename A1 > - struct Function2Traits - { - typedef VTable2 BaseType; - - typedef R (BaseType::* FunType)(A0, A1); - typedef BaseType * ObjType; - }; - - /**/ - - template < typename R, typename A0, typename A1, typename A2 > - struct VTable3 - { - R operator()(A0 a0, A1 a1, A2 a2) { return R(); }; - }; - - template < typename A0, typename A1, typename A2 > - struct VTable3< void, A0, A1, A2 > - { - void operator()(A0 a0, A1 a1, A2 a2) { return; }; - }; - - template < typename R, typename A0, typename A1, typename A2 > - struct Function3Traits - { - typedef VTable3 BaseType; - - typedef R (BaseType::* FunType)(A0, A1, A2); - typedef BaseType * ObjType; - }; - - /**/ - - template < typename R, typename A0, typename A1, typename A2, typename A3 > - struct VTable4 - { - R operator()(A0 a0, A1 a1, A2 a2, A3 a3) { return R(); }; - }; - - template < typename A0, typename A1, typename A2, typename A3 > - struct VTable4< void, A0, A1, A2, A3 > - { - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { return; }; - }; - - template < typename R, typename A0, typename A1, typename A2, typename A3 > - struct Function4Traits - { - typedef VTable4 BaseType; - - typedef R (BaseType::* FunType)(A0, A1, A2, A3); - typedef BaseType * ObjType; - }; - - /**/ - - template < typename R, typename A0 > - struct Function0 : public StorageBase < Function0Traits < R > > - { - typedef StorageBase < Function0Traits < R > > Storage; - - template < typename Functor > - Function0(const Functor f) - : Storage(f) {}; - - template < typename Functor > - Function0(Functor & f, bool m) - : Storage(f, m) {}; - - Function0(const typename Function0Traits < R >::FunType * m) - : Storage(m) {}; - - Function0() {}; - - R operator()(void) - { - if (reinterpret_cast(Storage::_object) == 0) - throw EmptyFunction(); - - return ((Storage::_object)->*(Storage::_function))(); - } - - template < typename Object > - R operator()(Object * object) - { - if (reinterpret_cast(Storage::_function) == 0) - throw EmptyFunction(); - - if (reinterpret_cast(Storage::_object) != 0) - throw NonMemberFunction(); - - return (reinterpret_cast< typename Function0Traits < R >::ObjType *>(object)->*(Storage::_function))(); - } - }; - - template < typename R, typename A0 > - struct Function1 : public StorageBase < Function1Traits < R, A0 > > - { - typedef StorageBase < Function1Traits < R, A0 > > Storage; - - template < typename Functor > - Function1(const Functor f) - : Storage(f) {}; - - template < typename Functor > - Function1(Functor & f, bool m) - : Storage(f, m) {}; - - Function1(const typename Function1Traits < R, A0 >::FunType * m) - : Storage(m) {}; - - Function1() {}; - - R operator()(A0 a0) - { - if (reinterpret_cast(Storage::_object) == 0) - throw EmptyFunction(); - - return ((Storage::_object)->*(Storage::_function))(a0); - } - - template < typename Object > - R operator()(Object * object, A0 a0) - { - if (reinterpret_cast(Storage::_function) == 0) - throw EmptyFunction(); - - if (reinterpret_cast(Storage::_object) != 0) - throw NonMemberFunction(); - - return (reinterpret_cast< typename Function1Traits < R, A0 >::ObjType *>(object)->*(Storage::_function))(a0); - } - }; - - template < typename R, typename A0, typename A1 > - struct Function2 : public StorageBase < Function2Traits < R, A0, A1 > > - { - typedef StorageBase < Function2Traits < R, A0, A1 > > Storage; - - template < typename Functor > - Function2(const Functor f) - : Storage(f) {}; - - template < typename Functor > - Function2(Functor & f, bool m) - : Storage(f, m) {}; - - Function2(const typename Function2Traits < R, A0, A1 >::FunType * m) - : Storage(m) {}; - - Function2() {}; - - R operator()(A0 a0, A1 a1) - { - if (reinterpret_cast(Storage::_object) == 0) - throw EmptyFunction(); - - return ((Storage::_object)->*(Storage::_function))(a0, a1); - } - - template < typename Object > - R operator()(Object * object, A0 a0, A1 a1) - { - if (reinterpret_cast(Storage::_function) == 0) - throw EmptyFunction(); - - if (reinterpret_cast(Storage::_object) != 0) - throw NonMemberFunction(); - - return (reinterpret_cast< typename Function2Traits < R, A0, A1 >::ObjType *>(object)->*(Storage::_function))(a0, a1); - } - }; - - template < typename R, typename A0, typename A1, typename A2 > - struct Function3 : public StorageBase < Function3Traits < R, A0, A1, A2 > > - { - typedef StorageBase < Function3Traits < R, A0, A1, A2 > > Storage; - - template < typename Functor > - Function3(const Functor f) - : Storage(f) {}; - - template < typename Functor > - Function3(Functor & f, bool m) - : Storage(f, m) {}; - - Function3(const typename Function3Traits < R, A0, A1, A2 >::FunType * m) - : Storage(m) {}; - - Function3() {}; - - R operator()(A0 a0, A1 a1, A2 a2) - { - if (reinterpret_cast(Storage::_object) == 0) - throw EmptyFunction(); - - return ((Storage::_object)->*(Storage::_function))(a0, a1, a2); - } - - template < typename Object > - R operator()(Object * object, A0 a0, A1 a1, A2 a2) - { - if (reinterpret_cast(Storage::_function) == 0) - throw EmptyFunction(); - - if (reinterpret_cast(Storage::_object) != 0) - throw NonMemberFunction(); - - return (reinterpret_cast< typename Function3Traits < R, A0, A1, A2 >::ObjType *>(object)->*(Storage::_function))(a0, a1, a2); - } - }; - - template < typename R, typename A0, typename A1, typename A2, typename A3 > - struct Function4 : public StorageBase < Function4Traits < R, A0, A1, A2, A3 > > - { - typedef StorageBase < Function4Traits < R, A0, A1, A2, A3 > > Storage; - - template < typename Functor > - Function4(const Functor f) - : Storage(f) {}; - - template < typename Functor > - Function4(Functor & f, bool m) - : Storage(f, m) {}; - - Function4(const typename Function4Traits < R, A0, A1, A2, A3 >::FunType * m) - : Storage(m) {}; - - Function4() {}; - - R operator()(A0 a0, A1 a1, A2 a2, A3 a3) - { - if (reinterpret_cast(Storage::_object) == 0) - throw EmptyFunction(); - - return ((Storage::_object)->*(Storage::_function))(a0, a1, a2, a3); - } - - template < typename Object > - R operator()(Object * object, A0 a0, A1 a1, A2 a2, A3 a3) - { - if (reinterpret_cast(Storage::_function) == 0) - throw EmptyFunction(); - - if (reinterpret_cast(Storage::_object) != 0) - throw NonMemberFunction(); - - return (reinterpret_cast< typename Function4Traits < R, A0, A1, A2, A3 >::ObjType *>(object)->*(Storage::_function))(a0, a1, a2, a3); - } - }; -}; - -#endif /* _FUNCTION_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/initializer.hpp b/src/mod/endpoints/mod_khomp/commons/base/initializer.hpp deleted file mode 100644 index 16359e8c97..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/initializer.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#ifndef _INITIALIZER_HPP_ -#define _INITIALIZER_HPP_ - -template < typename Type > -struct Initializer: public std::vector< Type > -{ - typedef std::vector< Type > Super; - - Initializer(Type e) { Super::push_back(e); }; - Initializer(Type & e) { Super::push_back(e); }; - - Initializer & operator&(const Initializer v) - { - Super::insert(Super::end(), v.begin(), v.end()); - return *this; - }; - - Initializer & operator&(Initializer & v) - { - Super::insert(Super::end(), v.begin(), v.end()); - return *this; - }; - - Initializer & operator&(Type v) - { - Super::insert(Super::end(), v); - return *this; - }; - - Initializer & operator&(Type & v) - { - Super::insert(Super::end(), v); - return *this; - }; -}; - -#endif /* _INITIALIZER_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/k3lapi.cpp b/src/mod/endpoints/mod_khomp/commons/base/k3lapi.cpp deleted file mode 100644 index ffc9d93435..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/k3lapi.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#include - -K3LAPIBase::K3LAPIBase() -: _device_count(0), _channel_count(0), _link_count(0), - _device_config(0), _channel_config(0), _link_config(0) -{}; - -/* initialize the whole thing! */ - -void K3LAPIBase::start(void) -{ - /* tie the used k3l to the compiled k3l version */ - char *ret = k3lStart(k3lApiMajorVersion, k3lApiMinorVersion, 0); //k3lApiBuildVersion); - - if (ret && *ret) - throw start_failed(ret); - - /* call init automagically */ - init(); -} - -void K3LAPIBase::stop(void) -{ - k3lStop(); - fini(); -} - -/* envio de comandos para placa */ - -void K3LAPIBase::mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const -{ - KMixerCommand mix; - - mix.Track = track; - mix.Source = src; - mix.SourceIndex = index; - - command(dev, obj, CM_MIXER, (const char *) &mix); -} - -void K3LAPIBase::mixerRecord(int32 dev, KDeviceType type, int32 obj, byte track, KMixerSource src, int32 index) const -{ - /* estes buffers *NAO PODEM SER ESTATICOS*! */ - char cmd[] = { 0x3f, 0x03, (char)obj, (char)track, 0xff, 0xff }; - - switch (src) - { - case kmsChannel: - cmd[4] = 0x05; - cmd[5] = (char)index; - break; - - case kmsNoDelayChannel: - cmd[4] = 0x0a; - cmd[5] = (char)index; - break; - - case kmsGenerator: - cmd[4] = 0x09; - - switch ((KMixerTone)index) - { - case kmtSilence: - cmd[5] = 0x0F; - break; - case kmtDial: - cmd[5] = 0x08; - break; - case kmtBusy: - cmd[5] = 0x0D; - break; - - case kmtFax: - case kmtVoice: - case kmtEndOf425: - case kmtCollect: - case kmtEndOfDtmf: - /* TODO: exception, unable to generate */ - break; - } - break; - - case kmsCTbus: - case kmsPlay: - /* TODO: exception, not implemented! */ - break; - } - - int32 dsp = get_dsp(type, DSP_AUDIO); - - raw_command(dev, dsp, cmd, sizeof(cmd)); -} - -void K3LAPIBase::mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const -{ - KMixerCommand mix; - - mix.Track = track; - mix.Source = src; - mix.SourceIndex = index; - - command(dev, obj, CM_MIXER_CTBUS, (const char *) &mix); -} - -void K3LAPIBase::command(int32 dev, int32 obj, int32 code, std::string & str) const -{ - command(dev, obj, code, str.c_str()); -} - -void K3LAPIBase::command (int32 dev, int32 obj, int32 code, const char * parms) const -{ - K3L_COMMAND cmd; - - cmd.Cmd = code; - cmd.Object = obj; - cmd.Params = (byte *)parms; - - int32 rc = k3lSendCommand(dev, &cmd); - - if (rc != ksSuccess) - throw failed_command(code, dev, obj, rc); -} - -void K3LAPIBase::raw_command(int32 dev, int32 dsp, std::string & str) const -{ - raw_command(dev, dsp, str.data(), str.size()); -} - -void K3LAPIBase::raw_command(int32 dev, int32 dsp, const char * cmds, int32 size) const -{ - std::string str(cmds, size); - - int32 rc = k3lSendRawCommand(dev, dsp, (void *)cmds, size); - - if (rc != ksSuccess) - throw failed_raw_command(dev, dsp, rc); -} - -KLibraryStatus K3LAPIBase::get_param(K3L_EVENT *ev, const char *name, std::string &res) const -{ - char tmp_param[256]; - memset((void*)tmp_param, 0, sizeof(tmp_param)); - - int32 rc = k3lGetEventParam (ev, (sbyte *)name, (sbyte *)tmp_param, sizeof(tmp_param)-1); - - if (rc != ksSuccess) - return (KLibraryStatus)rc; - - res.append(tmp_param, strlen(tmp_param)); - return ksSuccess; -} - -std::string K3LAPIBase::get_param(K3L_EVENT *ev, const char *name) const -{ - std::string res; - - KLibraryStatus rc = get_param(ev, name, res); - - if (rc != ksSuccess) - throw get_param_failed(name, rc); - - return res; -} - -std::string K3LAPIBase::get_param_optional(K3L_EVENT *ev, const char *name) const -{ - std::string res; - - (void)get_param(ev, name, res); - - return res; -} - -void K3LAPIBase::init(void) -{ - if (_device_count != 0) return; - - _device_count = k3lGetDeviceCount(); - - _device_type = new KDeviceType[_device_count]; - _device_config = new device_conf_type[_device_count]; - _channel_config = new channel_ptr_conf_type[_device_count]; - _link_config = new link_ptr_conf_type[_device_count]; - _channel_count = new unsigned int[_device_count]; - _link_count = new unsigned int[_device_count]; - - for (unsigned int dev = 0; dev < _device_count; dev++) - { - _device_type[dev] = (KDeviceType) k3lGetDeviceType(dev); - - /* caches each device config */ - if (k3lGetDeviceConfig(dev, ksoDevice + dev, &(_device_config[dev]), sizeof(_device_config[dev])) != ksSuccess) - throw start_failed("k3lGetDeviceConfig(device)"); - - /* adjust channel/link count for device */ - _channel_count[dev] = _device_config[dev].ChannelCount; - _link_count[dev] = _device_config[dev].LinkCount; - - /* caches each channel config */ - _channel_config[dev] = new channel_conf_type[_channel_count[dev]]; - - for (unsigned int obj = 0; obj < _channel_count[dev]; obj++) - { - if (k3lGetDeviceConfig(dev, ksoChannel + obj, &(_channel_config[dev][obj]), - sizeof(_channel_config[dev][obj])) != ksSuccess) - throw start_failed("k3lGetDeviceConfig(channel)"); - } - - /* adjust link count for device */ - _link_count[dev] = _device_config[dev].LinkCount; - - /* caches each link config */ - _link_config[dev] = new link_conf_type[_link_count[dev]]; - - for (unsigned int obj = 0; obj < _link_count[dev]; obj++) - { - if (k3lGetDeviceConfig(dev, ksoLink + obj, &(_link_config[dev][obj]), - sizeof(_link_config[dev][obj])) != ksSuccess) - throw start_failed("k3lGetDeviceConfig(link)"); - } - } -} - -void K3LAPIBase::fini(void) -{ - for (unsigned int dev = 0; dev < _device_count; dev++) - { - if (_channel_config[dev]) - { - delete[] _channel_config[dev]; - _channel_config[dev] = NULL; - } - - if (_link_config[dev]) - { - delete[] _link_config[dev]; - _link_config[dev] = NULL; - } - } - - _device_count = 0; - - if (_device_type) { delete[] _device_type; _device_type = NULL; } - if (_device_config) { delete[] _device_config; _device_config = NULL; } - if (_channel_config) { delete[] _channel_config; _channel_config = NULL; } - if (_link_config) { delete[] _link_config; _link_config = NULL; } - if (_channel_count) { delete[] _channel_count; _channel_count = NULL; } - if (_link_count) { delete[] _link_count; _link_count = NULL; } -} - -int32 K3LAPIBase::get_dsp(KDeviceType devtype, K3LAPI::DspType type) const -{ - switch (devtype) - { - case kdtFXO: - case kdtFXOVoIP: -#if K3L_AT_LEAST(1,6,0) - case kdtGSM: - case kdtGSMSpx: -#endif -#if K3L_AT_LEAST(2,1,0) - case kdtGSMUSB: - case kdtGSMUSBSpx: -#endif - return 0; - - default: - return (type == DSP_AUDIO ? 1 : 0); - } -} - -int32 K3LAPIBase::get_dsp(const K3LAPIBase::GenericTarget & tgt, K3LAPI::DspType type) const -{ - return get_dsp(_device_type[tgt.device], type); -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/k3lapi.hpp b/src/mod/endpoints/mod_khomp/commons/base/k3lapi.hpp deleted file mode 100644 index f65d52405a..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/k3lapi.hpp +++ /dev/null @@ -1,494 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include - -#include - -#include - -/* if using full k3l.h (for softpbx), version already defined. */ -#ifndef k3lApiMajorVersion -# include -#endif - -#ifdef __GNUC_PREREQ -#if __GNUC_PREREQ(4,3) -#include -#endif -#endif - -#include - -#ifndef _K3LAPI_HPP_ -#define _K3LAPI_HPP_ - -struct K3LAPITraits -{ - struct invalid_device; - struct invalid_channel; - struct invalid_link; - - struct invalid_target: public std::runtime_error - { - friend class invalid_device; - friend class invalid_channel; - friend class invalid_link; - - const int32 device, object; - - protected: - invalid_target(int32 _device, int32 _object, const std::string & msg) - : std::runtime_error(msg), device(_device), object(_object) {}; - }; - - struct invalid_device: public invalid_target - { - invalid_device(int32 _device) - : invalid_target(_device, -1, STG(FMT("invalid device number '%d'") % _device)) {}; - }; - - struct invalid_channel: public invalid_target - { - invalid_channel(int32 _device, int32 _channel) - : invalid_target(_device, _channel, STG(FMT("invalid channel number '%d' on device '%d'") % _channel % _device)) {}; - }; - - struct invalid_link: public invalid_target - { - invalid_link(int32 _device, int32 _link) - : invalid_target(_device, _link, STG(FMT("invalid link number '%d' on device '%d'") % _link % _device)) {}; - }; -}; - -struct K3LAPIBase -{ - /* High level checked object identifier. */ - - struct GenericTarget - { - typedef enum { DEVICE, CHANNEL, MIXER, LINK } Type; - - GenericTarget(const K3LAPIBase & k3lapi, Type _type, int32 _device, int32 _object) - : type(_type), device((unsigned int)_device), object((unsigned int)_object) - { - switch (_type) - { - case DEVICE: - if (!k3lapi.valid_device(_device)) - throw K3LAPITraits::invalid_device(_device); - break; - - case CHANNEL: - case MIXER: - if (!k3lapi.valid_channel(_device, _object)) - throw K3LAPITraits::invalid_channel(_device, _object); - break; - - case LINK: - if (!k3lapi.valid_link(_device, _object)) - throw K3LAPITraits::invalid_link(_device, _object); - break; - } - }; - - const Type type; - - const unsigned int device; - const unsigned int object; - }; - -/* - struct LinkTarget : public GenericTarget - { - LinkTarget(const K3LAPIBase & k3lapi, int32 _device, int32 _object) - : GenericTarget(k3lapi, GenericTarget::LINK, _device, _object) {}; - }; - - struct ChannelTarget : public GenericTarget - { - ChannelTarget(const K3LAPIBase & k3lapi, int32 _device, int32 _object) - : GenericTarget(k3lapi, GenericTarget::CHANNEL, _device, _object) {}; - }; - -*/ - template < GenericTarget::Type T > - struct Target: public GenericTarget - { - Target(const K3LAPIBase & k3lapi, int32 _device, int32 _object) - : GenericTarget(k3lapi, T, _device, _object) {}; - -// operator const GenericTarget&() const { return static_cast(*this); }; - }; - - /* exceptions */ - - struct start_failed: public std::runtime_error - { - start_failed(const char * msg) - : std::runtime_error(msg) {}; - }; - - struct failed_command - { - failed_command(int32 _code, unsigned short _dev, unsigned short _obj, int32 _rc) - : code(_code), dev(_dev), obj(_obj), rc(_rc) {}; - - int32 code; - unsigned short dev; - unsigned short obj; - int32 rc; - }; - - struct failed_raw_command - { - failed_raw_command(unsigned short _dev, unsigned short _dsp, int32 _rc) - : dev(_dev), dsp(_dsp), rc(_rc) {}; - - unsigned short dev; - unsigned short dsp; - int32 rc; - }; - - struct get_param_failed - { - get_param_failed(std::string _name, int32 _rc) - : name(_name), rc((KLibraryStatus)_rc) {}; - - std::string name; - KLibraryStatus rc; - }; - - /* typedefs essenciais */ - - typedef K3L_DEVICE_CONFIG device_conf_type; - typedef K3L_CHANNEL_CONFIG channel_conf_type; - typedef K3L_CHANNEL_CONFIG * channel_ptr_conf_type; - typedef K3L_LINK_CONFIG link_conf_type; - typedef K3L_LINK_CONFIG * link_ptr_conf_type; - - /* constructors/destructors */ - - K3LAPIBase(); - virtual ~K3LAPIBase() {}; - - /* (init|final)ialize the whole thing! */ - - void start(void); - void stop(void); - - /* verificacao de intervalos */ - - inline bool valid_device(int32 dev) const - { - return (dev >= 0 && dev < ((int32)_device_count)); - } - - inline bool valid_channel(int32 dev, int32 obj) const - { - return (valid_device(dev) && obj >= 0 && obj < ((int32)_channel_count[dev])); - } - - inline bool valid_link(int32 dev, int32 obj) const - { - return (valid_device(dev) && obj >= 0 && obj < ((int32)_link_count[dev])); - } - - /* envio de comandos para placa (geral) */ - - void raw_command(int32 dev, int32 dsp, std::string & str) const; - void raw_command(int32 dev, int32 dsp, const char * cmds, int32 size) const; - - /* obter dados 'cacheados' (geral) */ - - inline unsigned int device_count(void) const - { - return _device_count; - } - - /* envio de comandos para placa (sem identificadores) */ - - void mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const; - void mixerRecord(int32 dev, KDeviceType type, int32 obj, byte track, KMixerSource src, int32 index) const; - void mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const; - - void command (int32 dev, int32 obj, int32 code, std::string & str) const; - void command (int32 dev, int32 obj, int32 code, const char * parms = NULL) const; - - - /* envio de comandos para placa (com identificadores) */ - - void mixer(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const - { - mixer(tgt.device, tgt.object, track, src, index); - } - - void mixerRecord(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const - { - mixerRecord((int32)tgt.device, _device_type[tgt.device], (int32)tgt.object, track, src, index); - } - - void mixerCTbus(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const - { - mixerCTbus((int32)tgt.device, (int32)tgt.object, track, src, index); - } - - void command(const GenericTarget & tgt, int32 code, std::string & str) const - { - command((int32)tgt.device, (int32)tgt.object, code, str); - }; - - void command(const GenericTarget & tgt, int32 code, const char * parms = NULL) const - { - command((int32)tgt.device, (int32)tgt.object, code, parms); - }; - - /* obter dados 'cacheados' (com indentificadores) */ - - inline unsigned int channel_count(const GenericTarget & tgt) const - { - return _channel_count[tgt.device]; - } - - inline unsigned int link_count(const GenericTarget & tgt) const - { - return _link_count[tgt.device]; - } - - KDeviceType device_type(const GenericTarget & tgt) const - { - return _device_type[tgt.device]; - } - - const K3L_DEVICE_CONFIG & device_config(const GenericTarget & tgt) const - { - return _device_config[tgt.device]; - } - - const K3L_CHANNEL_CONFIG & channel_config(const Target & tgt) const - { - return _channel_config[tgt.device][tgt.object]; - } - - const K3L_LINK_CONFIG & link_config(const Target & tgt) const - { - return _link_config[tgt.device][tgt.object]; - } - - /* pega valores em strings de eventos */ - - KLibraryStatus get_param(K3L_EVENT *ev, const char *name, std::string &res) const; - - std::string get_param(K3L_EVENT *ev, const char *name) const; - std::string get_param_optional(K3L_EVENT *ev, const char *name) const; - - /* inicializa valores em cache */ - - void init(void); - void fini(void); - - /* utilidades diversas e informacoes */ - - enum DspType - { - DSP_AUDIO, - DSP_SIGNALING, - }; - - int32 get_dsp(KDeviceType, DspType) const; - - int32 get_dsp(const GenericTarget &, DspType) const; - - protected: - - unsigned int _device_count; - unsigned int * _channel_count; - unsigned int * _link_count; - - device_conf_type * _device_config; - channel_ptr_conf_type * _channel_config; - link_ptr_conf_type * _link_config; - KDeviceType * _device_type; -}; - -/* exceptions */ -template < bool E = false > -struct K3LAPIException -{ - void invalid_device(const int32 device) const - { - /* NOTHING */ - } - - void invalid_channel(const int32 device, const int32 channel) const - { - /* NOTHING */ - } - - void invalid_link(const int32 device, const int32 link) const - { - /* NOTHING */ - } -}; - -template < > -struct K3LAPIException < true > -{ - void invalid_device(const int32 device) const - { - throw K3LAPITraits::invalid_device(device); - } - - void invalid_channel(const int32 device, const int32 channel) const - { - throw K3LAPITraits::invalid_channel(device, channel); - } - - void invalid_link(const int32 device, const int32 link) const - { - throw K3LAPITraits::invalid_link(device, link); - } -}; - -template < bool E = false > -struct K3LAPITemplate: public K3LAPIBase, protected K3LAPIException < E > -{ - using K3LAPIBase::device_config; - using K3LAPIBase::channel_config; - using K3LAPIBase::link_config; - - using K3LAPIBase::device_type; - using K3LAPIBase::get_dsp; - - using K3LAPIBase::mixerRecord; - - /* obter dados 'cacheados' (sem identificadores) */ - - inline unsigned int channel_count(int32 dev) const - { - if (!valid_device(dev)) - { - K3LAPIException< E >::invalid_device(dev); - return 0; - } - - return _channel_count[dev]; - } - - inline unsigned int link_count(int32 dev) const - { - if (!valid_device(dev)) - { - K3LAPIException< E >::invalid_device(dev); - return 0; - } - - return _link_count[dev]; - } - - inline uint32 channel_stats(int32 dev, int32 obj, uint32 index) const - { - if (!valid_channel(dev, obj)) - { - K3LAPIException< E >::invalid_channel(dev, obj); - return 0u; - } - - uint32 res_value = 0u; - -#if K3L_AT_LEAST(2,1,0) - if (k3lGetChannelStats(dev, obj, index, &res_value) != ksSuccess) - return 0u; - - return res_value; -#endif - } - - KDeviceType device_type(int32 dev) const - { - if (!valid_device(dev)) - { - K3LAPIException< E >::invalid_device(dev); - return kdtDevTypeCount; - } - - return _device_type[dev]; - } - - const K3L_DEVICE_CONFIG & device_config(int32 dev) const - { - if (!valid_device(dev)) - throw K3LAPITraits::invalid_device(dev); - - return _device_config[dev]; - } - - const K3L_CHANNEL_CONFIG & channel_config(int32 dev, int32 obj) const - { - if (!valid_channel(dev, obj)) - throw K3LAPITraits::invalid_channel(dev, obj); - - return _channel_config[dev][obj]; - } - - const K3L_LINK_CONFIG & link_config(int32 dev, int32 obj) const - { - if (!valid_link(dev, obj)) - throw K3LAPITraits::invalid_link(dev, obj); - - return _link_config[dev][obj]; - } - - int32 get_dsp(int32 dev, DspType type) const - { - return get_dsp(device_type(dev), type); - } - - void mixerRecord(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const - { - mixerRecord(dev, device_type(dev), obj, track, src, index); - } -}; - -typedef K3LAPITemplate<> K3LAPI; - -#endif /* _K3LAPI_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/k3lutil.cpp b/src/mod/endpoints/mod_khomp/commons/base/k3lutil.cpp deleted file mode 100644 index 3fda813a03..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/k3lutil.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -std::string K3LUtil::channelStatus(int32 dev, int32 channel, - Verbose::Presentation fmt) -{ - try - { - const K3L_CHANNEL_CONFIG & config = _k3lapi.channel_config(dev, channel); - - K3L_CHANNEL_STATUS status; - - KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev, - channel + ksoChannel, &status, sizeof(status)); - - switch (ret) - { - case ksSuccess: return Verbose::channelStatus(config.Signaling, - status.AddInfo, fmt); - default: return (fmt == Verbose::EXACT ? "" - : "Unknown (fail)"); - } - } - catch(K3LAPITraits::invalid_channel & e) - { - return (fmt == Verbose::EXACT ? "" : "Unknown (fail)"); - } -} - -std::string K3LUtil::callStatus(int32 dev, int32 channel, - Verbose::Presentation fmt) -{ - K3L_CHANNEL_STATUS status; - - KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus(dev, - channel + ksoChannel, &status, sizeof(status)); - - switch (ret) - { - case ksSuccess: return Verbose::callStatus(status.CallStatus, fmt); - default: return (fmt == Verbose::EXACT ? "" - : "Unknown (fail)"); - } -} - -std::string K3LUtil::linkStatus(int32 dev, int32 link, - Verbose::Presentation fmt, KSignaling signaling, bool simpleStatus) -{ - try - { - if (signaling == ksigInactive) - { - const K3L_LINK_CONFIG & config = _k3lapi.link_config(dev, link); - signaling = config.Signaling; - } - - K3L_LINK_STATUS status; - - KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev, - link + ksoLink, &status, sizeof(status)); - - switch (ret) - { - case ksSuccess: return Verbose::linkStatus(signaling, status.E1, fmt, simpleStatus); - default: return (fmt == Verbose::EXACT ? - "" : "Unknown (failure)"); - } - } - catch(K3LAPITraits::invalid_channel & e) - { - return (fmt == Verbose::EXACT ? "" - : "Unknown (failure)"); - } -} - - -unsigned int K3LUtil::physicalLinkCount(int32 dev, bool count_virtual) -{ - unsigned int number = 0; - - try - { - switch (_k3lapi.device_type(dev)) - { -#if K3L_AT_LEAST(1,6,0) - case kdtFXS: - number = (count_virtual ? (_k3lapi.channel_count(dev) < 50 ? 1 : 2) : 0); - break; - - case kdtFXSSpx: - number = (count_virtual ? (_k3lapi.channel_count(dev) < 30 ? 1 : 2) : 0); - break; -#endif - -#if K3L_AT_LEAST(2,1,0) - case kdtE1FXSSpx: - number = (count_virtual ? 2 : 1); - break; -#endif - - /* E1 boards */ - case kdtE1: - case kdtE1Spx: - case kdtE1IP: - number = _k3lapi.link_count(dev); - break; - - case kdtPR: - case kdtE1GW: - number = 1; - break; - -#if K3L_AT_LEAST(1,6,0) - case kdtFXO: - case kdtFXOVoIP: - case kdtGSM: - case kdtGSMSpx: -#else - case kdtFX: - case kdtFXVoIP: -#endif - case kdtConf: - case kdtGWIP: -#if K3L_AT_LEAST(2,1,0) - case kdtGSMUSB: - case kdtGSMUSBSpx: - case kdtReserved1: // just to avoid warnings. - case kdtDevTypeCount: // just to avoid warnings. -#endif - number = 0; - break; - } - } - catch(K3LAPITraits::invalid_device & e) - { - return 0; - } - - return number; -} - - -K3LUtil::ErrorCountType K3LUtil::linkErrorCount(int32 dev, int32 link, - Verbose::Presentation fmt) -{ - ErrorCountType result; - K3L_LINK_ERROR_COUNTER status; - - KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev, - link + ksoLinkMon, &status, sizeof(status)); - - switch (ret) - { - case ksSuccess: - for (unsigned int i = klecChangesToLock; i < klecCount; i++) - { - result.push_back(ErrorCountPairType(Verbose::linkErrorCounter - ((KLinkErrorCounter)i, fmt), status.ErrorCounters[i])); - } - /* fall */ - - default: - return result; - } -} - diff --git a/src/mod/endpoints/mod_khomp/commons/base/k3lutil.hpp b/src/mod/endpoints/mod_khomp/commons/base/k3lutil.hpp deleted file mode 100644 index 9d87d8b0f6..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/k3lutil.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include -#include - -#include -#include - -#ifndef _K3LUTIL_HPP_ -#define _K3LUTIL_HPP_ - -struct K3LUtil -{ - typedef std::pair < std::string, unsigned int > ErrorCountPairType; - typedef std::list < ErrorCountPairType > ErrorCountType; - - K3LUtil(K3LAPI & k3lapi): _k3lapi(k3lapi) {}; - - std::string callStatus(int32 dev, int32 channel, - Verbose::Presentation fmt = Verbose::HUMAN); - - std::string channelStatus(int32, int32, - Verbose::Presentation fmt = Verbose::HUMAN); - - std::string linkStatus(int32, int32, - Verbose::Presentation fmt = Verbose::HUMAN, - KSignaling sig = ksigInactive, - bool simpleStatus = false); - - unsigned int physicalLinkCount(int32 dev, bool count_virtual = false); - - ErrorCountType linkErrorCount(int32, int32, - Verbose::Presentation fmt = Verbose::HUMAN); - - protected: - K3LAPI & _k3lapi; -}; - -#endif /* _K3LUTIL_HPP_ */ - diff --git a/src/mod/endpoints/mod_khomp/commons/base/logger.hpp b/src/mod/endpoints/mod_khomp/commons/base/logger.hpp deleted file mode 100644 index 2a119afb9c..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/logger.hpp +++ /dev/null @@ -1,557 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_FREESWITCH) -extern "C" -{ - #include -} -#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) -extern "C" -{ - #include -} -#endif -/* - -******************************************************************************** -***************************** 'Logger' user manual ***************************** -******************************************************************************** - -* Description: - -This class does the management of log messages for applications. It works with -the following axioms: - -<*> There are several class of messages. -<*> There are some outputs, which may be files, sockets, or a console device. -<*> There are options for classes, for outputs and for the association of both. - -The last rule also shows the order in which options are processed: first the -'classes' options are processed, then 'output' options are processed, and then -the options for the tuple '(class, output)' are processed. - -The options are mapped like this: - - -> options [prefix, flags] - -> options [prefix] -( , ) -> options [prefix, flags] - - - "prefix" means a fixed string prefix before the real message. - - "flags" means auxiliary flags (DATETIME, THREADID) which are - used to add information based on OS or process context info. - -* Example of use: - -typedef enum -{ - C_DBG_FUNC, - C_DBG_LOCK, - C_WARNING, - C_ERROR, - C_CLI, -} -AstClassId; - -typedef enum -{ - F_CONSOLE, - F_GENERIC, - F_TRACE, -} -AstOutputId; - -// used to indicate the console log // -struct AstConsoleLog {}; - -struct AstPrinter: public Logger::DefaultPrinter -{ - typedef Logger::DefaultPrinter Super; - - using namespace Tagged; - - using Super::operator()(int); - - // just 2 type of descriptors // - typedef Union < int, Union < AstConsoleLog > > Container; - - ast_printer(std::string & msg): Super(msg) {}; - - bool operator()(const AstConsoleLog & log) - { - ast_console_puts(_msg.c_str()); - return true; - }; - -#if 0 - bool operator()(int log) - { - return Super::operator()(log); - }; -#endif -}; - -bool start_log() -{ - typedef Logger::Manager LogManager; - - LogManager logger; - - // shortcut definition // - typedef LogManager::Option LogOption; - - FILE * log_file = fopen( "output.log", "a"); - - if (!log_file) - return false; - - logger.add( F_CONSOLE, AstConsoleLog(), "chan_khomp: "); - logger.add( F_GENERIC, log_file); - - logger.classe( C_WARNING ) - & LogOption(F_CONSOLE, "WARNING: ", LogOption::Flags(LogOption::Flag(LogOption::DATETIME))) - & LogOption(F_GENERIC, "W: ", LogOption::Flags(LogOption::Flag(LogOption::DATETIME))) - - logger.classe( C_DBG_LOCK ).enabled(false); - - logger.classe( C_DBG_LOCK ) - & LogOption(F_GENERIC, "L: ", LogOption::Flags - (LogOption::flag_type(LogOption::ENABLED) & - LogOption::flag_type(LogOption::DATETIME)) - - logger(C_WARNING, "eu sou uma mensagem de warning"); - - logger.classe(C_WARNING).set(F_GENERIC, LogOption::ENABLED, true); - logger.classe(C_WARNING).set(F_CONSOLE, LogOption::ENABLED, false); - - logger.classe(C_CLI).prefix(""); - - return true; -} - -void message_the_user(int fd) -{ - logger(C_CLI, fd, "eu sou uma mensagem de cli!"); - logger(C_WARNING, "eu sou um warning"); -} - -******************************************************************************** -******************************************************************************** - -Now, the code..! - -*/ - -#ifndef _LOGGER_HPP_ -#define _LOGGER_HPP_ - -#include - -struct Logger -{ - /*** a base struct for printing messages in many ways ***/ - - struct DefaultPrinter - { - typedef Tagged::Union < int, Tagged::Union < FILE *, Tagged::Union < std::ostream * > > > BaseType; - - typedef bool ReturnType; - - DefaultPrinter(std::string & msg): _msg(msg) {}; - - bool operator()(std::ostream * out) - { - (*out) << _msg; - out->flush(); - - return out->good(); - } - - bool operator()(FILE * out) - { - if (fputs(_msg.c_str(), out) < 0) - return false; - - if (fflush(out) < 0) - return false; - - return true; - } - - bool operator()(int out) - { -#ifndef KWIN32 - return (write(out, _msg.c_str(), _msg.size()) == (int)_msg.size()); -#else - // no need for file descriptors on windows - return false; -#endif - } - - std::string & msg() { return _msg; } - - protected: - std::string & _msg; - }; - - /*** manage the printing of messages ***/ - - template - struct Manager - { - typedef typename Printer::BaseType BaseType; - - protected: - /* holds a stream, and an optimal message prefix */ - struct OutputOptions - { - OutputOptions(BaseType & stream, std::string & prefix) - : _stream(stream), _prefix(prefix) {}; - - BaseType _stream; - std::string _prefix; - LockType _lock; - }; - - typedef std::map < OutputId, OutputOptions > OutputMap; - - public: - - /* print in a specific 'message class' */ - struct ClassType - { - ClassType(void) - : _enabled(true) - {}; - -// ClassType(ClassType & o) -// : _stream_map(o._stream_map), _prefix(o.prefix), -// _lock(o._lock),_enabled(o._enabled) -// {}; - - /* initializes the options of the (class, stream) pair */ - struct Option - { - typedef enum { ENABLED, DATETIME, THREADID, DATETIMEMS } EnumType; - - typedef Flagger< EnumType > Flags; - typedef typename Flags::InitFlags InitFlags; - - Option(OutputId output, const char * prefix, - Flags flags = InitFlags(ENABLED)) - : _output(output), _prefix(prefix), _flags(flags) {}; - - Option(OutputId output, std::string prefix, - Flags flags = InitFlags(ENABLED)) - : _output(output), _prefix(prefix), _flags(flags) {}; - - Option(OutputId output, - Flags flags = InitFlags(ENABLED)) - : _output(output), _flags(flags) {}; - - OutputId _output; - std::string _prefix; - Flags _flags; - }; - - protected: - - /* holds a prefix and a activation status */ - struct OptionContainer - { - OptionContainer(std::string prefix, typename Option::Flags flags) - : _prefix(prefix), _flags(flags) {}; - - std::string _prefix; - typename Option::Flags _flags; - }; - - typedef std::multimap < OutputId, OptionContainer > OptionMap; - - /* utility function for printing */ - bool print(std::string & msg, BaseType & stream, LockType & lock) - { - lock.lock(); - - Printer p(msg); - bool ret = stream.visit(p); - - lock.unlock(); - - return ret; - }; - -/* - bool print(std::string & msg, BaseType & stream, LockType & lock) - { - lock.lock(); - - Printer p(msg); - bool ret = stream.visit(p); - - lock.unlock(); - - return ret; - }; -*/ - - public: - ClassType & operator&(const Option & value) - { - add(value._output, value._prefix, value._flags); - return *this; - } - - void add(OutputId output_id, std::string prefix, - typename Option::Flags flags) - { - typedef std::pair < OutputId, OptionContainer > pair_type; - _stream_map.insert(pair_type(output_id, OptionContainer(prefix, flags))); - } - - /* get and set methods for active mode */ - void set(OutputId id, typename Option::EnumType flag, bool value = true) - { - typename OptionMap::iterator iter = _stream_map.find(id); - - if (iter == _stream_map.end()) - return; - - (*iter).second._flags.set(flag, value); - } - - bool get(OutputId idx, typename Option::EnumType flag) - { - typename OptionMap::iterator iter = _stream_map.find(idx); - - if (iter == _stream_map.end()) - return false; - - return (*iter).second._flags.is_set(flag); - } - - /* get/adjust the enable/disable value for the class */ - void enabled(bool enabled) { _enabled = enabled; }; - bool enabled() { return _enabled; }; - - /* get/adjust the classe prefix */ - void prefix(const char * prefix) { _prefix = prefix; } - void prefix(std::string & prefix) { _prefix = prefix; } - std::string & prefix() { return _prefix; } - - /* printing function (operator, actually) */ - bool operator()(OutputMap & out_map, std::string & msg) - { - if (!_enabled) - return true; - - typedef typename OptionMap::iterator Iter; - - bool ret = true; - - for (Iter iter = _stream_map.begin(); iter != _stream_map.end(); iter++) - { - OptionContainer & opt = (*iter).second; - - if (!opt._flags[Option::ENABLED]) - continue; - - typename OutputMap::iterator out_iter = out_map.find((*iter).first); - - /* this stream have been added already? if not, skip! */ - if (out_iter == out_map.end()) - continue; - - /* final message */ - std::string out_msg; - - if (opt._flags[Option::DATETIME]) - { -#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH) - time_t tv; - struct tm lt; - - time (&tv); - localtime_r (&tv, <); - - out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d] ") - % (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour - % lt.tm_min % lt.tm_sec); -#endif - } - - if (opt._flags[Option::DATETIMEMS]) - { -#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH) - time_t tv; - struct tm lt; - - time (&tv); - localtime_r (&tv, <); - - out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ") - % (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min - % lt.tm_sec % (tv * 1000)); -#endif - } - - OutputOptions & out_opt = (*out_iter).second; - - if (opt._flags[Option::THREADID]) - { -#if defined (COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH) - out_msg += STG(FMT("%08x ") % ((unsigned long)pthread_self())); -#endif - } - - out_msg += _prefix; - out_msg += out_opt._prefix; - out_msg += opt._prefix; - out_msg += msg; - out_msg += "\n"; - - ret |= print(out_msg, out_opt._stream, out_opt._lock); - } - - return ret; - } - - bool operator()(BaseType & stream, std::string & msg) - { - std::string final_msg; - - final_msg += _prefix; - final_msg += msg; - final_msg += "\n"; - - return print(final_msg, stream, _lock); - } - - protected: - OptionMap _stream_map; - std::string _prefix; - LockType _lock; - bool _enabled; - }; - - /* util declaration */ - typedef typename ClassType::Option Option; - - /* class_id_type -> ClassType mapper */ - typedef std::map < ClassId, ClassType > ClassMap; - - /* local option pair */ - typedef std::pair < OutputId, OutputOptions > OutputOptionPair; - - void add(OutputId output, BaseType stream, const char * prefix = "") - { - std::string str_prefix(prefix); - - _output_map.insert(OutputOptionPair(output, OutputOptions(stream, str_prefix))); - } - - void add(OutputId output, BaseType stream, std::string prefix) - { - _output_map.insert(OutputOptionPair(output, OutputOptions(stream, prefix))); - } - - ClassType & classe(ClassId classeid) - { - return _classe_map[classeid]; - } - - bool operator()(ClassId classeid, const char * msg) - { - std::string str_msg(msg); - return _classe_map[classeid](_output_map, str_msg); - } - - bool operator()(ClassId classeid, std::string & msg) - { - return _classe_map[classeid](_output_map, msg); - } - - bool operator()(ClassId classeid, Format fmt) - { - std::string str_fmt = STG(fmt); - return _classe_map[classeid](_output_map, str_fmt); - } - - bool operator()(ClassId classeid, BaseType stream, const char * msg) - { - std::string str_msg(msg); - return _classe_map[classeid](stream, str_msg); - } - - bool operator()(ClassId classeid, BaseType stream, std::string & msg) - { - return _classe_map[classeid](stream, msg); - } - - bool operator()(ClassId classeid, BaseType stream, Format fmt) - { - std::string str_fmt = STG(fmt); - return _classe_map[classeid](stream, str_fmt); - } - - protected: - ClassMap _classe_map; - OutputMap _output_map; - }; - - private: - Logger(); -}; - -#endif /* _LOGGER_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/noncopyable.hpp b/src/mod/endpoints/mod_khomp/commons/base/noncopyable.hpp deleted file mode 100644 index d32faa8913..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/noncopyable.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _NONCOPYABLE_HPP_ -#define _NONCOPYABLE_HPP_ - -struct NonCopyable -{ - NonCopyable() {}; - private: - NonCopyable(NonCopyable const &) { }; - NonCopyable & operator=(NonCopyable const &) { return *this; }; -}; - -#endif /* _NONCOPYABLE_HPP_ */ - diff --git a/src/mod/endpoints/mod_khomp/commons/base/refcounter.hpp b/src/mod/endpoints/mod_khomp/commons/base/refcounter.hpp deleted file mode 100644 index d1738185bb..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/refcounter.hpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the "LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -/* This struct uses static polymorphism, and derived classes should implement * - * the "unreference()" method, which should release all resources when called */ - -#ifndef _REFCOUNTER_HPP_ -#define _REFCOUNTER_HPP_ - -#define COUNTER_CLASS(...) ReferenceCounter< __VA_ARGS__ > -#define COUNTER_SUPER(...) public COUNTER_CLASS( __VA_ARGS__ ) -#define COUNTER_REFER(o, ...) COUNTER_CLASS( __VA_ARGS__ )(static_cast< const COUNTER_CLASS( __VA_ARGS__ ) & >(o)) - -// DEPRECATED DECLARATIONS /// -#define NEW_REFCOUNTER(...) public ReferenceCounter< __VA_ARGS__ > -#define INC_REFCOUNTER(o, ...) ReferenceCounter< __VA_ARGS__ >(static_cast< const ReferenceCounter < __VA_ARGS__ > & >(o)) - -#include - -#include -#include - -#ifdef DEBUG -# include -#endif - -struct ReferenceData: public NonCopyable -{ - ReferenceData() - : _data_count(1) - {}; - - inline unsigned int increment(void) - { - if (!_data_count) - abort(); - - Atomic::doAdd(&_data_count); - - return _data_count; - } - - inline unsigned int decrement(void) - { - if (!_data_count) - abort(); - - Atomic::doSub(&_data_count); - return _data_count; - } - - volatile unsigned int _data_count; -}; - -template < typename T > -struct ReferenceCounter -{ - typedef T Type; - - ReferenceCounter(bool create_counter = true) - : _reference_count(0) - { - reference_restart(create_counter); - -#ifdef DEBUG - std::cerr << ((void*)this) << ": ReferenceCounter() [ref_count=" - << (_reference_count ? (*_reference_count) : -1) << "]" << std::endl; -#endif - }; - - ReferenceCounter(const ReferenceCounter & o) - : _reference_count(0) - { - reference_reflect(o); - -#ifdef DEBUG - std::cerr << ((void*)this) << ": ReferenceCounter(" << ((void*)(&o)) << ") [ref_count=" - << (_reference_count ? (*_reference_count) : -1) << "]" << std::endl; -#endif - }; - - virtual ~ReferenceCounter() - { -#ifdef DEBUG - std::cerr << ((void*)this) << ": ~ReferenceCounter() [ref_count=" - << (_reference_count ? (*_reference_count) : -1) << "]" << std::endl; -#endif - reference_disconnect(_reference_count); - } - - ReferenceCounter & operator=(const ReferenceCounter & o) - { - reference_reflect(o); - -#ifdef DEBUG - std::cerr << ((void*)this) << ": ReferenceCounter::operator=(" << ((void*)(&o)) << ") [ref_count=" - << (_reference_count ? (*_reference_count) : -1) << "]" << std::endl; -#endif - - return *this; - }; - - protected: - inline void reference_restart(bool create_counter = false) - { - ReferenceData * oldref = _reference_count; - - _reference_count = (create_counter ? new ReferenceData() : 0); - - if (oldref) reference_disconnect(oldref); - } - - inline void reference_reflect(const ReferenceCounter & other) - { - ReferenceData * newref = other._reference_count; - ReferenceData * oldref = _reference_count; - - /* NOTE: increment before, avoid our reference being zero, even * - * for a short period of time. */ - - if (newref) newref->increment(); - - _reference_count = newref; - - if (oldref) reference_disconnect(oldref); - }; - - inline void reference_disconnect(ReferenceData *& counter) - { - if (counter) - { - unsigned int result = counter->decrement(); - - if (!result) - { - static_cast< Type * >(this)->unreference(); - delete counter; - } - - counter = 0; - } - }; - - private: - ReferenceData * _reference_count; -}; - -template < typename T > -struct ReferenceContainer: COUNTER_SUPER(ReferenceContainer< T >) -{ - /* type */ - typedef T Type; - - /* shorthand */ - typedef COUNTER_CLASS(ReferenceContainer< Type >) Counter; - - // TODO: make this a generic exception someday - struct NotFound {}; - - ReferenceContainer() - : Counter(false), - _reference_value(0) - {}; - - ReferenceContainer(Type * value) - : _reference_value(value) - {}; - - ReferenceContainer(const ReferenceContainer & value) - : Counter(false), - _reference_value(0) - { - operator()(value); - }; - - virtual ~ReferenceContainer() - {}; - - ReferenceContainer operator=(const ReferenceContainer & value) - { - operator()(value); - return *this; - }; - - /**/ - - void unreference() - { - if (_reference_value) - { - delete _reference_value; - _reference_value = 0; - } - } - - // simulates a copy constructor - void operator()(const ReferenceContainer & value) - { - Counter::reference_reflect(value); - - _reference_value = const_cast(value._reference_value); - }; - - // shortcut for operator below - void operator=(const Type * value) - { - operator()(value); - }; - - // accept value (pointer)! - void operator()(const Type * value) - { - Counter::reference_restart((value != 0)); - - _reference_value = const_cast(value); - }; - - // return value (pointer)! - Type * operator()(void) const - { - return _reference_value; - }; - - protected: - Type * _reference_value; - - protected: -}; - -#endif /* _REFCOUNTER_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/regex.cpp b/src/mod/endpoints/mod_khomp/commons/base/regex.cpp deleted file mode 100644 index d2b8cd0469..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/regex.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#include - -void Regex::Expression::initialize(void) -{ - unsigned int tmplen = strlen(_expression); - - bool extflag = (_flags & E_EXTENDED); - - for (unsigned int i = 0; i < tmplen; ++i) - { - switch (_expression[i]) - { - case '\\': - ++i; - - if (!extflag && i < tmplen) - if (_expression[i] == '(') - ++_subcounter; - - break; - - case '(': - if (extflag) - ++_subcounter; - - default: - break; - } - } - - _errorstate = regcomp(&_comp_regex, _expression, _flags); -} - -std::string Regex::Expression::regerror_as_string(void) const -{ - unsigned int count = regerror(_errorstate, &_comp_regex, 0, 0) + 1; - - char * msg = new char[count]; - - regerror(_errorstate, &_comp_regex, msg, count); - - std::string tmp(msg, count); - - delete[] msg; - - return tmp; -} - -void Regex::Match::initialize(void) -{ - if (_expression.valid()) - { - _subcounter = (_expression.subcount() + 2); // 0 + N.. + invalid - _submatches = new regmatch_t[_subcounter]; - _subcaching = new std::string[_subcounter]; - _have_match = (regexec(_expression.repr(), _basestring.c_str(), - _subcounter, _submatches, _flags) == 0); - } -} - -std::string Regex::Match::replace(std::string rep, unsigned int index) -{ - ReplaceMap tmp; - tmp.insert(ReplacePair(index,rep)); - return replace(tmp); -} - -std::string Regex::Match::replace(Regex::ReplaceMap & map) -{ - if (!_have_match) - return _basestring; - - std::string buffer = _basestring; - - try - { - if (_submatches[0].rm_so != 0 && (map.find(0) != map.end())) - return buffer.replace(_submatches[0].rm_so, _submatches[0].rm_eo - _submatches[0].rm_so, map.find(0)->second); - - for (unsigned int n = 1; (_submatches[n].rm_so != -1) && (n < _subcounter); n++) - { - //// s f RRR s f RRR s f RRRR s f - //// XXXYYY(ZZZ)AAA(BBB)CCCEEE(FFFF)GGGG - - bool globalsubs = false; - - if (map.find(n) == map.end()) - { - if (map.find(UINT_MAX) == map.end()) - continue; - - globalsubs = true; - } - - buffer = buffer.replace(_submatches[n].rm_so, - _submatches[n].rm_eo - _submatches[n].rm_so, - map.find((globalsubs ? UINT_MAX : n))->second); - } - } - catch (std::out_of_range e) - { - return ""; - } - - return buffer; -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/regex.hpp b/src/mod/endpoints/mod_khomp/commons/base/regex.hpp deleted file mode 100644 index 61325238b8..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/regex.hpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#ifndef _REGEX_HPP_ -#define _REGEX_HPP_ - -struct Regex -{ - enum - { - E_EXTENDED = REG_EXTENDED, - E_IGNORE_CASE = REG_ICASE, - E_NO_SUB_MATCH = REG_NOSUB, - E_EXPLICIT_NEWLINE = REG_NEWLINE, - }; - - enum - { - M_NO_BEGIN_OF_LINE = REG_NOTBOL, - M_NO_END_OF_LINE = REG_NOTEOL, - }; - - enum - { - /* mark replace for full match (submatch "0"). */ - REP_BASE = 0u, - /* mark global string for replace. */ - REP_ALL = UINT_MAX, - }; - - typedef std::pair < unsigned int, std::string > ReplacePair; - typedef std::map < unsigned int, std::string > ReplaceMap; - - struct Expression : public NonCopyable - { - Expression(const char * expression, unsigned int flags = 0) - : _expression(expression), _alloced(false), - _subcounter(0), _errorstate(INT_MAX), _flags(flags) - { - initialize(); - } - - Expression(std::string & expression, unsigned int flags = 0) - : _expression(strdup(expression.c_str())), _alloced(true), - _subcounter(0), _errorstate(INT_MAX), _flags(flags) - { - initialize(); - } - - ~Expression() - { - if (_errorstate != INT_MAX) - regfree(&_comp_regex); - - if (_alloced) - { - delete _expression; - _expression = 0; - } - } - - bool valid(void) const { return (_errorstate == 0); } - - unsigned int subcount(void) const { return _subcounter; } - const regex_t * repr(void) const { return &_comp_regex; } - - std::string error(void) const - { - switch (_errorstate) - { - case 0: return ""; - case INT_MAX: return "uninitialized"; - default: return regerror_as_string(); - } - } - - private: - std::string regerror_as_string(void) const; - - private: - void initialize(void); - - protected: - const char * _expression; - const bool _alloced; - - unsigned int _subcounter; - - int _errorstate; - regex_t _comp_regex; - - const unsigned int _flags; - }; - - struct Match: COUNTER_SUPER(Match) - { - Match(const char * basestring, const Expression & expression, unsigned int flags = 0) - : _basestring(basestring), _expression(expression), _subcounter(0), _submatches(0), - _have_match(false), _flags(flags) - { - initialize(); - } - - Match(const std::string & basestring, const Expression & expression, unsigned int flags = 0) - : _basestring(basestring), _expression(expression), _subcounter(0), _submatches(0), - _have_match(false), _flags(flags) - { - initialize(); - } - - Match(const Match & o) - : COUNTER_REFER(o, Match), - _basestring(o._basestring), _expression(o._expression), - _subcounter(o._subcounter), _submatches(o._submatches), - _have_match(o._have_match), _flags(o._flags) - { - } - - void unreference() - { - delete[] _submatches; - delete[] _subcaching; - - _submatches = 0; - _subcaching = 0; - } - - bool matched(void) - { - return _have_match; - } - - bool matched(unsigned int number) - { - if (_have_match && number < _subcounter) - return (_submatches[number].rm_so != -1); - - return false; - } - - const std::string & submatch(int number) - { - if (!matched(number)) - return _subcaching[_subcounter - 1 /* invalid, always empty! */ ]; - - if (_subcaching[number].empty()) - { - _subcaching[number].assign(_basestring, _submatches[number].rm_so, - _submatches[number].rm_eo - _submatches[number].rm_so); - } - - return _subcaching[number]; - } - - const std::string & operator[](int number) - { - return submatch(number); - } - - /** - * \brief replaces strings matched by parentesis - * \param each item of the vector is a parentesis replaced - * \return string replaced - * \note The overload method match only one string in parentesis. - * \author Eduardo Nunes Pereira - * - * If fails the empty string is returned. - */ - std::string replace(ReplaceMap &); - std::string replace(std::string, unsigned int index = REP_BASE); - - // NOTE: there is already a way to get subcount defined on EXPRESSION class! - - private: - void initialize(void); - - protected: - const std::string _basestring; - const Expression & _expression; - - unsigned int _subcounter; - regmatch_t * _submatches; - std::string * _subcaching; - bool _have_match; - - const unsigned int _flags; - }; -}; - -#endif /* _REGEX_HPP_ */ - diff --git a/src/mod/endpoints/mod_khomp/commons/base/ringbuffer.cpp b/src/mod/endpoints/mod_khomp/commons/base/ringbuffer.cpp deleted file mode 100644 index 42056307e0..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/ringbuffer.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -// #include - - - /* Documentation of the formula used in the buffer arithmetic. - * - * [0|1|2|3|4|5|6|7] => size=8 - * | | - * reader | - * writer - * - * => writer has places [5,6,7,0,1] to write (5 places). - * - * => 8 - (4-2+1) = 8 - (2+1) = 8 - 3 = 5 - * - * > writer goes 1 up, amount goes 1 down. - * > reader goes 1 up, amount goes 1 up. - * > size goes 1 down, amount goes 1 down. - * - */ - -/********** BUFFER FUNCTIONS **********/ - -/* writes everything or nothing */ -bool Ringbuffer_traits::traits_provide(char * buffer, const char * value, unsigned int amount, bool do_not_overwrite) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - bool need_overwrite = false; - - if (amount > free_blocks(cache)) - { - if (do_not_overwrite) - return false; - - /* if we are allowed to overwrite, just the buffer size matters for us */ - if (amount >= _size) - return false; - - /* we need to change reader pointer below... */ - need_overwrite = true; - } - - const unsigned int wr = cache.writer.complete; - const unsigned int wp = cache.writer.complete - 1; - - /* should we go around the buffer for writing? */ - if ((wr + amount) > _size) - { -// fprintf(stderr, "%p> first if matched\n", this); - - if (need_overwrite) - { - do - { - Buffer_pointer extra(cache.reader); - extra.complete = ((wr + amount) % _size); // (extra.complete + amount) % _size; -// extra.complete = (extra.complete + amount) % _size; - - if (update(cache.reader, extra)) - break; - } - while (true); - } - - unsigned int wr1 = _size - wr + 1; /* writer is already 1 position after */ - unsigned int wr2 = amount - wr1; - -// fprintf(stderr, "%p> partial write: (%d/%d) %d/%d [%d/%d]\n", this, wr1, wr2, amount, _size, reader, writer); - - /* two partial writes (one at the end, another at the beginning) */ - memcpy((void *) &(buffer[wp]), (const void *) (value), _block * wr1); - memcpy((void *) (buffer), (const void *) &(value[wr1]), _block * wr2); - } - else - { -// fprintf(stderr, "%p> second if matched\n", this); - - if (need_overwrite) - { - do - { - Buffer_pointer extra(cache.reader); - extra.complete = ((wr + amount) % _size); // (extra.complete + amount) % _size; - - if (update(cache.reader, extra)) - break; - } - while (true); - } - -// fprintf(stderr, "%p> full write: a=%d/s=%d [r=%d/w=%d]\n", this, amount, _size, reader, writer); - - /* we are talking about buffers here, man! */ - memcpy((void *) &(buffer[wp]), (const void *) value, _block * amount); - } - - _pointers.writer.complete = ((wp + amount) % _size) + 1; - _pointers.writer.partial = 1; - -// if (need_overwrite) -// fprintf(stdout, "%p> write end: w=%d/r=%d\n", this, _pointers.writer.complete, _pointers.reader.complete); - - return true; -} - -/* returns the number of itens that have been read */ -unsigned int Ringbuffer_traits::traits_consume(const char * buffer, char * value, unsigned int amount, bool atomic_mode) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - const unsigned int available = used_blocks(cache); - - if (atomic_mode && amount > available) - return false; - - const unsigned int rd = _pointers.reader.complete; - - unsigned int total = std::min(amount, available); - - /* should we go around the buffer for reading? */ - if ((rd + total) >= _size) - { - unsigned int rd1 = _size - rd; - unsigned int rd2 = total - rd1; - -// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer); - - /* two partial consumes (one at the end, another at the beginning) */ - memcpy((void *) (value), (const void *) &(buffer[rd]), _block * rd1); - memcpy((void *) &(value[rd1]), (const void *) (buffer), _block * rd2); - } - else - { -// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer); - - /* we are talking about buffers here, man! */ - memcpy((void *) value, (const void *) &(buffer[rd]), _block * total); - } - - do - { - /* jump the reader forward */ - Buffer_pointer index((cache.reader.complete + total) % _size, 0); - - if (update(cache.reader, index)) - break; - } - while (true); - -// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block); - - return total; -} - -/********** TWO-PHASE BUFFER FUNCTIONS ***********/ - -/* returns the number of itens that have been read */ -unsigned int Ringbuffer_traits::traits_consume_begins(const char * buffer, char * value, unsigned int amount, bool atomic_mode) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - const unsigned int available = used_blocks(cache); - - if (amount > available) - { - if (atomic_mode) - return false; - } - - const unsigned int rd = _pointers.reader.complete; - - unsigned int total = std::min(amount, available); - - /* should we go around the buffer for reading? */ - if ((rd + total) >= _size) - { - unsigned int rd1 = _size - rd; - unsigned int rd2 = total - rd1; - -// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer); - - /* two partial consumes (one at the end, another at the beginning) */ - memcpy((void *) (value), (const void *) &(buffer[rd]), _block * rd1); - memcpy((void *) &(value[rd1]), (const void *) (buffer), _block * rd2); - } - else - { -// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer); - - /* we are talking about buffers here, man! */ - memcpy((void *) value, (const void *) &(buffer[rd]), _block * total); - } - - return total; -} - -bool Ringbuffer_traits::traits_consume_commit(unsigned int amount) -{ - if (amount == 0) - return true; - - /* avoid using different values */ - Buffer_table cache = _pointers; - - const unsigned int available = used_blocks(cache); - - /* cannot commit more than available! */ - if (amount > available) - return false; - - unsigned int total = std::min(amount, available); - - do - { - /* jump the reader forward */ - Buffer_pointer index((cache.reader.complete + total) % _size, 0); - - if (update(cache.reader, index)) - break; - } - while (true); - -// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block); - - return true; -} - -/********** PARTIAL BUFFER FUNCTIONS (bytes) ***********/ - -/* writes everything or nothing */ -bool Ringbuffer_traits::traits_provide_partial(char * buffer, const char * value, unsigned int amount) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - const unsigned int memsize = (_size * _block); - - if (amount > (free_blocks(cache) * _block)) - return false; - - const unsigned int wr = ((cache.writer.complete - 1) * _block) + cache.writer.partial; - const unsigned int wp = wr - 1; - - /* should we go around the buffer for writing? */ - if ((wr + amount) > memsize) - { -// fprintf(stderr, "%p> first if matched\n", this); - - unsigned int wr1 = memsize - wr + 1; /* writer is already 1 position after */ - unsigned int wr2 = amount - wr1; - -// fprintf(stderr, "%p> partial write: (%d/%d) %d/%d [%d/%d]\n", this, wr1, wr2, amount, _size, reader, writer); - - /* two partial writes (one at the end, another at the beginning) */ - memcpy((void *) &(buffer[wp]), (const void *) (value), wr1); - memcpy((void *) (buffer), (const void *) &(value[wr1]), wr2); - } - else - { -// fprintf(stderr, "%p> second if matched\n", this); - -// fprintf(stderr, "%p> full write: a=%d/s=%d [r=%d/w=%d]\n", this, amount, _size, reader, writer); - - /* we are talking about buffers here, man! */ - memcpy((void *) &(buffer[wp]), (const void *) value, amount); - } - - const unsigned int new_wp = (wp + amount) % memsize; - - _pointers.writer.complete = (unsigned int)(floor((double)new_wp / (double)_block) + 1); - _pointers.writer.partial = (new_wp % _block) + 1; - -// if (need_overwrite) -// fprintf(stdout, "%p> write end: w=%d/r=%d\n", this, _pointers.writer.complete, _pointers.reader.complete); - - return true; -} - -/* returns the number of bytes that have been read */ -unsigned int Ringbuffer_traits::traits_consume_partial(const char * buffer, char * value, unsigned int amount) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - const unsigned int available = used_blocks(cache) * _block; - - const unsigned int rd = (_pointers.reader.complete * _block) + _pointers.reader.partial; - - const unsigned int memsize = _size * _block; - - unsigned int total = std::min(amount, available); - - /* should we go around the buffer for reading? */ - if ((rd + total) >= _size) - { - unsigned int rd1 = memsize - rd; - unsigned int rd2 = total - rd1; - -// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer); - - /* two partial consumes (one at the end, another at the beginning) */ - memcpy((void *) (value), (const void *) &(buffer[rd]), rd1); - memcpy((void *) &(value[rd1]), (const void *) (buffer), rd2); - } - else - { -// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer); - - /* we are talking about buffers here, man! */ - memcpy((void *) value, (const void *) &(buffer[rd]), total); - } - - do - { - const unsigned int new_rd = (((cache.reader.complete * _block) + cache.reader.partial) + total) % memsize; - - /* jump the reader forward */ - Buffer_pointer index((unsigned int)floor((double)new_rd / (double)_block), (unsigned short)(new_rd % _block)); - - if (update(cache.reader, index)) - break; - } - while (true); - -// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block); - - return total; -} - -/********** IO FUNCTIONS **********/ - -/* returns the number of items written to from buffer to stream */ -unsigned int Ringbuffer_traits::traits_put(const char * buffer, std::ostream &fd, unsigned int amount) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - const unsigned int available = used_blocks(cache); - - if (amount > available) - return false; - - const unsigned int wr = _pointers.writer.complete; - const unsigned int rd = _pointers.reader.complete; - - unsigned int total = std::min(amount, available); - - /* should we go around the buffer for reading? */ - if ((rd + total) >= _size) - { - unsigned int rd1 = _size - rd; - unsigned int rd2 = total - rd1; - -// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer); - - /* two partial consumes (one at the end, another at the beginning) */ - fd.write((const char *) &(buffer[rd]), _block * rd1); - fd.write((const char *) (buffer), _block * rd2); - } - else - { -// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer); - fd.write((const char *) &(buffer[rd]), _block * total); - } - - do - { - /* jump the reader forward */ - Buffer_pointer index((cache.reader.complete + total) % _size, 0); - - if (update(cache.reader, index)) - break; - } - while (true); - -// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block); - - return total; -} - -/* returns number of items read from stream to buffer */ -unsigned int Ringbuffer_traits::traits_get(char * buffer, std::istream &fd, unsigned int amount) -{ - /* avoid using different values */ - Buffer_table cache = _pointers; - - if (amount > free_blocks(cache)) - return false; - - const unsigned int wr = cache.writer.complete; - const unsigned int wp = cache.writer.complete - 1; - - unsigned int real_amount = 0; - - /* should we go around the buffer for writing? */ - if ((wr + amount) > _size) - { -// fprintf(stderr, "%p> first if matched\n", this); - - unsigned int wr1 = _size - wr + 1; /* writer is already 1 position after */ - unsigned int wr2 = amount - wr1; - -// fprintf(stderr, "%p> partial write: (%d/%d) %d/%d [%d/%d]\n", this, wr1, wr2, amount, _size, reader, writer); - - /* two partial writes (one at the end, another at the beginning) */ - unsigned int char_amount = 0; - - /* one partial write on the buffer (at the end) */ - fd.read((char *) &(buffer[wp]), _block * wr1); - char_amount += fd.gcount(); - - if (fd.gcount() == (int)(_block * wr1)) - { - /* another partial write on the buffer (at the beginning) */ - fd.read((char *) (buffer), _block * wr2); - char_amount += fd.gcount(); - } - - real_amount = char_amount / _block; - } - else - { -// fprintf(stderr, "%p> second if matched\n", this); - -// fprintf(stderr, "%p> full write: a=%d/s=%d [r=%d/w=%d]\n", this, amount, _size, reader, writer); - - /* we are talking about buffers here, man! */ - fd.read((char *) &(buffer[wp]), _block * amount); - - real_amount = fd.gcount() / _block; - } - - _pointers.writer.complete = ((wp + amount) % _size) + 1; - _pointers.writer.partial = 1; - -// fprintf(stdout, "%p> write end: %d\n", this, _pointers.writer.complete); - - return real_amount; -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/ringbuffer.hpp b/src/mod/endpoints/mod_khomp/commons/base/ringbuffer.hpp deleted file mode 100644 index b9ecd7e6bd..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/ringbuffer.hpp +++ /dev/null @@ -1,448 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -/* WARNING: This is a generic ringbuffer abstraction, which works for single-sized elements, - partial elements, single/multi-elements read/writes. It is not wise to mix some - functions (partial element write / full element write), since it was not designed - with this use in mind. - - Also, it works only for single-reader + single-writer, since it does not depends - on external mutex functions. - - NOTE: for single element provide/consume, this abstraction has standard C++ semantics. - - for multiple and partial element provide/consume, memcpy is used - thus complex C++ - objects which need correct copy constructor semantics should not copied this way. - - */ - -#include - -#include -#include - -#include -#include - -#ifndef _RINGBUFFER_HPP_ -#define _RINGBUFFER_HPP_ - -struct Buffer_pointer -{ - Buffer_pointer(unsigned int _complete, unsigned short _partial) - : complete(_complete), partial(_partial) - {}; - - Buffer_pointer(const Buffer_pointer & o) - : complete(o.complete), partial(o.partial) - {}; - - Buffer_pointer(const volatile Buffer_pointer & o) - : complete(o.complete), partial(o.partial) - {}; - - void operator=(const volatile Buffer_pointer o) - { - complete = o.complete; - partial = o.partial; - } - - void operator=(const Buffer_pointer o) volatile - { - complete = o.complete; - partial = o.partial; - } - - bool operator==(const Buffer_pointer & o) - { - return (complete == o.complete && partial == o.partial); - } - - unsigned int complete:20; - unsigned short partial:12; -} -__attribute__((packed)); - -struct Buffer_table -{ - Buffer_table() - : reader(0,0), - writer(1,1) - {}; - - Buffer_table(const Buffer_table & o) - : reader(o.reader), writer(o.writer) - {}; - - Buffer_table(const volatile Buffer_table & o) - : reader(o.reader), writer(o.writer) - {}; - - void operator=(const volatile Buffer_table o) - { - reader = o.reader; - writer = o.writer; - } - - void operator=(const Buffer_table o) volatile - { - reader = o.reader; - writer = o.writer; - } - - bool operator==(const Buffer_table & o) - { - return (reader == o.reader && writer == o.writer); - } - - Buffer_pointer reader; - Buffer_pointer writer; -} -__attribute__((packed)); - -struct Ringbuffer_traits -{ - struct BufferFull {}; - struct BufferEmpty {}; - - protected: - Ringbuffer_traits(unsigned int block, unsigned int size) - : _block(block), _size(size) - {}; - - bool traits_provide( char *, const char *, unsigned int, bool); - unsigned int traits_consume(const char *, char *, unsigned int, bool); - - unsigned int traits_consume_begins(const char *, char *, unsigned int, bool); - bool traits_consume_commit(unsigned int); - - bool traits_provide_partial( char *, const char *, unsigned int); - unsigned int traits_consume_partial(const char *, char *, unsigned int); - - unsigned int traits_get( char *, std::istream &, unsigned int); - unsigned int traits_put(const char *, std::ostream &, unsigned int); - - bool update(Buffer_pointer & cache, Buffer_pointer & update) - { - return Atomic::doCAS(&(_pointers.reader), &cache, update); - } - - inline unsigned int free_blocks(const Buffer_table & cache) const - { - const unsigned int r = cache.reader.complete; - const unsigned int w = cache.writer.complete; - - if (r >= w) - return (r - w); - - return _size - (w - r); - } - - inline unsigned int used_blocks(const Buffer_table & cache) const - { - const unsigned int r = cache.reader.complete; - const unsigned int w = cache.writer.complete; - - if (r >= w) - return (_size - (r - w)) - 1; - - return (w - r) - 1; - } - - protected: - const unsigned int _block; - const unsigned int _size; - - volatile Buffer_table _pointers; -}; - -template -struct Ringbuffer: public Ringbuffer_traits, public NonCopyable -{ - Ringbuffer(unsigned int size) - : Ringbuffer_traits(sizeof(T), size) - { - _buffer = new T[_size]; - _malloc = true; - }; - - Ringbuffer(unsigned int size, T * buffer) - : Ringbuffer_traits(sizeof(T), size) - { - _buffer = buffer; - _malloc = false; - }; - - ~Ringbuffer() - { - if (_malloc) - delete[] _buffer; - } - - /***** GENERIC RANGE/INDEX CALCULATION FUNCTIONS *****/ - - protected: - inline bool may_write(const Buffer_table & cache) const - { - const unsigned int r = cache.reader.complete; - const unsigned int w = cache.writer.complete; - - return (((r - w) != 0) && (!(r == 0 && w == _size))); - } - - inline bool may_read(const Buffer_table & cache) const - { - if ((cache.writer.complete - cache.reader.complete) == 1) - return false; - - return true; - } - - inline unsigned int writer_next(const Buffer_pointer & cache, Buffer_pointer & index) const - { - unsigned int dest = cache.complete - 1, - temp = cache.complete + 1; - - if (temp > _size) index.complete = 1; - else index.complete = temp; - - index.partial = 1; - - return dest; - }; - - inline void reader_next(const Buffer_pointer & cache, Buffer_pointer & index) const - { - unsigned int temp = cache.complete + 1; - - if (temp == _size) index.complete = 0; - else index.complete = temp; - - index.partial = 0; - } - - /***** BUFFER FUNCTIONS *****/ - - public: - bool provide(const T & value) - { - Buffer_table cache = _pointers; - Buffer_pointer index = _pointers.writer; - - if (!may_write(cache)) - return false; - -// fprintf(stderr, "%p> provide %d/%d!\n", this, reader, writer); - - unsigned int dest = writer_next(cache.writer, index); - - _buffer[dest] = value; - - _pointers.writer = index; - -// fprintf(stderr, "%p> write: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial); - - return true; - } - - bool consume(T & value) - { - Buffer_table cache = _pointers; - Buffer_pointer index = _pointers.reader; - - if (!may_read(cache)) - return false; - -// fprintf(stderr, "%p> consume %d/%d!\n", this, reader, writer); - - value = _buffer[index.complete]; - - do - { - reader_next(cache.reader, index); - - if (update(cache.reader, index)) - break; - - cache.reader = index; - } - while (true); - -// fprintf(stderr, "%p> read: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial); - - return true; - } - - /* writes everything or nothing */ - inline bool provide(const T * value, unsigned int amount, bool do_not_overwrite = true) - { - return traits_provide((char *)_buffer, (const char *) value, amount, do_not_overwrite); - } - - /* returns the number of items that have been read (atomic_mode == true means 'all or nothing') */ - inline unsigned int consume(T * value, unsigned int amount, bool atomic_mode = false) - { - return traits_consume((const char *)_buffer, (char *) value, amount, atomic_mode); - } - - /***** TWO-PHASE BUFFER FUNCTIONS *****/ - - /* returns the number of items that have been read (atomic_mode == true means 'all or nothing') */ - inline unsigned int consume_begins(T * value, unsigned int amount, bool atomic_mode = false) - { - return traits_consume_begins((const char *)_buffer, (char *) value, amount, atomic_mode); - } - - /* returns true if we could commit that much of buffer (use only after consume_begins). * - * note: you may commit less bytes that have been read to keep some data inside the buffer */ - inline bool consume_commit(unsigned int amount) - { - return traits_consume_commit(amount); - } - - /***** TWO-PHASE SINGLE-ELEMENT BUFFER FUNCTIONS *****/ - - T & provider_start(void) - { - Buffer_table cache = _pointers; - - if (!may_write(cache)) - throw BufferFull(); - - unsigned writer = _pointers.writer.complete - 1; - -// fprintf(stderr, "%p> provider start %d/%d!\n", this, reader, writer); - - return _buffer[writer]; - } - - void provider_commit(void) - { - unsigned int temp = _pointers.writer.complete + 1; - -// fprintf(stderr, "%p> provider commit %d!\n", this, temp); - - if (temp > _size) - temp = 1; - - _pointers.writer.complete = temp; - _pointers.writer.partial = 1; - -// fprintf(stderr, "%p> write: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial); - } - - const T & consumer_start(void) - { - Buffer_table cache = _pointers; - - if (!may_read(cache)) - throw BufferEmpty(); - - unsigned int reader = _pointers.reader.complete; - -// fprintf(stderr, "%p> consumer start %d/%d!\n", this, reader, writer); - - return _buffer[reader]; - } - - void consumer_commit(void) - { - Buffer_pointer cache = _pointers.reader; - Buffer_pointer index(cache); - - do - { - reader_next(cache, index); - - if (update(cache, index)) - break; - - cache = index; - } - while (true); - -// fprintf(stderr, "%p> consumer commit %d!\n", this, temp); - -// fprintf(stderr, "%p> read: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial); - } - - /* writes everything or nothing, but works on bytes (may write incomplete elements) */ - /* WARNING: do not mix this with full element provider */ - inline bool provider_partial(const char *buffer, unsigned int amount) - { - return traits_provide_partial((char *)_buffer, buffer, amount); - } - - /* returns the number of bytes that have been read (may read incomplete elements) */ - /* WARNING: do not mix this with full element consumer */ - inline unsigned int consumer_partial(char *buffer, unsigned int amount) - { - return traits_consume_partial((const char *)_buffer, buffer, amount); - } - - /***** IO FUNCTIONS *****/ - - /* returns the number of items written to from buffer to stream */ - inline unsigned int put(std::ostream &fd, unsigned int amount) - { - return traits_put((const char *)_buffer, fd, amount); - } - - /* returns number of items read from stream to buffer */ - inline unsigned int get(std::istream &fd, unsigned int amount) - { - return traits_get((char *)_buffer, fd, amount); - } - - void clear() - { - _pointers.reader.complete = 0; - _pointers.reader.partial = 0; - _pointers.writer.complete = 1; - _pointers.writer.partial = 1; - } - - protected: - T * _buffer; - bool _malloc; -}; - -#endif /* _RINGBUFFER_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/saved_condition.cpp b/src/mod/endpoints/mod_khomp/commons/base/saved_condition.cpp deleted file mode 100644 index 4c9f80f47f..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/saved_condition.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - - -#include - -#include COMMONS_INCLUDE(saved_condition.cpp) - diff --git a/src/mod/endpoints/mod_khomp/commons/base/saved_condition.hpp b/src/mod/endpoints/mod_khomp/commons/base/saved_condition.hpp deleted file mode 100644 index dcfd22423d..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/saved_condition.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _SAVED_CONDITION_COMMON_HPP_ -#define _SAVED_CONDITION_COMMON_HPP_ - -#include - -//#include - -struct SavedConditionCommon -{ - SavedConditionCommon() : _signaled(false) {} - - protected: - bool _signaled; -}; - - -#include COMMONS_INCLUDE(saved_condition.hpp) - -#endif /* _SAVED_CONDITION_COMMON_HPP_ */ - diff --git a/src/mod/endpoints/mod_khomp/commons/base/scoped_lock.hpp b/src/mod/endpoints/mod_khomp/commons/base/scoped_lock.hpp deleted file mode 100644 index a85627f3cd..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/scoped_lock.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -struct ScopedLockBasic -{ - ScopedLockBasic(void) - : _locked(true) {}; - - ScopedLockBasic(bool locked) - : _locked(locked) {}; - - virtual ~ScopedLockBasic() {}; - - protected: - bool _locked; -}; - - -struct ScopedLock : public ScopedLockBasic -{ - struct LockFailed {}; - - ScopedLock(SimpleLock & mutex) - : ScopedLockBasic(false), _mutex(mutex) - { - switch (_mutex.lock()) - { - case SimpleLock::ISINUSE: - case SimpleLock::FAILURE: - throw LockFailed(); - default: - break; - } - - _locked = true; - } - - ~ScopedLock() - { - unlock(); - } - - void unlock() - { - if (_locked) - { - _locked = false; - _mutex.unlock(); - } - } - - protected: - SimpleLock & _mutex; -}; - diff --git a/src/mod/endpoints/mod_khomp/commons/base/simple_lock.hpp b/src/mod/endpoints/mod_khomp/commons/base/simple_lock.hpp deleted file mode 100644 index 16d85fb053..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/simple_lock.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _SIMPLE_LOCK_COMMON_HPP_ -#define _SIMPLE_LOCK_COMMON_HPP_ - -#include - -#include -#include - -#include - -/* This struct uses static polymorphism, and derived classes should implement * - * the "lock/trylock/unlock()" methods for correct code compilation. * - * The base class also features reference counting, so derived classes should * - * implement the "unreference_data()" method for releasing resources. */ - -template < typename Implementor > -struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > ) -{ - friend class ReferenceCounter < SimpleLockCommon < Implementor > >; - - typedef enum - { - ISINUSE = 0, // operation not succeded (no error) - SUCCESS = 1, // operation succeded (no error) - FAILURE = 2, // mutex or state is somehow invalid (error! run for your life!) - } - Result; - - SimpleLockCommon() - {}; - - SimpleLockCommon(const SimpleLockCommon & o) - : COUNTER_REFER(o, SimpleLockCommon) - {}; - - virtual ~SimpleLockCommon() - {}; - - inline Result lock() - { - return static_cast(this)->lock(); - } - - inline Result trylock() - { - return static_cast(this)->trylock(); - } - - inline void unlock() - { - static_cast(this)->unlock(); - } - - protected: - void unreference(void) - { - static_cast(this)->unreference_data(); - } -}; - -#include COMMONS_INCLUDE(simple_lock.hpp) - -#endif /* _SIMPLE_LOCK_COMMON_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/strings.cpp b/src/mod/endpoints/mod_khomp/commons/base/strings.cpp deleted file mode 100644 index b7b84025a8..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/strings.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -void Strings::Merger::add(std::string s) -{ - _list.push_back(s); -}; - -std::string Strings::Merger::merge(const std::string & sep) -{ - list_type::iterator i = _list.begin(); - - std::string res; - - if (i != _list.end()) - { - res += (*i); - ++i; - }; - - while (i != _list.end()) - { - res += sep; - res += (*i); - ++i; - } - - return res; -}; - -std::string Strings::Merger::merge(const char *sep) -{ - std::string ssep(sep); - return merge(ssep); -} - -unsigned int Strings::tokenize(const std::string & str, Strings::vector_type & tokens, - const std::string & delims, long int max_tokens, bool keep_empty) -{ - std::string::size_type base = 0; - - std::string::size_type init = str.find_first_not_of(delims, 0); - std::string::size_type fini = str.find_first_of(delims, init); - - long int cur_token = 1; - - while (std::string::npos != init) - { - if (keep_empty && base < init) - { - std::string::size_type cur_empty = init - base; - - while (cur_empty && cur_token < max_tokens) - { - tokens.push_back(""); - - ++cur_token; - --cur_empty; - } - } - - if (std::string::npos != fini && cur_token < max_tokens) - { - base = fini + 1; - - tokens.push_back(str.substr(init, fini - init)); - ++cur_token; - } - else - { - base = str.size(); // find_first_of(delims, init); - - tokens.push_back(str.substr(init, str.size() - init)); - break; - } - - init = str.find_first_not_of(delims, fini); - fini = str.find_first_of(delims, init); - } - - if (keep_empty && base != str.size()) - { - std::string::size_type cur_empty = str.size() - base + 1; - - while (cur_empty && cur_token < max_tokens) - { - tokens.push_back(""); - - ++cur_token; - --cur_empty; - } - - if (cur_empty) - { - std::string::size_type pos = base + cur_empty - 1; - tokens.push_back(str.substr(pos, str.size() - pos)); - ++cur_token; - } - } - - return (cur_token - 1); -} - -long Strings::tolong(const std::string & str, int base) -{ - return tolong(str.c_str(), base); -} - -unsigned long Strings::toulong(const std::string & str, int base) -{ - return toulong(str.c_str(), base); -} - -unsigned long long Strings::toulonglong(const std::string & str, int base) -{ - return toulonglong(str.c_str(), base); -} - -double Strings::todouble(const std::string & str) -{ - return todouble(str.c_str()); -} - -long Strings::tolong(const char * str, int base) -{ - char *str_end = 0; - - unsigned long value = strtol(str, &str_end, base); - - if (str_end && *str_end == 0) - return value; - - throw invalid_value(str); -} - -bool Strings::toboolean(std::string str) -{ - std::string tmp(str); - - Strings::lower(tmp); - - if ((tmp == "true") || (tmp == "yes")) return true; - if ((tmp == "false") || (tmp == "no")) return false; - - throw invalid_value(str); -} - -unsigned long Strings::toulong(const char * str, int base) -{ - char *str_end = 0; - - unsigned long value = strtoul(str, &str_end, base); - - if (str_end && *str_end == 0) - return value; - - throw invalid_value(str); -} - -unsigned long long Strings::toulonglong(const char * str, int base) -{ -#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32) - throw not_implemented(); -#else - char *str_end = 0; - - unsigned long long value = strtoull(str, &str_end, base); - - if (str_end && *str_end == 0) - return value; - - throw invalid_value(str); -#endif -} - -double Strings::todouble(const char * str) -{ - char *str_end = 0; - - double value = strtod(str, &str_end); - - if (str_end && *str_end == 0) - return value; - - throw invalid_value(str); -} - -std::string Strings::fromboolean(bool value) -{ - if (value) return "true"; - else return "false"; -} - -std::string Strings::lower(std::string str) -{ - std::string res; - - for (std::string::iterator i = str.begin(); i != str.end(); i++) - res += tolower((*i)); - - return res; -} - -std::string Strings::hexadecimal(std::string value) -{ - std::string result; - - for (std::string::iterator i = value.begin(); i != value.end(); i++) - { - if (i != value.begin()) - result += " "; - - result += STG(FMT("%2x") % (unsigned int)(*i)); - } - - return result; -} - -std::string Strings::trim(const std::string& str, const std::string& trim_chars) -{ - std::string result(str); - - result.erase( result.find_last_not_of( trim_chars ) + 1 ); - result.erase( 0, result.find_first_not_of( trim_chars ) ); - - return result; -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/strings.hpp b/src/mod/endpoints/mod_khomp/commons/base/strings.hpp deleted file mode 100644 index 947da384d9..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/strings.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#include -#include -#include - -#include - -#include - -/* Generic string funcions */ - -#ifndef _STRINGS_HPP_ -#define _STRINGS_HPP_ - -struct Strings -{ - typedef std::list list_type; - typedef std::vector vector_type; - - struct Merger - { - void add(std::string); - - std::string merge(const std::string &); - std::string merge(const char *); - - bool empty() { return _list.empty(); }; - - const list_type & list() { return _list; }; - - protected: - list_type _list; - }; - - public: - struct invalid_value - { - invalid_value(const char * value): _value(value) {}; - invalid_value(const std::string & value): _value(value) {}; - - std::string & value() { return _value; } - - protected: - std::string _value; - }; - - struct not_implemented {}; - - static unsigned int tokenize(const std::string &, vector_type &, const std::string & delims = ",;:", - long int max_toxens = LONG_MAX, bool keep_empty = true); - - static bool toboolean(std::string); - static std::string fromboolean(bool); - - static long tolong(const std::string &, int base = 10); - static unsigned long toulong(const std::string &, int base = 10); - static unsigned long long toulonglong(const std::string &, int base = 10); - static double todouble(const std::string &); - - static long tolong(const char *, int base = 10); - static unsigned long toulong(const char *, int base = 10); - static unsigned long long toulonglong(const char *, int base = 10); - static double todouble(const char *); - - static std::string lower(std::string); - static std::string hexadecimal(std::string); - - static std::string trim(const std::string&, const std::string& trim_chars = " \f\n\r\t\v"); -}; - -#endif // _STRINGS_HPP_ // diff --git a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.cpp b/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.cpp deleted file mode 100644 index d4d9861f5c..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include "saved_condition.hpp" - -bool SavedCondition::wait(unsigned int msec) -{ - bool ret = true; - - switch_mutex_lock(_mutex); - - if (!_signaled) - { - /* msec * 1000 = The amount of time in microseconds to wait. */ - if (switch_thread_cond_timedwait(_condition, _mutex, (switch_interval_time_t)msec * 1000) != 0) - ret = false; - } - - _signaled = false; - - switch_mutex_unlock(_mutex); - - return ret; -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.hpp b/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.hpp deleted file mode 100644 index b34e40b0c0..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/saved_condition.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _SAVED_CONDITION_ -#define _SAVED_CONDITION_ - -#include - -extern "C" -{ - #include -} - -struct SavedCondition : public SavedConditionCommon// : public RefCounter < SavedCondition > -{ - typedef switch_thread_cond_t BaseConditionType; - typedef switch_mutex_t BaseMutexType; - - SavedCondition(switch_memory_pool_t *pool=NULL): - _pool(pool), - _can_delete_pool(false) - { - if(!_pool) - { - switch_core_new_memory_pool(&_pool); - _can_delete_pool = true; - } - - switch_thread_cond_create(&_condition, _pool); - switch_mutex_init(&_mutex, SWITCH_MUTEX_DEFAULT, _pool); - } - - //SavedCondition(const SavedCondition &); - ~SavedCondition() - { - switch_thread_cond_destroy(_condition); - switch_mutex_destroy(_mutex); - - if(_can_delete_pool) - switch_core_destroy_memory_pool(&_pool); - } - - void signal(void) - { - switch_mutex_lock(_mutex); - - _signaled = true; - switch_thread_cond_signal(_condition); - - switch_mutex_unlock(_mutex); - } - - void broadcast(void) - { - switch_mutex_lock(_mutex); - - _signaled = true; - switch_thread_cond_broadcast(_condition); - - switch_mutex_unlock(_mutex); - } - - void wait(void) - { - switch_mutex_lock(_mutex); - - if (!_signaled) - switch_thread_cond_wait(_condition, _mutex); - - _signaled = false; - - switch_mutex_unlock(_mutex); - } - - bool wait(unsigned int); - - void reset(void) - { - switch_mutex_lock(_mutex); - - _signaled = false; - - switch_mutex_unlock(_mutex); - } - - BaseMutexType * mutex() { return _mutex; }; - BaseConditionType * condition() { return _condition; }; - - protected: - - BaseConditionType *_condition; - BaseMutexType *_mutex; - switch_memory_pool_t *_pool; - bool _can_delete_pool; -}; - -#endif /* _SAVED_CONDITION_ */ - diff --git a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/simple_lock.hpp b/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/simple_lock.hpp deleted file mode 100644 index 6b3a17f46d..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/simple_lock.hpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _SIMPLE_LOCK_HPP_ -#define _SIMPLE_LOCK_HPP_ - -#include - -extern "C" -{ - #include -} - -template < typename Implementor > -struct SimpleLockBasic: public SimpleLockCommon < Implementor > -{ - typedef SimpleLockCommon < Implementor > Super; - typedef typename Super::Result Result; - - typedef switch_mutex_t BaseMutexType; - - SimpleLockBasic(switch_memory_pool_t *pool = NULL) - : _pool(pool), _can_delete_pool( (_pool == NULL) ) - - { - if(!_pool) - switch_core_new_memory_pool(&_pool); - - //switch_mutex_init(&_mutex, SWITCH_MUTEX_DEFAULT, _pool); - switch_mutex_init(&_mutex, SWITCH_MUTEX_NESTED, _pool); - } - - virtual ~SimpleLockBasic() - { - /* do nothing */ - }; - - void unreference_data() - { - switch_mutex_destroy(_mutex); - - if (_can_delete_pool) - switch_core_destroy_memory_pool(&_pool); - } - - Result trylock() - { - switch (switch_mutex_trylock(_mutex)) - { - case SWITCH_STATUS_SUCCESS: - return Super::SUCCESS; - case SWITCH_STATUS_FALSE: - case SWITCH_STATUS_TERM: - case SWITCH_STATUS_NOTIMPL: - case SWITCH_STATUS_MEMERR: - case SWITCH_STATUS_GENERR: - case SWITCH_STATUS_SOCKERR: - case SWITCH_STATUS_NOTFOUND: - case SWITCH_STATUS_UNLOAD: - case SWITCH_STATUS_NOUNLOAD: - case SWITCH_STATUS_NOT_INITALIZED: - return Super::FAILURE; - //case SWITCH_STATUS_INUSE: - default: - return Super::ISINUSE; - } - } - - void unlock() - { - switch_mutex_unlock(_mutex); - } - - BaseMutexType * mutex() { return _mutex; }; - - protected: - BaseMutexType *_mutex; - switch_memory_pool_t *_pool; - bool _can_delete_pool; -}; - -struct SimpleLock: public SimpleLockBasic < SimpleLock > -{ - typedef SimpleLockBasic < SimpleLock > Super; - typedef Super::Result Result; - - SimpleLock(switch_memory_pool_t *pool = NULL) - : Super(pool) {}; - - Result lock() - { - switch (switch_mutex_lock(_mutex)) - { - case SWITCH_STATUS_SUCCESS: - return Super::SUCCESS; - case SWITCH_STATUS_FALSE: - case SWITCH_STATUS_TERM: - case SWITCH_STATUS_NOTIMPL: - case SWITCH_STATUS_MEMERR: - case SWITCH_STATUS_GENERR: - case SWITCH_STATUS_SOCKERR: - case SWITCH_STATUS_NOTFOUND: - case SWITCH_STATUS_UNLOAD: - case SWITCH_STATUS_NOUNLOAD: - case SWITCH_STATUS_NOT_INITALIZED: - return Super::FAILURE; - //case SWITCH_STATUS_INUSE: - default: - return Super::ISINUSE; - } - } -}; - -template < unsigned int Retries = 10, unsigned int Interval = 50 > -struct SimpleNonBlockLock: public SimpleLockBasic < SimpleNonBlockLock < Retries, Interval > > -{ - typedef SimpleLockBasic < SimpleNonBlockLock < Retries, Interval > > Super; - typedef typename Super::Result Result; - - SimpleNonBlockLock(switch_memory_pool_t *pool = NULL) - : Super(pool) {}; - - inline Result lock() - { - for (unsigned int i = 0; i < Retries; i++) - { - Result ret = Super::trylock(); - - if (ret != Super::ISINUSE) - return ret; - - usleep(Interval * 1000); - } - - return Super::ISINUSE; - } -}; - -#endif /* _SIMPLE_LOCK_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp b/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp deleted file mode 100644 index 3c61b6a6ec..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _THREAD_HPP_ -#define _THREAD_HPP_ - -#include - -extern "C" -{ - #include -} - -struct Thread : ThreadCommon -{ - typedef switch_thread_t BaseThreadType; - - template - struct ThreadData : ThreadDataCommon - { - ThreadData(T data, A arg) : _data(data), _arg(arg) {} - - int run() - { - return _data(_arg); - } - - T _data; - A _arg; - }; - - template - struct ThreadData < T, R, void > : ThreadDataCommon - { - ThreadData(T data) : _data(data) {} - - int run() - { - return _data(); - } - - T _data; - }; - - template - struct ThreadData < T, void, A > : ThreadDataCommon - { - ThreadData(T data, A arg) : _data(data), _arg(arg) {} - - int run() - { - _data(_arg); - return 0; - } - - T _data; - A _arg; - }; - - - template - struct ThreadData < T, void, void > : ThreadDataCommon - { - ThreadData(T data) : _data(data) {} - - int run() - { - _data(); - return 0; - } - - T _data; - }; - - template - Thread(T obj, switch_memory_pool_t *pool=NULL) : - _thread_info(new ThreadData::Return, void>(obj)), - _pool(pool), - _can_delete_pool(false) - { - if(!_pool) - { - switch_core_new_memory_pool(&_pool); - _can_delete_pool = true; - } - - _thread_info->_thread = this; - _thread_info->_self = NULL; - _thread_info->_attribute = NULL; - - if(switch_threadattr_create( - (switch_threadattr_t **)&_thread_info->_attribute, _pool) != 0) - { - _thread_info->_attribute = NULL; - return; - } - - switch_threadattr_stacksize_set( - (switch_threadattr_t *)_thread_info->_attribute, - SWITCH_THREAD_STACKSIZE); - - if(!priority()) - { - _thread_info->_attribute = NULL; - } - - } - - template - Thread(T obj, A arg, switch_memory_pool_t *pool=NULL) : - _thread_info(new ThreadData::Return, A>(obj, arg)), - _pool(pool), - _can_delete_pool(false) - { - if(!_pool) - { - switch_core_new_memory_pool(&_pool); - _can_delete_pool = true; - } - - _thread_info->_thread = this; - _thread_info->_self = NULL; - _thread_info->_attribute = NULL; - - if(switch_threadattr_create( - (switch_threadattr_t **)&_thread_info->_attribute, _pool) != 0) - { - _thread_info->_attribute = NULL; - return; - } - - switch_threadattr_stacksize_set( - (switch_threadattr_t *)_thread_info->_attribute, - SWITCH_THREAD_STACKSIZE); - - if(!priority()) - { - _thread_info->_attribute = NULL; - } - - } - - ~Thread() - { - if(_thread_info) - delete _thread_info; - - if (_can_delete_pool) - switch_core_destroy_memory_pool(&_pool); - } - - void detach(bool d = true) - { - if(!_thread_info->_attribute) - return; - - /* Non-zero if detached threads should be created. */ - switch_threadattr_detach_set( - (switch_threadattr_t *)_thread_info->_attribute, d ? 1 : 0); - } - - bool start() - { - if(!_pool || !_thread_info->_attribute) - return false; - - switch_thread_create((switch_thread_t**)&_thread_info->_self, - (switch_threadattr_t *)_thread_info->_attribute, - run, - _thread_info, - _pool); - - if(!_thread_info->_self) - return false; - - return true; - } - - int join() - { - /* - * block until the desired thread stops executing. - * @param retval The return value from the dead thread. - * @param thd The thread to join - * - * SWITCH_DECLARE(switch_status_t) switch_thread_join(switch_status_t *retval, switch_thread_t *thd); - */ - - if(!_thread_info->_self) - return -2; - - int retval = 0; - - if(switch_thread_join((switch_status_t*)&retval, - (switch_thread_t *)_thread_info->_self) != 0) - return -1; - - return retval; - } - - BaseThreadType * self() - { - //switch_thread_self(); - //apr_os_thread_current(); - return (BaseThreadType *)_thread_info->_self; - } - -private: - void exit(int status) - { - /** - * stop the current thread - * @param thd The thread to stop - * @param retval The return value to pass back to any thread that cares - */ - //SWITCH_DECLARE(switch_status_t) switch_thread_exit(switch_thread_t *thd, switch_status_t retval); - switch_thread_exit((switch_thread_t *)_thread_info->_self, (switch_status_t)status); - - } - -#ifndef WIN32 - struct apr_threadattr_t { - apr_pool_t *pool; - pthread_attr_t attr; - }; -#endif - - bool priority() - { -#ifndef WIN32 - struct sched_param param; - - struct apr_threadattr_t *myattr = (struct apr_threadattr_t *)_thread_info->_attribute; - - if (pthread_attr_setschedpolicy( - (pthread_attr_t *)&myattr->attr, SCHED_RR) < 0) - return false; - - if (pthread_attr_getschedparam( - (pthread_attr_t *)&myattr->attr, ¶m) < 0) - return false; - - param.sched_priority = sched_get_priority_max(SCHED_RR); - - if (pthread_attr_setschedparam( - (pthread_attr_t *)&myattr->attr, ¶m) < 0) - return false; - -#endif - return true; - -/* - //BUG in Freeswitch - -THANKS FOR NOT REPORTING IT SO WE MUST LIVE WITH A PROBLEM YOU KNOW ABOUT ..... - - if(switch_threadattr_priority_increase( - (switch_threadattr_t *)_thread_info->_attribute) != 0) - return false; - - return true; -*/ - } - - -protected: - ThreadDataCommon * _thread_info; - switch_memory_pool_t *_pool; - bool _can_delete_pool; - -protected: - - static void *SWITCH_THREAD_FUNC run(BaseThreadType *thread, void * obj) - { - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - // "Starting new Thread\n"); - - ThreadDataCommon * data = (ThreadDataCommon *)obj; - int retval = data->run(); - - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - // "Stopping new Thread = %d\n", retval); - - ((Thread *)(data->_thread))->exit(retval); - - return NULL; - } - -}; - - -#endif /* _THREAD_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/tagged_union.hpp b/src/mod/endpoints/mod_khomp/commons/base/tagged_union.hpp deleted file mode 100644 index f46aab0b75..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/tagged_union.hpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _TAGGED_UNION_HPP_ -#define _TAGGED_UNION_HPP_ - -#include - -#include -#include -#include - -#include - -namespace Tagged -{ - struct EmptyUnion - { - friend class Value; - - EmptyUnion() - : _adjusted(false) {}; - - // copy constructor - EmptyUnion(const EmptyUnion & o) - : _adjusted(o._adjusted) {}; - - // copy assignment operator - EmptyUnion & operator=(const EmptyUnion & o) - { - _adjusted = o._adjusted; - return *this; - }; - - ~EmptyUnion() { _adjusted = false; }; - - bool operator==(const EmptyUnion & o) const - { - return true; - }; - - public: - void clear(void) { _adjusted = false; }; - protected: - void setup(void) { _adjusted = true; }; - - protected: - bool value_set(void) const { return false; }; - bool value_get(void) const { return false; }; - - bool value_check(void) const { return false; }; - - template < typename S > - bool value_visit(S & visitor, typename S::ReturnType & ret) const - { - return false; - }; - - template < typename S > - bool value_visit_void(S & visitor) const - { - return false; - }; - - bool adjusted() const { return _adjusted; }; - - private: - bool _adjusted; - }; - - template < typename V, typename E = EmptyUnion > - struct Union: public E - { - friend class Value; - - // default constructor - Union() - : _value(0) {}; - - // constructor with initializer - template < typename U > - Union(U value) - : _value(0) - { - set(value); - }; - - // copy constructor - Union(const Union & o) - : E(static_cast(o)), - _value( (o._value ? new V(*(o._value)) : 0) ) - {}; - - // copy assignment operator - Union & operator=(const Union & o) - { - if (_value) - { - delete _value; - _value = 0; - } - - if (o._value) - { - _value = new V(*(o._value)); - } - - E::operator=(static_cast(o)); - - return *this; - }; - - // destructor - ~Union() - { - if (_value) - { - delete _value; - _value = 0; - } - }; - - // equal sign operator - template < typename U > - void operator=(U value) - { - set(value); - } - - template < typename U > - bool check(void) const - { - return value_check(static_cast< const U * const>(0)); - }; - - template < typename U > - U & get(void) const - { - U * res = 0; - - if (!E::adjusted()) - throw std::runtime_error("tagged union empty!"); - - if (!value_get(&res) || !res) - throw std::runtime_error(STG(FMT("type mismatch when asked for '%s'") % typeid(U).name())); - - return *res; - }; - - template < typename U > - void set(U val) - { - if (E::adjusted()) - clear(); - - if (!value_set(val)) - throw std::runtime_error("unable to set value of invalid type"); - }; - - template < typename S > - typename S::ReturnType visit(S visitor) const - { - typename S::ReturnType ret; - - if (!value_visit(visitor, ret)) - throw std::runtime_error("unable to visit empty value"); - - return ret; - }; - - template < typename S > - void visit_void(S visitor) const - { - if (!value_visit_void(visitor)) - throw std::runtime_error("unable to visit empty value"); - }; - - void clear() - { - if (_value) - { - delete _value; - _value = 0; - } - - E::clear(); - }; - - // compare (equal) operator - bool operator==(const Union & o) const - { - bool are_equal = false; - - if (!_value && !(o._value)) - are_equal = true; - - if (_value && o._value) - are_equal = (*_value == *(o._value)); - - if (are_equal) - return E::operator==(static_cast(o)); - - return false; - }; - - // compare types - bool sameType(const Union & o) const - { - if ((!(_value) && !(o._value)) || (_value && o._value)) - return E::operator==(static_cast(o)); - - return false; - }; - - protected: - using E::value_set; - using E::value_get; - - using E::value_check; - using E::value_visit; - using E::value_visit_void; - - bool value_set(V val) - { - _value = new V(val); - E::setup(); - - return true; - }; - - bool value_get(V ** val) const - { - if (!_value) - return false; - - *val = _value; - return true; - } - - bool value_check(const V * const junk) const - { - (void)junk; - return (_value != 0); - }; - - template < typename S > - bool value_visit(S & visitor, typename S::ReturnType & ret) const - { - if (_value) - { - ret = visitor(*const_cast(_value)); - return true; - }; - - return E::value_visit(visitor, ret); - }; - - template < typename S > - bool value_visit_void(S & visitor) const - { - if (_value) - { - visitor(*const_cast(_value)); - return true; - }; - - return E::value_visit_void(visitor); - }; - - private: - V * _value; - }; -}; - -#endif /* _TAGGED_UNION_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/thread.hpp b/src/mod/endpoints/mod_khomp/commons/base/thread.hpp deleted file mode 100644 index e00d7c875a..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/thread.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _THREAD_COMMON_HPP_ -#define _THREAD_COMMON_HPP_ - -#include - -#include -//#include - -struct ThreadCommon -{ - protected: - template - struct DecomposeFuncPtr; - - template - struct DecomposeFuncPtr - { - typedef ReturnType Return; - }; - - template - struct DecomposeFuncPtr - { - typedef void Return; - }; - - template - struct DecomposeFuncPtr - { - typedef ReturnType Return; - }; - - template< typename FunctionType > - struct DecomposeFunction - { - typedef typename Select < IsClass< FunctionType >::Result, int, - typename DecomposeFuncPtr< FunctionType >::Return >::Result - Return; - }; - - public: - struct ThreadDataCommon - { - ThreadDataCommon() {} - - virtual ~ThreadDataCommon() {} - - virtual int run() = 0; - - ThreadCommon * _thread; - - void * _self; - void * _attribute; - }; - - ThreadCommon() {} -}; - - -#include COMMONS_INCLUDE(thread.hpp) - -#endif /* _THREAD_COMMON_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/timer.cpp b/src/mod/endpoints/mod_khomp/commons/base/timer.cpp deleted file mode 100644 index 0cb0ac4340..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/timer.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -TimerTraits::TimerTraits() -: _thread((Thread*)0), _purify(false), _last_tick(0), _age_count(0), _shutdown(false) -{}; - -bool TimerTraits::start (void) -{ - _shutdown = false; - - _condition.reset(); - _finalized.reset(); - - if (!_thread) - { - _thread = new Thread(TimerTraits::loop_thread(this)); - _purify = true; - } - -#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32) - // set priority ... -#else - pthread_attr_t attrs; - sched_param param; - - if (pthread_attr_init(&attrs) < 0) - return false; - - if (pthread_attr_setschedpolicy(&attrs, SCHED_RR) < 0) - return false; - - if (pthread_attr_getschedparam(&attrs, ¶m) < 0) - return false; - - param.sched_priority = sched_get_priority_max(SCHED_RR); - - if (pthread_attr_setschedparam(&attrs, ¶m) < 0) - return false; - - // set priority... - -// if (pthread_create(&_thread, &attrs, TimerTraits::loop_thread, NULL) < 0) -// return false; - - _thread->start(); -#endif - - return true; -} - -bool TimerTraits::stop (void) -{ - _shutdown = true; - - _condition.signal(); - - _finalized.wait(10000); /* 10 seconds max wait */ - - if (_thread && _purify) - { - delete _thread; - - _thread = (Thread *)0; - _purify = false; - } - - return true; -} - -//----------------------------------------- - -int TimerTraits::loop_thread::operator()(void) -{ - try - { - _timer->loop(); - } - catch( ... ) - { - /* something wrong happened! */ - } - - _timer->_finalized.signal(); - - return 0; -} - -void TimerTraits::execute(ControlSet::iterator init, const TimerTraits::Control & ctrl) -{ - volatile CallbackFuncType func = (volatile CallbackFuncType) ctrl._func; - volatile CallbackDataType data = (volatile CallbackDataType) ctrl._data; - - _timer_set.erase(init); - - _mutex.unlock(); - - func(data); -} - -void TimerTraits::loop (void) -{ - while (true) - { - if (_shutdown) break; - - _mutex.lock(); - - ControlSet::iterator init = _timer_set.begin(); - - if (init == _timer_set.end()) - { - _mutex.unlock(); - _condition.wait(); - } - else - { - const Control & ctrl = *init; - - unsigned int ts_now = TimerTraits::tick(); - - if (_age_count == ctrl._age) - { - if (ts_now < ctrl._msecs) - { - /* age is right, but it is not time to expire yet... */ - volatile unsigned int wait_time = ctrl._msecs - ts_now; - _mutex.unlock(); - _condition.wait(wait_time); /* expire - now */ - } - else - { - /* age is right, and we should expire! */ - execute(init, ctrl); /* called locked, return unlocked */ - } - } - else if (_age_count < ctrl._age) - { - /* age is not there yet (need some time to overlap)... */ - volatile unsigned int wait_time = (UINT_MAX - ts_now) + ctrl._msecs; - _mutex.unlock(); - _condition.wait(wait_time); /* MAX - now + expire */ - } - else - { - /* age has passed, we should have expired before! */ - execute(init, ctrl); /* called locked, return unlocked */ - } - } - } - - _finalized.signal(); -} - -unsigned int TimerTraits::tick() -{ -#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32) - unsigned int tick = GetTickCount(); -#else - struct timespec ticks; - - // error condition, make the user notice this.. - if (clock_gettime(CLOCK_MONOTONIC, &ticks) < 0) - return 0; - - unsigned int tick = ( ticks.tv_sec * 1000 ) + ( ticks.tv_nsec / 1000000 ); -#endif - - if (_last_tick > tick) - ++_age_count; - - _last_tick = tick; - - return tick; -} - -//----------------------------------------- - -TimerTraits::Index TimerTraits::traits_add_unlocked (unsigned int msecs, const void * func, const void * data, unsigned int value) -{ - unsigned int ms_tick = TimerTraits::tick(); - - unsigned int ms_left = UINT_MAX - ms_tick; - unsigned int ms_real = msecs; - - unsigned int age_num = _age_count; - - if (ms_left < msecs) - { - ms_real -= ms_left; - ++age_num; - } - else - { - ms_real += ms_tick; - } - - ControlSet::iterator it = _timer_set.insert(Control(age_num,ms_real,func,data,value)); - - if (_timer_set.size() == 1 || _timer_set.begin() == it) - { - _condition.signal(); - }; - - return Index(age_num, ms_real, msecs, func, data, value); -} - -TimerTraits::Index TimerTraits::traits_add (unsigned int msecs, const void * func, const void * data, unsigned int value) -{ - _mutex.lock(); - - Index idx = traits_add_unlocked(msecs, func, data, value); - - _mutex.unlock(); - - return idx; -} - -bool TimerTraits::traits_restart (TimerTraits::Index & idx, bool force) -{ - bool ret = false; - - _mutex.lock(); - - if (idx.valid) - { - if (traits_del_unlocked(idx) || force) - { - idx = traits_add_unlocked(idx.delta, idx.func, idx.data, idx.value); - ret = true; - } - } - - _mutex.unlock(); - - return ret; -} - -void TimerTraits::traits_setup(TimerTraits::Index * idx, unsigned int msecs, const void * func, void * data, unsigned int value) -{ - _mutex.lock(); - - if (idx->valid) - { - (void)traits_del_unlocked(*idx); - } - - *idx = traits_add_unlocked(msecs, func, data, value); - - _mutex.unlock(); -} - -bool TimerTraits::traits_del_unlocked (TimerTraits::Index & idx) -{ - bool ret = false; - - if (idx.valid) - { - ControlSet::iterator i = _timer_set.lower_bound(Control(idx.era, idx.msec)); - ControlSet::iterator j = _timer_set.upper_bound(Control(idx.era, idx.msec)); - - for (; i != j; i++) - { - const Control & ctrl = (*i); - - if ((idx.value && !(ctrl._value & idx.value))) - continue; - - if (((idx.func && ctrl._func == idx.func) || !idx.func) && ((idx.data && ctrl._data == idx.data) || !idx.data)) - { - if (_timer_set.begin() == i) - _condition.signal(); - - _timer_set.erase(i); - - ret = true; - break; - } - } - - idx.valid = false; - } - - return ret; -} - -bool TimerTraits::traits_del (TimerTraits::Index & idx) -{ - _mutex.lock(); - - bool ret = traits_del_unlocked(idx); - - _mutex.unlock(); - - return ret; -} - -bool TimerTraits::traits_del (const void * func, const void * data, unsigned int value) -{ - bool ret = false; - - _mutex.lock(); - - for (ControlSet::iterator i = _timer_set.begin(); i != _timer_set.end(); i++) - { - const Control & ctrl = (*i); - - if ((value && !(ctrl._value & value))) - continue; - - if (((func && ctrl._func == func) || !func) && ((data && ctrl._data == data) || !data)) - { - if (_timer_set.begin() == i) - _condition.signal(); - - _timer_set.erase(i); - - ret = true; - break; - } - } - - _mutex.unlock(); - - return ret; -} diff --git a/src/mod/endpoints/mod_khomp/commons/base/timer.hpp b/src/mod/endpoints/mod_khomp/commons/base/timer.hpp deleted file mode 100644 index 24d115d991..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/timer.hpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32) -#include -#else -#include -#endif - -#include - -#include -#include -#include -#include - -#ifndef _TIMER_HPP_ -#define _TIMER_HPP_ - -struct TimerTraits -{ - typedef bool (* CallbackFuncType)(const void * volatile); - typedef const void * CallbackDataType; - - TimerTraits(); - - virtual ~TimerTraits() {}; - - protected: - - /* pre-declaration, used below */ - struct ControlCompare; - - struct Control - { - Control(unsigned int age, unsigned int msecs, const void * func = 0, const void * data = 0, unsigned int value = 0) - : _age(age), _msecs(msecs), _func(func), _data(data), _value(value) {} - - unsigned int _age; - - unsigned int _msecs; - - const void * _func; - const void * _data; - - unsigned int _value; - }; - - struct ControlCompare - { - bool operator()(const Control & c1, const Control & c2) const - { - return (c1._age < c2._age ? true : c1._msecs < c2._msecs); - } - }; - - typedef std::multiset < Control, ControlCompare > ControlSet; - - public: - struct Index - { - Index(): era(0), msec(0), valid(false) {}; - - Index(unsigned int _era, unsigned int _msec, unsigned int _delta, const void * _func, const void * _data, unsigned int _value) - : era(_era), msec(_msec), delta(_delta), func(_func), data(_data), value(_value), valid(true) {}; - - unsigned int era; - unsigned int msec; - - unsigned int delta; - - const void * func; - const void * data; - - unsigned int value; - - bool valid; - - void reset(void) { era = 0; msec = 0; valid = false; }; - }; - - /* timer add/remove functions */ - Index traits_add (unsigned int msecs, const void * func, const void * data = 0, unsigned int value = 0); - - bool traits_restart (Index & idx, bool force); - - bool traits_del (Index & idx); - bool traits_del (const void * func, const void * data = 0, unsigned int value = 0); - - void traits_setup(Index * idx, unsigned int msecs, const void * func, void * data = 0, unsigned int value = 0); - - /* timer start/stop functions */ - bool start(void); - bool stop(void); - - protected: - Index traits_add_unlocked (unsigned int msecs, const void * func, const void * data, unsigned int value); - - bool traits_del_unlocked (Index & idx); - - protected: - void execute(ControlSet::iterator, const Control &); - - void loop(void); - - struct loop_thread - { - loop_thread(TimerTraits *timer) : _timer(timer) {}; - - int operator()(void); - - protected: - TimerTraits * _timer; - }; - - unsigned int tick(); - - /* variables */ - - SavedCondition _condition; - - SimpleLock _mutex; - Thread * _thread; - bool _purify; - - ControlSet _timer_set; - - unsigned int _last_tick; - unsigned int _age_count; - - SavedCondition _finalized; - bool _shutdown; -}; - -template < typename F, typename D > -struct TimerTemplate: COUNTER_SUPER(TimerTemplate< F, D >) -{ - typedef TimerTraits::Index Index; - typedef TimerTraits::Control Control; - - TimerTemplate() - : _timer(new TimerTraits()) - {}; - - TimerTemplate(const TimerTemplate< F, D > & o) - : COUNTER_REFER(o, TimerTemplate< F, D >), - _timer(o._timer) - {}; - - void unreference(void) - { - if (_timer) - delete _timer; - }; - - bool start() { return _timer->start(); } - bool stop() { return _timer->stop(); } - - inline void setup(Index * idx, unsigned int msecs, F * func, D data = 0, unsigned int value = 0) - { - _timer->traits_setup(idx, msecs, (const void *)func, (void *)(data), value); - } - - inline Index add(unsigned int msecs, F * func, D data = 0, unsigned int value = 0) - { - return _timer->traits_add(msecs, (const void *)func, (void *)(data), value); - } - - inline bool restart(Index & idx, bool force = false) - { - return _timer->traits_restart(idx, force); - } - - inline bool del(Index & idx) - { - return _timer->traits_del(idx); - } - - inline bool del(F * func, D data, unsigned int value = 0) - { - return _timer->traits_del((const void *)func, (void *)(data), value); - } - - inline bool del(unsigned int value) - { - return _timer->traits_del((const void *)0, (void *)0, value); - } - - protected: - TimerTraits * _timer; -}; - -#endif /* _TIMER_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/types.hpp b/src/mod/endpoints/mod_khomp/commons/base/types.hpp deleted file mode 100644 index 5ab6d292c6..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/types.hpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _TYPES_HPP_ -#define _TYPES_HPP_ - -/*** Used for conditional compilation based on K3L version ***/ - -#define K3L_AT_LEAST(major,minor,build) \ - (((k3lApiMajorVersion == major) && ((k3lApiMinorVersion == minor) && (k3lApiBuildVersion >= build)) || \ - ((k3lApiMajorVersion == major) && (k3lApiMinorVersion > minor))) || \ - (k3lApiMajorVersion > major)) - -#define K3L_EXACT(major,minor,build) \ - ((k3lApiMajorVersion == major) && (k3lApiMinorVersion == minor) && (k3lApiBuildVersion >= build)) - -/*** Used for checking information on classes and stuff.. ***/ - -template< typename T > -struct IsClass -{ - protected: - template < typename X > static char ( &A( void(X::*)() ) )[1]; - template < typename X > static char ( &A( X ) )[2]; - public: - static bool const Result = sizeof( A< T >(0) ) == 1; -}; - -template < typename T > -struct IsConst -{ - static bool const Result = false; -}; - -template < typename T > -struct IsConst< const T > -{ - static bool const Result = true; -}; - -template < typename T > -struct IsConst< T const * > -{ - static bool const Result = true; -}; - -/*** Used for template metaprogramming ***/ - -template < bool Value, typename Then, typename Else > -struct Select -{ - typedef Then Result; -}; - -template < typename Then, typename Else > -struct Select < false, Then, Else > -{ - typedef Else Result; -}; - -#endif /* _TYPES_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/variable.hpp b/src/mod/endpoints/mod_khomp/commons/base/variable.hpp deleted file mode 100644 index efeb0f53b7..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/variable.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the "LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include - -#ifndef _VARIABLE_HPP_ -#define _VARIABLE_HPP_ - -template < typename R > -struct VariableBaseTable -{ - R value; -}; - -struct EmptyVariable {}; - -template < typename R > -struct Variable -{ - protected: - typedef VariableBaseTable< R > BaseType; - - typedef const BaseType * ConstObjType; - typedef BaseType * ObjType; - typedef R BaseType::* VarType; - - public: - template < typename ConstructorObjType > - Variable(R ConstructorObjType::* v) - : _adjusted(true), - _variable(reinterpret_cast(v)) - {}; - - Variable() - : _adjusted(false) - {}; - - template < typename MemberType > - void operator=(const MemberType v) - { - _adjusted = true; - _variable = reinterpret_cast(v); - } - - template < typename Type > - R & operator()(Type * obj) const - { - if (!_adjusted) - throw EmptyVariable(); - - return (reinterpret_cast< ObjType >(obj))->*(_variable); - } - - template < typename Type > - R & operator()(Type & obj) const - { - if (!_adjusted) - throw EmptyVariable(); - - return (reinterpret_cast< ObjType >(&obj))->*(_variable); - } - - template < typename Type > - const R & operator()(const Type * obj) const - { - if (!_adjusted) - throw EmptyVariable(); - - return (reinterpret_cast< ConstObjType >(obj))->*(_variable); - } - - template < typename Type > - const R & operator()(const Type & obj) const - { - if (!_adjusted) - throw EmptyVariable(); - - return (reinterpret_cast< ConstObjType >(&obj))->*(_variable); - } - - protected: - bool _adjusted; - VarType _variable; -}; - -#endif /* _VARIABLE_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/base/verbose.cpp b/src/mod/endpoints/mod_khomp/commons/base/verbose.cpp deleted file mode 100644 index bacd269736..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/verbose.cpp +++ /dev/null @@ -1,2992 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include - -#define PRESENTATION_CHECK_RETURN(fmt, txtexact, txthuman) \ - { \ - switch(fmt) \ - { \ - case EXACT: return txtexact; \ - case HUMAN: return txthuman; \ - } \ - return txtexact; \ - } - -/********************************************/ - -std::string Verbose::channelStatus(const int32 dev, const int32 obj, const int32 cs, const Verbose::Presentation fmt) const -{ - try - { - const K3L_CHANNEL_CONFIG & config = _api.channel_config(dev, obj); - return Verbose::channelStatus(config.Signaling, cs, fmt); - } - catch (...) - { - return presentation(fmt, "", "Unknown"); - } -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::event(const int32 obj, const K3L_EVENT * const ev, const R2CountryType r2_country, const Verbose::Presentation fmt) const -#else -std::string Verbose::event(const int32 obj, const K3L_EVENT * const ev, const Verbose::Presentation fmt) const -#endif -{ - try - { - const K3L_CHANNEL_CONFIG & config = _api.channel_config(ev->DeviceId, obj); -#if K3L_AT_LEAST(2,0,0) - return Verbose::event(config.Signaling, obj, ev, r2_country, fmt); -#else - return Verbose::event(config.Signaling, obj, ev, fmt); -#endif - } - catch (...) - { -#if K3L_AT_LEAST(2,0,0) - return Verbose::event(ksigInactive, obj, ev, r2_country, fmt); -#else - return Verbose::event(ksigInactive, obj, ev, fmt); -#endif - } -} - -/********************************************/ - -std::string Verbose::echoLocation(const KEchoLocation ec, const Verbose::Presentation fmt) -{ - switch (ec) - { -#if K3L_AT_LEAST(1,5,4) - case kelNetwork: return presentation(fmt, "kelNetwork", "Network"); -#else - case kelE1: return presentation(fmt, "kelE1", "Network"); -#endif - case kelCtBus: return presentation(fmt, "kelCtBus", "CT-Bus"); - }; - - return presentation(fmt, "", "Unknown"); -}; - -std::string Verbose::echoCancellerConfig(KEchoCancellerConfig ec, const Verbose::Presentation fmt) -{ - switch (ec) - { - case keccNotPresent: return presentation(fmt, "keccNotPresent", "Not Present"); - case keccOneSingleBank: return presentation(fmt, "keccOneSingleBank", "One, Single Bank"); - case keccOneDoubleBank: return presentation(fmt, "keccOneDoubleBank", "One, Double Bank"); - case keccTwoSingleBank: return presentation(fmt, "keccTwoSingleBank", "Two, Single Bank"); - case keccTwoDoubleBank: return presentation(fmt, "keccTwoDoubleBank", "Two, Double Bank"); - case keccFail: return presentation(fmt, "keccFail", "Failure"); - }; - - return presentation(fmt, "", "Unknown"); -}; - -std::string Verbose::deviceName(const KDeviceType dt, const int32 model, const Verbose::Presentation fmt) -{ - return deviceName(dt, model, 0, fmt); -} - -std::string Verbose::deviceName(const KDeviceType dt, const int32 model, const int32 count, const Verbose::Presentation fmt) -{ - try - { - std::string value; - - value += internal_deviceType(dt, count); - value += "-"; - value += internal_deviceModel(dt, model, count); - - return value; - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[type/model='%d/%d']") % (int)dt % (int)model), - STG(FMT("Unknown device type/model (%d/%d)") % (int)dt % (int)model)); - } -} - -std::string Verbose::deviceType(const KDeviceType dt, const Verbose::Presentation fmt) -{ - return deviceType(dt, 0, fmt); -} - -std::string Verbose::deviceType(const KDeviceType dt, const int32 count, const Verbose::Presentation fmt) -{ - try - { - return internal_deviceType(dt, count); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[type='%d']") % (int)dt), - STG(FMT("Unknown device type (%d)") % (int)dt)); - } -} - -std::string Verbose::internal_deviceType(const KDeviceType dt, const int32 count) -{ - switch (dt) - { - case kdtE1: return (count > 34 || count == 0 ? "K2E1" : "K1E1"); - -#if K3L_AT_LEAST(1,6,0) - case kdtFXO: return "KFXO"; -#else - case kdtFX: return "KFXO"; -#endif - - case kdtConf: return "KCONF"; - case kdtPR: return "KPR"; - case kdtE1GW: return "KE1GW"; - -#if K3L_AT_LEAST(1,6,0) - case kdtFXOVoIP: return "KFXVoIP"; -#else - case kdtFXVoIP: return "KFXVoIP"; -#endif - -#if K3L_AT_LEAST(1,5,0) - case kdtE1IP: return (count > 90 || count == 0 ? "K2E1" : "K1E1"); -#endif -#if K3L_AT_LEAST(1,5,1) - case kdtE1Spx: return (count > 30 || count == 0 ? "K2E1" : "K1E1"); - case kdtGWIP: return "KGWIP"; -#endif - -#if K3L_AT_LEAST(1,6,0) - case kdtFXS: return "KFXS"; - case kdtFXSSpx: return "KFXS"; - case kdtGSM: return "KGSM"; - case kdtGSMSpx: return "KGSM"; -#endif - -#if K3L_AT_LEAST(2,1,0) - case kdtGSMUSB: return "KGSMUSB"; - case kdtGSMUSBSpx: return "KGSMUSB"; - - case kdtE1FXSSpx: return "KE1FXS"; -#endif - -#if K3L_EXACT(2,1,0) - case kdtReserved1: return "Reserved1"; -#endif - -#if K3L_AT_LEAST(2,2,0) - case kdtE1AdHoc: return "KE1AdHoc"; -#endif - case kdtDevTypeCount: break; - } - - throw internal_not_found(); -} - -std::string Verbose::deviceModel(const KDeviceType dt, const int32 model, const Verbose::Presentation fmt) -{ - return deviceModel(dt, model, 0, fmt); -}; - -std::string Verbose::deviceModel(const KDeviceType dt, const int32 model, const int32 count, const Verbose::Presentation fmt) -{ - try - { - return internal_deviceModel(dt, model, count); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[model='%d']") % (int)model), - STG(FMT("Unknown device model (%d)") % (int)model)); - } -} - -std::string Verbose::internal_deviceModel(const KDeviceType dt, const int32 model, const int32 count) -{ - switch (dt) - { - case kdtE1: - switch ((KE1DeviceModel)model) - { - case kdmE1600: return (count > 34 || count == 0 ? "600" : "300"); - case kdmE1600E: return (count > 34 || count == 0 ? "600" : "300"); -#if K3L_AT_LEAST(2,0,0) - case kdmE1600EX: return (count > 34 || count == 0 ? "600" : "300"); -#endif - } - throw internal_not_found(); - -#if K3L_AT_LEAST(1,6,0) - case kdtFXO: - switch ((KFXODeviceModel)model) -#else - case kdtFX: - switch ((KFXDeviceModel)model) -#endif - { -#if K3L_AT_LEAST(1,6,0) - case kdmFXO80: - switch (count) - { - case 0: /* default */ - case 8: return "80"; - case 4: return "40"; - } - break; - - case kdmFXOHI: - switch (count) - { - case 0: /* default */ - case 8: return "80-HI"; - case 4: return "40-HI"; - } - break; - - case kdmFXO160HI: return "160HI"; -#if K3L_AT_LEAST(2,1,0) - case kdmFXO240HI: return "240HI"; -#endif -#else - case kdmFXO80: - switch (count) - { - case 0: /* default */ - case 8: return "80"; - case 4: return "40"; - } - break; - -#endif - } - - throw internal_not_found(); - - case kdtConf: - switch ((KConfDeviceModel)model) - { - case kdmConf240: return "240"; - case kdmConf120: return "120"; -#if K3L_AT_LEAST(2,0,0) - case kdmConf240EX: return "240EX"; - case kdmConf120EX: return "120EX"; -#endif - } - - throw internal_not_found(); - - case kdtPR: - switch ((KPRDeviceModel)model) - { -#if K3L_AT_LEAST(1,6,0) - case kdmPR300v1: return "300v1"; - case kdmPR300SpxBased: return "300S"; -#if K3L_AT_LEAST(2,0,0) - case kdmPR300EX: return "300EX"; -#endif - case kdmPR300: return "300"; - } -#endif - throw internal_not_found(); - -#if K3L_AT_LEAST(1,4,0) - case kdtE1GW: - switch ((KE1GWDeviceModel)model) - { -#if K3L_AT_LEAST(1,6,0) - case kdmE1GW640: return "640"; -#if K3L_AT_LEAST(2,0,0) - case kdmE1GW640EX: return "640EX"; -#endif -#else - case kdmE1600V: return (count > 34 || count == 0 ? "600V" : "300V" ); - case kdmE1600EV: return (count > 34 || count == 0 ? "600EV" : "600EV"); -#endif - } - - throw internal_not_found(); -#endif - -#if K3L_AT_LEAST(1,6,0) - case kdtFXOVoIP: - switch ((KFXOVoIPDeviceModel)model) - { - case kdmFXGW180: return "180"; - } - - throw internal_not_found(); - -#elif K3L_AT_LEAST(1,4,0) - case kdtFXVoIP: - switch ((KFXVoIPDeviceModel)model) - { - case kdmFXO80V: return "80V"; - } - - throw internal_not_found(); -#endif - -#if K3L_AT_LEAST(1,5,0) - case kdtE1IP: - switch ((KE1IPDeviceModel)model) - { -#if K3L_AT_LEAST(1,6,0) - case kdmE1IP: return "E1IP"; -#if K3L_AT_LEAST(2,0,0) - case kdmE1IPEX: return "E1IPEX"; -#endif -#else - case kdmE1600EG: return (count > 90 || count == 0 ? "600EG" : "300EG"); -#endif - } - - throw internal_not_found(); -#endif - -#if K3L_AT_LEAST(1,5,1) - case kdtE1Spx: - switch ((KE1SpxDeviceModel)model) - { - case kdmE1Spx: return "SPX"; - case kdm2E1Based: return "SPX-2E1"; -#if K3L_AT_LEAST(2,0,0) - case kdmE1SpxEX: return "SPXEX"; -#endif - } - throw internal_not_found(); - - case kdtGWIP: - switch ((KGWIPDeviceModel)model) - { -#if K3L_AT_LEAST(1,6,0) - case kdmGWIP: return "GWIP"; -#if K3L_AT_LEAST(2,0,0) - case kdmGWIPEX: return "GWIPEX"; -#endif -#else - case kdmGW600G: return "600G"; - case kdmGW600EG: return "600EG"; -#endif - } - - throw internal_not_found(); -#endif - -#if K3L_AT_LEAST(1,6,0) - case kdtFXS: - switch ((KFXSDeviceModel)model) - { - case kdmFXS300: return (count > 30 || count == 0 ? "300" : "150"); -#if K3L_AT_LEAST(2,0,0) - case kdmFXS300EX: return (count > 30 || count == 0 ? "300EX" : "150EX"); -#endif - } - - throw internal_not_found(); - - case kdtFXSSpx: - switch ((KFXSSpxDeviceModel)model) - { - case kdmFXSSpx300: return (count > 30 || count == 0 ? "300-SPX" : "150-SPX"); - case kdmFXSSpx2E1Based: return "SPX-2E1"; -#if K3L_AT_LEAST(2,0,0) - case kdmFXSSpx300EX: return (count > 30 || count == 0 ? "300-SPXEX" : "150-SPXEX"); -#endif - } - - throw internal_not_found(); - - case kdtGSM: - switch ((KGSMDeviceModel)model) - { - case kdmGSM: - switch (count) - { - case 0: /* default */ - case 4: return "40"; - case 3: return "30"; - case 2: return "20"; - case 1: return "10"; - } - break; -#if K3L_AT_LEAST(2,0,0) - case kdmGSMEX: - switch (count) - { - case 0: /* default */ - case 4: return "40EX"; - case 3: return "80EX"; - case 2: return "20EX"; - case 1: return "10EX"; - } - break; -#endif - } - - throw internal_not_found(); - - case kdtGSMSpx: - switch ((KGSMSpxDeviceModel)model) - { - case kdmGSMSpx: - switch (count) - { - case 0: /* default */ - case 4: return "40"; - case 3: return "30"; - case 2: return "20"; - case 1: return "10"; - } - break; -#if K3L_AT_LEAST(2,0,0) - case kdmGSMSpxEX: - switch (count) - { - case 0: /* default */ - case 4: return "40-SPXEX"; - case 3: return "80-SPXEX"; - case 2: return "20-SPXEX"; - case 1: return "10-SPXEX"; - } - break; -#endif - } - - throw internal_not_found(); - -#if K3L_AT_LEAST(2,1,0) - case kdtGSMUSB: - switch ((KGSMUSBDeviceModel)model) - { - case kdmGSMUSB: return "20"; - } - - throw internal_not_found(); - - case kdtGSMUSBSpx: - switch ((KGSMUSBSpxDeviceModel)model) - { - case kdmGSMUSBSpx: return "SPX"; - } - - throw internal_not_found(); - - case kdtE1FXSSpx: - switch ((KGSMSpxDeviceModel)model) - { - case kdmE1FXSSpx: return "450-SPX"; - case kdmE1FXSSpxEX: return "450-SPXEX"; - } - - throw internal_not_found(); -#if K3L_AT_LEAST(2,2,0) - case kdtE1AdHoc: - switch((KE1AdHocModel)model) - { - case kdmE1AdHoc100: return "E1AdHoc100"; - case kdmE1AdHoc100E: return "E1AdHoc100E"; - case kdmE1AdHoc240: return "E1AdHoc240"; - case kdmE1AdHoc240E: return "E1AdHoc240E"; - case kdmE1AdHoc400: return "E1AdHoc240"; - case kdmE1AdHoc400E: return "E1AdHoc240E"; - } - throw internal_not_found(); -#endif - -#if K3L_EXACT(2,1,0) - case kdtReserved1: -#endif - case kdtDevTypeCount: - throw internal_not_found(); - -#endif -#endif - } - - throw internal_not_found(); -} - -std::string Verbose::signaling(const KSignaling sig, const Verbose::Presentation fmt) -{ - switch (sig) - { - case ksigInactive: return presentation(fmt, "ksigInactive", "Inactive"); - case ksigAnalog: return presentation(fmt, "ksigAnalog", "FXO (analog)"); - case ksigContinuousEM: return presentation(fmt, "ksigContinuousEM", "E+M Continuous"); - case ksigPulsedEM: return presentation(fmt, "ksigPulsedEM", "E+M PUlsed"); - case ksigOpenCAS: return presentation(fmt, "ksigOpenCAS", "Open CAS"); - case ksigOpenR2: return presentation(fmt, "ksigOpenR2", "Open R2"); - case ksigR2Digital: return presentation(fmt, "ksigR2Digital", "R2/MFC"); - case ksigUserR2Digital: return presentation(fmt, "ksigUserR2Digital", "R2/Other"); -#if K3L_AT_LEAST(1,4,0) - case ksigSIP: return presentation(fmt, "ksigSIP", "SIP"); -#endif - -#if K3L_AT_LEAST(1,5,1) - case ksigOpenCCS: return presentation(fmt, "ksigOpenCCS", "Open CCS"); - case ksigPRI_EndPoint: return presentation(fmt, "ksigPRI_EndPoint", "ISDN Endpoint"); - case ksigPRI_Network: return presentation(fmt, "ksigPRI_Network", "ISDN Network"); - case ksigPRI_Passive: return presentation(fmt, "ksigPRI_Passive", "ISDN Passive"); -#endif -#if K3L_AT_LEAST(1,5,3) - case ksigLineSide: return presentation(fmt, "ksigLineSide", "Line Side"); -#endif -#if K3L_AT_LEAST(1,6,0) - case ksigAnalogTerminal: return presentation(fmt, "ksigAnalogTerminal", "FXS (analog)"); - case ksigGSM: return presentation(fmt, "ksigGSM", "GSM"); - case ksigCAS_EL7: return presentation(fmt, "ksigCAS_EL7", "CAS EL7"); - case ksigE1LC: return presentation(fmt, "ksigE1LC", "E1 LC"); -#endif -#if K3L_AT_LEAST(2,1,0) - case ksigISUP: return presentation(fmt, "ksigISUP", "ISUP"); -#endif -#if K3L_EXACT(2,1,0) - case ksigFax: return presentation(fmt, "ksigFax", "Fax"); -#endif -#if K3L_AT_LEAST(2,2,0) - case ksigISUPPassive: return presentation(fmt, "ksigISUPPassive", "ISUP Passive"); -#endif - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KSignaling='%d']") % (int)sig), - STG(FMT("Unknown signaling (%d)") % (int)sig)); -} - -std::string Verbose::systemObject(const KSystemObject so, const Verbose::Presentation fmt) -{ - switch (so) - { - case ksoLink: return presentation(fmt, "ksoLink", "Link"); - case ksoLinkMon: return presentation(fmt, "ksoLinkMon", "Link Monitor"); - case ksoChannel: return presentation(fmt, "ksoChannel", "Channel"); -#if K3L_AT_LEAST(2,1,0) - case ksoGsmChannel:return presentation(fmt, "ksoGsmChannel","GsmChannel"); -#endif - case ksoH100: return presentation(fmt, "ksoH100", "H.100"); - case ksoFirmware: return presentation(fmt, "ksoFirmware", "Firmware"); - case ksoDevice: return presentation(fmt, "ksoDevice", "Device"); - case ksoAPI: return presentation(fmt, "ksoAPI", "Software Layer"); - } - - return presentation(fmt, - STG(FMT("[KSystemObject='%d']") % (int)so), - STG(FMT("Unknown object (%d)") % (int)so)); -} - -std::string Verbose::mixerTone(const KMixerTone mt, const Verbose::Presentation fmt) -{ - switch (mt) - { - case kmtSilence: return presentation(fmt, "kmtSilence", "Silence"); - case kmtDial: return presentation(fmt, "kmtDial", "Dialtone begin"); - case kmtEndOf425: return presentation(fmt, "kmtEndOf425", "Dialtone end"); - case kmtBusy: return presentation(fmt, "kmtBusy", "Busy"); - case kmtFax: return presentation(fmt, "kmtFax", "Fax"); - case kmtVoice: return presentation(fmt, "kmtVoice", "Voice"); -#if K3L_AT_LEAST(1,5,0) - case kmtCollect: return presentation(fmt, "kmtCollect", "Collect Call"); -#endif -#if K3L_AT_LEAST(1,5,1) - case kmtEndOfDtmf: return presentation(fmt, "kmtEndOfDtmf", "DTMF end"); -#endif - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KMixerTone='%d']") % (int)mt), - STG(FMT("Unknonwn tone (%d)") % (int)mt)); -} - -std::string Verbose::mixerSource(const KMixerSource ms, const Verbose::Presentation fmt) -{ - switch (ms) - { - case kmsChannel: return presentation(fmt, "kmsChannel", "Channel"); - case kmsPlay: return presentation(fmt, "kmsPlay", "Player"); - case kmsGenerator: return presentation(fmt, "kmsGenerator", "Generator"); - case kmsCTbus: return presentation(fmt, "kmsCTbus", "CT-bus"); -#if (K3L_AT_LEAST(1,4,0) && !K3L_AT_LEAST(1,6,0)) - case kmsVoIP: return presentation(fmt, "kmsVoIP", "VoIP"); -#endif -#if K3L_AT_LEAST(1,6,0) - case kmsNoDelayChannel: return presentation(fmt, "kmsNoDelayChannel", "No delay channel"); -#endif - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KMixerSource='%d']") % (int)ms), - STG(FMT("Unknonwn source (%d)") % (int)ms)); -} - -std::string Verbose::channelFeatures(const int32 flags, const Verbose::Presentation fmt) -{ - if (0x00 != flags) - { - Strings::Merger strs; - - if (kcfDtmfSuppression & flags) strs.add(presentation(fmt, "DtmfSuppression", "DTMF Suppression")); - if (kcfCallProgress & flags) strs.add(presentation(fmt, "CallProgress", "Call Progress")); - if (kcfPulseDetection & flags) strs.add(presentation(fmt, "PulseDetection", "Pulse Detection")); - if (kcfAudioNotification & flags) strs.add(presentation(fmt, "AudioNotification", "Audio Notification")); - if (kcfEchoCanceller & flags) strs.add(presentation(fmt, "EchoCanceller", "Echo Canceller")); - if (kcfAutoGainControl & flags) strs.add(presentation(fmt, "AutoGainControl", "Input AGC")); - if (kcfHighImpEvents & flags) strs.add(presentation(fmt, "HighImpEvents", "High Impedance Events")); -#if K3L_AT_LEAST(1,6,0) - if (kcfCallAnswerInfo & flags) strs.add(presentation(fmt, "CallAnswerInfo", "Call Answer Info")); - if (kcfOutputVolume & flags) strs.add(presentation(fmt, "OutputVolume", "Output Volume")); - if (kcfPlayerAGC & flags) strs.add(presentation(fmt, "PlayerAGC", "Player AGC")); -#endif - - return presentation(fmt, - STG(FMT("kcf{%s}") % strs.merge(",")), - STG(FMT("%s") % strs.merge(", "))); - }; - - PRESENTATION_CHECK_RETURN(fmt, "", "No features"); -} - -std::string Verbose::seizeFail(const KSeizeFail sf, const Verbose::Presentation fmt) -{ - switch (sf) - { - case ksfChannelLocked: return presentation(fmt, "ksfChannelLocked", "Channel Locked"); - case ksfChannelBusy: return presentation(fmt, "ksfChannelBusy", "Channel Busy"); - case ksfIncomingChannel: return presentation(fmt, "ksfIncomingChannel", "Incoming Channel"); - case ksfDoubleSeizure: return presentation(fmt, "ksfDoubleSeizure", "Double Seizure"); - case ksfCongestion: return presentation(fmt, "ksfCongestion", "Congestion"); - case ksfNoDialTone: return presentation(fmt, "ksfNoDialTone", "No Dial Tone"); - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KSeizeFail='%d']") % (int)sf), - STG(FMT("Unknown seize fail (%d)") % (int)sf)); -} - -#if K3L_AT_LEAST(1,5,0) -std::string Verbose::internal_sipFailures(const KSIP_Failures code, const Verbose::Presentation fmt) -{ - switch (code) - { -#if K3L_AT_LEAST(1,6,0) - case kveResponse_200_OK_Success: return presentation(fmt, "kveResponse_200_OK_Success", "200 OK"); -#endif - case kveRedirection_300_MultipleChoices: return presentation(fmt, "kveRedirection_300_MultipleChoices", "300 Multiple Choices"); - case kveRedirection_301_MovedPermanently: return presentation(fmt, "kveRedirection_301_MovedPermanently", "301 Moved Permanently"); - case kveRedirection_302_MovedTemporarily: return presentation(fmt, "kveRedirection_302_MovedTemporarily", "302 Moved Temporarily"); - case kveRedirection_305_UseProxy: return presentation(fmt, "kveRedirection_305_UseProxy", "305 Use Proxy"); - case kveRedirection_380_AlternativeService: return presentation(fmt, "kveRedirection_380_AlternativeService", "380 Alternate Service"); - case kveFailure_400_BadRequest: return presentation(fmt, "kveFailure_400_BadRequest", "400 Bad Request"); - case kveFailure_401_Unauthorized: return presentation(fmt, "kveFailure_401_Unauthorized", "401 Unauthorized"); - case kveFailure_402_PaymentRequired: return presentation(fmt, "kveFailure_402_PaymentRequired", "402 Payment Required"); - case kveFailure_403_Forbidden: return presentation(fmt, "kveFailure_403_Forbidden", "403 Forbidden"); - case kveFailure_404_NotFound: return presentation(fmt, "kveFailure_404_NotFound", "404 Not Found"); - case kveFailure_405_MethodNotAllowed: return presentation(fmt, "kveFailure_405_MethodNotAllowed", "405 Method Not Allowed"); - case kveFailure_406_NotAcceptable: return presentation(fmt, "kveFailure_406_NotAcceptable", "406 Not Acceptable"); - case kveFailure_407_ProxyAuthenticationRequired: return presentation(fmt, "kveFailure_407_ProxyAuthenticationRequired", "407 Proxy Authentication Required"); - case kveFailure_408_RequestTimeout: return presentation(fmt, "kveFailure_408_RequestTimeout", "408 Request Timeout"); - case kveFailure_410_Gone: return presentation(fmt, "kveFailure_410_Gone", "410 Gone"); - case kveFailure_413_RequestEntityTooLarge: return presentation(fmt, "kveFailure_413_RequestEntityTooLarge", "413 Request Entity Too Large"); - case kveFailure_414_RequestURI_TooLong: return presentation(fmt, "kveFailure_414_RequestURI_TooLong", "414 Request URI Too Long"); - case kveFailure_415_UnsupportedMediaType: return presentation(fmt, "kveFailure_415_UnsupportedMediaType", "415 Unsupported Media Type"); - case kveFailure_416_UnsupportedURI_Scheme: return presentation(fmt, "kveFailure_416_UnsupportedURI_Scheme", "416 Unsupported URI Scheme"); - case kveFailure_420_BadExtension: return presentation(fmt, "kveFailure_420_BadExtension", "420 Bad Extension"); - case kveFailure_421_ExtensionRequired: return presentation(fmt, "kveFailure_421_ExtensionRequired", "421 Extension Required"); - case kveFailure_423_IntervalTooBrief: return presentation(fmt, "kveFailure_423_IntervalTooBrief", "423 Internal Too Brief"); - case kveFailure_480_TemporarilyUnavailable: return presentation(fmt, "kveFailure_480_TemporarilyUnavailable", "480 Temporarily Unavailable"); - case kveFailure_481_CallDoesNotExist: return presentation(fmt, "kveFailure_481_CallDoesNotExist", "481 Call Does Not Exist"); - case kveFailure_482_LoopDetected: return presentation(fmt, "kveFailure_482_LoopDetected", "482 Loop Detected"); - case kveFailure_483_TooManyHops: return presentation(fmt, "kveFailure_483_TooManyHops", "483 Too Many Hops"); - case kveFailure_484_AddressIncomplete: return presentation(fmt, "kveFailure_484_AddressIncomplete", "484 Address Incomplete"); - case kveFailure_485_Ambiguous: return presentation(fmt, "kveFailure_485_Ambiguous", "485 Ambiguous"); - case kveFailure_486_BusyHere: return presentation(fmt, "kveFailure_486_BusyHere", "486 Busy Here"); - case kveFailure_487_RequestTerminated: return presentation(fmt, "kveFailure_487_RequestTerminated", "487 Request Terminated"); - case kveFailure_488_NotAcceptableHere: return presentation(fmt, "kveFailure_488_NotAcceptableHere", "488 Not Acceptable Here"); - case kveFailure_491_RequestPending: return presentation(fmt, "kveFailure_491_RequestPending", "491 Request Pending"); - case kveFailure_493_Undecipherable: return presentation(fmt, "kveFailure_493_Undecipherable", "493 Undecipherable"); - case kveServer_500_InternalError: return presentation(fmt, "kveServer_500_InternalError", "500 Internal Error"); - case kveServer_501_NotImplemented: return presentation(fmt, "kveServer_501_NotImplemented", "501 Not Implemented"); - case kveServer_502_BadGateway: return presentation(fmt, "kveServer_502_BadGateway", "502 Bad Gateway"); - case kveServer_503_ServiceUnavailable: return presentation(fmt, "kveServer_503_ServiceUnavailable", "503 Service Unavailable"); - case kveServer_504_TimeOut: return presentation(fmt, "kveServer_504_TimeOut", "504 Timed Out"); - case kveServer_505_VersionNotSupported: return presentation(fmt, "kveServer_505_VersionNotSupported", "505 Version Not Supported"); - case kveServer_513_MessageTooLarge: return presentation(fmt, "kveServer_513_MessageTooLarge", "513 Message Too Large"); - case kveGlobalFailure_600_BusyEverywhere: return presentation(fmt, "kveGlobalFailure_600_BusyEverywhere", "600 Busy Everywhere"); - case kveGlobalFailure_603_Decline: return presentation(fmt, "kveGlobalFailure_603_Decline", "603 Decline"); - case kveGlobalFailure_604_DoesNotExistAnywhere: return presentation(fmt, "kveGlobalFailure_604_DoesNotExistAnywhere", "604 Does Not Exist Anywhere"); - case kveGlobalFailure_606_NotAcceptable: return presentation(fmt, "kveGlobalFailure_606_NotAcceptable", "606 Not Acceptable"); - } - - throw internal_not_found(); -} - -std::string Verbose::sipFailures(const KSIP_Failures code, const Verbose::Presentation fmt) -{ - try - { - return internal_sipFailures(code, fmt); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KSIP_Failures='%d']") % (int)code), - STG(FMT("Unknown SIP failure (%d)") % (int)code)); - } -} - -#endif - -#if K3L_AT_LEAST(1,5,1) -std::string Verbose::internal_isdnCause(const KQ931Cause code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kq931cNone: return presentation(fmt, "kq931cNone", "None"); - case kq931cUnallocatedNumber: return presentation(fmt, "kq931cUnallocatedNumber", "Unallocated number"); - case kq931cNoRouteToTransitNet: return presentation(fmt, "kq931cNoRouteToTransitNet", "No route to transmit to network"); - case kq931cNoRouteToDest: return presentation(fmt, "kq931cNoRouteToDest", "No route to destination"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cSendSpecialInfoTone: return presentation(fmt, "kq931cSendSpecialInfoTone", "Send special information tone"); - case kq931cMisdialedTrunkPrefix: return presentation(fmt, "kq931cMisdialedTrunkPrefix", "Misdialed trunk prefix"); -#endif - case kq931cChannelUnacceptable: return presentation(fmt, "kq931cChannelUnacceptable", "Channel unacceptable"); - case kq931cCallAwarded: return presentation(fmt, "kq931cCallAwarded", "Call awarded"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cPreemption: return presentation(fmt, "kq931cPreemption", "Preemption"); - case kq931cPreemptionCircuitReuse: return presentation(fmt, "kq931cPreemptionCircuitReuse", "Preemption circuit reuse"); - case kq931cQoR_PortedNumber: return presentation(fmt, "kq931cQoR_PortedNumber", "QoR ported number"); -#endif - case kq931cNormalCallClear: return presentation(fmt, "kq931cNormalCallClear", "Normal call clear"); - case kq931cUserBusy: return presentation(fmt, "kq931cUserBusy", "User busy"); - case kq931cNoUserResponding: return presentation(fmt, "kq931cNoUserResponding", "No user responding"); - case kq931cNoAnswerFromUser: return presentation(fmt, "kq931cNoAnswerFromUser", "No answer from user"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cSubscriberAbsent: return presentation(fmt, "kq931cSubscriberAbsent", "Subscriber absent"); -#endif - case kq931cCallRejected: return presentation(fmt, "kq931cCallRejected", "Call rejected"); - case kq931cNumberChanged: return presentation(fmt, "kq931cNumberChanged", "Number changed"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cRedirectionToNewDest: return presentation(fmt, "kq931cRedirectionToNewDest", "Redirection to new destination"); - case kq931cCallRejectedFeatureDest: return presentation(fmt, "kq931cCallRejectedFeatureDest", "Call rejected feature destination"); - case kq931cExchangeRoutingError: return presentation(fmt, "kq931cExchangeRoutingError", "Exchange routing error"); -#endif - case kq931cNonSelectedUserClear: return presentation(fmt, "kq931cNonSelectedUserClear", "Non selected user clear"); - case kq931cDestinationOutOfOrder: return presentation(fmt, "kq931cDestinationOutOfOrder", "Destination out of order"); - case kq931cInvalidNumberFormat: return presentation(fmt, "kq931cInvalidNumberFormat", "Invalid number format"); - case kq931cFacilityRejected: return presentation(fmt, "kq931cFacilityRejected", "Facility rejected"); - case kq931cRespStatusEnquiry: return presentation(fmt, "kq931cRespStatusEnquiry", "Response status enquiry"); - case kq931cNormalUnspecified: return presentation(fmt, "kq931cNormalUnspecified", "Normal unespecified"); - case kq931cNoCircuitChannelAvail: return presentation(fmt, "kq931cNoCircuitChannelAvail", "No circuit channel available"); - case kq931cNetworkOutOfOrder: return presentation(fmt, "kq931cNetworkOutOfOrder", "Network out of order"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cPermanentFrameConnOutOfService: return presentation(fmt, "kq931cPermanentFrameConnOutOfService", "Permanent frame connection out of service"); - case kq931cPermanentFrameConnOperational: return presentation(fmt, "kq931cPermanentFrameConnOperational", "Permanent frame connection operational"); -#endif - case kq931cTemporaryFailure: return presentation(fmt, "kq931cTemporaryFailure", "Temporary failure"); - case kq931cSwitchCongestion: return presentation(fmt, "kq931cSwitchCongestion", "Switch congestion"); - case kq931cAccessInfoDiscarded: return presentation(fmt, "kq931cAccessInfoDiscarded", "Access information discarded"); - case kq931cRequestedChannelUnav: return presentation(fmt, "kq931cRequestedChannelUnav", "Requested channel unavailable"); - case kq931cPrecedenceCallBlocked: return presentation(fmt, "kq931cPrecedenceCallBlocked", "Precedence call blocked"); - case kq931cResourceUnavailable: return presentation(fmt, "kq931cResourceUnavailable", "Request resource unavailable"); - case kq931cQosUnavailable: return presentation(fmt, "kq931cQosUnavailable", "QoS unavailable"); - case kq931cReqFacilityNotSubsc: return presentation(fmt, "kq931cReqFacilityNotSubsc", "Request facility not subscribed"); - case kq931cOutCallsBarredWithinCUG: return presentation(fmt, "kq931cOutCallsBarredWithinCUG", "Out calls barred within UG"); - case kq931cInCallsBarredWithinCUG: return presentation(fmt, "kq931cInCallsBarredWithinCUG", "In calls barred within UG"); - case kq931cBearerCapabNotAuthor: return presentation(fmt, "kq931cBearerCapabNotAuthor", "Bearer capability not authorized"); - case kq931cBearerCapabNotAvail: return presentation(fmt, "kq931cBearerCapabNotAvail", "Bearer capability not available"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cInconsistency: return presentation(fmt, "kq931cInconsistency", "Inconsistency"); -#endif - case kq931cServiceNotAvailable: return presentation(fmt, "kq931cServiceNotAvailable", "Service not available"); - case kq931cBcNotImplemented: return presentation(fmt, "kq931cBcNotImplemented", "Bearer capability not implemented"); - case kq931cChannelTypeNotImplem: return presentation(fmt, "kq931cChannelTypeNotImplem", "Channel type not implemented"); - case kq931cReqFacilityNotImplem: return presentation(fmt, "kq931cReqFacilityNotImplem", "Request facility not implemented"); - case kq931cOnlyRestrictedBcAvail: return presentation(fmt, "kq931cOnlyRestrictedBcAvail", "Only restricted bearer capability available"); - case kq931cServiceNotImplemented: return presentation(fmt, "kq931cServiceNotImplemented", "Service not implemented"); - case kq931cInvalidCrv: return presentation(fmt, "kq931cInvalidCrv", "Invalid call reference value"); - case kq931cChannelDoesNotExist: return presentation(fmt, "kq931cChannelDoesNotExist", "Channel does not exist"); - case kq931cCallIdDoesNotExist: return presentation(fmt, "kq931cCallIdDoesNotExist", "Call identification does not exist"); - case kq931cCallIdInUse: return presentation(fmt, "kq931cCallIdInUse", "Call identification in use"); - case kq931cNoCallSuspended: return presentation(fmt, "kq931cNoCallSuspended", "No call suspended"); - case kq931cCallIdCleared: return presentation(fmt, "kq931cCallIdCleared", "Call identification cleared"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cUserNotMemberofCUG: return presentation(fmt, "kq931cUserNotMemberofCUG", "User not member of UG"); -#endif - case kq931cIncompatibleDestination: return presentation(fmt, "kq931cIncompatibleDestination", "Incompatible destination"); - case kq931cInvalidTransitNetSel: return presentation(fmt, "kq931cInvalidTransitNetSel", "Invalid transit network selected"); - case kq931cInvalidMessage: return presentation(fmt, "kq931cInvalidMessage", "Invalid message"); - case kq931cMissingMandatoryIe: return presentation(fmt, "kq931cMissingMandatoryIe", "Missing mandatory information element"); - case kq931cMsgTypeNotImplemented: return presentation(fmt, "kq931cMsgTypeNotImplemented", "Message type not implemented"); - case kq931cMsgIncompatWithState: return presentation(fmt, "kq931cMsgIncompatWithState", "Message incompatible with state"); - case kq931cIeNotImplemented: return presentation(fmt, "kq931cIeNotImplemented", "Information element not implemented"); - case kq931cInvalidIe: return presentation(fmt, "kq931cInvalidIe", "Invalid information element"); - case kq931cMsgIncompatWithState2: return presentation(fmt, "kq931cMsgIncompatWithState2", "Message incompatible with state (2)"); - case kq931cRecoveryOnTimerExpiry: return presentation(fmt, "kq931cRecoveryOnTimerExpiry", "Recovery on timer expiry"); - case kq931cProtocolError: return presentation(fmt, "kq931cProtocolError", "Protocol error"); -#if 1 /* this changed during K3L 1.6.0 development cycle... */ - case kq931cMessageWithUnrecognizedParam: return presentation(fmt, "kq931cMessageWithUnrecognizedParam", "Message with unrecognized parameters"); - case kq931cProtocolErrorUnspecified: return presentation(fmt, "kq931cProtocolErrorUnspecified", "Protocol error unspecified"); -#endif - case kq931cInterworking: return presentation(fmt, "kq931cInterworking", "Interworking"); - case kq931cCallConnected: return presentation(fmt, "kq931cCallConnected", "Call connected"); - case kq931cCallTimedOut: return presentation(fmt, "kq931cCallTimedOut", "Call timeout"); - case kq931cCallNotFound: return presentation(fmt, "kq931cCallNotFound", "Call not found"); - case kq931cCantReleaseCall: return presentation(fmt, "kq931cCantReleaseCall", "Cannot realese call"); - case kq931cNetworkFailure: return presentation(fmt, "kq931cNetworkFailure", "Network failure"); - case kq931cNetworkRestart: return presentation(fmt, "kq931cNetworkRestart", "Network restart"); - } - - throw internal_not_found(); -} - -std::string Verbose::isdnCause(const KQ931Cause code, const Verbose::Presentation fmt) -{ - try - { - return internal_isdnCause(code); - } - catch (internal_not_found e) - { - return STG(FMT("[KQ931Cause='%d']") % (int)code); - } -} -#endif - -#if K3L_AT_LEAST(1,5,2) -std::string Verbose::isdnDebug(const int32 flags, const Verbose::Presentation fmt) -{ - if (0x00 != flags) - { - Strings::Merger strs; - - if (flags & kidfQ931) strs.add("Q931"); - if (flags & kidfLAPD) strs.add("LAPD"); - if (flags & kidfSystem) strs.add("System"); - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("kidf{%s}") % strs.merge(",")), - strs.merge(", ")); - } - - return presentation(fmt, "", "No debug active"); -} -#endif - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::internal_signGroupB(const KSignGroupB group, const R2CountryType country, const Verbose::Presentation fmt) -#else -std::string Verbose::internal_signGroupB(const KSignGroupB group, const Verbose::Presentation fmt) -#endif -{ -#if K3L_AT_LEAST(2,0,0) - switch (country) - { - case R2_COUNTRY_ARG: - switch ((KSignGroupB_Argentina)group) - { - case kgbArNumberChanged: return presentation(fmt, "kgbArNumberChanged", "Number Changed"); - case kgbArBusy: return presentation(fmt, "kgbArBusy", "Busy"); - case kgbArCongestion: return presentation(fmt, "kgbArCongestion", "Congestion"); - case kgbArInvalidNumber: return presentation(fmt, "kgbArInvalidNumber", "Invalid Number"); - case kgbArLineFreeCharged: return presentation(fmt, "kgbArLineFreeCharged", "Line Free Charged"); - case kgbArLineFreeNotCharged: return presentation(fmt, "kgbArLineFreeNotCharged", "Line Free Not Charged"); - case kgbArLineOutOfOrder: return presentation(fmt, "kgbArLineOutOfOrder", "Line Out Of Order"); - case kgbArNone: return presentation(fmt, "kgbArNone", "None"); - } - break; - - case R2_COUNTRY_BRA: - switch ((KSignGroupB_Brazil)group) - { - case kgbBrLineFreeCharged: return presentation(fmt, "kgbBrLineFreeCharged", "Line Free Charged"); - case kgbBrLineFreeNotCharged: return presentation(fmt, "kgbBrLineFreeNotCharged", "Line Free Not Charged"); - case kgbBrLineFreeChargedLPR: return presentation(fmt, "kgbBrLineFreeChargedLPR", "Line Free Charged PLR"); - case kgbBrBusy: return presentation(fmt, "kgbBrBusy", "Busy"); - case kgbBrNumberChanged: return presentation(fmt, "kgbBrNumberChanged", "Number Changed"); - case kgbBrCongestion: return presentation(fmt, "kgbBrCongestion", "Congestion"); - case kgbBrInvalidNumber: return presentation(fmt, "kgbBrInvalidNumber", "Invalid Number"); - case kgbBrLineOutOfOrder: return presentation(fmt, "kgbBrLineOutOfOrder", "Line Out Of Order"); - case kgbBrNone: return presentation(fmt, "kgbBrNone", "None"); - } - break; - - case R2_COUNTRY_CHI: - switch ((KSignGroupB_Chile)group) - { - case kgbClNumberChanged: return presentation(fmt, "kgbClNumberChanged", "Number Changed"); - case kgbClBusy: return presentation(fmt, "kgbClBusy", "Busy"); - case kgbClCongestion: return presentation(fmt, "kgbClCongestion", "Congestion"); - case kgbClInvalidNumber: return presentation(fmt, "kgbClInvalidNumber", "Invalid Number"); - case kgbClLineFreeCharged: return presentation(fmt, "kgbClLineFreeCharged", "Line Free Charged"); - case kgbClLineFreeNotCharged: return presentation(fmt, "kgbClLineFreeNotCharged", "Line Free Not Charged"); - case kgbClLineOutOfOrder: return presentation(fmt, "kgbClLineOutOfOrder", "Line Out Of Order"); - case kgbClNone: return presentation(fmt, "kgbClNone", "None"); - } - break; - - case R2_COUNTRY_MEX: - switch ((KSignGroupB_Mexico)group) - { - case kgbMxLineFreeCharged: return presentation(fmt, "kgbMxLineFreeCharged", "Line Free Charged"); - case kgbMxBusy: return presentation(fmt, "kgbMxBusy", "Busy"); - case kgbMxLineFreeNotCharged: return presentation(fmt, "kgbMxLineFreeNotCharged", "Line Free Not Charged"); - case kgbMxNone: return presentation(fmt, "kgbMxNone", "None"); - } - break; - - case R2_COUNTRY_URY: - switch ((KSignGroupB_Uruguay)group) - { - case kgbUyNumberChanged: return presentation(fmt, "kgbUyNumberChanged", "Number Changed"); - case kgbUyBusy: return presentation(fmt, "kgbUyBusy", "Busy"); - case kgbUyCongestion: return presentation(fmt, "kgbUyCongestion", "Congestion"); - case kgbUyInvalidNumber: return presentation(fmt, "kgbUyInvalidNumber", "Invalid Number"); - case kgbUyLineFreeCharged: return presentation(fmt, "kgbUyLineFreeCharged", "Line Free Charged"); - case kgbUyLineFreeNotCharged: return presentation(fmt, "kgbUyLineFreeNotCharged", "Line Free Not Charged"); - case kgbUyLineOutOfOrder: return presentation(fmt, "kgbUyLineOutOfOrder", "Line Out Of Order"); - case kgbUyNone: return presentation(fmt, "kgbUyNone", "None"); - } - break; - - case R2_COUNTRY_VEN: - switch ((KSignGroupB_Venezuela)group) - { - case kgbVeLineFreeChargedLPR: return presentation(fmt, "kgbVeLineFreeChargedLPR", "Line Free Charged PLR"); - case kgbVeNumberChanged: return presentation(fmt, "kgbVeNumberChanged", "Number Changed"); - case kgbVeBusy: return presentation(fmt, "kgbVeBusy", "Busy"); - case kgbVeCongestion: return presentation(fmt, "kgbVeCongestion", "Congestion"); - case kgbVeInformationTone: return presentation(fmt, "kgbVeInformationTone", "Information Tone"); - case kgbVeLineFreeCharged: return presentation(fmt, "kgbVeLineFreeCharged", "Line Free Charged"); - case kgbVeLineFreeNotCharged: return presentation(fmt, "kgbVeLineFreeNotCharged", "Line Free Not Charged"); - case kgbVeLineBlocked: return presentation(fmt, "kgbVeLineBlocked", "Line Blocked"); - case kgbVeIntercepted: return presentation(fmt, "kgbVeIntercepted", "Intercepted"); - case kgbVeDataTrans: return presentation(fmt, "kgbVeDataTrans", "Data Transfer"); - case kgbVeNone: return presentation(fmt, "kgbVeNone", "None"); - } - break; - } -#else - switch ((KSignGroupB)group) - { - case kgbLineFreeCharged: return presentation(fmt, "kgbLineFreeCharged", "Line Free Charged"); - case kgbLineFreeNotCharged: return presentation(fmt, "kgbLineFreeNotCharged", "Line Free Not Charged"); - case kgbLineFreeChargedLPR: return presentation(fmt, "kgbLineFreeChargedLPR", "Line Free Charged PLR"); - case kgbBusy: return presentation(fmt, "kgbBusy", "Busy"); - case kgbNumberChanged: return presentation(fmt, "kgbNumberChanged", "Number Changed"); - case kgbCongestion: return presentation(fmt, "kgbCongestion", "Congestion"); - case kgbInvalidNumber: return presentation(fmt, "kgbInvalidNumber", "Invalid Number"); - case kgbLineOutOfOrder: return presentation(fmt, "kgbLineOutOfOrder", "Line Out Of Order"); - case kgbNone: return presentation(fmt, "kgbNone", "None"); - } -#endif - - throw internal_not_found(); -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::signGroupB(const KSignGroupB group, const R2CountryType r2_country, const Verbose::Presentation fmt) -#else -std::string Verbose::signGroupB(const KSignGroupB group, const Verbose::Presentation fmt) -#endif -{ - try - { -#if K3L_AT_LEAST(2,0,0) - return internal_signGroupB(group, r2_country, fmt); -#else - return internal_signGroupB(group, fmt); -#endif - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KSignGroupB='%d']") % (int)group), - STG(FMT("Unknown group B (%d)") % (int)group)); - } -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::internal_signGroupII(const KSignGroupII group, const R2CountryType country, const Verbose::Presentation fmt) -#else -std::string Verbose::internal_signGroupII(const KSignGroupII group, const Verbose::Presentation fmt) -#endif -{ -#if K3L_AT_LEAST(2,0,0) - switch (country) - { - case R2_COUNTRY_ARG: - switch ((KSignGroupII_Argentina)group) - { - case kg2ArOrdinary: return presentation(fmt, "kg2ArOrdinary", "Ordinary"); - case kg2ArPriority: return presentation(fmt, "kg2ArPriority", "Priority"); - case kg2ArMaintenance: return presentation(fmt, "kg2ArMaintenance", "Maintenance"); - case kg2ArLocalPayPhone: return presentation(fmt, "kg2ArLocalPayPhone", "Local pay phone"); - case kg2ArTrunkOperator: return presentation(fmt, "kg2ArTrunkOperator", "Trunk operator"); - case kg2ArDataTrans: return presentation(fmt, "kg2ArDataTrans", "Data transfer"); - case kg2ArCPTP: return presentation(fmt, "kg2ArCPTP", "CPTP"); - case kg2ArSpecialLine: return presentation(fmt, "kg2ArSpecialLine", "Special line"); - case kg2ArMobileUser: return presentation(fmt, "kg2ArMobileUser", "Mobile user"); - case kg2ArPrivateRedLine: return presentation(fmt, "kg2ArPrivateRedLine", "Private red line"); - case kg2ArSpecialPayPhoneLine: return presentation(fmt, "kg2ArSpecialPayPhoneLine", "Special pay phone line"); - } - break; - - case R2_COUNTRY_BRA: - switch ((KSignGroupII_Brazil)group) - { - case kg2BrOrdinary: return presentation(fmt, "kg2BrOrdinary", "Ordinary"); - case kg2BrPriority: return presentation(fmt, "kg2BrPriority", "Priority"); - case kg2BrMaintenance: return presentation(fmt, "kg2BrMaintenance", "Maintenance"); - case kg2BrLocalPayPhone: return presentation(fmt, "kg2BrLocalPayPhone", "Local pay phone"); - case kg2BrTrunkOperator: return presentation(fmt, "kg2BrTrunkOperator", "Trunk operator"); - case kg2BrDataTrans: return presentation(fmt, "kg2BrDataTrans", "Data transfer"); - case kg2BrNonLocalPayPhone: return presentation(fmt, "kg2BrNonLocalPayPhone", "Non local pay phone"); - case kg2BrCollectCall: return presentation(fmt, "kg2BrCollectCall", "Collect call"); - case kg2BrOrdinaryInter: return presentation(fmt, "kg2BrOrdinaryInter", "Ordinary international"); - case kg2BrTransfered: return presentation(fmt, "kg2BrTransfered", "Transfered"); - } - break; - - case R2_COUNTRY_CHI: - switch ((KSignGroupII_Chile)group) - { - case kg2ClOrdinary: return presentation(fmt, "kg2ClOrdinary", "Ordinary"); - case kg2ClPriority: return presentation(fmt, "kg2ClPriority", "Priority"); - case kg2ClMaintenance: return presentation(fmt, "kg2ClMaintenance", "Maintenance"); - case kg2ClTrunkOperator: return presentation(fmt, "kg2ClTrunkOperator", "Trunk operator"); - case kg2ClDataTrans: return presentation(fmt, "kg2ClDataTrans", "Data transfer"); - case kg2ClUnidentifiedSubscriber: return presentation(fmt, "kg2ClUnidentifiedSubscriber", "Unidentified subscriber"); - } - break; - - case R2_COUNTRY_MEX: - switch ((KSignGroupII_Mexico)group) - { - case kg2MxTrunkOperator: return presentation(fmt, "kg2MxTrunkOperator", "Trunk operator"); - case kg2MxOrdinary: return presentation(fmt, "kg2MxOrdinary", "Ordinary"); - case kg2MxMaintenance: return presentation(fmt, "kg2MxMaintenance", "Maintenance"); - } - break; - - case R2_COUNTRY_URY: - switch ((KSignGroupII_Uruguay)group) - { - case kg2UyOrdinary: return presentation(fmt, "kg2UyOrdinary", "Ordinary"); - case kg2UyPriority: return presentation(fmt, "kg2UyPriority", "Priority"); - case kg2UyMaintenance: return presentation(fmt, "kg2UyMaintenance", "Maintenance"); - case kg2UyLocalPayPhone: return presentation(fmt, "kg2UyLocalPayPhone", "Local pay phone"); - case kg2UyTrunkOperator: return presentation(fmt, "kg2UyTrunkOperator", "Trunk operator"); - case kg2UyDataTrans: return presentation(fmt, "kg2UyDataTrans", "Data transfer"); - case kg2UyInternSubscriber: return presentation(fmt, "kg2UyInternSubscriber", "International subscriber"); - } - break; - - case R2_COUNTRY_VEN: - switch ((KSignGroupII_Venezuela)group) - { - case kg2VeOrdinary: return presentation(fmt, "kg2VeOrdinary", "Ordinary"); - case kg2VePriority: return presentation(fmt, "kg2VePriority", "Priority"); - case kg2VeMaintenance: return presentation(fmt, "kg2VeMaintenance", "Maintenance"); - case kg2VeLocalPayPhone: return presentation(fmt, "kg2VeLocalPayPhone", "Local pay phone"); - case kg2VeTrunkOperator: return presentation(fmt, "kg2VeTrunkOperator", "Trunk operator"); - case kg2VeDataTrans: return presentation(fmt, "kg2VeDataTrans", "Data transfer"); - case kg2VeNoTransferFacility: return presentation(fmt, "kg2VeNoTransferFacility", "No transfer facility"); - } - break; - } -#else - switch ((KSignGroupII)group) - { - case kg2Ordinary: return presentation(fmt, "kg2Ordinary", "Ordinary"); - case kg2Priority: return presentation(fmt, "kg2Priority", "Priority"); - case kg2Maintenance: return presentation(fmt, "kg2Maintenance", "Maintenance"); - case kg2LocalPayPhone: return presentation(fmt, "kg2LocalPayPhone", "Local pay phone"); - case kg2TrunkOperator: return presentation(fmt, "kg2TrunkOperator", "Trunk operator"); - case kg2DataTrans: return presentation(fmt, "kg2DataTrans", "Data transfer"); - case kg2NonLocalPayPhone: return presentation(fmt, "kg2NonLocalPayPhone", "Non local pay phone"); - case kg2CollectCall: return presentation(fmt, "kg2CollectCall", "Collect call"); - case kg2OrdinaryInter: return presentation(fmt, "kg2OrdinaryInter", "Ordinary international"); - case kg2Transfered: return presentation(fmt, "kg2Transfered", "Transfered"); - } -#endif - - throw internal_not_found(); -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::signGroupII(const KSignGroupII group, const R2CountryType r2_country, const Verbose::Presentation fmt) -#else -std::string Verbose::signGroupII(const KSignGroupII group, const Verbose::Presentation fmt) -#endif -{ - try - { -#if K3L_AT_LEAST(2,0,0) - return internal_signGroupII(group, r2_country); -#else - return internal_signGroupII(group); -#endif - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KSignGroupII='%d']") % (int)group), - STG(FMT("Unknown group II (%d)") % (int)group)); - } -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::callFail(const KSignaling sig, const R2CountryType country, const int32 info, const Verbose::Presentation fmt) -#else -std::string Verbose::callFail(const KSignaling sig, const int32 info, const Verbose::Presentation fmt) -#endif -{ - try - { - switch (sig) - { - case ksigInactive: - throw internal_not_found(); - - case ksigAnalog: - if (('a' <= ((char)info) && 'z' >= ((char)info)) || ('A' <= ((char)info) && 'Z' >= ((char)info))) - return STG(FMT("%c") % (char)info); - else - throw internal_not_found(); - -#if K3L_AT_LEAST(1,5,4) - case ksigLineSide: -#endif -#if K3L_EXACT(2,1,0) - case ksigISUP: -#if !K3L_AT_LEAST(2,2,0) - case ksigFax: -#endif -#endif -#if K3L_AT_LEAST(1,6,0) - case ksigCAS_EL7: - case ksigE1LC: - return "NOT IMPLEMENTED"; - - case ksigAnalogTerminal: -#endif - case ksigContinuousEM: - case ksigPulsedEM: - - case ksigR2Digital: - case ksigOpenR2: -#if K3L_AT_LEAST(2,0,0) - return internal_signGroupB((KSignGroupB)info, country); -#else - return internal_signGroupB((KSignGroupB)info); -#endif - - case ksigOpenCAS: - case ksigUserR2Digital: -#if K3L_AT_LEAST(2,0,0) - return internal_signGroupB((KSignGroupB)info, R2_COUNTRY_BRA); -#else - return internal_signGroupB((KSignGroupB)info); -#endif - -#if K3L_AT_LEAST(1,5,0) - case ksigSIP: - return internal_sipFailures((KSIP_Failures)info); -#endif - -#if K3L_AT_LEAST(1,5,1) - case ksigOpenCCS: - case ksigPRI_EndPoint: - case ksigPRI_Network: - case ksigPRI_Passive: -#if K3L_AT_LEAST(2,2,0) - case ksigISUP: - case ksigISUPPassive: -#endif - return internal_isdnCause((KQ931Cause)info); -#endif - -#if K3L_AT_LEAST(1,6,0) - case ksigGSM: - return internal_gsmCallCause((KGsmCallCause)info); -#endif - } - } - catch (internal_not_found e) - { - /* this exception is used for breaking the control flow */ - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[%s, callFail='%d']") % signaling(sig, fmt) % (int)info), - STG(FMT("Unknown call fail code for '%s' (%d)") % signaling(sig, fmt) % (int)info)); -} - -std::string Verbose::channelFail(const KSignaling sig, const int32 code, const Verbose::Presentation fmt) -{ - try - { - switch (sig) - { - case ksigInactive: - case ksigAnalog: - case ksigSIP: -#if K3L_EXACT(2,1,0) - case ksigISUP: -#if !K3L_AT_LEAST(2,2,0) - case ksigFax: -#endif -#endif - throw internal_not_found(); - -#if K3L_AT_LEAST(1,6,0) - case ksigGSM: - return internal_gsmMobileCause((KGsmMobileCause)code); - - case ksigAnalogTerminal: - case ksigCAS_EL7: - case ksigE1LC: -#endif - - case ksigContinuousEM: - case ksigPulsedEM: - - case ksigLineSide: - - case ksigOpenCAS: - case ksigOpenR2: - case ksigR2Digital: - case ksigUserR2Digital: - switch ((KChannelFail)code) - { - case kfcRemoteFail: return presentation(fmt, "kfcRemoteFail", "Remote failure"); - case kfcLocalFail: return presentation(fmt, "kfcLocalFail", "Local failure"); - case kfcRemoteLock: return presentation(fmt, "kfcRemoteLock", "Remote lock"); - case kfcLineSignalFail: return presentation(fmt, "kfcLineSignalFail", "Line signal failure"); - case kfcAcousticSignalFail: return presentation(fmt, "kfcAcousticSignalFail", "Acoustic signal failure"); - } - - throw internal_not_found(); - -#if K3L_AT_LEAST(1,5,1) - case ksigOpenCCS: - case ksigPRI_EndPoint: - case ksigPRI_Network: - case ksigPRI_Passive: -#if K3L_AT_LEAST(2,2,0) - case ksigISUP: - case ksigISUPPassive: -#endif - return internal_isdnCause((KQ931Cause)code); -#endif - } - } - catch (internal_not_found e) - { - /* this exception is used for breaking the control flow */ - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[%s, channelFail='%d']") % signaling(sig, fmt) % (int)code), - STG(FMT("Unknown channel fail code for '%s' (%d)") % signaling(sig, fmt) % (int)code)); -} - -std::string Verbose::internalFail(const KInternalFail inf, const Verbose::Presentation fmt) -{ - switch (inf) - { - case kifInterruptCtrl: return presentation(fmt, "kifInterruptCtrl", "Interrupt control"); - case kifCommunicationFail: return presentation(fmt, "kifCommunicationFail", "Communication failure"); - case kifProtocolFail: return presentation(fmt, "kifProtocolFail", "Protocol failure"); - case kifInternalBuffer: return presentation(fmt, "kifInternalBuffer", "Internal buffer"); - case kifMonitorBuffer: return presentation(fmt, "kifMonitorBuffer", "Monitor buffer"); - case kifInitialization: return presentation(fmt, "kifInitialization", "Initialization"); - case kifInterfaceFail: return presentation(fmt, "kifInterfaceFail", "Interface failure"); - case kifClientCommFail: return presentation(fmt, "kifClientCommFail", "Client communication failure"); - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KInternalFail='%d']") % (int)inf), - STG(FMT("Unknown internal failure (%d)") % (int)inf)); -} - -std::string Verbose::linkErrorCounter(const KLinkErrorCounter ec, const Verbose::Presentation fmt) -{ - switch (ec) - { - case klecChangesToLock: return presentation(fmt, "klecChangesToLock", "Changes to lock"); - case klecLostOfSignal: return presentation(fmt, "klecLostOfSignal", "Lost of signal"); - case klecAlarmNotification: return presentation(fmt, "klecAlarmNotification", "Alarm notification"); - case klecLostOfFrame: return presentation(fmt, "klecLostOfFrame", "Lost of frame"); - case klecLostOfMultiframe: return presentation(fmt, "klecLostOfMultiframe", "Lost of multiframe"); - case klecRemoteAlarm: return presentation(fmt, "klecRemoteAlarm", "Remote alarm"); - case klecUnknowAlarm: return presentation(fmt, "klecUnknowAlarm", "Slip alarm"); - case klecPRBS: return presentation(fmt, "klecPRBS", "PRBS"); - case klecWrogrBits: return presentation(fmt, "klecWrongBits", "Wrong bits"); - case klecJitterVariation: return presentation(fmt, "klecJitterVariation", "Jitter variation"); - case klecFramesWithoutSync: return presentation(fmt, "klecFramesWithoutSync", "Frames without sync"); - case klecMultiframeSignal: return presentation(fmt, "klecMultiframeSignal", "Multiframe Signal"); - case klecFrameError: return presentation(fmt, "klecFrameError", "Frame error"); - case klecBipolarViolation: return presentation(fmt, "klecBipolarViolation", "Bipolar violation"); - case klecCRC4: return presentation(fmt, "klecCRC4", "CRC4 error"); - case klecCount: return ""; /* this should never be verbosed */ - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KLinkErrorCounter='%d']") % (int)ec), - STG(FMT("Unknown link error counter (%d)") % (int)ec)); -} - -std::string Verbose::callStatus(const KCallStatus code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kcsFree: return presentation(fmt, "kcsFree", "Free"); - case kcsIncoming: return presentation(fmt, "kcsIncoming", "Incoming"); - case kcsOutgoing: return presentation(fmt, "kcsOutgoing", "Outgoing"); - case kcsFail: return presentation(fmt, "kcsFail", "Failure"); - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KCallStatus='%d']") % (int)code), - STG(FMT("Unknown call status (%d)") % (int)code)); -} - -std::string Verbose::linkStatus(const KSignaling sig, const int32 code, const Verbose::Presentation fmt, const bool simpleStatus) -{ - switch (sig) - { - case ksigInactive: - return presentation(fmt, "[ksigInactive]", "Inactive trunk"); - - case ksigAnalog: - return presentation(fmt, "[ksigAnalog]", "Analog trunk"); - -#if K3L_AT_LEAST(1,4,1) - case ksigSIP: - return presentation(fmt, "[ksigSIP]", "SIP trunk"); -#endif - -#if K3L_AT_LEAST(1,6,0) - case ksigGSM: - return presentation(fmt, "[ksigGSM]", "GSM trunk"); -#endif - -#if K3L_EXACT(2,1,0) -#if !K3L_AT_LEAST(2,2,0) - case ksigFax: -#endif - return presentation(fmt, "[ksigFax]", "FAX"); -#endif - case ksigContinuousEM: - case ksigPulsedEM: - - case ksigOpenCAS: - case ksigOpenR2: - case ksigR2Digital: - case ksigUserR2Digital: - -#if K3L_AT_LEAST(1,5,1) - case ksigOpenCCS: - case ksigPRI_EndPoint: - case ksigPRI_Network: - case ksigPRI_Passive: -#endif -#if K3L_AT_LEAST(1,5,3) - case ksigLineSide: -#endif -#if K3L_AT_LEAST(1,6,0) - case ksigAnalogTerminal: - case ksigCAS_EL7: - case ksigE1LC: -#endif -#if K3L_AT_LEAST(2,2,0) - case ksigISUP: - case ksigISUPPassive: -#endif - if (kesOk == code) - { - return presentation(fmt, "kesOk", "Up"); - } - else - { - Strings::Merger strs; - - if (kesSignalLost & code) strs.add(presentation(fmt, "SignalLost", "Signal lost")); - if (kesNetworkAlarm & code) strs.add(presentation(fmt, "NetworkAlarm", "Network alarm")); - if (kesFrameSyncLost & code) strs.add(presentation(fmt, "FrameSyncLost", "Frame sync lost")); - if (kesMultiframeSyncLost & code) strs.add(presentation(fmt, "MultiframeSyncLost", "Multiframe sync lost")); - if (kesRemoteAlarm & code) strs.add(presentation(fmt, "RemoteAlarm", "Remote alarm")); - if (kesHighErrorRate & code) strs.add(presentation(fmt, "HighErrorRate", "High error rate")); - if (kesUnknownAlarm & code) strs.add(presentation(fmt, "UnknownAlarm", "Slip alarm")); - if (kesE1Error & code) strs.add(presentation(fmt, "E1Error", "E1 error")); - - if (simpleStatus) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("kes{%s}") % *(strs.list().begin())), - *(strs.list().begin())); - } - else - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("kes{%s}") % strs.merge(",")), - strs.merge(", ")); - } - } - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[%s, linkStatus='%d']") % signaling(sig) % (int)code), - STG(FMT("Unknown link status for '%s' (%d)") % signaling(sig) % (int)code)); -} - -std::string Verbose::channelStatus(const KSignaling sig, const int32 flags, const Verbose::Presentation fmt) -{ - try - { - switch (sig) - { - case ksigInactive: - return presentation(fmt, "[ksigInactive]", "Inactive channel"); - -#if K3L_AT_LEAST(1,4,1) - case ksigSIP: - return presentation(fmt, "[ksigSIP]", "SIP channel"); -#endif -#if K3L_EXACT(2,1,0) - case ksigISUP: - return presentation(fmt, "[ksigISUP]", "ISUP trunk"); -#if !K3L_AT_LEAST(2,2,0) - case ksigFax: - return presentation(fmt, "[ksigFax]", "FAX"); -#endif -#endif - - case ksigAnalog: -#if K3L_AT_LEAST(1,6,0) - switch ((KFXOChannelStatus)flags) -#else - switch ((KFXChannelStatus)flags) -#endif - { - case kfcsDisabled: return presentation(fmt, "kfcsDisabled", "Disabled"); - case kfcsEnabled: return presentation(fmt, "kfcsEnabled", "Enabled"); - } - - throw internal_not_found(); - -#if K3L_AT_LEAST(1,6,0) - case ksigAnalogTerminal: - switch ((KFXSChannelStatus)flags) - { - case kfxsOnHook: return presentation(fmt, "kfxsOnHook", "On Hook"); - case kfxsOffHook: return presentation(fmt, "kfxsOffHook", "Off Hook"); - case kfxsRinging: return presentation(fmt, "kfxsRinging", "Ringing"); - case kfxsFail: return presentation(fmt, "kfxsFail", "Failure"); - } - - throw internal_not_found(); - - case ksigGSM: - switch ((KGsmChannelStatus)flags) - { - case kgsmIdle: return presentation(fmt, "kgsmIdle", "Idle"); - case kgsmCallInProgress: return presentation(fmt, "kgsmCallInProgress", "Call in progress"); - case kgsmSMSInProgress: return presentation(fmt, "kgsmSMSInProgress", "SMS in progress"); - case kgsmModemError: return presentation(fmt, "kgsmModemError", "Modem error"); - case kgsmSIMCardError: return presentation(fmt, "kgsmSIMCardError", "SIM card error"); - case kgsmNetworkError: return presentation(fmt, "kgsmNetworkError", "Network error"); - case kgsmNotReady: return presentation(fmt, "kgsmNotReady", "Initializing"); - } - - throw internal_not_found(); -#endif - - /* deprecated, but still.. */ - case ksigPulsedEM: - case ksigContinuousEM: - - case ksigOpenCAS: - case ksigOpenR2: - case ksigR2Digital: - case ksigUserR2Digital: - -#if K3L_AT_LEAST(1,5,1) - case ksigOpenCCS: - case ksigPRI_EndPoint: - case ksigPRI_Network: - case ksigPRI_Passive: -#endif -#if K3L_AT_LEAST(1,5,3) - case ksigLineSide: -#endif -#if K3L_AT_LEAST(1,6,0) - case ksigCAS_EL7: - case ksigE1LC: -#endif -#if K3L_AT_LEAST(2,2,0) - case ksigISUP: - case ksigISUPPassive: -#endif - { - if (flags == kecsFree) - { - return presentation(fmt, "kecsFree", "Free"); - } - else - { - Strings::Merger strs; - - if (flags & kecsBusy) - strs.add("Busy"); - - switch (flags & 0x06) - { - case kecsOutgoing: - strs.add("Outgoing"); - break; - case kecsIncoming: - strs.add("Incoming"); - break; - case kecsLocked: - strs.add("Locked"); - default: - break; - } - - int32 value = (flags & 0xf0); - - if (kecsOutgoingLock & value) - strs.add(presentation(fmt, "OutgoingLock", "Outgoing Lock")); - - if (kecsLocalFail & value) - strs.add(presentation(fmt, "LocalFail", "Local Failure")); - - if (kecsIncomingLock & value) - strs.add(presentation(fmt, "IncomingLock", "Incoming Lock")); - - if (kecsRemoteLock & value) - strs.add(presentation(fmt, "RemoteLock", "Remote Lock")); - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("kecs{%s}") % strs.merge(",")), - strs.merge(", ")); - } - - throw internal_not_found(); - } - } - } - catch (internal_not_found e) - { - /* we use this exception to break the control flow */ - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[%s, channelStatus='%d']") % signaling(sig) % flags), - STG(FMT("Unknown channel status for '%s' (%d)") % signaling(sig) % flags)); -} - -std::string Verbose::status(const KLibraryStatus code, const Verbose::Presentation fmt) -{ - switch (code) - { - case ksSuccess: return presentation(fmt, "ksSuccess", "Success"); - case ksFail: return presentation(fmt, "ksFail", "Failure"); - case ksTimeOut: return presentation(fmt, "ksTimeOut", "Time Out"); - case ksBusy: return presentation(fmt, "ksBusy", "Busy"); - case ksLocked: return presentation(fmt, "ksLocked", "Locked"); - case ksInvalidParams: return presentation(fmt, "ksInvalidParams", "Invalid Parameters"); - case ksEndOfFile: return presentation(fmt, "ksEndOfFile", "End of File"); - case ksInvalidState: return presentation(fmt, "ksInvalidState", "Invalid State"); - case ksServerCommFail: return presentation(fmt, "ksServerCommFail", "Communication Failure"); - case ksOverflow: return presentation(fmt, "ksOverflow", "Overflow"); - case ksUnderrun: return presentation(fmt, "ksUnderrun", "Underrun"); - -#if K3L_AT_LEAST(1,4,0) - case ksNotFound: return presentation(fmt, "ksNotFound", "Not Found"); - case ksNotAvailable: return presentation(fmt, "ksNotAvaiable", "Not Available"); -#endif - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KLibraryStatus='%d']") % (int)code), - STG(FMT("Unknown library status (%d)") % (int)code)); -} - -std::string Verbose::h100configIndex(const KH100ConfigIndex code, const Verbose::Presentation fmt) -{ - switch (code) - { - case khciDeviceMode: return presentation(fmt, "khciDeviceMode", "Device Mode"); - case khciMasterGenClock: return presentation(fmt, "khciMasterGenClock", "Master Generated Clock"); - case khciCTNetRefEnable: return presentation(fmt, "khciCTNetRefEnable", "CTBus Network Reference Enable"); - case khciSCbusEnable: return presentation(fmt, "khciSCbusEnable", "SCBus Enable"); - case khciHMVipEnable: return presentation(fmt, "khciHMVipEnable", "HMVip Enable"); - case khciMVip90Enable: return presentation(fmt, "khciMVip90Enable", "MVip90 Enable"); - case khciCTbusDataEnable: return presentation(fmt, "khciCTbusDataEnable", "CTBus Data Enable"); - case khciCTbusFreq03_00: return presentation(fmt, "khciCTbusFreq03_00", "CTBus Frequency 03 00"); // TODO: find better name - case khciCTbusFreq07_04: return presentation(fmt, "khciCTbusFreq07_04", "CTBus Frequency 07 04"); // TODO: find better name - case khciCTbusFreq11_08: return presentation(fmt, "khciCTbusFreq11_08", "CTBus Frequency 11 08"); // TODO: find better name - case khciCTbusFreq15_12: return presentation(fmt, "khciCTbusFreq15_12", "CTBus Frequency 15 12"); // TODO: find better name - case khciMax: return presentation(fmt, "khciMax", "Max"); // TODO: find better name - case khciMasterDevId: return presentation(fmt, "khciMasterDevId", "Master Device Number"); - case khciSecMasterDevId: return presentation(fmt, "khciSecMasterDevId", "Secondary Master Device Number"); - case khciCtNetrefDevId: return presentation(fmt, "khciCtNetrefDevId", "CTBus Network Reference Device Number"); -#if K3L_AT_LEAST(1,6,0) - case khciMaxH100ConfigIndex: return ""; /* do not verbose this value */ -#endif - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KH100ConfigIndex='%d']") % (int)code), - STG(FMT("Unknown H.100 config index (%d)") % (int)code)); -} - -#if K3L_AT_LEAST(1,6,0) -std::string Verbose::callStartInfo(const KCallStartInfo code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kcsiHumanAnswer: return presentation(fmt, "kcsiHumanAnswer", "Human Answer"); - case kcsiAnsweringMachine: return presentation(fmt, "kcsiAnsweringMachine", "Answering Machine"); - case kcsiCellPhoneMessageBox: return presentation(fmt, "kcsiCellPhoneMessageBox", "Cell Phone Message Box"); - case kcsiCarrierMessage: return presentation(fmt, "kcsiCarrierMessage", "Carrier Message"); - case kcsiUnknown: return presentation(fmt, "kcsiUnknown", "Unknown"); - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KCallStartInfo='%d']") % (int)code), - STG(FMT("Unknown call answer info (%d)") % (int)code)); -} - -std::string Verbose::gsmCallCause(const KGsmCallCause code, const Verbose::Presentation fmt) -{ - try - { - return internal_gsmCallCause(code, fmt); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KGsmCallCause='%d']") % (int)code), - STG(FMT("Unknown GSM call cause (%d)") % (int)code)); - } -} - -std::string Verbose::internal_gsmCallCause(const KGsmCallCause code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kgccNone: return presentation(fmt, "kgccNone", "None"); - case kgccUnallocatedNumber: return presentation(fmt, "kgccUnallocatedNumber", "Unallocated number"); - case kgccNoRouteToDest: return presentation(fmt, "kgccNoRouteToDest", "No route to destination"); - case kgccChannelUnacceptable: return presentation(fmt, "kgccChannelUnacceptable", "Channel unacceptable"); - case kgccOperatorDeterminedBarring: return presentation(fmt, "kgccOperatorDeterminedBarring", "Operator determined barring"); - case kgccNormalCallClear: return presentation(fmt, "kgccNormalCallClear", "Normal call clear"); - case kgccUserBusy: return presentation(fmt, "kgccUserBusy", "User busy"); - case kgccNoUserResponding: return presentation(fmt, "kgccNoUserResponding", "No user responding"); - case kgccNoAnswerFromUser: return presentation(fmt, "kgccNoAnswerFromUser", "No answer from user"); - case kgccCallRejected: return presentation(fmt, "kgccCallRejected", "Call rejected"); - case kgccNumberChanged: return presentation(fmt, "kgccNumberChanged", "Number changed"); - case kgccNonSelectedUserClear: return presentation(fmt, "kgccNonSelectedUserClear", "Non Selected user clear"); - case kgccDestinationOutOfOrder: return presentation(fmt, "kgccDestinationOutOfOrder", "Destination out of order"); - case kgccInvalidNumberFormat: return presentation(fmt, "kgccInvalidNumberFormat", "Invalid number format"); - case kgccFacilityRejected: return presentation(fmt, "kgccFacilityRejected", "Facility rejected"); - case kgccRespStatusEnquiry: return presentation(fmt, "kgccRespStatusEnquiry", "Response status enquiry"); - case kgccNormalUnspecified: return presentation(fmt, "kgccNormalUnspecified", "Normal, unspecified"); - case kgccNoCircuitChannelAvail: return presentation(fmt, "kgccNoCircuitChannelAvail", "No circuit channel available"); - case kgccNetworkOutOfOrder: return presentation(fmt, "kgccNetworkOutOfOrder", "Network out of order"); - case kgccTemporaryFailure: return presentation(fmt, "kgccTemporaryFailure", "Temporary failure"); - case kgccSwitchCongestion: return presentation(fmt, "kgccSwitchCongestion", "Switch congestion"); - case kgccAccessInfoDiscarded: return presentation(fmt, "kgccAccessInfoDiscarded", "Access information discarded"); - case kgccRequestedChannelUnav: return presentation(fmt, "kgccRequestedChannelUnav", "Requested channel unavailable"); - case kgccResourceUnavailable: return presentation(fmt, "kgccResourceUnavailable", "Resource unavailable"); - case kgccQosUnavailable: return presentation(fmt, "kgccQosUnavailable", "QoS unavailable"); - case kgccReqFacilityNotSubsc: return presentation(fmt, "kgccReqFacilityNotSubsc", "Request facility not subscribed"); - case kgccCallBarredWitchCUG: return presentation(fmt, "kgccCallBarredWitchCUG", "Call barred with UG"); - case kgccBearerCapabNotAuthor: return presentation(fmt, "kgccBearerCapabNotAuthor", "Bearer capability not authorized"); - case kgccBearerCapabNotAvail: return presentation(fmt, "kgccBearerCapabNotAvail", "Bearer capability not available"); - case kgccServiceNotAvailable: return presentation(fmt, "kgccServiceNotAvailable", "Service not available"); - case kgccBcNotImplemented: return presentation(fmt, "kgccBcNotImplemented", "Bearer capability not implemented"); - case kgccReqFacilityNotImplem: return presentation(fmt, "kgccReqFacilityNotImplem", "Request facility not implemented"); - case kgccOnlyRestrictedBcAvail: return presentation(fmt, "kgccOnlyRestrictedBcAvail", "Only restricted bearer capability available"); - case kgccServiceNotImplemented: return presentation(fmt, "kgccServiceNotImplemented", "Service not implemented"); - case kgccInvalidCrv: return presentation(fmt, "kgccInvalidCrv", "Invalid call reference value"); - case kgccUserNotMemberOfCUG: return presentation(fmt, "kgccUserNotMemberOfCUG", "User not member of UG"); - case kgccIncompatibleDestination: return presentation(fmt, "kgccIncompatibleDestination", "Incompatible destination"); - case kgccInvalidTransitNetSel: return presentation(fmt, "kgccInvalidTransitNetSel", "Invalid transit network selected"); - case kgccInvalidMessage: return presentation(fmt, "kgccInvalidMessage", "Invalid message"); - case kgccMissingMandatoryIe: return presentation(fmt, "kgccMissingMandatoryIe", "Missing mandatory information element"); - case kgccMsgTypeNotImplemented: return presentation(fmt, "kgccMsgTypeNotImplemented", "Message type not implemented"); - case kgccMsgIncompatWithState: return presentation(fmt, "kgccMsgIncompatWithState", "Message incompatible with state"); - case kgccIeNotImplemented: return presentation(fmt, "kgccIeNotImplemented", "Information element not implemented"); - case kgccInvalidIe: return presentation(fmt, "kgccInvalidIe", "Invalid information element"); - case kgccMsgIncompatWithState2: return presentation(fmt, "kgccMsgIncompatWithState2", "Message incompatible with state (2)"); - case kgccRecoveryOnTimerExpiry: return presentation(fmt, "kgccRecoveryOnTimerExpiry", "Recovery on timer expiry"); - case kgccProtocolError: return presentation(fmt, "kgccProtocolError", "Protocol error"); - case kgccInterworking: return presentation(fmt, "kgccInterworking", "Interworking"); - } - - throw internal_not_found(); -} - -std::string Verbose::gsmMobileCause(const KGsmMobileCause code, const Verbose::Presentation fmt) -{ - try - { - return internal_gsmMobileCause(code, fmt); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KGsmMobileCause='%d']") % (int)code), - STG(FMT("Unknown GSM mobile cause (%d)") % (int)code)); - } -} - -std::string Verbose::internal_gsmMobileCause(const KGsmMobileCause code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kgmcPhoneFailure: return presentation(fmt, "kgmcPhoneFailure", "Phone failure"); - case kgmcNoConnectionToPhone: return presentation(fmt, "kgmcNoConnectionToPhone", "No connection to phone"); - case kgmcPhoneAdaptorLinkReserved: return presentation(fmt, "kgmcPhoneAdaptorLinkReserved", "Phone adaptor link reserved"); -#if 0 /* this changed during K3L 1.6.0 development cycle... */ - case kgmcCoperationNotAllowed: return presentation(fmt, "kgmcCoperationNotAllowed", ""); - case kgmcCoperationNotSupported: return presentation(fmt, "kgmcCoperationNotSupported", ""); -#else - case kgmcOperationNotAllowed: return presentation(fmt, "kgmcOperationNotAllowed", "Operation not allowed"); - case kgmcOperationNotSupported: return presentation(fmt, "kgmcOperationNotSupported", "Operation not supported"); -#endif - case kgmcPH_SIMPINRequired: return presentation(fmt, "kgmcPH_SIMPINRequired", "Phone SIM PIN required"); - case kgmcPH_FSIMPINRequired: return presentation(fmt, "kgmcPH_FSIMPINRequired", "Phone FSIM PIN required"); - case kgmcPH_FSIMPUKRequired: return presentation(fmt, "kgmcPH_FSIMPUKRequired", "Phone FSIM PUK required"); - case kgmcSIMNotInserted: return presentation(fmt, "kgmcSIMNotInserted", "SIM not inserted"); - case kgmcSIMPINRequired: return presentation(fmt, "kgmcSIMPINRequired", "SIM PIN required"); - case kgmcSIMPUKRequired: return presentation(fmt, "kgmcSIMPUKRequired", "SIM PUK required"); - case kgmcSIMFailure: return presentation(fmt, "kgmcSIMFailure", "SIM failure"); - case kgmcSIMBusy: return presentation(fmt, "kgmcSIMBusy", "SIM busy"); - case kgmcSIMWrong: return presentation(fmt, "kgmcSIMWrong", "SIM wrong"); - case kgmcIncorrectPassword: return presentation(fmt, "kgmcIncorrectPassword", "Incorrect password"); - case kgmcSIMPIN2Required: return presentation(fmt, "kgmcSIMPIN2Required", "SIM PIN2 required"); - case kgmcSIMPUK2Required: return presentation(fmt, "kgmcSIMPUK2Required", "SIM PUK2 required"); - case kgmcMemoryFull: return presentation(fmt, "kgmcMemoryFull", "Memory full"); - case kgmcInvalidIndex: return presentation(fmt, "kgmcInvalidIndex", "Invalid index"); - case kgmcNotFound: return presentation(fmt, "kgmcNotFound", "Not found"); - case kgmcMemoryFailure: return presentation(fmt, "kgmcMemoryFailure", "Memory failure"); - case kgmcTextStringTooLong: return presentation(fmt, "kgmcTextStringTooLong", "Text string too long"); - case kgmcInvalidCharInTextString: return presentation(fmt, "kgmcInvalidCharInTextString", "Invalid character in text string"); - case kgmcDialStringTooLong: return presentation(fmt, "kgmcDialStringTooLong", "Dial string too long"); - case kgmcInvalidCharInDialString: return presentation(fmt, "kgmcInvalidCharInDialString", "Invalid character in dial string"); - case kgmcNoNetworkService: return presentation(fmt, "kgmcNoNetworkService", "No network service"); - case kgmcNetworkTimeout: return presentation(fmt, "kgmcNetworkTimeout", "Network timeout"); - case kgmcNetworkNotAllowed: return presentation(fmt, "kgmcNetworkNotAllowed", "Network not allowed"); - case kgmcCommandAborted: return presentation(fmt, "kgmcCommandAborted", "Command aborted"); - case kgmcNumParamInsteadTextParam: return presentation(fmt, "kgmcNumParamInsteadTextParam", "Number parameter instead of text parameter"); - case kgmcTextParamInsteadNumParam: return presentation(fmt, "kgmcTextParamInsteadNumParam", "Text parameter instead of number parameter"); - case kgmcNumericParamOutOfBounds: return presentation(fmt, "kgmcNumericParamOutOfBounds", "Numeric parameter out of bounds"); - case kgmcTextStringTooShort: return presentation(fmt, "kgmcTextStringTooShort", "Text string too short"); - case kgmcNetworkPINRequired: return presentation(fmt, "kgmcNetworkPINRequired", "Network PIN required"); - case kgmcNetworkPUKRequired: return presentation(fmt, "kgmcNetworkPUKRequired", "Network PUK required"); - case kgmcNetworkSubsetPINRequired: return presentation(fmt, "kgmcNetworkSubsetPINRequired", "Network subset PIN required"); - case kgmcNetworkSubnetPUKRequired: return presentation(fmt, "kgmcNetworkSubnetPUKRequired", "Network subset PUK required"); - case kgmcServiceProviderPINRequired: return presentation(fmt, "kgmcServiceProviderPINRequired", "Network service provider PIN required"); - case kgmcServiceProviderPUKRequired: return presentation(fmt, "kgmcServiceProviderPUKRequired", "Network service provider PUK required"); - case kgmcCorporatePINRequired: return presentation(fmt, "kgmcCorporatePINRequired", "Corporate PIN required"); - case kgmcCorporatePUKRequired: return presentation(fmt, "kgmcCorporatePUKRequired", "Corporate PUK required"); - case kgmcSIMServiceOptNotSupported: return presentation(fmt, "kgmcSIMServiceOptNotSupported", "SIM Service option not supported"); - case kgmcUnknown: return presentation(fmt, "kgmcUnknown", "Unknown"); - case kgmcIllegalMS_N3: return presentation(fmt, "kgmcIllegalMS_N3", "Illegal MS #3"); - case kgmcIllegalME_N6: return presentation(fmt, "kgmcIllegalME_N6", "Illegal MS #6"); - case kgmcGPRSServicesNotAllowed_N7: return presentation(fmt, "kgmcGPRSServicesNotAllowed_N7", "GPRS service not allowed #7"); - case kgmcPLMNNotAllowed_No11: return presentation(fmt, "kgmcPLMNNotAllowed_No11", "PLMN not allowed #11"); - case kgmcLocationAreaNotAllowed_N12: return presentation(fmt, "kgmcLocationAreaNotAllowed_N12", "Location area not allowed #12"); - case kgmcRoamingNotAllowed_N13: return presentation(fmt, "kgmcRoamingNotAllowed_N13", "Roaming not allowed #13"); - case kgmcServiceOptNotSupported_N32: return presentation(fmt, "kgmcServiceOptNotSupported_N32", "Service option not supported #32"); - case kgmcReqServOptNotSubscribed_N33: return presentation(fmt, "kgmcReqServOptNotSubscribed_N33", "Registration service option not subscribed #33"); - case kgmcServOptTempOutOfOrder_N34: return presentation(fmt, "kgmcServOptTempOutOfOrder_N34", "Service option temporary out of order #34"); - case kgmcLongContextActivation: return presentation(fmt, "kgmcLongContextActivation", "Long context activation"); - case kgmcUnspecifiedGPRSError: return presentation(fmt, "kgmcUnspecifiedGPRSError", "Unspecified GPRS error"); - case kgmcPDPAuthenticationFailure: return presentation(fmt, "kgmcPDPAuthenticationFailure", "PDP authentication failure"); - case kgmcInvalidMobileClass: return presentation(fmt, "kgmcInvalidMobileClass", "Invalid mobile class"); - case kgmcGPRSDisconnectionTmrActive: return presentation(fmt, "kgmcGPRSDisconnectionTmrActive", "GPRS disconnection TMR active"); - case kgmcTooManyActiveCalls: return presentation(fmt, "kgmcTooManyActiveCalls", "Too many active calls"); - case kgmcCallRejected: return presentation(fmt, "kgmcCallRejected", "Call rejected"); - case kgmcUnansweredCallPending: return presentation(fmt, "kgmcUnansweredCallPending", "Unanswered call pending"); - case kgmcUnknownCallingError: return presentation(fmt, "kgmcUnknownCallingError", "Unknown calling error"); - case kgmcNoPhoneNumRecognized: return presentation(fmt, "kgmcNoPhoneNumRecognized", "No phone number recognized"); - case kgmcCallStateNotIdle: return presentation(fmt, "kgmcCallStateNotIdle", "Call state not idle"); - case kgmcCallInProgress: return presentation(fmt, "kgmcCallInProgress", "Call in progress"); - case kgmcDialStateError: return presentation(fmt, "kgmcDialStateError", "Dial state error"); - case kgmcUnlockCodeRequired: return presentation(fmt, "kgmcUnlockCodeRequired", "Unlock code required"); - case kgmcNetworkBusy: return presentation(fmt, "kgmcNetworkBusy", "Network busy"); - case kgmcInvalidPhoneNumber: return presentation(fmt, "kgmcInvalidPhoneNumber", "Invalid phone number"); - case kgmcNumberEntryAlreadyStarted: return presentation(fmt, "kgmcNumberEntryAlreadyStarted", "Number entry already started"); - case kgmcCancelledByUser: return presentation(fmt, "kgmcCancelledByUser", "Cancelled by user"); - case kgmcNumEntryCouldNotBeStarted: return presentation(fmt, "kgmcNumEntryCouldNotBeStarted", "Number entry could not be started"); - case kgmcDataLost: return presentation(fmt, "kgmcDataLost", "Data lost"); - case kgmcInvalidBessageBodyLength: return presentation(fmt, "kgmcInvalidBessageBodyLength", "Invalid message body length"); - case kgmcInactiveSocket: return presentation(fmt, "kgmcInactiveSocket", "Inactive socket"); - case kgmcSocketAlreadyOpen: return presentation(fmt, "kgmcSocketAlreadyOpen", "Socket already open"); -#if K3L_AT_LEAST(2,1,0) - case kgmcSuccess: return presentation(fmt, "kgmcSuccess", "Success"); -#endif - } - - throw internal_not_found(); -} - -std::string Verbose::gsmSmsCause(const KGsmSmsCause code, const Verbose::Presentation fmt) -{ - try - { - return internal_gsmSmsCause(code, fmt); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KGsmSmsCause='%d']") % (int)code), - STG(FMT("Unknown GSM SMS cause (%d)") % (int)code)); - } -} - -std::string Verbose::internal_gsmSmsCause(const KGsmSmsCause code, const Verbose::Presentation fmt) -{ - switch (code) - { -#if K3L_AT_LEAST(2,1,0) - case kgscNone: return presentation(fmt, "kgscNone", "None"); -#endif - case kgscUnassigned: return presentation(fmt, "kgscUnassigned", "Unassigned number"); - case kgscOperatorDeterminedBarring: return presentation(fmt, "kgscOperatorDeterminedBarring", "Operator determined barring"); - case kgscCallBarred: return presentation(fmt, "kgscCallBarred", "Call barred"); - case kgscSMSTransferRejected: return presentation(fmt, "kgscSMSTransferRejected", "SMS transfer rejected"); - case kgscDestinationOutOfService: return presentation(fmt, "kgscDestinationOutOfService", "Destination out of service"); - case kgscUnidentifiedSubscriber: return presentation(fmt, "kgscUnidentifiedSubscriber", "Unidentified subscriber"); - case kgscFacilityRejected: return presentation(fmt, "kgscFacilityRejected", "Facility rejected"); - case kgscUnknownSubscriber: return presentation(fmt, "kgscUnknownSubscriber", "Unknown subscriber"); - case kgscNetworkOutOfOrder: return presentation(fmt, "kgscNetworkOutOfOrder", "Network out of order"); - case kgscTemporaryFailure: return presentation(fmt, "kgscTemporaryFailure", "Temporary failure"); - case kgscCongestion: return presentation(fmt, "kgscCongestion", "Congestion"); - case kgscResourcesUnavailable: return presentation(fmt, "kgscResourcesUnavailable", "Resources unavailable"); - case kgscFacilityNotSubscribed: return presentation(fmt, "kgscFacilityNotSubscribed", "Facility not subscribed"); - case kgscFacilityNotImplemented: return presentation(fmt, "kgscFacilityNotImplemented", "Facility not implemented"); - case kgscInvalidSMSTransferRefValue: return presentation(fmt, "kgscInvalidSMSTransferRefValue", "Invalid SMS transfer reference value"); - case kgscInvalidMessage: return presentation(fmt, "kgscInvalidMessage", "Invalid message"); - case kgscInvalidMandatoryInformation: return presentation(fmt, "kgscInvalidMandatoryInformation", "Invalid mandatory information"); - case kgscMessageTypeNonExistent: return presentation(fmt, "kgscMessageTypeNonExistent", "Message type non existent"); - case kgscMsgNotCompatWithSMProtState: return presentation(fmt, "kgscMsgNotCompatWithSMProtState", "Message not compatible with SMS protection state"); - case kgscInformationElementNonExiste: return presentation(fmt, "kgscInformationElementNonExiste", "Information element non existent"); - case kgscProtocolError: return presentation(fmt, "kgscProtocolError", "Protocol error"); - case kgscInterworking: return presentation(fmt, "kgscInterworking", "Interworking"); - case kgscTelematicInterworkingNotSup: return presentation(fmt, "kgscTelematicInterworkingNotSup", "Telematic interworking not supported"); - case kgscSMSTypeZeroNotSupported: return presentation(fmt, "kgscSMSTypeZeroNotSupported", "SMS type zero not supported"); - case kgscCannotReplaceSMS: return presentation(fmt, "kgscCannotReplaceSMS", "Cannot replace SMS"); - case kgscUnspecifiedTPPIDError: return presentation(fmt, "kgscUnspecifiedTPPIDError", "Unspecified TPPID error"); - case kgscAlphabetNotSupported: return presentation(fmt, "kgscAlphabetNotSupported", "Alphabet not supported"); - case kgscMessageClassNotSupported: return presentation(fmt, "kgscMessageClassNotSupported", "Message class not supported"); - case kgscUnspecifiedTPDCSError: return presentation(fmt, "kgscUnspecifiedTPDCSError", "Unspecified TPDCS error"); - case kgscCommandCannotBeActioned: return presentation(fmt, "kgscCommandCannotBeActioned", "Command cannot be actioned"); - case kgscCommandUnsupported: return presentation(fmt, "kgscCommandUnsupported", "Command unsupported"); - case kgscUnspecifiedTPCommandError: return presentation(fmt, "kgscUnspecifiedTPCommandError", "Unspecified TP command error"); - case kgscTPDUNotSupported: return presentation(fmt, "kgscTPDUNotSupported", "TPDU not supported"); - case kgscSCBusy: return presentation(fmt, "kgscSCBusy", "SC busy"); - case kgscNoSCSubscription: return presentation(fmt, "kgscNoSCSubscription", "No SC subscription"); - case kgscSCSystemFailure: return presentation(fmt, "kgscSCSystemFailure", "SC system failure"); - case kgscInvalidSMEAddress: return presentation(fmt, "kgscInvalidSMEAddress", "Invalid SME address"); - case kgscDestinationSMEBarred: return presentation(fmt, "kgscDestinationSMEBarred", "Destination SME barred"); - case kgscSMRejectedDuplicateSM: return presentation(fmt, "kgscSMRejectedDuplicateSM", "SM rejected duplicate SM"); - case kgscTPVPFNotSupported: return presentation(fmt, "kgscTPVPFNotSupported", "TPVPF not supported"); - case kgscTPVPNotSupported: return presentation(fmt, "kgscTPVPNotSupported", "TPVP not supported"); - case kgscSIMSMSStorageFull: return presentation(fmt, "kgscSIMSMSStorageFull", "SIM SMS storage full"); - case kgscNoSMSStorageCapabilityInSIM: return presentation(fmt, "kgscNoSMSStorageCapabilityInSIM", "No SMS storage capability in SIM"); - case kgscErrorInMS: return presentation(fmt, "kgscErrorInMS", "Error in SMS"); - case kgscMemoryCapacityExceeded: return presentation(fmt, "kgscMemoryCapacityExceeded", "Memory capatity exceeded"); - case kgscSIMDataDownloadError: return presentation(fmt, "kgscSIMDataDownloadError", "SIM data download error"); - case kgscUnspecifiedError: return presentation(fmt, "kgscUnspecifiedError", "Unspecified error"); - case kgscPhoneFailure: return presentation(fmt, "kgscPhoneFailure", "Phone failure"); - case kgscSmsServiceReserved: return presentation(fmt, "kgscSmsServiceReserved", "SMS service reserved"); - case kgscOperationNotAllowed: return presentation(fmt, "kgscOperationNotAllowed", "Operation not allowed"); - case kgscOperationNotSupported: return presentation(fmt, "kgscOperationNotSupported", "Operation not supported"); - case kgscInvalidPDUModeParameter: return presentation(fmt, "kgscInvalidPDUModeParameter", "Invalid PDU mode parameter"); - case kgscInvalidTextModeParameter: return presentation(fmt, "kgscInvalidTextModeParameter", "Invalid text mode parameter"); - case kgscSIMNotInserted: return presentation(fmt, "kgscSIMNotInserted", "SIM not inserted"); - case kgscSIMPINNecessary: return presentation(fmt, "kgscSIMPINNecessary", "SIM PIN necessary"); - case kgscPH_SIMPINNecessary: return presentation(fmt, "kgscPH_SIMPINNecessary", "Phone SIM PIN necessary"); - case kgscSIMFailure: return presentation(fmt, "kgscSIMFailure", "SIM failure"); - case kgscSIMBusy: return presentation(fmt, "kgscSIMBusy", "SIM busy"); - case kgscSIMWrong: return presentation(fmt, "kgscSIMWrong", "SIM wrong"); - case kgscMemoryFailure: return presentation(fmt, "kgscMemoryFailure", "Memory failure"); - case kgscInvalidMemoryIndex: return presentation(fmt, "kgscInvalidMemoryIndex", "Invalid memory index"); - case kgscMemoryFull: return presentation(fmt, "kgscMemoryFull", "Memory full"); - case kgscSMSCAddressUnknown: return presentation(fmt, "kgscSMSCAddressUnknown", "SMSC address unknown"); - case kgscNoNetworkService: return presentation(fmt, "kgscNoNetworkService", "No network service"); - case kgscNetworkTimeout: return presentation(fmt, "kgscNetworkTimeout", "Network timeout"); - case kgscUnknownError: return presentation(fmt, "kgscUnknownError", "Unknown error"); - case kgscNetworkBusy: return presentation(fmt, "kgscNetworkBusy", "Network busy"); - case kgscInvalidDestinationAddress: return presentation(fmt, "kgscInvalidDestinationAddress", "Invalid destination address"); - case kgscInvalidMessageBodyLength: return presentation(fmt, "kgscInvalidMessageBodyLength", "Invalid message body length"); - case kgscPhoneIsNotInService: return presentation(fmt, "kgscPhoneIsNotInService", "Phone is not in service"); - case kgscInvalidPreferredMemStorage: return presentation(fmt, "kgscInvalidPreferredMemStorage", "Invalid preferred memory storage"); - case kgscUserTerminated: return presentation(fmt, "kgscUserTerminated", "User terminated"); - } - - throw internal_not_found(); -} - -std::string Verbose::q931ProgressIndication(const KQ931ProgressIndication code, const Verbose::Presentation fmt) -{ - try - { - return internal_q931ProgressIndication(code); - } - catch (internal_not_found e) - { - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KQ931ProgressIndication='%d']") % (int)code), - STG(FMT("Unknown Q931 progress indication (%d)") % (int)code)); - } -} - -std::string Verbose::internal_q931ProgressIndication(const KQ931ProgressIndication code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kq931pTonesMaybeAvailable: return presentation(fmt, "kq931pTonesMaybeAvailable", "Tones may be available"); - case kq931pDestinationIsNonIsdn: return presentation(fmt, "kq931pDestinationIsNonIsdn", "Destination is not ISDN"); - case kq931pOriginationIsNonIsdn: return presentation(fmt, "kq931pOriginationIsNonIsdn", "Origination is not ISDN"); - case kq931pCallReturnedToIsdn: return presentation(fmt, "kq931pCallReturnedToIsdn", "Call returned to ISDN"); - case kq931pTonesAvailable: return presentation(fmt, "kq931pTonesAvailable", "Tones available"); - } - - throw internal_not_found(); -} - -#endif /* K3L_AT_LEAST(1,6,0) */ - - - - -#if K3L_AT_LEAST(2,1,0) -std::string Verbose::faxResult(const KFaxResult code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kfaxrEndOfTransmission: return presentation(fmt, "kfaxrEndOfTransmission", "EndOfTransmission"); - case kfaxrStoppedByCommand: return presentation(fmt, "kfaxrStoppedByCommand", "StoppedByCommand"); - case kfaxrProtocolTimeout: return presentation(fmt, "kfaxrProtocolTimeout", "ProtocolTimeout"); - case kfaxrProtocolError: return presentation(fmt, "kfaxrProtocolError", "ProtocolError"); - case kfaxrRemoteDisconnection: return presentation(fmt, "kfaxrRemoteDisconnection", "RemoteDisconnection"); - case kfaxrFileError: return presentation(fmt, "kfaxrFileError", "FileError"); - case kfaxrUnknown: return presentation(fmt, "kfaxrUnknown", "Unknown"); - case kfaxrEndOfReception: return presentation(fmt, "kfaxrEndOfReception", "EndOfReception"); - case kfaxrCompatibilityError: return presentation(fmt, "kfaxrCompatibilityError", "CompatibilityError"); - case kfaxrQualityError: return presentation(fmt, "kfaxrQualityError", "QualityError"); - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KFaxResult='%d']") % (int)code), - STG(FMT("Unknown fax result (%d)") % (int)code)); -} - -std::string Verbose::faxFileErrorCause(const KFaxFileErrorCause code, const Verbose::Presentation fmt) -{ - switch (code) - { - case kfaxfecTransmissionStopped: return presentation(fmt, "kfaxfecTransmissionStopped", "TransmissionStopped"); - case kfaxfecTransmissionError: return presentation(fmt, "kfaxfecTransmissionError", "TransmissionError"); - case kfaxfecListCleared: return presentation(fmt, "kfaxfecListCleared", "ListCleared"); - case kfaxfecCouldNotOpen: return presentation(fmt, "kfaxfecCouldNotOpen", "CouldNotOpen"); - case kfaxfecInvalidHeader: return presentation(fmt, "kfaxfecInvalidHeader", "InvalidHeader"); - case kfaxfecDataNotFound: return presentation(fmt, "kfaxfecDataNotFound", "DataNotFound"); - case kfaxfecInvalidHeight: return presentation(fmt, "kfaxfecInvalidHeight", "InvalidHeight"); - case kfaxfecUnsupportedWidth: return presentation(fmt, "kfaxfecUnsupportedWidth", "UnsupportedWidth"); - case kfaxfecUnsupportedCompression: return presentation(fmt, "kfaxfecUnsupportedCompression", "UnsupportedCompression"); - case kfaxfecUnsupportedRowsPerStrip: return presentation(fmt, "kfaxfecUnsupportedRowsPerStrip", "UnsupportedRowsPerStrip"); - case kfaxfecUnknown: return presentation(fmt, "kfaxfecUnknown", "Unknown"); - } - - PRESENTATION_CHECK_RETURN(fmt, - STG(FMT("[KFaxFileErrorCause='%d']") % (int)code), - STG(FMT("Unknown fax file error cause (%d)") % (int)code)); -} - -#endif - -/********/ - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::command(const int32 dev, const K3L_COMMAND * const k3lcmd, const R2CountryType r2_country, const Verbose::Presentation fmt) -#else -std::string Verbose::command(const int32 dev, const K3L_COMMAND * const k3lcmd, const Verbose::Presentation fmt) -#endif -{ -#if K3L_AT_LEAST(2,0,0) - return command(k3lcmd->Cmd, dev, k3lcmd->Object, (const char *) k3lcmd->Params, r2_country, fmt); -#else - return command(k3lcmd->Cmd, dev, k3lcmd->Object, (const char *) k3lcmd->Params, fmt); -#endif -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::command(const int32 cmd_code, const int32 dev_idx, const int32 obj_idx, const char * const params, const R2CountryType r2_country, const Verbose::Presentation fmt) -#else -std::string Verbose::command(const int32 cmd_code, const int32 dev_idx, const int32 obj_idx, const char * const params, const Verbose::Presentation fmt) -#endif -{ - unsigned short int dev = (unsigned short int) dev_idx; - unsigned short int obj = (unsigned short int) obj_idx; - - VerboseTraits::Command code = (VerboseTraits::Command) cmd_code; - - std::string buf, extra; - - switch (code) - { - case VerboseTraits::K_CM_SEIZE: - case VerboseTraits::K_CM_SYNC_SEIZE: - case VerboseTraits::K_CM_VOIP_SEIZE: - case VerboseTraits::K_CM_DIAL_MFC: - case VerboseTraits::K_CM_DIAL_DTMF: - - case VerboseTraits::K_CM_CONNECT: - case VerboseTraits::K_CM_PRE_CONNECT: - case VerboseTraits::K_CM_DISCONNECT: - case VerboseTraits::K_CM_DROP_COLLECT_CALL: - - case VerboseTraits::K_CM_START_SEND_FAIL: - case VerboseTraits::K_CM_STOP_SEND_FAIL: - - case VerboseTraits::K_CM_ENABLE_DTMF_SUPPRESSION: - case VerboseTraits::K_CM_DISABLE_DTMF_SUPPRESSION: - case VerboseTraits::K_CM_ENABLE_AUDIO_EVENTS: - case VerboseTraits::K_CM_DISABLE_AUDIO_EVENTS: - case VerboseTraits::K_CM_ENABLE_CALL_PROGRESS: - case VerboseTraits::K_CM_DISABLE_CALL_PROGRESS: - case VerboseTraits::K_CM_ENABLE_PULSE_DETECTION: - case VerboseTraits::K_CM_DISABLE_PULSE_DETECTION: - case VerboseTraits::K_CM_ENABLE_ECHO_CANCELLER: - case VerboseTraits::K_CM_DISABLE_ECHO_CANCELLER: - case VerboseTraits::K_CM_ENABLE_AGC: - case VerboseTraits::K_CM_DISABLE_AGC: - case VerboseTraits::K_CM_ENABLE_HIGH_IMP_EVENTS: - case VerboseTraits::K_CM_DISABLE_HIGH_IMP_EVENTS: - - case VerboseTraits::K_CM_FLASH: - case VerboseTraits::K_CM_RESET_LINK: - case VerboseTraits::K_CM_CLEAR_MIXER: - - case VerboseTraits::K_CM_LOCK_INCOMING: - case VerboseTraits::K_CM_UNLOCK_INCOMING: - case VerboseTraits::K_CM_LOCK_OUTGOING: - case VerboseTraits::K_CM_UNLOCK_OUTGOING: - - case VerboseTraits::K_CM_INCREASE_VOLUME: - case VerboseTraits::K_CM_DECREASE_VOLUME: - - case VerboseTraits::K_CM_STOP_RECORD: - case VerboseTraits::K_CM_PAUSE_RECORD: - case VerboseTraits::K_CM_RESUME_RECORD: - - case VerboseTraits::K_CM_STOP_LISTEN: - - case VerboseTraits::K_CM_PLAY_SOUND_CARD: - case VerboseTraits::K_CM_STOP_SOUND_CARD: - case VerboseTraits::K_CM_RINGBACK: -#if K3L_AT_LEAST(1,4,0) && !K3L_AT_LEAST(2,0,0) - case VerboseTraits::K_CM_VOIP_START_DEBUG: - case VerboseTraits::K_CM_VOIP_STOP_DEBUG: - case VerboseTraits::K_CM_VOIP_DUMP_STAT: -#endif - -#if K3L_AT_LEAST(1,5,3) - case VerboseTraits::K_CM_END_OF_NUMBER: -#endif - -#if K3L_AT_LEAST(1,5,4) - case VerboseTraits::K_CM_SET_VOLUME: -#endif - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::K_CM_ENABLE_CALL_ANSWER_INFO: - case VerboseTraits::K_CM_DISABLE_CALL_ANSWER_INFO: - - case VerboseTraits::K_CM_SS_TRANSFER: - - case VerboseTraits::K_CM_CHECK_NEW_SMS: - case VerboseTraits::K_CM_GET_SMS: - case VerboseTraits::K_CM_PREPARE_SMS: - case VerboseTraits::K_CM_SEND_SMS: - - case VerboseTraits::K_CM_START_CADENCE: - case VerboseTraits::K_CM_STOP_CADENCE: - case VerboseTraits::K_CM_SEND_TO_MODEM: -#endif -#if K3L_HAS_MPTY_SUPPORT - case VerboseTraits::K_CM_HOLD_SWITCH: - case VerboseTraits::K_CM_MPTY_CONF: - case VerboseTraits::K_CM_MPTY_SPLIT: -#endif -#if K3L_AT_LEAST(2,1,0) - case VerboseTraits::K_CM_SIM_CARD_SELECT: - case VerboseTraits::K_CM_CT_TRANSFER: -#endif - if (params != NULL) - { - extra += "param='"; - extra += (params ? params : ""); - extra += "'"; - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - else - { - return show(buf, commandName(code), Target(CHANNEL, dev, obj)); - } - - case VerboseTraits::K_CM_SEND_DTMF: /* ?? */ - return show(buf, commandName(code), Target(CHANNEL, dev, obj)); - - /****/ - - case VerboseTraits::K_CM_STOP_AUDIO: - extra = "stop='"; - switch ((params ? (int)(*params) : -1)) - { - case 1: extra += "tx"; - case 2: extra += "rx"; - case 3: extra += "tx+rx"; - default: extra += ""; - } - extra = "'"; - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - - /****/ - -#if K3L_AT_LEAST(1,5,2) && !K3L_AT_LEAST(2,0,0) - case VerboseTraits::K_CM_ISDN_DEBUG: - extra = "flags='"; - extra += isdnDebug((unsigned long)params); - extra += "'"; - - return show(buf, commandName(code), Target(NONE), extra); -#endif - - /****/ - -#if K3L_AT_LEAST(1,5,1) - case VerboseTraits::K_CM_USER_INFORMATION: -#endif - if (params != NULL) - { - KUserInformation * userinfo = (KUserInformation *)params; - - std::string tmp((const char*) userinfo->UserInfo, userinfo->UserInfoLength); - - extra = STG(FMT("proto='%d',length='%d',data='%s'") - % userinfo->ProtocolDescriptor % userinfo->UserInfoLength % tmp); - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - else - { - return show(buf, commandName(code), Target(CHANNEL, dev, obj)); - } - - /****/ - - - - case VerboseTraits::K_CM_CAS_CHANGE_LINE_STT: - { - const char status = (params ? *params : 0x00); - - extra += "status='"; - extra += (status & 0x01 ? "1" : "0"); - extra += (status & 0x02 ? "1" : "0"); - extra += (status & 0x04 ? "1" : "0"); - extra += (status & 0x08 ? "1" : "0"); - extra += "'"; - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - - case VerboseTraits::K_CM_CAS_SEND_MFC: - { - char mfc = (params ? *params : 0xff); - - extra = STG(FMT("mfc='%d'") % (int) mfc); - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - - case VerboseTraits::K_CM_CAS_SET_MFC_DETECT_MODE: - { - int mode = (params ? *((int *)params) : -1); - - extra = STG(FMT("mode='%d'") % mode); - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - - case VerboseTraits::K_CM_SET_FORWARD_CHANNEL: - { - int channel = (params ? *((int*) params) : -1); - - extra = STG(FMT("forward='%03d'") % channel); - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - -#if K3L_AT_LEAST(1,5,0) - case VerboseTraits::K_CM_MAKE_CALL: - extra = "options='"; - extra += (params ? params : ""); - extra += "'"; - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); -#endif - - case VerboseTraits::K_CM_MIXER: - case VerboseTraits::K_CM_MIXER_CTBUS: - { - if (params) - { - KMixerCommand *m = (KMixerCommand*)params; - - std::string src = mixerSource((KMixerSource)m->Source); - std::string idx(""); - - switch (m->Source) - { - case kmsChannel: - case kmsPlay: - case kmsCTbus: -#if (K3L_AT_LEAST(1,4,0) && !K3L_AT_LEAST(1,6,0)) - case kmsVoIP: -#endif -#if K3L_AT_LEAST(1,6,0) - case kmsNoDelayChannel: -#endif - idx = STG(FMT("%02d") % (int)m->SourceIndex); - break; - - case kmsGenerator: - idx = mixerTone((KMixerTone)m->SourceIndex); - break; - }; - - extra = STG(FMT("track='%d',src='%s',index='%s'") % (int)m->Track % src % idx); - } - else - { - extra = ""; - } - - return show(buf, commandName(code), Target(MIXER, dev, obj), extra); - }; - - case VerboseTraits::K_CM_PLAY_FROM_FILE: - extra = "file='"; - extra += (params ? params : ""); - extra += "'"; - - return show(buf, commandName(code), Target(PLAYER, dev, obj), extra); - - case VerboseTraits::K_CM_RECORD_TO_FILE: - extra = "file='"; - extra += (params ? params : ""); - extra += "'"; - - return show(buf, commandName(code), Target(PLAYER, dev, obj), extra); - - case VerboseTraits::K_CM_RECORD_TO_FILE_EX: - extra = "params='"; - extra += (params ? params : ""); - extra += "'"; - - return show(buf, commandName(code), Target(PLAYER, dev, obj), extra); - - case VerboseTraits::K_CM_PLAY_FROM_STREAM: - case VerboseTraits::K_CM_ADD_STREAM_BUFFER: - { - struct buffer_param - { - const void * ptr; - const int size; - } - *p = (buffer_param *) params; - - std::stringstream stream; - - extra = STG(FMT("buffer='%p',size='%d'") - % (const void *) p->ptr % (const int) p->size); - - return show(buf, commandName(code), Target(PLAYER, dev, obj), extra); - } - - case VerboseTraits::K_CM_PLAY_FROM_STREAM_EX: - { - struct buffer_param - { - const void * ptr; - const int size; - const char codec; - } - *p = (buffer_param *) params; - - std::string codec; - - switch (p->codec) - { - case 0: codec = "A-Law"; - case 1: codec = "PCM-08khz"; - case 2: codec = "PCM-11khz"; - default: codec = ""; - } - - std::stringstream stream; - - extra = STG(FMT("buffer='%p',size='%d',codec='%s'") - % (const void *) p->ptr % (const int) p->size % codec); - - return show(buf, commandName(code), Target(PLAYER, dev, obj), extra); - } - - case VerboseTraits::K_CM_STOP_PLAY: - case VerboseTraits::K_CM_PAUSE_PLAY: - case VerboseTraits::K_CM_RESUME_PLAY: - - case VerboseTraits::K_CM_START_STREAM_BUFFER: - case VerboseTraits::K_CM_STOP_STREAM_BUFFER: - - case VerboseTraits::K_CM_ENABLE_PLAYER_AGC: - case VerboseTraits::K_CM_DISABLE_PLAYER_AGC: - - case VerboseTraits::K_CM_SEND_BEEP: - case VerboseTraits::K_CM_SEND_BEEP_CONF: - - case VerboseTraits::K_CM_INTERNAL_PLAY: - case VerboseTraits::K_CM_INTERNAL_PLAY_EX: - return show(buf, commandName(code), Target(PLAYER, dev, obj)); - - case VerboseTraits::K_CM_ADD_TO_CONF: - extra += "conference='"; - extra += (params ? (int) (*params) : -1); - extra += "'"; - - return show(buf, commandName(code), Target(MIXER, dev, obj), extra); - - case CM_REMOVE_FROM_CONF: - return show(buf, commandName(code), Target(MIXER, dev, obj)); - - case VerboseTraits::K_CM_LISTEN: - case VerboseTraits::K_CM_PREPARE_FOR_LISTEN: - { - int msecs = (params ? *((int*)params) : -1); - - extra = STG(FMT("msecs='%d'") % msecs); - - return show(buf, commandName(code), Target(PLAYER, dev, obj), extra); - } - - case VerboseTraits::K_CM_SEND_TO_CTBUS: - case VerboseTraits::K_CM_RECV_FROM_CTBUS: - { - KCtbusCommand *p = (KCtbusCommand*)(params); - - extra = STG(FMT("stream='%02d',timeslot='%02d',enable='%d'") - % (int)p->Stream % (int)p->TimeSlot % (int)p->Enable); - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - } - - case VerboseTraits::K_CM_SET_LINE_CONDITION: - case VerboseTraits::K_CM_SEND_LINE_CONDITION: - extra = "condition='"; -#if K3L_AT_LEAST(2,0,0) - extra += signGroupB((KSignGroupB) *((int *) params), r2_country); -#else - extra += signGroupB((KSignGroupB) *((int *) params)); -#endif - extra += "'"; - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::K_CM_SET_CALLER_CATEGORY: - extra = "category='"; -#if K3L_AT_LEAST(2,0,0) - extra += signGroupII((KSignGroupII) *((int *) params), r2_country); -#else - extra += signGroupII((KSignGroupII) *((int *) params)); -#endif - extra += "'"; - - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::K_CM_CLEAR_LINK_ERROR_COUNTER: - return show(buf, commandName(code), Target(LINK, dev, obj)); - - case VerboseTraits::K_CM_SIP_REGISTER: - if (params != NULL) - { - extra += "param='"; - extra += (params ? params : ""); - extra += "'"; - - return show(buf, commandName(code), Target(DEVICE, dev), extra); - } - else - { - return show(buf, commandName(code), Target(DEVICE, dev)); - } -#endif - - case VerboseTraits::K_CM_SETUP_H100: - extra += "option='"; - extra += h100configIndex((KH100ConfigIndex)obj_idx); - extra += "'value='"; - extra += (params ? STG(FMT("%02d") % (int)(*params)) : ""); - extra += "'"; - - return show(buf, commandName(code), Target(DEVICE, dev), extra); - - case VerboseTraits::K_CM_HARD_RESET: - return show(buf, commandName(code), Target(LINK, dev, obj)); - -#if !K3L_AT_LEAST(2,0,0) - /* como funciona? */ - case VerboseTraits::K_CM_LOG_REQUEST: - case VerboseTraits::K_CM_LOG_CREATE_DISPATCHER: - case VerboseTraits::K_CM_LOG_DESTROY_DISPATCHER: - case VerboseTraits::K_CM_PING: -#endif -//#if K3L_AT_LEAST(2,1,0) -// case VerboseTraits::K_CM_LOG_UPDATE: -//#endif - return show(buf, commandName(code), Target(NONE)); -#if K3L_AT_LEAST(2,1,0) - case VerboseTraits::K_CM_START_FAX_TX: - case VerboseTraits::K_CM_START_FAX_RX: - case VerboseTraits::K_CM_ADD_FAX_FILE: - extra = "params='"; - extra += (params ? params : ""); - extra += "'"; - return show(buf, commandName(code), Target(CHANNEL, dev, obj), extra); - case VerboseTraits::K_CM_STOP_FAX_TX: - case VerboseTraits::K_CM_STOP_FAX_RX: - case VerboseTraits::K_CM_ADD_FAX_PAGE_BREAK: - return show(buf, commandName(code), Target(CHANNEL, dev, obj)); -#endif - -#if K3L_AT_LEAST(2,1,0) - case VerboseTraits::K_CM_NOTIFY_WATCHDOG: - case VerboseTraits::K_CM_STOP_WATCHDOG: - case VerboseTraits::K_CM_START_WATCHDOG: - return show(buf, commandName(code) , Target(DEVICE, obj)); - case VerboseTraits::K_CM_WATCHDOG_COUNT: - return show(buf, commandName(code) , Target(NONE)); -#endif - - } - - /* default command handler */ - return show(buf, commandName(code), Target(CHANNEL, dev, obj)); -} - -#if K3L_AT_LEAST(2,0,0) -std::string Verbose::event(const KSignaling sig, const int32 obj_idx, const K3L_EVENT * const ev, const R2CountryType r2_country, const Verbose::Presentation fmt) -#else -std::string Verbose::event(const KSignaling sig, const int32 obj_idx, const K3L_EVENT * const ev, const Verbose::Presentation fmt) -#endif -{ - unsigned short int dev = (unsigned short int) ev->DeviceId; - unsigned short int obj = (unsigned short int) obj_idx; - - VerboseTraits::Event code = (VerboseTraits::Event) ev->Code; - - std::string buf; - std::string extra; - - switch (code) - { - case VerboseTraits::VerboseTraits::K_EV_CHANNEL_FREE: - case VerboseTraits::VerboseTraits::K_EV_SEIZE_SUCCESS: - case VerboseTraits::VerboseTraits::K_EV_CALL_SUCCESS: - case VerboseTraits::VerboseTraits::K_EV_NO_ANSWER: - case VerboseTraits::VerboseTraits::K_EV_CONNECT: - case VerboseTraits::VerboseTraits::K_EV_DTMF_SEND_FINISH: - case VerboseTraits::VerboseTraits::K_EV_SEIZURE_START: - case VerboseTraits::VerboseTraits::K_EV_BILLING_PULSE: - case VerboseTraits::VerboseTraits::K_EV_REFERENCE_FAIL: - -#if K3L_AT_LEAST(1,4,0) - case VerboseTraits::VerboseTraits::K_EV_CALL_HOLD_START: - case VerboseTraits::VerboseTraits::K_EV_CALL_HOLD_STOP: -#endif - -#if K3L_AT_LEAST(1,5,0) - case VerboseTraits::VerboseTraits::K_EV_NEW_CALL: -#endif - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::VerboseTraits::K_EV_FLASH: - case VerboseTraits::VerboseTraits::K_EV_POLARITY_REVERSAL: - case VerboseTraits::VerboseTraits::K_EV_COLLECT_CALL: - case VerboseTraits::VerboseTraits::K_EV_RING_DETECTED: - case VerboseTraits::VerboseTraits::K_EV_SS_TRANSFER_FAIL: -#endif -#if K3L_HAS_MPTY_SUPPORT - case VerboseTraits::VerboseTraits::K_EV_CALL_MPTY_START: - case VerboseTraits::VerboseTraits::K_EV_CALL_MPTY_STOP: -#endif - break; - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::VerboseTraits::K_EV_RECV_FROM_MODEM: - case VerboseTraits::VerboseTraits::K_EV_SMS_INFO: - case VerboseTraits::VerboseTraits::K_EV_SMS_DATA: -#endif - extra = "data='"; - extra += (ev->Params ? (const char *)(ev->Params) : ""); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::VerboseTraits::K_EV_SMS_SEND_RESULT: - extra = "result='"; -#if K3L_AT_LEAST(2,0,0) - extra += gsmSmsCause((KGsmSmsCause)ev->AddInfo); -#else - extra += gsmCallCause((KGsmCallCause)ev->AddInfo); -#endif - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - -#if K3L_HAS_MPTY_SUPPORT - case VerboseTraits::VerboseTraits::K_EV_GSM_COMMAND_STATUS: - extra = "result='"; - extra += gsmMobileCause((KGsmMobileCause)ev->AddInfo); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); -#endif - - case VerboseTraits::VerboseTraits::K_EV_CALL_ANSWER_INFO: - extra = "info='"; - extra += callStartInfo((KCallStartInfo)ev->AddInfo); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_NEW_SMS: - if (ev->AddInfo != 0) - { - extra = "messages='"; - extra += STG(FMT("%d") % ev->AddInfo); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - } - else - { - return show(buf, eventName(code), Target(CHANNEL, dev, obj)); - } - - case VerboseTraits::VerboseTraits::K_EV_ISDN_PROGRESS_INDICATOR: - if (ev->AddInfo != 0) - { - extra = "indication='"; - extra += q931ProgressIndication((KQ931ProgressIndication)ev->AddInfo); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - } - else - { - return show(buf, eventName(code), Target(CHANNEL, dev, obj)); - } -#endif - - case VerboseTraits::VerboseTraits::K_EV_CAS_LINE_STT_CHANGED: - extra = STG(FMT("[a=%d,b=%d,c=%d,d=%d]") - % ((ev->AddInfo & 0x8) >> 3) % ((ev->AddInfo & 0x4) >> 2) - % ((ev->AddInfo & 0x2) >> 1) % (ev->AddInfo & 0x1)); - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_CAS_MFC_RECV: - extra = STG(FMT("digit='%d'") % ev->AddInfo); - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_CALL_FAIL: - extra = "cause='"; -#if K3L_AT_LEAST(2,0,0) - extra += callFail(sig, r2_country, ev->AddInfo); -#else - extra += callFail(sig, ev->AddInfo); -#endif - extra += "'"; - - if (ev->Params != NULL && ev->ParamSize != 0) - { - if (!extra.empty()) - extra += ","; - - extra += "params='"; - extra += (const char *) ev->Params; - extra += "'"; - } - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_DISCONNECT: - switch (sig) - { -#if K3L_AT_LEAST(1,5,1) - case ksigOpenCCS: - case ksigPRI_EndPoint: - case ksigPRI_Network: - case ksigPRI_Passive: - extra = "cause='"; - extra += isdnCause((KQ931Cause) ev->AddInfo); - extra += "'"; -#endif - default: - break; - } - - if (ev->Params != NULL && ev->ParamSize != 0) - { - if (!extra.empty()) - extra += ","; - - extra += "params='"; - extra += (const char *) ev->Params; - extra += "'"; - } - - if (!extra.empty()) - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - else - return show(buf, eventName(code), Target(CHANNEL, dev, obj)); - - break; - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::VerboseTraits::K_EV_SIP_DTMF_DETECTED: -#endif - case VerboseTraits::VerboseTraits::K_EV_DTMF_DETECTED: - case VerboseTraits::VerboseTraits::K_EV_PULSE_DETECTED: - case VerboseTraits::VerboseTraits::K_EV_DIALED_DIGIT: - extra = STG(FMT("digit='%c'") % (char)ev->AddInfo); - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_SEIZURE: - { - KIncomingSeizeParams *n = (KIncomingSeizeParams *) - ( ((char*)ev) + sizeof(K3L_EVENT) ); - - extra += "orig_addr='"; - extra += n->NumberA; - extra += "',dest_addr='"; - extra += n->NumberB; - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - } - -#if K3L_AT_LEAST(1,4,0) - case VerboseTraits::VerboseTraits::K_EV_VOIP_SEIZURE: - { - char *numB = ((char*)ev) + sizeof(K3L_EVENT); - char *numA = numB + 61; - - extra = "numberA='"; - extra += numA; - extra += "',numberB='"; - extra += numB; - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - } -#endif - - - case VerboseTraits::VerboseTraits::K_EV_END_OF_STREAM: - return show(buf, eventName(code), Target(PLAYER, dev, obj)); - - case VerboseTraits::VerboseTraits::K_EV_AUDIO_STATUS: - extra = "tone='"; - extra += mixerTone((KMixerTone)ev->AddInfo); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_CADENCE_RECOGNIZED: - extra = STG(FMT("cadence='%c'") % (char)(ev->AddInfo)); - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_CHANNEL_FAIL: - extra = "reason='"; - extra += channelFail(sig, ev->AddInfo); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_SEIZE_FAIL: - extra = "reason='"; - extra += seizeFail((KSeizeFail) ev->AddInfo); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_INTERNAL_FAIL: - extra = "reason='"; - extra += internalFail((KInternalFail) ev->AddInfo); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_HARDWARE_FAIL: - extra = "component='"; - extra += systemObject((KSystemObject) ev->AddInfo); - extra += "'"; - - switch (ev->AddInfo) - { - case ksoChannel: - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - case ksoLink: - return show(buf, eventName(code), Target(LINK, dev, obj), extra); - case ksoLinkMon: - case ksoH100: - case ksoFirmware: - case ksoDevice: - return show(buf, eventName(code), Target(DEVICE, dev), extra); - case ksoAPI: - return show(buf, eventName(code), Target(NONE), extra); - } - - - case VerboseTraits::VerboseTraits::K_EV_LINK_STATUS: - // EV_LINK_STATUS has always zero in ObjectInfo (and AddInfo!) - /* fall throught... */ - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::VerboseTraits::K_EV_PHYSICAL_LINK_UP: - case VerboseTraits::VerboseTraits::K_EV_PHYSICAL_LINK_DOWN: - return show(buf, eventName(code), Target(LINK, dev, obj)); -#endif - -#if K3L_AT_LEAST(1,5,1) - case VerboseTraits::VerboseTraits::K_EV_USER_INFORMATION: - { - KUserInformation *info = (KUserInformation *)(ev->Params); - - std::string data((const char *)info->UserInfo, - std::min(info->UserInfoLength, KMAX_USER_USER_LEN)); - - extra = STG(FMT("proto='%d',length='%d',data='%s'") - % info->ProtocolDescriptor % info->UserInfoLength % data); - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - } -#endif - -#if K3L_AT_LEAST(1,6,0) - case VerboseTraits::VerboseTraits::K_EV_SIP_REGISTER_INFO: - extra = "params='"; - extra += (ev->Params ? (const char *) (ev->Params) : ""); - extra += "',status='"; - extra += sipFailures((KSIP_Failures)(ev->AddInfo)); - extra += "'"; - - return show(buf, eventName(code), Target(DEVICE, dev), extra); -#endif - -#if !K3L_AT_LEAST(2,0,0) - case VerboseTraits::VerboseTraits::K_EV_PONG: -#endif - -#if K3L_AT_LEAST(1,4,0) - case VerboseTraits::VerboseTraits::K_EV_CLIENT_RECONNECT: -#endif - return show(buf, eventName(code), Target(NONE)); - -#if K3L_AT_LEAST(2,1,0) - case VerboseTraits::VerboseTraits::K_EV_FAX_CHANNEL_FREE: - extra = "status='"; - extra += faxResult((KFaxResult)ev->AddInfo); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_FAX_FILE_SENT: - extra = "filename='"; - extra += (ev->Params ? (const char *) (ev->Params) : ""); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_FAX_FILE_FAIL: - extra = "cause='"; - extra += faxFileErrorCause((KFaxFileErrorCause)ev->AddInfo); - extra += "',filename='"; - extra += (ev->Params ? (const char *) (ev->Params) : ""); - extra += "'"; - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_FAX_REMOTE_INFO: - extra = ((ev->Params && ev->ParamSize != 0) ? (const char *) ev->Params : ""); - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - - case VerboseTraits::VerboseTraits::K_EV_FAX_PAGE_CONFIRMATION: - case VerboseTraits::VerboseTraits::K_EV_FAX_TX_TIMEOUT: - return show(buf, eventName(code), Target(CHANNEL, dev, obj)); -#endif - -#if K3L_AT_LEAST(2,1,0) - case VerboseTraits::VerboseTraits::K_EV_WATCHDOG_COUNT: - extra = STG(FMT("count='%d'") % (char)ev->AddInfo); - return show(buf , eventName(code), Target(NONE), extra); -#endif - -#if K3L_AT_LEAST(2,1,0) - case VerboseTraits::VerboseTraits::K_EV_CT_TRANSFER_FAIL: - extra = "cause='"; - extra += isdnCause((KQ931Cause)ev->AddInfo); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); -#endif - } - - // default handler... - if (ev->Params != NULL && ev->ParamSize != 0) - { - extra += "params='"; - extra.append((const char *) ev->Params, (unsigned int) std::max(ev->ParamSize - 1, 0)); - extra += "'"; - - return show(buf, eventName(code), Target(CHANNEL, dev, obj), extra); - } - else - return show(buf, eventName(code), Target(CHANNEL, dev, obj)); -} - -/********************************************/ - -std::string Verbose::show(std::string & buf, const std::string & name, const Target tgt, const std::string & extra) -{ - if (tgt.type == NONE) - { - generate(buf, name, tgt, extra); - } - else - { - std::string tmp(","); - tmp += extra; - - generate(buf, name, tgt, tmp); - } - - return buf; -} - -std::string Verbose::show(std::string & buf, const std::string & name, const Target tgt) -{ - std::string tmp(""); - - generate(buf, name, tgt, tmp); - return buf; -} - -void Verbose::generate(std::string & buf, const std::string & name, const Target tgt, const std::string & extra) -{ - switch (tgt.type) - { - case NONE: - if (extra.empty()) - buf += STG(FMT("<%s>") % name); - else - buf += STG(FMT("<%s> (%s)") % name % extra); - break; - - case DEVICE: - buf += STG(FMT("<%s> (d=%02d%s)") - % name % tgt.device % extra); - break; - - default: - { - const char *kind = "o"; - - switch (tgt.type) - { - case CHANNEL: - kind = "c"; - break; - case PLAYER: - kind = "p"; - break; - case MIXER: - kind = "m"; - break; - case LINK: - kind = "l"; - default: - break; - } - - buf += STG(FMT("<%s> (d=%02d,%s=%03d%s)") - % name % tgt.device % kind % tgt.object % extra); - break; - } - } -} - diff --git a/src/mod/endpoints/mod_khomp/commons/base/verbose.hpp b/src/mod/endpoints/mod_khomp/commons/base/verbose.hpp deleted file mode 100644 index a0ea290b7e..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/base/verbose.hpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2009 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file under - the MPL, indicate your decision by deleting the provisions above and replace them - with the notice and other provisions required by the LGPL License. If you do not - delete the provisions above, a recipient may use your version of this file under - either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef _VERBOSE_HPP_ -#define _VERBOSE_HPP_ - -#include -#include -#include - -#include - -// k3lApiMajorVersion -#ifndef CM_PING -# include -# include -#endif - -#include -#include -#include - -#include - -struct Verbose -{ - typedef enum - { - R2_COUNTRY_BRA = 1, - R2_COUNTRY_ARG = 2, - R2_COUNTRY_CHI = 3, - R2_COUNTRY_MEX = 4, - R2_COUNTRY_URY = 5, - R2_COUNTRY_VEN = 6 - } - R2CountryType; - - typedef enum - { - HUMAN, - EXACT - } - Presentation; - - /* dynamic (object) stuff */ - - Verbose(const K3LAPI & api) - : _api(api) {}; - -#if K3L_AT_LEAST(2,0,0) - std::string event(const int32, const K3L_EVENT * const, - const R2CountryType r2_country = R2_COUNTRY_BRA, - const Presentation fmt = HUMAN) const; -#else - std::string event(const int32, const K3L_EVENT * const, - const Presentation fmt = HUMAN) const; -#endif - - std::string channelStatus(const int32, const int32, const int32, - const Presentation fmt = HUMAN) const; - - /* end of dynamic (object) stuff */ - - protected: - const K3LAPI & _api; - - /* used internally */ - struct internal_not_found {}; - - public: - - /* static (class) stuff */ - - static std::string echoLocation(const KEchoLocation, const Presentation fmt = HUMAN); - static std::string echoCancellerConfig(const KEchoCancellerConfig, const Presentation fmt = HUMAN); - -#if K3L_AT_LEAST(2,0,0) - static std::string event(const KSignaling, const int32, const K3L_EVENT * const, - const R2CountryType = R2_COUNTRY_BRA, Presentation fmt = HUMAN); -#else - static std::string event(const KSignaling, const int32, const K3L_EVENT * const, - const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(2,0,0) - static std::string command(const int32, const K3L_COMMAND * const, - const R2CountryType = R2_COUNTRY_BRA, - const Presentation fmt = HUMAN); - - static std::string command(const int32, const int32, const int32, const char * const, - const R2CountryType = R2_COUNTRY_BRA, - const Presentation fmt = HUMAN); -#else - static std::string command(const int32, const K3L_COMMAND * const, - const Presentation fmt = HUMAN); - - static std::string command(const int32, const int32, const int32, const char * const, - const Presentation fmt = HUMAN); -#endif - - static std::string deviceName(const KDeviceType, const int32, const int32 count = 0, const Presentation fmt = HUMAN); - static std::string deviceName(const KDeviceType, const int32, const Presentation fmt); - - static std::string deviceType(const KDeviceType, const int32 count = 0, const Presentation fmt = HUMAN); - static std::string deviceType(const KDeviceType, const Presentation fmt); - - static std::string deviceModel(const KDeviceType, const int32, const int32 count = 0, const Presentation fmt = HUMAN); - static std::string deviceModel(const KDeviceType, const int32, const Presentation fmt); - - static std::string channelFeatures(const int32, const Presentation fmt = HUMAN); - static std::string signaling(const KSignaling, const Presentation fmt = HUMAN); - static std::string systemObject(const KSystemObject, const Presentation fmt = HUMAN); - static std::string mixerTone(const KMixerTone, const Presentation fmt = HUMAN); - static std::string mixerSource(const KMixerSource, const Presentation fmt = HUMAN); - - static std::string seizeFail(const KSeizeFail, const Presentation fmt = HUMAN); - -#if K3L_AT_LEAST(2,0,0) - static std::string callFail(const KSignaling, const R2CountryType, const int32, const Presentation fmt = HUMAN); -#else - static std::string callFail(const KSignaling, const int32, const Presentation fmt = HUMAN); -#endif - - static std::string channelFail(const KSignaling, const int32, const Presentation fmt = HUMAN); - static std::string internalFail(const KInternalFail, const Presentation fmt = HUMAN); - - static std::string linkErrorCounter(const KLinkErrorCounter, const Presentation fmt = HUMAN); - - static std::string linkStatus(const KSignaling, const int32, const Presentation fmt = HUMAN, const bool simpleStatus = false); - static std::string channelStatus(const KSignaling, const int32, const Presentation fmt = HUMAN); - static std::string callStatus(const KCallStatus, const Presentation fmt = HUMAN); - static std::string status(const KLibraryStatus, const Presentation fmt = HUMAN); - -#if K3L_AT_LEAST(2,0,0) - static std::string signGroupB(const KSignGroupB, const R2CountryType contry = R2_COUNTRY_BRA, - Presentation fmt = HUMAN); -#else - static std::string signGroupB(const KSignGroupB, const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(2,0,0) - static std::string signGroupII(const KSignGroupII, const R2CountryType contry = R2_COUNTRY_BRA, - Presentation fmt = HUMAN); -#else - static std::string signGroupII(const KSignGroupII, const Presentation fmt = HUMAN); -#endif - - static std::string h100configIndex(const KH100ConfigIndex, const Presentation fmt = HUMAN); - - static std::string eventName(const int32 value) - { - return VerboseTraits::eventName((VerboseTraits::Event)value); - }; - - static std::string commandName(const int32 value) - { - return VerboseTraits::commandName((VerboseTraits::Command)value); - }; - -#if K3L_AT_LEAST(1,5,0) - static std::string sipFailures(const KSIP_Failures, const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(1,5,1) - static std::string isdnCause(const KQ931Cause, const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(1,5,2) - static std::string isdnDebug(const int32, const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(1,6,0) - static std::string callStartInfo(const KCallStartInfo, const Presentation fmt = HUMAN); - - static std::string gsmCallCause(const KGsmCallCause, const Presentation fmt = HUMAN); - static std::string gsmMobileCause(const KGsmMobileCause, const Presentation fmt = HUMAN); - static std::string gsmSmsCause(const KGsmSmsCause, const Presentation fmt = HUMAN); - - static std::string q931ProgressIndication(const KQ931ProgressIndication, - Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(2,1,0) - static std::string faxResult(const KFaxResult code, const Presentation fmt = HUMAN); - static std::string faxFileErrorCause(const KFaxFileErrorCause code, const Presentation fmt = HUMAN); -#endif - - /* end of static (class) stuff */ - - private: - static std::string internal_deviceType(const KDeviceType, const int32); - static std::string internal_deviceModel(const KDeviceType, const int32, const int32); - -#if K3L_AT_LEAST(1,5,0) - static std::string internal_sipFailures(const KSIP_Failures, const Presentation fmt = HUMAN); -#endif -#if K3L_AT_LEAST(1,5,1) - static std::string internal_isdnCause(const KQ931Cause, const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(2,0,0) - static std::string internal_signGroupB(const KSignGroupB, const R2CountryType contry, const Presentation fmt = HUMAN); - static std::string internal_signGroupII(const KSignGroupII, const R2CountryType contry, const Presentation fmt = HUMAN); -#else - static std::string internal_signGroupB(const KSignGroupB, const Presentation fmt = HUMAN); - static std::string internal_signGroupII(const KSignGroupII, const Presentation fmt = HUMAN); -#endif - -#if K3L_AT_LEAST(1,6,0) - static std::string internal_gsmCallCause(const KGsmCallCause, const Presentation fmt = HUMAN); - static std::string internal_gsmMobileCause(const KGsmMobileCause, const Presentation fmt = HUMAN); - static std::string internal_gsmSmsCause(const KGsmSmsCause, const Presentation fmt = HUMAN); - - static std::string internal_q931ProgressIndication(const KQ931ProgressIndication, const Presentation fmt = HUMAN); -#endif - - private: - enum Type - { - DEVICE, - CHANNEL, - PLAYER, - MIXER, - LINK, - NONE - }; - - struct Target - { - Target(Type _type) - : type(_type), device(-1), object(-1) - {}; - - Target(Type _type, int32 _device) - : type(_type), device(_device), object(-1) - {}; - - Target(Type _type, int32 _device, int32 _object) - : type(_type), device(_device), object(_object) - {}; - - const Type type; - const int32 device; - const int32 object; - }; - - static void generate(std::string &, const std::string &, const Target, const std::string &); - - static std::string show(std::string &, const std::string &, const Target, const std::string &); - static std::string show(std::string &, const std::string &, const Target); - - template < typename ReturnType > - static ReturnType presentation(const Presentation fmt, ReturnType str_exact, ReturnType str_human) - { - switch (fmt) - { - case HUMAN: return str_human; - case EXACT: return str_exact; - }; - - return str_exact; - } -}; - -#endif /* _VERBOSE_HPP_ */ diff --git a/src/mod/endpoints/mod_khomp/commons/tools/generate-verbose-headers.sh b/src/mod/endpoints/mod_khomp/commons/tools/generate-verbose-headers.sh deleted file mode 100755 index 7b9012baea..0000000000 --- a/src/mod/endpoints/mod_khomp/commons/tools/generate-verbose-headers.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/sh - -cut_defines () -{ - cut -b9- | cut -f1 | cut -d' ' -f1 -} - -list_commands () -{ - egrep -h 'define.+CM_' "$@" | cut_defines -} - -list_events () -{ - # list and remove deprecations - egrep -h 'define.+EV_' "$@" | cut_defines | \ - grep -v 'EV_CALL_PROGRESS\|EV_FAX_MESSAGE_CONFIRMATION' -} - -make_enumeration_one_by_one () -{ - while read line - do - local size=$[50 - $(expr length "${line}")] - - echo -n " K_${line}" - - for ((i=0;i" - echo - echo "#include " - echo - echo "#include " - echo - echo "struct VerboseTraits" - echo "{" - make_enumeration "Command" list_commands "$@" || return 1 - echo - make_enumeration "Event" list_events "$@" || return 1 - echo - echo " static std::string eventName(const Event);" - echo " static std::string commandName(const Command);" - echo "};" - echo - echo "#endif /* _VERBOSE_TRAITS_H_ */" -} - -make_source () -{ - make_license - - echo "#include " - echo - - make_switch_case "Event" "event" list_events "$@" || return 1 - echo - make_switch_case "Command" "command" list_commands "$@" || return 1 -} - -make_run () -{ - local destdir="$1"; shift - - if [ ! -d "${destdir}" ] - then - echo "ERROR: First argument is not a directory!" - return 1 - fi - - make_header "$@" > "${destdir}/verbose_traits.hpp" - make_source "$@" > "${destdir}/verbose_traits.cpp" -} - -make_run "$@" diff --git a/src/mod/endpoints/mod_khomp/docs/Manual.html b/src/mod/endpoints/mod_khomp/docs/Manual.html deleted file mode 100644 index b1fcfc0107..0000000000 --- a/src/mod/endpoints/mod_khomp/docs/Manual.html +++ /dev/null @@ -1,1091 +0,0 @@ -Mod Khomp: Manual -

Consideraes iniciais

-

Este documento aborda informaes sobre o Endpoint da Khomp como um todo, desde opes disponveis de configurao, os applications disponibilizados, os possveis comandos de CLI, entre outros. -

Para procedimentos sobre a instalao, favor consultar o README do Endpoint. -
-

-

Configurao

-

Configurar o Endpoint da Khomp uma tarefa que consiste de trs etapas: -

-
  • Configurao das placas, atravs da K3L; -
  • Configurao do Endpoint; -
  • Configurao do FreeSWITCH. -
-

Estas etapas so descritas mais detalhadamente abaixo. -
-

-

Configurao da API K3L

-

Esta etapa realizada de maneira semi-automatizada atravs do programa khompwizard, um assistente que configura os parmetros bsicos das placas do sistema. Esse assistente inicializa os arquivos de configurao atravs de informaes obtidas do usurio, quando estas forem necessrias, inicializando as configuraes menos utilizadas com os valores padres. -

Normalmente, este programa executado automaticamente aps a instalao do sistema. Entretanto, pode ser necessrio execut-lo manualmente caso uma atualizao esteja sendo realizada, ou se novas placas foram adicionadas no sistema aps a instalao dos drivers da placa. -

Caso seja necessria a configurao de parmetros avanados da placa e/ou da sinalizao, o programa k3lconfig permite acessar todas as configuraes disponveis de cada placa instalada. Para maiores informaes sobre este programa, consulte a documentao do mesmo. Para solues de problemas de sincronismo, consulte a seo Soluo de problemas sobre o procedimento de configurao manual das placas. -
-

-

Configurao do Endpoint

-

A configurao padro do sistema costuma atender maior parte das necessidades. Entretanto, as configuraes do Endpoint da Khomp podem ser modificadas atravs do arquivo de configurao '/usr/local/freeswitch/conf/autoload_configs/khomp.conf.xml'. -

A lista de opes a seguinte: -

-

<channels>

-

Define as configuraes gerais de todos os canais da Khomp. -

-
Sintaxe: <param name="..." value="..."/>
-
-


-

-
  • accountcode: Define o account code padro para chamadas no Endpoint. Esta opo pode ser qualquer string alfanumrica; -
  • dialplan: Nome do mdulo de dialplan em uso. -
  • auto-fax-adjustment: Ativa ("yes") ou desativa ("no") o ajuste automtico do canal (desabilitar o cancelador de eco e a supresso DTMF) ao detectar tom de FAX; -
  • auto-gain-control: Ativa ("yes") ou desativa ("no") a ativao do controle automtico de ganho (AGC) pelo Endpoint; -
  • context-digital: Contexto de entrada para ligaes em placas digitais (o padro "khomp-DD-LL", onde "DD" ser substitudo, no momento da ligao, pelo nmero do dispositivo, "LL" pelo nmero do link, "CCC" pelo nmero do canal e "SSSS" pelo nmero serial do dispositivo); -
  • context-fxo: Contexto de entrada para placas FXO (o padro "khomp-DD-CC", onde "DD" ser substitudo, no momento da ligao, pelo nmero do dispositivo, "CC" pelo nmero do canal, e "SSSS" pelo nmero serial do dispositivo); -
  • context-fxs: Contexto de entrada para placas FXS (o padro "khomp-DD-CC", onde "DD" ser substitudo, no momento da ligao, pelo nmero do dispositivo, "CC" pelo nmero do canal, e "SSSS" pelo nmero serial do dispositivo); -
  • context-gsm-call (ou "context-gsm"): Contexto de entrada para ligaes GSM (o padro "khomp-DD-CC", onde "DD" ser substitudo no momento da ligao pelo nmero do dispositivo, "CC" pelo nmero do canal, e "SSSS" pelo nmero serial do dispositivo); -
  • context-gsm-sms: Contexto de entrada para SMSs (o padro "khomp-sms-DD-CC", onde "DD" ser substitudo pelo nmero de dispositivo, "CC" pelo nmero do canal, e "SSSS" pelo nmero serial do dispositivo); -
  • context-pr: Contexto de entrada para ligaes em placas KPR (o padro "khomp-DD-CC", onde "DD" ser substitudo, no momento da ligao, pelo nmero do dispositivo, "CC" pelo nmero do canal); -
  • delay-ringback-co: Define o tempo de delay para ativar a gerao de tom de controle de chamada (ringback) pelo Endpoint da Khomp quando h uma indicao de ringback, e no h udio sendo enviado por quem indicou a situao de controle da chamada; -
  • delay-ringback-pbx: Define o tempo de delay para ativar a gerao de controle de chamada (ringback) pelo Endpoint da Khomp quando h uma indicao de ringback, e o udio de controle enviado no possui nenhum tom (ou seja, est em silncio); -
  • disconnect-delay: Define o tempo em milissegundos para realizar o processamento de um evento de desconexo, para ignorar situaes onde outros equipamentos realizam o duplo atendimento para derrubar chamadas a cobrar; -
  • drop-collect-call: Ativa ("yes") ou desativa ("no") o derrubamento de chamadas cobrar. Caso ativo, todas as chamadas cobrar sero derrubadas no importando o que foi ajustado na varivel KDropCollectCall (o valor padro "no"); -
  • echo-canceller: Ativa ("yes") ou desativa ("no") o cancelamento de eco automtico pelo Endpoint; -
  • flash-to-digits: Define os dgitos para serem enviados quando o FLASH detectado na FXS; -
  • fxo-send-pre-audio: Quando ativada ("yes") libera canal de udio sainte antes da conexo da chamada em placas KFXO (o valor padro "yes"); -
  • fxs-digit-timeout: Define o timeout, em segundos, entre dgitos na FXS; -
  • fxs-global-orig: Nmero inicial para numerao seqencial de ramais das placas KFXS que no estiverem listadas na seo <fxs-branches> (a numerao segue ordem crescente por nmero da placa e nmero do canal fsico) (o padro "0"); -
  • fxs-co-dialtone: Seqncias de nmeros, separados por vrgula, que disparam um tom contnuo (de central pblica) em ramais FXS (ex: "0,99" faz com que, ao discar "0" ou "99", o usurio receba o tom de linha contnuo) (o padro vazio); -
  • fxs-bina: Quando ativada ("yes"), ligaes para ramais FXS enviaro os dgitos correspondentes ao telefone de origem em sinalizao BINA DTMF (o valor padro "no"); -
  • language: Define idioma para ligaes nas placas Khomp; -
  • ignore-letter-dtmfs: Define se o canal deve ignorar DTMFs incomuns detectados pela placa (A, B, C e D). Entretanto, se voc necessita passar esses dgitos pela placa, voc deve ajustar esta opo para "no" (o valor padro "yes"); -
  • input-volume: Define o volume de entrada das ligaes, varia de -10 a +10 ; -
  • kommuter-activation: Define se a ativao de dispositivos kommuter encontrados no sistema ser feita de forma automtica ("auto"), ou de forma manual ("manual") pelo usurio, atravs do comando "khomp kommuter on/off"; -
  • kommuter-timeout: Define o timeout (em segundos) com que os kommuters sero inicializados. Se chegarem a este timeout sem receberem notificao do channel, os dispositivos iro comutar para o estado "desligado". O valor mnimo "0" , onde os links permanecero sempre comutados no estado "ligado", e o valor mximo "255"; -
  • log-to-console: Define mensagens de log que devem ser impressas na console; -
  • log-to-disk: Define mensagens de log que devem ser salvar em disco; -
  • out-of-band-dtmfs: Ativa ("yes") ou desativa ("no") a supresso DTMF e o envio destes out-of-band; -
  • output-volume: Define o volume de sada das ligaes, varia de -10 a +10 ; -
  • pulse-forwarding: Ativa ("yes") ou desativa ("no") a deteco de pulsos e a converso dos mesmos em DTMFs; -
  • r2-preconnect-wait: Define o tempo de espera do envio da sinalizao de ringback, no protocolo R2/MFC, para iniciar o envio de udio de silncio. Apenas utilizado quando "r2-strict-behaviour" estiver ajustado para "no"; -
  • r2-strict-behaviour: Ativa ("yes") ou desativa ("no") o comportamento da sinalizao R2/MFC conforme a norma define. O padro "no", e pode ser alterado para "yes" caso seja necessrio receber/enviar dados precisos da sinalizao do protocolo (condio de B, por exemplo); -
  • suppression-delay: Ativa ("yes") ou desativa ("no") o delay necessrio para supresso DTMF. Se desativado ("no"), tambm desativa supresso de DTMFs; -
  • trace: Define opes de depurao. No deve ser utilizado em produo a no ser que estritamente necessrio; -
  • user-transfer-digits: Define uma seqncia de dgitos DTMF para iniciar a transferencia entre o FreeSWITCH® e um outro PABX (utilizando sinalizao de usurio, como QSig ou FXO FLASH); -
-


-

-

<groups>

-

Define os grupos para serem usados na alocao de canal. -

Neste caso, as opes so usadas para definir nomes para strings de alocao de canais. O formato segue o padro <param name="nome grupo" value="string alocao"/>, onde as strings de alocao de canais so as mesmas utilizadas no application bridge, e nome do grupo um nome arbitrrio escolhido pelo usurio. -

-
Por exemplo, para definir o grupo pstn como os canais 0 e 5 da placa 0, deveria-se utilizar a linha: -
-
<param name="pstn" value="b0c0 + b0c5"/> 
-
-

Este grupo, por sua vez, poderia ser usado no application bridge como <action application="bridge" data="Khomp/Gpstn/..."/>. -

-
Pode-se tambm associar um determinado contexto de entrada a um grupo de canais, bastando especificar um nome de contexto aps a string de alocao, separado por ':' da mesma. -
-

Por exemplo, para definir o mesmo grupo pstn acima como os canais 0 at 20 da placa 0, com contexto de entrada from-pstn, poderia-se utilizar a linha: -

-
<param name="pstn" value="b0c0-20:from-pstn"/>
-
-

Este grupo, por sua vez, poderia ser usado no application bridge como <action application="bridge" data="Khomp/Gpstn/..."/>, e todas as ligaes vindas destes canais seriam tratadas no contexto from-pstn. -
-

-

<cadences>

-

Define configuraes de cadncias para o Endpoint. -

Neste caso, as opes so nomes de cadncias e um ou dois pares de nmeros, que definem os intervalos de tom e silncio a ser utilizado nas cadncias. Para maiores detalhes, favor consultar o arquivo de configurao. -
-

-

<fxs-branches>

-

Define nmeros de origem para a placa KFXS. -

Neste caso, as opes so seqncias de prefixos de ramais e nmeros seriais das placas, que definem os nmeros base dos endereos de origem, e a ordem numrica das placas. O formato das opes : -

-
<param name="prefixo" value="serial1, serial2, ...."/>
-
-

Por exemplo, para definir que as placas K0374 e K2352 devem ser numeradas seqencialmente, partido do ramal 200, basta escrever: -

-
<param name="200" value="374, 2352"/>
-
-

Para maiores detalhes, favor consultar o arquivo de configurao. -
-

-

<fxs-hotlines>

-

Define hotlines para a placa KFXS. -

Neste caso, as opes so seqncias de ramais e nmeros de destino, definindo os ramais listados nesta seo para serem tratados como "hotlines". Para cada ramal listado, o nmero de destino especificado ser discado quando o ramal for retirado do gancho. Exemplo: -

-
<param name="100" value="1234"/>
-<param name="200" value="4321"/> 
-
-

No primeiro exemplo, o ramal de nmero 100 ir telefonar para nmero 1234 ao ser retirado do gancho; no segundo, o ramal de nmero 200 ir telefonar para o nmero 4321 ao ser retirado do gancho. -

-

<fxs-options>

-

Permite definir configuraes especficas por ramal FXS. -

Neste caso, as configuraes so nmeros de ramais (baseado nos definidos na seo <fxs-branches>), e as opes e seus valores. As opes disponveis so: -

-
  • context; -
  • input-volume; -
  • output-volume; -
  • language; -
  • accountcode; -
  • calleridnum; -
  • calleridname; -
  • flash-to-digits. -
-

Cada opo separada uma da outra por um pipe "|" ou uma barra "/" e definidas aps dois pontos ":", exemplo: -

-
 <param name="200" value="input-volume:1|context:master-branch" />
-
-

Para maiores informaes sobre a sintaxe e exemplos, favor consultar o arquivo de configurao. -


-

Para maiores informaes, consultar o arquivo de configurao 'khomp.conf.xml'. -
-

-

Configurao do FreeSWITCH

-

Quando as ligaes so recebidas nas placas e dispositivos Khomp, estas so encaminhadas pelo Endpoint da Khomp para contextos especficos dentro do plano de discagem do FreeSWITCH®. Estes contextos podem ser alterados atravs do arquivo de configuraes khomp.conf.xml, disponvel no diretrio de configurao do FreeSWITCH (por padro, "/usr/local/freeswitch/conf/autoload_configs"). -

Para maiores detalhes sobre os contextos especficos, consultar a seo de Configurao do Endpoint. -

Abaixo, encontram-se informaes de como configurar os contextos de entrada de chamadas: -
-


-

-

Contextos de entrada em canais E1

-

Para placas E1, as ligaes de entrada por padro chegam em um contexto pr-definido conforme a opo context-digital: -

-
<param name="context-digital" value="khomp-DD-LL"/>
-
-

Este contexto padro define que as ligaes sero redirecionadas de acordo com o nmero da placa e nmero do link: DD o nmero dispositivo (com dois dgitos), e LL o nmero do link (tambm com dois dgitos). -

Entretanto, possvel configurar outros contextos de entrada, com formatos diferenciados. Pode-se utilizar a opo CCC, que significa o nmero do canal na placa (com trs dgitos), e SSSS, que representa o nmero serial da placa (com quatro dgitos). -

Exemplos de configurao no arquivo khomp.conf.xml: -

-
<!-- nmero seqencial da placa e do link (ex: khomp-01-00) -->
-<param name="context-digital" value="khomp-DD-LL"/>
-
-
<!-- nmero serial da placa e seqencial do link (ex: khomp-3049-00) -->
-<param name="context-digital" value="khomp-SSSS-LL"/>
-
-
<!-- nmero seqencial da placa e do canal (ex: khomp-00-001) -->
-<param name="context-digital" value="khomp-DD-CCC"/>
-
-
<!-- recebe todas as chamadas em um s contexto (khomp-digital) -->
-<param name="context-digital" value="khomp-digital"/>
-
-

Abaixo um exemplo de contexto no plano de discagem: - -

-
<!-- 
-Este contexto presente em seu arquivo de dialplan, ir manipular chamadas
-de entrada no link 0 (primeiro link) da placa 0.
--->
-<context name="khomp-00-00">
-             .
-             .
-             .
-</context>
-
-

Outro exemplo, utilizando o mesmo formato: - -

-
<!-- 
-Este contexto presente em seu arquivo de dialplan, ir manipular chamadas
-de entrada no link 1 (segundo link) da placa 0.
--->
-<context name="khomp-00-01>
-             .
-             .
-             .
-</context>
-
-

Um exemplo completo, com algumas aes simples: - -

-
<context name="khomp-00-00">
-    <extension name="exemplo_1">
-        <condition field="destination_number" expression="^1234$">
-            <action application="bridge" data="Khomp/b0L1/2345"/>
-        </condition>
-    </extension>
-    <extension name="exemplo_2">
-        <condition field="destination_number" expression="^23(\d{2})$">
-            <action application="bridge" data="sofia/${use_profile}/11$1@${sip_from_host}"/>
-        </condition>
-    </extension>
-</context>
-
-
<context name="khomp-00-01">
-    <extension name="exemplo_3">
-        <condition field="destination_number" expression="^1111$">
-            <action application="bridge" data="Khomp/b0L0/2345"/>
-        </condition>
-    </extension>
-</context>
-
-

Este plano de discagem define o recebimento de chamadas na placa 0 e no link 0, redirecionando chamadas para o nmero 1234 feitas para o link 1 da placa 0, pro ramal/telefone 2345, e redirecionando qualquer nmero de quatro dgitos comeado com 23 para telefones SIP de quatro dgitos comeados com 11 mais os dois ltimos dgitos recebidos. -

Tambm h mais uma extenso definida, onde as ligaes recebidas no link 1 da placa 0 para o nmero 1111, so redirecionadas para o link 0 da placa 0, para o telefone/ramal 2345. -
-

-

Contextos de entrada em canais FXS/FXO/GSM

-

Da mesma forma que no contexto de placas E1, as ligaes de entrada so encaminhadas pelo Endpoint para o FreeSWITCH. -

O contexto pr-definido da seguinte forma, conforme o arquivo khomp.conf.xml: -

-
<param name="context-gsm" value="khomp-DD-CC"/> ;placas GSM
-
-
<param name="context-fxs" value="khomp-DD-CC"/> ; placas FXS
-
-
<param name="context-fxo" value="khomp-DD-CC"/> ; placas FXO
-
-


-Nestes casos, DD o nmero dispositivo (com dois dgitos), e CC o nmero do canal da placa. Pode-se utilizar tambm SSSS, que representa o nmero serial da placa. -

-
  • IMPORTANTE: No caso da placa KGSM, as ligaes entrantes so sempre encaminhadas para o extension "s" por padro, visto que o protocolo GSM no identifica o nmero de destino nas ligaes entrantes, apenas o nmero de origem - quando no omitido. -
-

Prioridade de contextos na placa FXS

-

Em ligaes originadas a partir de um ramal FXS, o Endpoint driver procura uma extenso vlida (dos dgitos discados) aps o dgito # ou aps o timeout (configurvel pela opo fxs-digit-timeout, no arquivo khomp.conf.xml). Essa busca realizada no contexto especfico do ramal (definido na seo <fxs-options> do arquivo de configurao khomp.conf.xml), caso no seja configurado, a busca realizada no contexto definido na opo context-fxs; -


-

-

Contextos de mensagens SMS (apenas GSM)

-

Mensagens SMS so recebidas pelo Endpoint da Khomp e encaminhadas para o FreeSWITCH como uma ligao normal, mas sem udio, que possui algumas variveis ajustadas com informaes recebidas na mensagem - para maiores informaes sobre estas variveis, consulte a documentao das variveis do Endpoint. Este contexto tambm pode ser alterado, de mesma forma que o contextos acima. -

Esta ligao entra no seguinte contexto, conforme o arquivo khomp.conf.xml: -

-
<param name="context-gsm-sms" value="khomp-sms-DD-CC"/> 
-
-

Onde DD o nmero dispositivo (com dois dgitos), e CC o nmero do canal (tambm com dois dgitos). Por exemplo: -

-
<context name="khomp-sms-00-01">
-    <extension name="sms">
-        <condition field="destination_number" expression="^s$">
-            <action application="log" data="DEBUG KSmsType=${KSmsType}"/>
-            <action application="log" data="DEBUG KSmsBody=${KSmsBody}"/>
-        </condition>
-    </extension>
-</context>
-
-

Contexto de entrada em canais Khomp_PR (KPR)

-

Para estas placas, as ligaes de entrada possuem um contexto pr-definido, conforme exemplo abaixo: -

-
<param name="context-pr" value="khomp-DD-CC"/> 
-
-

Neste caso, DD o nmero do dispositivo (com dois dgitos), e CC o nmero do canal da placa. -
-

-

Contextos por grupo de chamada

-

A seo groups, no arquivo de configurao khomp.conf.xml, pode ser utilizado para definir contextos especficos para determinados grupos de canais. -

Esta seo detalhada na seo Configurao do Endpoint. -
-

-

Utilizao do application bridge

-

O aplicativo (ou application) bridge responsvel por gerar chamadas no FreeSWITCH a partir de um dialplan. Este aplicativo pode ser utilizado para gerar chamadas a partir de diversos tipos de Endpoints, sendo que cada Endpoint segue um formato especfico para definir tanto as opes quanto os canais de comunicaes a serem utilizados. -

-

Campos relativos ao Endpoint

-

Quando utilizado para canais da Khomp, a string de bridge pode ter dois, trs ou quatro campos separados por uma barra (/). Algumas strings de exemplo: - -

-
<action application="bridge" data="Khomp/B2L0/32625644"/>
-<action application="bridge" data="Khomp/*B2L0/32625644"/>
-<action application="bridge" data="Khomp/S0411/99991234"/>
-<action application="bridge" data="Khomp/Gpstn/99991234"/>
-<action application="bridge" data="Khomp/*Gpstn/99991234"/>
-<action application="bridge" data="Khomp/B2C58/32625644/category=4:orig=4855553232"/>
-<action application="bridge" data="Khomp/b0c9"/>
-<action application="bridge" data="Khomp/b0c1+b0c14"/>
-<action application="bridge" data="Khomp/r304"/>
-
-

Nos cinco primeiros exemplos, temos trs campos sendo especificados; no sexto, quatros campos so utilizados; e por fim, nos trs ltimos exemplos, apenas dois so utilizados. -

Sobre os campos utilizados, segue a descrio: -

-
  • 1 campo, 'Khomp': identifica o tipo do Endpoint em questo; -
  • 2 campo, 'B2L0', 'S0411', 'Gpstn', etc: representa a Poltica de Alocao de Canais; -
  • 3 campo, '32625644' e '99991234': so os nmeros de destino, para onde ser efetuada a ligao (ausente em placas KFXS); -
  • 4 campo, 'category=4:orig=4855553232': opes adicionais no-obrigatrias, detalhadas mais frente. -
-

OBS: A string de bridge com somente dois campos especfica ligaes para uma placa KFXS, onde o destino est atrelado automaticamente ao canal alocado, ou ao ramal especificado. -

-

Poltica de alocao de canais

-

A poltica de alocao de canais, no mdulo da Khomp, pode ser especificado na prpria string de bridge ou atravs de grupos, no arquivo de configurao khomp.conf.xml. Para especificar placas, canais e links a serem alocados existe a seguinte sintaxe disponvel (considerando X, Y e Z como nmeros quaisquer): -

-
  • bX -- busca os canais na placa 'X', de maneira crescente. -
  • bXLY -- busca canais no link 'Y' da placa 'X', fazendo uma procura crescente (com relao ao nmero dos canais). -
  • bXcY -- utiliza apenas o canal 'Y' da placa 'X'. -
  • bXcY-Z -- busca por canais, iniciando do canal 'Y' e indo at o canal 'Z' (inclusive), da placa 'X', de maneira crescente. -
  • BXcY-Z -- idem ao anterior, de maneira decrescente. -
  • sX -- busca os canais na placa de serial 'X', de maneira crescente. -
  • sXLY -- busca canais no link 'Y' da placa de serial 'X', fazendo uma procura crescente (com relao ao nmero dos canais). -
  • sXcY -- utiliza apenas o canal 'Y' da placa de serial 'X'. -
  • sXcY-Z -- busca por canais, iniciando do canal 'Y' e indo at o canal 'Z' (inclusive), da placa de serial 'X', de maneira crescente. -
  • SXcY-Z -- idem ao anterior, de maneira decrescente. -
-

Para buscar por ramais de placas KFXS de acordo com o nmero do ramal, pode ser utilizada a seguinte sintaxe (considerando X e Y nmeros de ramais vlidos): -

-
  • rX -- busca ramal 'X'. -
  • RX -- equivalente ao anterior. -
  • rX-Y -- busca de ramal 'X' a 'Y', ordem crescente. -
  • RX-Y -- busca de ramal 'X' a 'Y', ordem decrescente. -
-

interessante notar que apenas a capitalizao da letra 'B', 'S' ou 'R' define a ordem de busca dos canais; se minscula, crescente, e se maiscula, decrescente. -

J para a alocao de canais atravs de grupos, existe a seguinte sintaxe disponvel: -

-
  • Ggroupname -- utiliza a string de bridge definida ao grupo "groupname" no arquivo de configurao; j detalhado na seo de configurao do Endpoint. -
  • ggroupname -- equivalente ao anterior. -
-

Agrupando alocaes de canais

-

Existem casos onde necessrio buscar canais mais de um determinado dispositivo, ou determinado grupo de ramais. Para isto, existe uma extenso disponvel na string de alocao, que diz respeito ao uso do smbolo de soma (+) para concatenar vrias strings de ligao, da seguinte forma: -

-
<action application="bridge" data="Khomp/B1L0+B2L0/32332933"/>
-<action application="bridge" data="Khomp/*B2+B3+B4/99887766"/>
-<action application="bridge" data="Khomp/S0411+B1L0/99887766"/>
-<action application="bridge" data="Khomp/Gpstn1+Gpstn2/99991234"/>
-<action application="bridge" data="Khomp/*gOperadora1+gOperadora2/98891234"/>
-
-

Esta extenso est disponvel tanto no application bridge quanto na especificao de grupos, e pode ser utilizada para agrupar qualquer string de alocao vlida outra. O processamento das strings de alocao se d da esquerda para a direita - exceto quanto utilizando a alocao cclica, onde todos os canais especificados so verificados simultaneamente. -

-

Escolha cclica e/ou justa

-

Uma variao da alocao de canais atravs de uma escolha cclica e/ou justa, que consiste em escolher o canal que completou - at o momento - o menor nmero de ligaes saintes. Essa forma caracterizada por um asterisco (*) antes da string de alocao de canais (conforme pode ser verificado acima, no segundo e quinto exemplos). -

Quando iniciada com um asterisco (*), as outras formas de alocao subseqentes (crescente, decrescente, etc) so utilizadas para decidir, entre os canais com menor nmero de ligaes saintes, qual ser verificado primeiro para realizar a chamada. -

-
  • AVISO: O uso da alocao justa e/ou cclica recomendvel somente em placas analgicas (KFXO), de ramais (KFXS) e de interface celular (KGSM). Conexes E1 tendem a alocar os canais de maneira crescente ou decrescente de um lado (na operadora, por exemplo), e o inverso do outro (no PABX, por exemplo), para evitar problemas de dupla ocupao (o que pode ocorrer na sinalizao R2/MFC). A alocao cclica/justa tambm consome mais recursos de memria e processamento que a alocao tradicional, o que agravado ainda mais pelo fato de placas E1 terem um nmero muito maior de canais (30 por link).

    Por estes motivos, alocaes justas e/ou cclicas devem ser utilizadas apenas em sinalizaes onde isso pode representar alguma diferena real, como equalizar a tarifao das linhas, o uso das mesmas, ou o nmero de ligaes recebidas por cada ponto de atendimento (PA). -
-

Opes disponves

-
  • orig: Define o nmero de origem a ser utilizado na chamada, sem alterar a varivel ${origination_caller_id_number}. Ou seja, a opo orig serve apenas para repassar um nmero de origem diferente do ${origination_caller_id_number}. Caso o FreeSWITCH j tenha ajustado a varivel ${origination_caller_id_number}, o que o comportamento padro, o Endpoint utiliza este valor automaticamente como referncia do nmero de origem, sem ser necessrio repassar nenhuma opo adicional.

    Nas placas KGSM, se ajustado para restricted, omite o nmero de origem. Exemplo:
    -
-
- <action application="bridge" data="Khomp/b0/99887766/orig=restricted"/>
-
-
  • category: Quando ajustado para um valor numrico, define a categoria do nmero de A. Disponvel apenas em sinalizao R2/MFC; -
  • uui: Quando ajustado para um nmero e uma string de texto, separados por cerquilha ("#"), envia uma mensagem "User-to-User" para a outra ponta, antes de realizar a chamada, utilizando o descritor como o nmero e a mensagem como o texto. Disponvel apenas em sinalizao RDSI (ISDN); -
  • ring_cadence: Quando ajustado para um identificador, utiliza cadncia definida com este nome na seo "cadences" do arquivo de configurao do Endpoint da Khomp para chamar o canal desejado. Disponvel apenas em sinalizao FXS; -
  • ring: Quando ajustado para dois nmeros, separados por ponto ("."), define as cadncias de chamada de um ramal FXS para estes valores, sendo o primeiro relativo ao tempo de chamando, e o segundo, ao tempo de silncio; -
  • ring_ext: Quando ajustado para dois nmeros, separados por ponto ("."), define as cadncias de chamada extendidas (a serem executadas depois da cadncia principal) de um ramal FXS para estes valores, sendo o primeiro relativo ao tempo de chamando, e o segundo, ao tempo de silncio; -
  • usr_xfer: Quando ajustado para uma seqncia de dgitos DTMF, define estes como dgitos a serem utilizados para iniciar uma transferncia entre PABXes (utilizando sinalizaes de usurio); -
  • drop_on: Quando ajustado para "message_box", "human_answer", "answering_machine", "carrier_message", "unknown" ou uma lista destes (separados por mais ("+") ou ponto (".")), faz com que a chamada seja derrubada ao detectar tons de caixa postal, atendimento humano, secretria eletrnica, mensagens da operadora, ou algum atendimento desconhecido - respectivamente. Disponvel em sinalizaes digitais (links E1 e placas KGSM). Adicionalmente, a informao de atendimento reportada para o usurio na varivel KCallAnswerInfo; -
  • answer_info: Opo booleana (no necessita de valor). Quando especificada, reporta informaes de atendimento para o usurio atravs da varivel KCallAnswerInfo; -
  • pre: Quando ajustado para uma seqncia de dgitos DTMF, utiliza estes para pre-alocar um canal de sada em um PABX analgico, discando o nmero de B desejado a seguir. Somente disponvel para sinalizao analgica (FXO); -
  • pre_answer: Opo booleana (no necessita de valor). Quando especificada, "antende" o canal antes de a ligao ser completada permitindo, por exemplo, que DTMFs possam ser enviados - til para utilizar em um DISA; -
  • output_volume: Define o volume de sada da ligao. Varia de -10 a +10; -
  • input_volume: Define o volume de entrada da ligao. Varia de -10 a +10; -
-


-

-

Lista das variveis

-

Segue lista de variveis disponveis no Endpoint: -

-
  • KDropCollectCall: Quando definida antes do atendimento (ao receber uma chamada), ativa ("yes") ou desativa ("no", padro) o derrubamento de chamadas cobrar baseado na sinalizao recebida da central pblica; atravs do duplo atendimento; ou atravs do reconhecimento por udio de uma chamada cobrar (pode ser definido de maneira global); -
  • KR2SendCondition: Quando definida antes do envio de ringback pelo FreeSWITCH (ao receber uma chamada), ajusta a condio de B para o valor numrico que foi ajustada. Apenas disponvel para sinalizao R2; -
  • KR2GotCategory: Ajustada pelo Endpoint ao receber uma chamada entrante, e possui a categoria do nmero de A. Apenas disponvel para sinalizao R2; -
  • KR2GotCondition: Ajustada pelo Endpoint, e disponvel aps o retorno de uma chamada realizada pelo FreeSWITCH. Contm a condio de B recebida ao realizar a chamada. Apenas disponvel para sinalizao R2; -
  • KISDNGotCause: Ajustada pelo Endpoint, e disponvel aps o retorno de uma chamada realizada pelo FreeSWITCH. Contm o cdigo de cause do ISDN recebido ao realizar a chamada. Apenas disponvel para sinalizao ISDN; -
  • KCallAnswerInfo: Ajustada pelo Endpoint, e disponvel aps o retorno de uma chamada realizada pelo FreeSWITCH. Contm as informaes de atendimento detectadas ao realizar a chamada e est disponvel apenas para sinalizaes digitais (E1, GSM); -
  • KSmsDelivered: Ajustada pelo Endpoint ao enviar uma mensagem SMS com o application KSendSMS, e define se a mensagem foi entregue com sucesso ("yes") ou no ("no"); -
  • KSmsErrorCode: Ajustada pelo Endpoint ao enviar uma mensagem SMS com o application KSendSMS, e define o cdigo de erro ao enviar a mensagem; -
  • KSmsErrorName: Ajustada pelo Endpoint ao enviar uma mensagem SMS com o application KSendSMS, contm o nome do erro em forma textual, ou "None" caso no tenha ocorrido nenhum erro. -
  • KSmsType: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, define o tipo da mensagem recebida (pode conter os valores "message", "confirm" ou "broadcast"; -
  • KSmsFrom: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, define o nmero de origem da mensagem recebida (disponvel em tipos "message" e "confirm"); -
  • KSmsDate: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, define a data de envio da mensagem (disponvel em tipos "message" e "confirm"); -
  • KSmsSize: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o tamanho (em bytes) da mensagem recebida (disponvel em tipos "message" e "broadcast"); -
  • KSmsMode: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o tipo codificao da mensagem recebida (disponvel em tipos "message" e "broadcast"); -
  • KSmsBody: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o texto da mensagem recebida (disponvel em tipos "message" e "broadcast"); -
  • KSmsDelivery: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm a data de entrega de mensagem enviada anteriormente cuja confirmao foi requisitada (disponvel no tipo "confirm"); -
  • KSmsStatus: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o status de envio de mensagem anteriormente cuja confirmao foi requisitada (disponvel no tipo "confirm"); -
  • KSmsSerial: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o nmero de srie da mensagem recebida (disponvel no tipo "broadcast"); -
  • KSmsPage: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o nmero da pgina relativo mensagem recebida (disponvel no tipo "broadcast"); -
  • KSmsPages: Ajustada pelo Endpoint no contexto de entrada das mensagens SMS, contm o nmero total de pginas a serem recebidas (disponvel no tipo "broadcast"); -
  • KUserInfoDescriptor: Define/informa descritor do protoloco utilizado na mensagem User-to-User Information (RDSI). -
  • KUserInfoData: Define/informa os dados na mensagem User-to-User Information (RDSI). -
  • KFaxSent: Ajustada pelo Endpoint ao enviar FAX com o application KSendFax, e define se o FAX foi enviado com sucesso ("yes") ou no ("no"); -
  • KFaxReceived: Ajustada pelo Endpoint ao receber FAX com o application KReceiveFax, e define se o FAX foi recebido com sucesso ("yes") ou no ("no"); -
  • KFaxResult: Ajustada pelo Endpoint ao enviar ou receber FAX com o application KSendFax ou KReceiveFax, respectivamente, e define o seu resultado. -
-


-

-

Descrio das variveis

-

Abaixo, segue uma explanao sobre como utilizar as variveis do Endpoint da Khomp disponveis no dialplan, tanto para comunicar quanto para receber informaes: -


-

-

KDropCollectCall

-

Quando ativada, faz com que o Endpoint da Khomp derrube chamadas a cobrar atravs de duplo atendimento (disponvel para sinalizaes 'R2 Digital' e FXO), atravs da informao disponvel no protocolo RDSI e R2/MFC, ou atravs da deteco do udio de chamada a cobrar (disponvel para qualquer sinalizao digital por link E1, e para sinalizao GSM). -

Esta varivel til para derrubar chamadas a cobrar para determinados ramais, e deve ser ajustado obrigatoriamente antes de realizar qualquer tipo de atendimento - aplicaes como playback e bridge devem ser executadas sempre aps ajustar esta varivel, por exemplo. -

Para melhor funcionalidade, recomendado tambm que nenhum estado de chamada (ringback) seja enviado antes desta varivel ser ajustada, ento aplicaes devem ser executadas apenas aps o ajuste correto desta varivel. -

Esta varivel pode ser ajustada localmente e globalmente, tanto para yes quanto para no. O ajuste da varivel global para yes far com que todas as chamadas a cobrar sejam derrubadas, a no ser que a chamada especfica seja ajustada para no - isto permite a criao de um filtro global de chamadas a cobrar, com algumas poucas excees. -

Ativando a varivel dentro do contexto default: - -

<context name="default"> -

-
<extension name="exemplo">
- .
- .
- .
- <action aplication="set" data="KDropCollectCall=yes"/>
- .
- .
- .
-</extension>
-
-

</context> -

Ativando a varivel no contexto global, lembrando que a mesma deve ser configurada no arquivo vars.xml: - -

-
<X-PRE-PROCESS cmd="set" data="KDropCollectCall=yes"/>
-
-

KR2SendCondition

-

Ao receber uma chamada, pode ser definida antes do envio de ringback pelo FreeSWITCH (ou seja, antes do FreeSWITCH executar as aplicaes answer, ou bridge). Quando utilizada em sinalizao R2/MFC, esta varivel ajusta a condio de B para o valor numrico desejado. -

Exemplo: - -

-
<!-- Condio "NUMBER CHANGED", avisa ao chamador que o nmero de B mudou. -->
-<action application="KR2SendCondition" data="3"/>
-
-

KR2GotCategory

-

Ao receber uma chamada, ajustada pelo Endpoint com a categoria recebida do nmero que originou a chamada. ajustada na sinalizao R2/MFC, e pode ser consultada em qualquer local do dialplan. -

Exemplo: - -

-
<action application="log" data="DEBUG KR2GotCategory [${KR2GotCategory}]"/> 
-
-

KR2GotCondition

-

Varivel ajustada pelo Endpoint, e disponvel aps o retorno de uma chamada realizada pelo FreeSWITCH. Contm a condio de B recebida ao realizar a chamada. Disponvel apenas para sinalizao R2/MFC. -

Exemplo: - -

-
<action application="log" data="DEBUG KR2GotCondition [${KR2GotCondition}]"/>
-
-

KUserInfoDescriptor

-

Varivel ajustada pelo Endpoint no contexto de entrada, a partir de informaes recebidas pela rede RDSI atravs da funcionalidade User-to-User Information. Contm o nmero do descritor do protocolo utilizado pela outra ponta, e normalmente contm valor '0', mas este valor dependente da aplicao utilizada. -

Maiores informaes, consultar a especificao ITU-T Q931 (mais precisamente, a tabela 4-26 da especificao). -

Exemplo (trabalhando com o nmero do descritor do protocolo): -

-
<action application="log" data="DEBUG KUserInfoDescriptor [${KUserInfoDescriptor}]"/>
-
-

KUserInfoData

-

Varivel ajustada pelo Endpoint no contexto de entrada, a partir de informaes recebidas pela rede RDSI atravs da funcionalidade User-to-User Information. Contm os dados propriamente ditos, que foram recebidos, em forma de uma 'string' de texto. -

Maiores informaes sobre este recurso, consultar a especificao ITU-T Q931. -

Exemplo (trabalhando com os dados recebidos): -

-
<action application="log" data="DEBUG KUserInfoData [${KUserInfoData}]"/>
-
-

importante salientar que as variveis so sensveis capitalizao das letras (case sensitive). -

-

KCallAnswerInfo

-

Varivel ajustada pelo Endpoint em ligaes de sada, representando o tipo de atendimento realizado pela outra ponta. Pode conter os seguintes valores: -

-
  • "MessageBox" (*): detectada caixa postal de um telefone celular; -
  • "CarrierMessage": mensagem de operadora enviada antes do atendimento; -
  • "AnsweringMachine" (**): atendimento por secretria eletrnica; -
  • "HumanAnswer" (**): atendimento humano; -
  • "Unknown": tipo de atendimento desconhecido; -
  • "Fax": reportado quando um tom de fax for detectado. -
-
-


-(*) Este tipo de atendimento detectado por sinais em determinadas freqncias que so enviados antes da chamada entrar em uma caixa postal, e variam conforme a operadora. O algoritmo captura a maior parte das caixas postais, mas pode falhar se no existir um sinal claro, ou se o mesmo no estiver dentro dos padres mais utilizados; -

(**) A diferenciao entre estes dois tipos de atendimento depende de configurao especfica utilizando o programa k3lanswerinfoconfig, sendo a deteco apenas baseada em heursticas e nunca com preciso de 100%. -
-

-

Comandos de console

-

Lista de comandos disponveis no console do FreeSWITCH para o Endpoint da Khomp: -


-

-
  • khomp channels disconnect : Desconecta um ou vrios canais. Este comando envia uma mensagem diretamente para o canal fsico da placa em questo, requisitando a desconexo. Use com cautela; -
  • khomp channels unblock : Desbloqueia canais bloqueados para entrada ou para sada. Somente disponvel em sinalizao digital via link E1; -
  • khomp clear links: Limpa os contadores de erros nos links; -
  • khomp clear statistics: Limpa as estatsticas de ligaes dos canais, ou as estatsticas de um canal especfico; -
  • khomp get : Obtm as opes diversas do Endpoint da Khomp; -
  • khomp kommuter : Ativa ou desativa os kommuters ligados via USB nesta mquina. Somente acessvel quando a configurao "kommuter-activation" estiver setada como "manual"; -
  • khomp kommuter count: Obtm a quantidade de kommuters ligados via USB nesta mquina; -
  • khomp log console: Ajusta opes de logs no console. -
  • khomp log disk: : Ajusta opes de log em disco. -
    • khomp log console e khomp log disk dispem de opes auxiliares no, que inverte a escolha de mensagens, e just, que generaliza a escolha. Exemplos: -
      • khomp log disk just commands events (Habilita somente o registro de comandos e eventos da API em disco). -
      • khomp log disk no commands (Desabilita o registro em disco de comandos enviados API). -
      • khomp log disk warnings (Habilita tambm o registro em disco dos avisos do Endpoint). -
      -
    • Mais informaes sobre as opes de log nos comando "help khomp log disk" ou "help khomp log console". -
    -
  • khomp log rotate: Rotaciona arquivos de log do Endpoint; -
  • khomp log status: Mostra mensagens de log atualmente sendo escritas em disco e mostradas no console; -
  • khomp log trace isdn: Ativa a depurao da sinalizao RDSI (ISDN); -
  • khomp log trace k3l : Ativa a depurao de baixo nvel da API K3L; -
  • khomp log trace r2 : Ativa a depurao de baixo nvel da sinalizao R2/MFC; -
  • khomp reset links: Envia um comando de reset para um determinado link E1 de uma determinada placa; -
  • khomp revision: Mostra nmero da verso e reviso do Endpoint; -
  • khomp select sim: Seleciona o SIM card, disponvel nas placas KGSM; -
  • khomp send command : Envia comando da API K3L diretamente para a placa. Apenas para depurao de problemas, pode compromenter a estabilidade do sistema se utilizado de maneira incorreta; -
  • khomp send raw command : Envia um comando diretamente para o DSP da placa. Apenas para depurao de problemas, pode compromenter a estabilidade do sistema se utilizado de maneira incorreta; -
  • khomp set : Ajusta opes diversas do Endpoint da Khomp; -
  • khomp show calls : Mostra estados das chamadas Khomp, podendo listar tambm por placa ou canal especfico; -
  • khomp show channels : Mostra o estado dos canais Khomp, podendo listar tambm por placa especfica; -
  • khomp show links: Mostra estados dos links E1 disponveis. -
  • khomp show statistics : Mostra as estatsticas de ligaes dos canais, ou as estatsticas de um canal especfico; -
  • khomp sms : Envia uma mensagem SMS utilizando canais da placa KGSM para um determinado nmero; -
  • khomp summary :Imprime um sumrio das placas do sistema e de suas caractersticas; -
-


-

-

Recursos adicionais

-

Este captulo trata de recursos adicionais do Endpoint, relacionados s funcionalidades especiais presentes em algumas sinalizaes. -
-

-

Aplicaes (applications) e canais

-

O Endpoint da Khomp, alm de registrar um tipo de canal de comunicao "Khomp", registra tambm os seguintes itens: -
-

-

Aplicao "KUserTransfer"

-

Realiza o processo de transferncia do canal atual para o ramal nmero' utilizando o protocolo de sinalizao QSig (Single Step Call Transfer) para placas E1 configuradas com sinalizao RDSI (ISDN), ou utiliza comando de FLASH para linhas FXO, LineSide, CAS_EL7 e E1LC. -

A sintaxe segue: -

-
<action application="KUserTransfer" data="nmero[,opes])"/>
-
-

Exemplo: -

-
<action application="answer"/>
-<action application="KUserTransfer" data="2345"/>
-
-

Os campos tm o seguinte significado: -

-
  • nmero: Nmero para onde a ligao deve ser transferida. -
  • opes: Define as opes de transferncia a utilizar, que so: -
    • n: Aguarda at o canal ser desconectado. -
    -
-


-


-

-

Aplicao "KSendSMS"

-

Esta aplicao tem a funo de enviar mensagens SMS atravs das placas KGSM da Khomp, utilizando os mdulos e SIM cards presentes na placa para tal. A sintaxe da aplicao a seguinte: -

-
<action application="KSendSMS" data="recurso|destino|mensagem" />
-
-

Podendo cada campo ser resumido em: -

-
  • recurso: Segue uma sintaxe idntica alocao de canais do application Bridge, e define qual modem utilizar; -
  • destino: Nmero para onde enviar a mensagem, podendo ser precedido ou sucedido por ! para requisitar uma mensagem de confirmao de envio; -
  • mensagem: Texto (sem aspas) que deve ser enviado para destino. -
-

Aps o envio da mensagem, as variveis KSmsDelivered e KSmsErrorCode contero o resultado do envio da mensagem. Para maiores informaes sobre estas, favor consultar a seo sobre as variveis utilizadas no Endpoint. -

Exemplos de uso desta aplicao seguem abaixo: -

-
  • Envia "Mensagem de teste." para telefone "99887766" utilizando o modem "1" (segundo modem) da placa "0": -
-
<action application="log" data="DEBUG Enviando SMS..." />
-<action application="KSendSMS" data="b0c1|99887766|Mensagem de teste" />
-
-
  • Envia "Mensagem de teste." para telefone "99887766" utilizando o primeiro modem livre da placa "0", e verifica retorno do envio: -
-
<action application="log" data="DEBUG Enviando SMS..." />
-<action application="KSendSMS" data="b0|99887766|Mensagem de teste" />
-<action application="log" data="DEBUG Enviou? ${KSmsDelivered}" />
-<action application="log" data="DEBUG Codigo: ${KSmsErrorCode}" />
-<action application="log" data="DEBUG Descr.: ${KSmsErrorName}" />
-
-
  • Envia "Mensagem de teste." para telefone "99887766" utilizando o primeiro modem livre da placa "0", ou para o primeiro canal livre da placa "1" (se no houver canal livre na primeira placa): -
-
<action application="log" data="DEBUG Enviando SMS..." />
-<action application="KSendSMS" data="b0+b1|99887766|Mensagem de teste" />
-
-
  • Envia "Mensagem de teste." para telefone "99887766" utilizando o primeiro modem livre da placa "0", requisitando confirmao: -
-
<action application="log" data="DEBUG Enviando SMS..." />
-<action application="KSendSMS" data="b0|99887766!|Mensagem de teste" />
-
-


-

-

Aplicao "KEchoCanceller"

-

Esta aplicao tem a funo de habilitar ou desabilitar o cancelador de eco do canal. -

-
<action application="KEchoCanceller" data="ao[,opes])"/>
-
-

Onde: -

-
  • ao: Pode ser on para habilitar o cancelador de eco, e off para desabilitar; -
-

Exemplo de uso desta aplicao: -

-
<action application="KEchoCanceller" data="off"/>
-
-


-

-

Aplicao "KAutoGainControl"

-

Esta aplicao tem a funo de habilitar ou desabilitar o controle automtico de ganho no canal. -

-
<action application="KAutoGainControl" data="ao[,opes])"/>
-
-

Onde: -

-
  • ao: Pode ser on para habilitar o controle automtico de ganho, e off para desabilitar; -
-

Exemplo de uso desta aplicao: -

-
<action application="KAutoGainControl" data="on"/>
-
-


-

-

Aplicao "KDTMFSuppression"

-

Esta aplicao tem a funo de habilitar ou desabilitar a supresso de DTMF do canal. A sintaxe da aplicao a seguinte: -

-
<action applicatin="KDTMFSuppression" value="ao[,opes])"/>
-
-

Onde: -

-
  • ao: Pode ser on para habilitar a supresso DTMF, e off para desabilitar; -
-

importante notar que quando desabilitada a supresso de DTMF, os DTMFs sero passados inband e no sero mais reportados ao FreeSWITCH. Dessa forma o FreeSWITCH no reconhecer os DTMFs, o que pode ocasionar em mau funcionamento de aplicaes como por exemplo, URAs. -

Exemplo de uso desta aplicao: -

-
<action applicatin="KDTMFSuppression" value="off"/>
-
-


-

-

Aplicao "KSetVolume"

-

Esta aplicao tem a funo de ajustar o volume de entrade e sada de canais da Khomp, sendo a sua sintaxe a seguinte: -

-
<action application="KSetVolume" data="<volume>"/>
-<action application="KSetVolume" data="<output-volume>|<input-volume>"/>
-
-

Onde os campos possuem o seguinte significado: -

-
  • volume: Ajusta o volume de entrada e sada (-10 a +10); -
  • output-volume: Ajusta o volume de sada (-10 a +10, "none" para no alterar); -
  • input-volume: Ajusta o volume de entrada (-10 a +10, "none" para no alterar). -
-


-

-

Aplicao "KAdjustForFax"

-

Esta aplicao tem a funo de ajustar um canal da Khomp para o recebimento de sinal de FAX/modem, otimizando o canal de comunicao para o trfego de dados. Sintaxe: -

-
<action application="KAdjustForFax" data=""/>
-
-

Esta aplicao no recebe parmetros. Exemplo de utilizao: -

-
<action application="KAdjustForFax" data=""/>
-
-


-

-

Aplicao "KSendFax"

-

Esta aplicao tem a funo de enviar fax utilizando canais digitais ou FXO da Khomp em ligaes pr-estabelecidas, sendo a sua sintaxe a seguinte: -

-
<action application="KSendFax" data="<arquivo>[:<arquivo2>[:...]][|<faxid>]"/>
-
-

Esta aplicao necessita de uma licena adquirida parte para ser utilizada em canais digitais. Os campos possuem os seguintes significados: -

-
  • arquivos: Arquivos a serem enviados para o fax devem estar encapsulados no formato TIFF e possurem resoluo de 98, 196 ou 392 dpi; -
  • faxid: Nmero do fax. Caso no seja especificado, o valor ser obtido pela id da ligao, e caso esta, tambm no seja vlida, o nmero do fax ser o configurado como padro na K3L. -
-

Exemplo de uso desta aplicao: -

-
<action application="KSendFax" data="/tmp/fax.tif:/home/root/fax2.tif,1234"/>
-
-


-

-

Aplicao "KReceiveFax"

-

Esta aplicao tem a funo de receber fax utilizando canais digitais ou FXO da Khomp, sendo a sua sintaxe a seguinte: -

-
<action application="KReceiveFax" data="<arquivo>[|<faxid>]/>
-
-

Esta aplicao necessita de uma licena adquirida parte para ser utilizada em canais digitais. Os campos possuem os seguintes significados: -

-
  • arquivo: Nome que ser atribudo ao arquivo de fax recebido. -
  • faxid: Nmero do fax. Caso no seja especificado, o valor ser obtido pela id da ligao, e caso esta, tambm no seja vlida, o nmero do fax ser o configurado como padro na K3L. -
-

Exemplo de uso desta aplicao: -

-
<action application="answer" />
-<action application="KReceiveFax" data="/tmp/fax.tif"/>
-
-


-

-

Canal "Khomp_SMS"

-

Este canal de comunicao utilizado para receber mensagens SMS e criar ligaes entrantes no FreeSWITCH para cada mensagem recebida. Este canal no possui qualquer tipo de tratamento ou processamento de udio, e chamado com cinco variveis ajustadas: -

-
  • KSmsFrom, contendo o nmero de origem de quem enviou a mensagem; -
  • KSmsDate, que define a data/hora do recebimento da mensagem; -
  • KSmsSize, representando o tamanho da mensagem (em bytes); -
  • KSmsMode, contendo a codificao utilizada para transmitir a mensagem; -
  • KSmsBody, que a mensagem em si. -
-

O processamento do dialplan do FreeSWITCH pode ser utilizado para guardar esta mensagem em um banco de dados, executar alguma aplicao, entre outros. Entretanto, a nica ao aceita por este channel desligamento (hangup) - ou seja, esta ligao entrante no pode ser considerada uma ligao comum. -
-

-

Canal "Khomp_PR"

-

Este canal de comunicao utilizado para receber ligaes em placas de gravao passiva (famlia KPR e KFXO-HI), criando ligaes entrantes no FreeSWITCH para cada chamada recebida. Este canal permite apenas o recebimento de udio capturado do link, no permitindo tanto o envio de mensagens de udio quanto o de sinalizaes de controle. -

O processamento do dialplan do FreeSWITCH pode ser utilizado para gravar dados sobre esta ligao em um banco de dados, executar alguma aplicao especial e/ou algum application de gravao (como o record), entre outros. Entretanto, a nica ao aceita por este channel desligamento (hangup) - ou seja, esta ligao entrante no pode ser considerada uma ligao comum. -
-


-

-

Cdigos e significados

-

Este captulo apresenta os cdigos presentes no Endpoint da Khomp e seus significados, utilizados nos comandos de console: -
-

-

Estados de canais

-

Refletem o estado do canal relativo placa. No caso de links E1, o estado pode ter uma ou mais das seguintes opes: -

-
  • Free: o canal est livre; -
  • Busy: o canal no est livre (ou ocupado, ou em falha); -
  • Outgoing: o canal possui uma ligao de sada; -
  • Incoming: o canal possui uma ligao de entrada; -
  • Locked: o canal est bloqueado; -
  • Outgoing Lock: o canal est bloqueado para chamadas saintes; -
  • Local Fail: o canal possui uma falha local (nesta ponta); -
  • Incoming Lock: o canal est bloqueado para chamadas entrantes; -
  • Remote Lock: h um bloqueio remoto (na outra ponta) neste canal. -
-

No caso de um canal FXS, o estado definido por um destes valores: -

-
  • On Hook: o telefone conectado neste canal est no gancho ou desconectado; -
  • Off Hook: o telefone conectado neste canal est fora do gancho; -
  • Ringing: o canal est sendo chamado; -
  • Failure: o canal est em falha devido a problemas de comunicao entre a central e a placa. -
-

No caso de um canal GSM, o estado tambm definido por um dos valores a seguir: -

-
  • Idle: o canal est livre e disponvel para realizar chamadas; -
  • Call In Progress: o canal est ocupado em uma ligao; -
  • Modem Error: ocorreu um erro na comunicao com o modem do canal; -
  • SIM Card Error: o SIM card no est presente ou no foi inserido/detectado corretamente; -
  • Network Error: ocorreu um erro ao comunicar-se com a rede; -
  • Not Ready: o modem est sendo inicializado no canal. -
-

E no caso de um canal FXO, os estados sero os seguintes: -

-
  • Disabled: o canal est desabilitado; -
  • Enabled: o canal est habilitado. -
-


-

-

Estados de chamada

-

Define o estado de cada canal relativo ao software, que pode ser:: -

-
  • Free: o canal est livre; -
  • Incoming: o canal est recebendo uma chamada; -
  • Outgoing: o canal est realizando uma chamada; -
  • Failure: o canal est em falha. -
-


-

-

Estados da chamada FreeSWITCH

-

Reflete diretamente o estado de chamada controlado pelo FreeSWITCH, que pode se -

-
  • new: Canal recm criado; -
  • init: Canal foi inicializado; -
  • routing: Canal est procurando uma extenso para executar; -
  • execute: Canal est executando seu dialplan; -
  • ex_media: Canal est trocando media com outro canal; -
  • cs_media: Canal est consumindo toda media; -
  • hangup: O canal est marcada para hangup e pronto para terminar. -
-


-

-

Cdigos GSM

-

Os seguintes cdigos numricos so reportados: -

-

Cdigos de SMS (SMS cause)

-
1	Unassigned number
-8	Operator determined barring
-10	Call barred
-21	SMS transfer rejected
-27	Destination out of service
-28	Unidentified subscriber
-29	Facility rejected
-30	Unknown subscriber
-38	Network out of order
-41	Temporary failure
-42	Congestion
-47	Resources unavailable
-50	Facility not subscribed
-69	Facility not implemented
-81	Invalid SMS transfer reference value
-95	Invalid message
-96	Invalid mandatory information
-97	Message type non existent
-98	Message not compatible with SMS protection state
-99	Information element non existent
-111	Protocol error
-127	Interworking
-128	Telematic interworking not supported
-129	SMS type zero not supported
-130	Cannot replace SMS
-143	Unspecified TPPID error
-144	Alphabet not supported
-145	Message class not supported
-159	Unspecified TPDCS error
-160	Command cannot be actioned
-161	Command unsupported
-175	Unspecified TP command error
-176	TPDU not supported
-192	SC busy
-193	No SC subscription
-194	SC system failure
-195	Invalid SME address
-196	Destination SME barred
-197	SM rejected duplicate SM
-198	TPVPF not supported
-199	TPVP not supported
-208	SIM SMS storage full
-209	No SMS storage capability in SIM
-210	Error in SMS
-211	Memory capatity exceeded
-213	SIM data download error
-255	Unspecified error
-300	Phone failure
-301	SMS service reserved
-302	Operation not allowed
-303	Operation not supported
-304	Invalid PDU mode parameter
-305	Invalid text mode parameter
-310	SIM not inserted
-311	SIM PIN necessary
-312	Phone SIM PIN necessary
-313	SIM failure
-314	SIM busy
-315	SIM wrong
-320	Memory failure
-321	Invalid memory index
-322	Memory full
-330	SMSC address unknown
-331	No network service
-332	Network timeout
-500	Unknown error
-512	Network busy
-513	Invalid destination address
-514	Invalid message body length
-515	Phone is not in service
-516	Invalid preferred memory storage
-517	User terminated
-
-

Cdigos de chamada (call cause)

-
1	Unallocated number
-3	No route to destination
-6	Channel unacceptable
-8	Operator determined barring
-16	Normal call clear
-17	User busy
-18	No user responding
-19	No answer from user
-21	Call rejected
-22	Number changed
-26	Non Selected user clear
-27	Destination out of order
-28	Invalid number format
-29	Facility rejected
-30	Response status enquiry
-31	Normal, unspecified
-34	No circuit channel available
-38	Network out of order
-41	Temporary failure
-42	Switch congestion
-43	Access information discarded
-44	Requested channel unavailable
-47	Resource unavailable
-49	QoS unavailable
-50	Request facility not subscribed
-55	Call barred with UG
-57	Bearer capability not authorized
-58	Bearer capability not available
-63	Service not available
-65	Bearer capability not implemented
-69	Request facility not implemented
-70	Only restricted bearer capability available
-79	Service not implemented
-81	Invalid call reference value
-82	User not member of UG
-88	Incompatible destination
-91	Invalid transit network selected
-95	Invalid message
-96	Missing mandatory information element
-97	Message type not implemented
-98	Message incompatible with state
-99	Information element not implemented
-100	Invalid information element
-101	Message incompatible with state (2)
-102	Recovery on timer expiry
-111	Protocol error
-127	Interworking
-
-

Cdigos gerais (mobile cause)

-
0	Phone failure
-1	No connection to phone
-2	Phone adaptor link reserved
-3	Operation not allowed
-4	Operation not supported
-5	Phone SIM PIN required
-6	Phone FSIM PIN required
-7	Phone FSIM PUK required
-10	SIM not inserted
-11	SIM PIN required
-12	SIM PUK required
-13	SIM failure
-14	SIM busy
-15	SIM wrong
-16	Incorrect password
-17	SIM PIN2 required
-18	SIM PUK2 required
-20	Memory full
-21	Invalid index
-22	Not found
-23	Memory failure
-24	Text string too long
-25	Invalid character in text string
-26	Dial string too long
-27	Invalid character in dial string
-30	No network service
-31	Network timeout
-32	Network not allowed
-33	Command aborted
-34	Number parameter instead of text parameter
-35	Text parameter instead of number parameter
-36	Numeric parameter out of bounds
-37	Text string too short
-40	Network PIN required
-41	Network PUK required
-42	Network subset PIN required
-43	Network subset PUK required
-44	Network service provider PIN required
-45	Network service provider PUK required
-46	Corporate PIN required
-47	Corporate PUK required
-60	SIM Service option not supported
-100	Unknown
-103	Illegal MS #3
-106	Illegal MS #6
-107	GPRS service not allowed #7
-111	PLMN not allowed #11
-112	Location area not allowed #12
-113	Roaming not allowed #13
-132	Service option not supported #32
-133	Registration service option not subscribed #33
-134	Service option temporary out of order #34
-147	Long context activation
-148	Unspecified GPRS error
-149	PDP authentication failure
-150	Invalid mobile class
-151	GPRS disconnection TMR active
-256	Too many active calls
-257	Call rejected
-258	Unanswered call pending
-259	Unknown calling error
-260	No phone number recognized
-261	Call state not idle
-262	Call in progress
-263	Dial state error
-264	Unlock code required
-265	Network busy
-266	Invalid phone number
-267	Number entry already started
-268	Cancelled by user
-269	Number entry could not be started
-280	Data lost
-281	Invalid message body length
-282	Inactive socket
-283	Socket already open
-
-


-

-

Soluo de problemas

-

Nesta seo, erros e suas solues mais comuns so apresentados. -

-

Erro durante a instalao do mdulo de kernel

-

Durante a instalao do Endpoint da Khomp, podem ocorrer as seguintes mensagens: - -

-
K3L: WARNING: Unable to find a module for [...]
-
-

ou - -

-
install: ******  THE KERNEL MODULE HAS NOT BEEN INSTALLED: *******
-install: 
-install: ** Please, untar the file kpdriver*.tar.gz located in: **
-install: **                 '/usr/src/khomp/'                   **
-install: **             then check the README.txt               **
-install: **  for knowing how to proceed with the installation.  **
-
-

Neste caso, ser necessrio compilar os drivers manualmente para o seu sistema. Prossiga para o item abaixo para maiores informaes. -
-

-

Compilandos os drivers e iniciando os servios

-

Basta seguir ao diretrio /usr/src/khomp, descompactar o arquivo "kpdriver_2.0.0XX.tar.gz", e acompanhar procedimentos descritos no arquivo README.txt. -

Aps realizar a compilao e a instalao do mdulo, basta carreg-lo no sistema, configurar as placas, e iniciar o servidor de processos da Khomp. -

Para carregar o driver de kernel, necessrio executar o seguinte comando: - -

-
# /etc/init.d/khompdrv start
-
-

Para configurar as placas, por sua vez, necessrio executar o comando: - -

-
# khompwizard
-
-

Isto executar um assistente de configurao, que ir perguntar a sinalizao utilizada no sistema, bem como outros parmetros de utilizao das placas. -

Caso seja necessrio configurar outros parmetros adicionais, pode-se utilizar o seguinte comando: - -

-
# k3lconfig
-
-

Este configurador, por sua vez, mostra todas as opes possveis de configurao da placa. Os parmetros que no forem configurados assumem os valores padro automaticamente, e so compatveis com a maior parte dos sistemas. Maiores detalhes sobre este programa podem ser obtidos na seo de nmero '2'. -


-

-
  • IMPORTANTE: Para o FreeSWITCH iniciar, preciso que a placa da khomp esteja configurada e todos mdulos estejam rodando (conforme mostrado acima).

    Se voc deseja rodar o sistema sem a placa da Khomp, preciso configurar o FreeSWITCH para ele no carregar o mdulo da Khomp. Para isso, abra o arquivo /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml, e comente a linha que carrega o mdulo:
    -
-
-  <!-- <load module="mod_khomp" /> -->
-

-

Quando a placa da Khomp estiver devidamente configurada e os mdulos da khomp carregados (explicado acima), lembre-se de descomentar esta linha no arquivo. -


-Por fim, para carregar o servidor de processos, basta executar o seguinte comando: - -

-
# kserver start
-
-

Aps realizar estes procedimentos, o Endpoint j estar operacional, e o FreeSWITCH j pode ser carregado. -
-

-

Configurando parmetros especiais de sinalizao ou udio

-

Para configurar parmetros especiais de sincronismo e/ou sinalizao, possvel utilizar o programa "k3lconfig": basta selecionar a placa desejada, e as opes das placas sero apresentadas, divididas em sees e subsees para facilitar o acesso. No necessrio efetuar a configurao de todos os parmetros: os valores padro so assumidos, caso no sejam configurados. -

Para ajustar a sinalizao do link, basta - depois de selecionar a placa - entrar na seo "Opes de sinalizao", e em seguida, em "Sinalizao da linha". Para escolher uma sinalizao especfica, basta utilizar as teclas de direcionamento (setas) at selecion-la, pressionar 'espao', e confirmar a opo pressionando 'Enter' sobre o boto "Confirmar". -

Por fim, para salvar as configuraes modificadas, basta sair do programa: ele ir mostrar uma janela, com opes para salvar ou no as alteraes realizadas. -

importante notar que no necessrio alterar/ativar as seguintes opes: -

-
  • Cancelamento de eco automtico; -
  • Supresso de DTMFs automtica; -
  • Controle de ganho (AGC) automtico. -
-

Estas opes so controladas pelo Endpoint, e devem estar desabilitadas no 'k3lconfig'. -
-

-

Inicializao automtica dos servios e mdulos de kernel

-

Se a carga dos mdulos de kernel ou a inicializao dos servios da Khomp no for realizada automaticamente na inicializao do sistema, possvel realizar esta instalao manualmente, criando um link para os scripts /etc/init.d/khompdrv e /etc/init.d/kserver no diretrio de inicializao do sistema. -

Na caso da distribuio Debian, o script de carga dos mdulos de kernel seria linkado dentro do diretrio /etc/rcS.d/, enquanto o script de inicializao dos servios seria linkado dentro dos diretrios /etc/rc2.d, /etc/rc3.d, /etc/rc4.d, /etc/rc5.d, da seguinte forma: -

-

-
# ln -s /etc/init.d/khompdrv  /etc/rcS.d/S19khompdrv
-# ln -s /etc/init.d/kserver   /etc/rc2.d/S20kserver
-# ln -s /etc/init.d/kserver   /etc/rc3.d/S20kserver
-# ln -s /etc/init.d/kserver   /etc/rc4.d/S20kserver
-# ln -s /etc/init.d/kserver   /etc/rc5.d/S20kserver
-
-

interessante verificar as normas da sua distribuio para inicializar os servios de acordo com o que esperado pela inicializao da mesma. -
-

-

Apndice

-

Nesta seo, encontram-se informaes teis sobre o Endpoint e componentes relacionados. -

-

Disposio dos arquivos

-

Os diretrios criados/modificados nesta instalao so: - -

-
/etc/init.d/                -- Scripts de inicializao;
-
-/etc/khomp/                 -- Arquivos de firmware e configuraes;
-
-/usr/local/freeswitch/conf/ -- Configuraes do FreeSWITCH e Endpoint;
-
-/usr/doc/khomp/             -- Documentao das placas, do mod_khomp e dos utilitrios;
-
-/usr/sbin/                  -- Utilitrios e servidor de processos;
-
-/usr/lib/                   -- Bibliotecas compartilhadas da K3L;
-
-/usr/local/freeswitch/mod/  -- Mdulo 'mod_khomp.so';
- 
-/var/log/khomp2.1/          -- Diretrio de logs da K3L e Endpoint
-
-


-O script /etc/init.d/khompdrv responsvel por carregar os mdulos kpci9030.ko e kpex8311.ko no kernel, que deve ser realizada automaticamente na inicializao do sistema. Em caso de problemas, verifique a seo Soluo de problemas. -
-


-Para mais detalhes: http://www.khomp.com.br -


-

\ No newline at end of file diff --git a/src/mod/endpoints/mod_khomp/docs/Manual.pdf b/src/mod/endpoints/mod_khomp/docs/Manual.pdf deleted file mode 100644 index ff578148248bb914d31114c16a29e4dcbb80f10f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 470577 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

h7S7&1)0{4w6i$juS#uIU4;1vc+PX$uB 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 z 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%0AMyMkG+;e&X{fstALr6cO^p&k#b(}18D8EsZ7F`& z>&Gv5B~8ytNX=T8sRhK9p~-f`EcrYnGZA

V-|nOnx#r~Cxa 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

N@?MOi`C(BzUAEE!*flP~{W81WtZh_r9 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 Ia|7xB10nhnzyJUM diff --git a/src/mod/endpoints/mod_khomp/docs/README.html b/src/mod/endpoints/mod_khomp/docs/README.html deleted file mode 100644 index c9756b36a2..0000000000 --- a/src/mod/endpoints/mod_khomp/docs/README.html +++ /dev/null @@ -1,39 +0,0 @@ -Mod Khomp: README

Guia Rpido

-

Depois de instalar a placa no sistema, e executar o programa de instalao pela primeira vez, os drivers e servios da Khomp sero adicionados na inicializao do sistema, e automaticamente carregados. -

Se o sistema possuir pelo menos uma placa de tronco E1 e/ou uma placa FXO, uma tela de configurao bsica dever ser apresentada ao final do processo, questionando parmetros de sinalizao - no caso de existirem placas E1 - e/ou realizando o ajuste de cadncias - no caso de existirem placas FXO. -

Se todas estas etapas foram executadas com sucesso, prossiga para o item Utilizando o Endpoint da Khomp. Caso algum problema ocorra, consulte o Manual do Endpoint, seguindo para a seo de Soluo de problemas. -

-

Utilizando o Endpoint da Khomp

-

Aps a instalao e inicializao dos servios necessrios pela Khomp, o FreeSWITCH j pode ser carregado ou inicializado. -

-
  • AVISO: Evite usar a opo -nort, pois ela desabilita escalonamento em tempo real, imprescindvel que o FreeSWITCH esteja utilizando o escalonamento em tempo real, especialmente se este estiver sendo executado lado-a-lado com servidores web ou servidores de banco de dados. Utilizar a opo -nort pode resultar em perda de qualidade do udio, gerando um srio comprometimento nas ligaes do sistema. -
-

Aps a inicializao do FreeSWITCH, pode-se verificar se o mdulo da Khomp foi carregado atravs do seguinte comando:
-

-
 freeswitch@hostname> module_exists mod_khomp
-
-

A prxima linha dever responder algo tipo: -

-
 true
-
-

Para verificar se o FreeSWITCH reconheceu todas as placas, digite: -

-
 freeswitch@hostname> khomp summary
-
-

A sada desse comando mostrar detalhes de todas placas reconhecidas. -

No caso de uma placa de tronco E1, pode-se verificar o estado dos links com o seguinte comando: -

-
 freeswitch@hostname> khomp show links
-
-

O estado dos canais individuais, por sua vez, pode ser aferido com o comando: -

-
 freeswitch@hostname> khomp show channels
-
-

Para mais detalhes sobre os comandos do Endpoint da khomp digite no console do FreeSWITCH: -

-
 freeswitch@hostname> help khomp
-
-
  • IMPORTANTE: Para fazer completo uso da sua placa Khomp, ser preciso configurar suas regras de discagem, seja atravs do arquivo default.xml ou de um aplicativo externo, definindo regras especficas para realizar ao receber ligaes.

    No Manual do Endpoint, podem ser encontradas informaes sobre o formato dos contextos de entrada (responsveis por receber as ligaes) e sobre as opes disponveis no application Bridge (responsvel por realizar ligaes) que podem ser utilizadas com o Endpoint da Khomp, alm de outras funcionalidades especiais providas pelo mesmo. -
-


-

\ No newline at end of file diff --git a/src/mod/endpoints/mod_khomp/docs/README.pdf b/src/mod/endpoints/mod_khomp/docs/README.pdf deleted file mode 100644 index 304f6e0dd347d122c13ad4ee138132fe6eb721f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399111 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 z zvCF0xM`s->A=CL}Y@(3%xFi^T>_s0}%mI}cxaPrG~pH4nDW@W2C8%tzB^yzMjVR9L7e;B@CprXjt}1OBE2e|u`ZpdZIkOQEmu)X>1ok4{3>sD3$J zn$6HG%pwdGaZ^Gd7;;!f0Gc|@jEvp3YsQ0XKqmd4Qfi`g&}@M*dF7H%CZbT3=e?-C zCa=WKv>l0L)ci{E->_L*#ny35GVxu<8BUrya{)X>*!oq>1yG?any!wY@tOK4@4`ZD zjUDf~I%RQs^XiT*TS}ZZ+lSQ0$=2G+49c8}2V584)($+sZk;z{Ou^OD}Z z0-PSAH@%6kcD#x97}YQq3bA5o`fF)C@k`uJ$Hp)MR|CZ}e_=(BppgXY701gUs!W^P zeD695@>|FA6q!+{&2={^lei4h5ifRh&i!ioc1oj2XE4&iiFzhYf~gk?{=}jlFxV3H zSVb5F?r%NrEKEaqM!dbCd|Pa~9h9#Ekz=DU!9c7^Ei8@UT#Et_!^$w)1yuozGl2qu)w=- zhW79Xf{}B9Z6HyC?JmyK8HP%EYPMZYIZ!Bzt*K9=D{nr2PJ1H9BNsejr!W zvw71b01~si4$#MkY`8odrSG=lpg%MWD_3VR_(=C+r{T=6CVt>;VjIIh!bQ;GRC?SJ z%nr4SCc3@2>gmh-tCNFo|02DigB{Qtb4IN)t~F7T}>P&U78_V{qsjsUh9)efiKcf2Ux`5k~< z)hFD%{lRPmEBUx|?TOqish&QHm5^6dej$Nkl=p>Y1z~_77C}5_?B}9Omr31CuDh zvMxHdJ+sEPZQHhOYmIH&wr$(CZJTfHbN9P{;+~G^sLYD0?2L|zud6Ha%S`JOplGV! zz1c-rKQS2)E1^TA(=LRDI^KLdO8y1AB)=4jI;*G-T7HIaw&c768sM5WtsJoT9ANr_ zCnMTSUzj~zY&3OaEM|D#V$eR7-Hem(by>(UrhoQoaf_s!T=xFD4YxHj9sAPG&F!|w zUZJjfzk0BwGv9-${Tl&XMg+7@8r#PEDCYrqpKbf>|j>?PN@AdBJjMQ#S38;L5`Syy)nkn z>_}AKbFsVC6>CSbNH;;mItGD88_SNSdM5U1UC&{mModxxS``Sxv||elA5vJRLup#- zi@Tb}1;0`UX*srdTo+-eRf7fMj!7y-zg46IO66|1o{Z z9`c)JtPe0E#TgIohcrPSC*|Peb!&B1xx}*y6b8!vTnZ3;GNq5YfX3<%=EbAH8D$Dg z&7AjxUL3L1l{#V3D{zma8xOyG?wF#uctP;C9n~MNU-spu#)X@8E9(K}u~uzH)Z!75qjm8f# zB;NE6a;C9Sm-SyR9kH>x5SpbJ*O8nu`#4DWg-;WO2Cc>=Yl^k#1nP;^)GEW@S&n^YpDIC!OOea1H# za{N-Ql=h9a!1OGMiNrpm{tCnaYH23KP(;%~9uL^m!ugn&LuY^Jqt_}zPGES}s*B-Z ze*z&cv3&7yccN!E_%&~veBi80w;Nrz8gSTNtA-ZOAFP1OcHqMKCpdFlQaIVO-+-g3 z#q}LuuwgEq0bIB}jTGyrf!Wsys051^H;9(IpQOpgrNW9(3yJA|X#X$~yA|M2W$n4# zh-KNDc*=x1mko0m6DA_;;VwOng#0{{#O!j3%B=jZ-cLL^b)FKgz}HJQ#m6LuMnoLB zanQHT>?1t6`U)1)B!UcU?URd+Bj!W3H|(+YW`Aq=Dv2)j}|&9AUn=^PgWHNLgth^_VH?#_?WT>*wizt%CslWTxTn}k@6#j z82vTe%)!vJ-fXeiY`Hcz{7;*vf68|?t!urjmb%)E?&bF*j)#GvIv zmDF9Zh|BGT9muKSAJ(tR)MEI1CfjRy?LPZFj*S$T)aRO^k7>GxqUdEoJ12y#2~Dzt zA<;5M$^utYellXz__dQ?q61JEtyag}JXF#5OcpIjn$oc|Y$}THf5felE@emIBB->G zIP&yE-wAgIlB{NO{Acm3n0a8V?$g4NjyO6ZwzKqx7xa{jl%``I`B+CA0csI$r_hS6 zmoiNeTgARDPLCqC=1oLFwLAqVYji~|4t6>?b5NGC0xOm1&i-jJ;(_EP#dP-40;19u zHO?4E+ry@gbZBdBktB5?V*}2e#+?;Y(uZn!o0zk$e+x)~peK4+96mG8IB;x7Hxhym zuGrBEl?d9@STdLM)!TO$y@ddOE;|>8fo2wO3S6Ifr=`#MK2!Ya`btyQrY01!LiFF? zdiZzc8&WoXf%#1|@e~CfqREpL;+ve;nkNgudA*eBg$aO4^Mje(B>al3N`78WQe{t! zZi*SKq5;rtE}z5 zT3OSnGv|j=pC2WC;@s_6v*2VJxq zj$F3u(INC!TbU+%i&N7P!RMKmPpE0nqbqN-D`pSA$dWrZWU=Sq2NX)0h|lkPB{E~{ zNUH^bCA`ySB6eSu>3<3ML1XubtNa3hi7C4_F*vWhe}s4F{(5Odg&(%G6iCb3O~`v@ zmtrpjFq@t!2{qe+k2A0+A&Z>ZZW**c&-y z!BhisCZxiqKv#@s5ZcGh68;=A7DVAQET3GuEyk23D!oP=z)f#?I#Vi4c;G2({RhEAQT9>yfXCo-|@c6Dy^? zv!{{yW%Nf{)!4v?AAfW#fwW$%>>0UGaJ=VXyj)mx1a6bzS-$s^0|&CQ`$ahgir zPYKh@@&1@;RHVjWHH2+nw?}EV--cy!fCkrGtTiA_qQ9z5iluRCf!OLvOXYRSpOaok%Y39U=nEkf2u$)hFqK9PMHnxN@fBb=1t)5Pj%0 zXa3;Bi$di%Wzyi5ueKSmY*7fJ@G=>MUNrH3oS@Xj?oayg_9^z{RE>>6l0Xu>H|h68 zGn=-STza?|Pfb(_bP*vzDru|#jy`fhL!>RHsfq3 z?Gr@4^!T8+df=IZ=TeG(MFE!PuQ3KOJmLr7BDe{1?c%bur6T#b8gHgrK#fR7DhO>4 zWrG`=8((cle?eo+2!>ooM+rZ)htbYE&&{$;fM+-%+~9-o!-@oAx+XB`1faOdCz0nT zl)UZS{4nV%-+Ox`%?c-kZsir&dTvoSNVa4sLAUCW$-WDW8w?ll)jGM;|3l3)jQ6Tg0nlicLQs{D9TZ zN?d9p(&~^ECtW!v79{FKvIVG`Rmx(`U$E+lHv>$cRs_rAqwW1x?F6i#f+kXmQqT%H zN#(Zp0VXT)eEY3FB%RVNHIv>x{3xqFWDHPzc}0IqoV2dJa{Rysx)G&0wB?!a%fv2g z1wTqMR*2+qKL~paByE5n=p*imL^@}S zNQ380*hSLtRh&?+_?YQAO64b1mCxk+hqh21qHFbL^v$Rn-n#93Hj=di6s!bb(#$(z zIsz*v&jXauQy*>JUo0k?4|QGeTG7s6E@?te^KpR+q6Fs97_F%NFvPB;7{#^sf`h=M z%1LpP6$1Ba2pSk4WknOjy+nV|KSgusi{aoMq8qnitY4Hcf3=2i8x&0c=DpN`<^HDB zo)ySGv9UY_!EdTkRY(&#`I{_ zO;Aztpquqh$pD!^%P~>ub?j99QsD~KqY%U@ahcdz3AlhNaJ}F)^}3D zL4xs9gNuz_B1^k5md`=nZTpw>d)k9TkgENiBf7%bGYqlTkDn)dnM03zUEK}+@9n`_ z7O>KJ&0wu=8U?CakfgCQ2B3?g9@l9$XsQy<4(XOQn07r}Iu{T3=XMWmgC~-$nP@0* zD2*4}&;o5&`w~$ZRQbx>#w0a1|nA zS@G4LN2|45(>pO1Wm{fiQBMYezXLO)LeIE*8z{{M^F4zaWOMEmvL8Nsl5u4dl=LoR zH#a7Nd^}zy5RA49aDBxM<>v%Fo*S;ZCFs+CB_@_vcR$>EOf4OVjbi9{pNnfv_bHlR z^eN?OHLZP(*R0NZH3ZxKu6DgP&}TOeF$LL@$_{q>U2Tw`_#?BP1j>{`3LY=>r0EyX zLmZqxf>U!C`m#K(1+vdzKe2kqRwR1;fSIXdgB^`Py4TOdQgk6ZiWE^4DDddlN(>c~_9wl&cFo@^ zRJycBlh*JdC`yEL52yH&-0stsMNn_#iN%#M-r11Icv?rE+w~FL$91wVcpSKUvBqD_ zFdf-ZO3s;LopwCnk&wlTNlNthD8x?z+$ORY4wUj4$CN1wk6heu?C>>MBT%g z-PH0xX>~0UfQh^z_NOJu^cd{;!|4orI;2K0O8{TfICPjxkDm5rGHO(flRuj{KiDSe zM*Aa3dhDHN5+M(3WA+cGuooErO;B)nT}xC+vQxb(RC>#(dmVuXPM3sHDQt9%tURRs zk*!5@!U@M@STa@ip51$Qr$T}XpkkJwnm_&1xYMh?DTmgJ<*BTpT3g`LFy+8Sn5gBl zr}X_EE5h&uQ$q&RqaPFMX~}G3wJv+}_FyvH11)`H%jm?={y-8TZ&0%OT4GW-LvWI` z&zQiASfSNUC$F5(_PyDIb9Z?SvL>XnH&y5^vkO1($OkvN2ilnkipJHJ#(}2XmMAu< zbA8oE#dDV+u};*JD}dTg;ScoFMsDcM!DHNd=uGy2fSm{#Xuud}*G(X|1e=L4Kr;xm z6(lq>)F#^>KKk0$^mWh-9S3wOAg*hNhh>6HeG?>L_QjBxC|H95JKU_y%49M|lmOZ2>#gaq3<_;-*vynnA;a@q1 zj6r>;38r*jv>o&JU36VQ+SV_39Z)lWPb(~suYuRct9}f7$Jo%j+D{0?{z1jaFfa4H zI4RFmJw?1ONW;L)_>h0w&rsWZf-BrlOBo-y5LQ(HBGEgLXrI)jAJ*Q$61@6L>{oaT zLT_=g)%ue&t!&gCc8PIRPy9Jo)t2<$JUJtO~ zL$v402QyBYhe8_-tJ=w(We#n!W)lJ42@T<;h*1DJqdd0D2W;TBVRMr_{}|(P=#%Bh zcf-cmYi|yEXbYBl4{)!NN5{6&=PCt#54h4!2S)O<;bd_I1a&bKTW`;bQ@}h}iT2U< z9iR@3uc|4c&yY}{`#fi{oahVGqAf4sTxoPU+Qx>r;S{Mjc$0$>BNyT!GD3oI)Ss5`EbR`zaj24n#Pv7<;StT`>@fyM34I|J=R_3MwQ^|nmky~xba?}BtXTh1 zvO)QDgvw@6A9Gj9vC;-~>X^R}a%e`1y{6JUZpb{KmC8r>5qPqeZ%d}Q@*n4m9H-5nT>D}YVv6NvUY$0Xy zwUYAsn)1B$5&91`(hIVROu|MXC|eejHH;NMkqU;H^Xqn8Fp! z*5@e~UtO@J#y9}>fTzl;1+YhDYTVA<@Aq0-IPYjw-Qkt%v2>Ss+yQ&icw8#TIx+*O zsh!LD4eQE+4u$pAt*FJMZD1}w<_(su*YKTQcNGokyWsvpv)lBD6H6t5cVVque+H)w zb%QjVNa&K+ju~vJ}EccmG}8^mFEkY3ajR zX2eWVXZ({DR>VAEG(A)yXiep|ANvDWd($i`Ax$k&vB!xIH}r@;%G9Su7rbquiKyX+ zM!2p#(Pk$5+!)O%MP3-=RwKAh@YzM}#(j1x6;oRjkyHnZ~K5Fe_Uja1@klMYD zbW02~&$ni}Uc|aHj`6yPxS9Eg!40!tr;BZvsFZr^0XJkeRe6ZB%RG^o{3Zo>!R2L5 ztWe`ZR`ai*J31z-7QbtXchQq#NljL11h>xpd&QWBuu(N@L);4}}!I!&pmtdjCwa^7l7tKMzFKmKKm! zYl^FQTIR=OP!S?W{q!W~6r*gc2A<)SZo7H3OA0N)g-2rqNkKmbKrlY59-a9xO*x>N zorO^S2P(0jVQQ)!g-TXfldNWQ2CgdK)Ke_=!dXG&ix@J2c5_3)FubnxHq?=M^cwOP zZMxawc@}irAB5T3LSyRhej7UR(`(DA#)=L0VxF9wR1>;=@N+goeG3SISGr(Pfz%?8 z)uWP%bidN88D|TZ*YnPPjIZU|sE(I{o3u9cf~32V7WnA)^Y`ZvbkGCJ_(FCV7KK{j zI$_|SL4o&usE7e2d>GMUs+HkSSWYn)@bjiv$L7v3h^QN5A)7y5oUMBGxyj8?x){4@ zIYZ>Y3HxhJDI>hCqBW~Oz98Bmc3;Sleszi&#w0gr9;*Z_X1;C#8T$jW^-E=-t9v)P zPV2^~eyp~ya`V{}&J`K~Z5-qs2qLp)sba)}h2$AE&jmp}pw_T3U>v7=og--k4`y9A zMMpO|6ctRM(L{y7N?=Lq3937Yx?$3n4jBV_GxVy5o+7>%PVW1CfNS=$@;$r{ep;~^ zPy-y$Vy|$Cw4qjvL?)eS)Y<#?<<5?|xvqTpQ#;ER2AgY_prNK>7d(cEI;T-_@dE9I z6U^~FBYtodcZfhr>ATdXu~}U+@LvQhws~nSUU5paJAEo!bwDjPqEFKbD;Ar!Lc!lp zRo5^!2xHCDG3C*9^iJ?3DTXAja+EWN+M)8$aN*pqQ1eh;$y6i<#-*VGAeCb9X_!%* zn7H&#ecstg@a2GyKhkFysu~=9$`WCa?J#OdbxnvxV(q%smM6h%?#C=VQlS@^2%YTV z+O7TH+fy^x)zW=WXxVpyp#4oY3eye4P$Rar`i-ecEq(|12GhkV@pH3cA4?*O?nU~n zJkYeo`@NDd-K9GAEJFH1=MMo?4B7X^T7Rmf*`^pNfNWqK zWIx8-m+8VK4q*Y`B^~{?gclfX!W~aS$vq*(gcwlAQm%d77y*qkJm0jhwXhN#)A{aZ z16cfSvu$J=dI9P8H83O(`V|@sk z=h#9a1}mz;2T&o~{E0tMWzlQb{AMc#V|!U;IL%gatn{1nAq&%oUMS)xwlZGtKz+4R zJ*hS-q{t%4dmIE3LY{e=bkkzqu}j!sLb5yC^>v_`0y&R&3Fb8tG7&c0Tz#qK!{H2( z6yGFYJ4PrG^qq_m@6hi+N8O8fwSZYOq?M0p1YG-E0N;H=DS|EmK?)3ncCsy(qKx7n zVG!W6u#>hSdzAqfp=KA@xR)|_2d_9`1sV+t4lgqsOZUHmZuZ;-$2EXWcDw z3j{%wy0E$W7PWeOeWTXLd@p6LdX}>aGr!G>&AIj4Td4*))HIQ4@;8iRaA9c-nMbd{ z3s=eX5~&DRf*W#fb<-#*n5`oJxdqR--m9EhZRB};M_?fv)@2-NGHRHy)2y0C^P|9vkaf#qJa0Y$colO=%>AphNehWsR>56~snQApz|Z;x91EIE&N((u1o;i<~tOJbnvb%g2W4-Uo2C zA%brr)8tGE_4ytwLF|%j??8?H0dniqrUJ)siQy?pZ;R()3pB;#)bP%Lu3H zU&Cvpt43*EotcMig>z32_~$MGM}_npXj_)l64*dTSBi-#3X^+Ih%^P0Z}32dbMah) zTlD3D8l(NhHv_wj%&|jT3C(Cs>psHFsXCD8^a1?BH`Pn0mEPm4M?^`UZ}Grcq8iP< znU^@m8VQ$TmlCfT7^Oc=^(miHg2r(PbTTqhx53VraY;d>U0844OEK_KS=9wg9D<_O zdOfVxje=y@rR^;y49i7QehzBkbXEM#u+HEhMIsFtPBX*aRTQuxBroP9R0FOM9HEdk zPqK6ylqfNqT~h`$yd7VpGEA`Zyf9x_*M9}&$0BY7=&2U>bgghDYGaiRGt?6yP_jsG zI{z+Jr{X>3Q}@jS*!9B$p}Lk4b)+sy?m?l7=O7$d{w5tJ>6p z8k7>1x=m;tdGaxbJ0KLUbuY=@a~RBisgf*Jf%3qjTREaTZ}`jGB?{ho1_)E?Xu53f z%&2}X^Q5z|<5$d0P&NXysJHxF{@hfy#%YDS}LyUL?MgGAP$!jW7$^mk3$Yt z0G@t3g`C|f-aS6=L^lRaAvi~3N_RPwldKVva50WF*QAJx!AUyd za#Vt;0C(9?Bu{@dPd1`Yilz$Z3DqPp2Rt?&zC02iMuG=nJ577tKp!PmRA17(#;9t> z6ndq6bl)>&P|Sk$S)KQCfWkwF-tWQf^_+wQPm-oeh2Ip6QDOOoVeu-XULZ6Xpr81Z z)G-ves2L18ck4gED@~wk#m8*>q&57x8dfvm&IM^m5CUD92h%!R06Sw6?D{Ir8&Tnm# zIuIyvs}FXQE#OTgKW{^FRZc3Ilk3I!N+5v&N@#`oIbARG4Cw0+Cci097zJsfNRFDp zx6X=G>o|7zjRh`fTh3syoQr(RTzL&ny|G?RO_ds(%+PTjm`Cr;eAI8`tXyPq;6(H` z%0sDDPky5wl$ieypV<3562Dro!Cv$UhJT7(DoW^nOzj1Ze@4ZYVN$Y+cE z--aQ)sW)Xy2J5Is$L1eCX1x3!*Y&>`s)|&B;ES$?j}5$lEsZR&#mQwzlVy~Uo2)8^ z7;==HPi-rC{v|_(e=c3ld+iArT*SPm-oLJw#RYL?=wl}wpub^RB@QR{Y0xEGxm&&c zAV2EAaqHCQHcR2TGTFO@I%K3-5MMdZdL`7m4>1`lJfNnw9&6CQ-n+Q*@2Pbtu#$=|4U5)BEMrv!ljZ-oRT)$}WPxZ4_J$Zel>L;q-Bes{+h0ic%?*A*s?bv>x(MBXY3F$R z9_kkei&Q8@E3R;Ep}>}w$E{oTy83^vx~I~%vy@oU_kYW-mKUZ<9)ukmJ*b*#$YAUG zbNvCB(b!D16T#4X_w7+MzYr3JLEuBHRPfMnFvQY>NnCS5Jd$|Y>z7Up147%bK`(zs z;4==-d?Y(ocW3e@(KvI;bJG)Dh}uJ2q!$3&l4RB|q$+Z)Vh^h3F~+y(AjL6h0?V_# zxujR)Sa08qSDhNPpxSOYpLzy%r5+~$=}J-qM?m<(9v@y!h^gV4x!I$!iNMA{`Ux6n zU&B|L`mKSAn!X3$PpM_Yrp3td3C=v)e3@SDC54ID;0rmF!{wVE27}A=dCqlTa9*PC z0VV?WleEIocowaSWZXt~P-|!zM^&8y1&>ODjFT(X4Yb1%vEe@&T1;=GxpiGTeC`$t z0gAeXQ;>Ht{LuU!%V?{?W>N^sXv!lEGg6JSrz#J%Dlzm8h$MR(1JMRA!M>9N%L;Ht zKu0wqD_g7@h=qh3?$Ja@UpJ6J=SaAd28u#R5yB%8Wmnu!`+*3^E=EvUE6~p_YWdx; zD6^)iAj)YpdjGH%nn+!y`?<+aGW7%K%hKy@_a`}+K_hmFEo_RoZrl*UNI*G7TvObo zsXjZBO6~k{k6`pN9Ym9*uyUf?cxq#$XRCTD%Y;1*Cn<_be6Y)(ENz`gfmtDz;iD#4 zmMC;<2hJ^78>i%t;15x;j3YJJYf#8(;yE4zRnjT3qu2>J1N?@%9B7gAtR54x)K%Y( zxi~uV;b;l;^!)BK-6slJ9r``g=cOc?3tZKk=`J{4!+m?&AQ$_%N#)Y@4}$5RePZ~O z#}`l*7N5u`gZAe-4HUhNdc4W&sF5co$5ngr$|UAtfX|bksC^)oUpBpKG#qa~ydk{Q zcB?A$2)tQJL8r^@kdd}(`;piI72$q`>KFftReptXewz_Yv`{Jqp#(mOdBTTb^%(FQvB#2d}m*yGG*c7?20=A zs=DOqcWvbX@v=+1syI@=TJXtWL{;#LIhIs?j~m6@_F- zgO=7CvdY~~4j5kc;jfO9<1}+OSKvgirR8Xmj@=_QF0;0i2znc~+#j`bTH^Mt6P}%~ zZH`_G&kp85@d8K<2HxL{IB5tRUMjrLLWu~7a}8bL(sNKxe9M59|wc#WRsK(^3iOjcVv$Rt6krHG!I3(WfC9gV8iK7I%cV*4yFka^IK^&& z3FAK7s@f*ZE3(IfH^@**hpxmC(klhJ*B_^V@H7XSzQLK>viH4E*4h0^MWUm(+7HZ+ zcb#aw4WrRUOX-q>gE{tdd3BJ*62Cl$!O~o}Wamle|)OhS^LwricR~l=tP!RIrgo z0-VB8ur3f(;fS*JPeNg;YLmQ=okV>R{)_c!IJmh^!k-!@&mU5;dW{ffBxL3{xUN~O zb!}ISWW5H%X(1i7ax2#}VM;DDGU8#tkx&@x5cGv@6|9OA&^&v{?|=OYsBL06`K%tA zrvx{-jQ08VF#6lt2x>(rya+bG1H(sa=5-1hIIfMU%2a8#n$4A_Vy`FL7aPY+ArKkJ zQ|>IT&c6q4w~vbgd7mbY|5Tk(qKw7n*Pt@OmdxF0ejURARX+=^@)Dj{qh8l6KClhe zW~TY3eO8WYh1t12#{*e*D|$5W-TUCEL`~@Q?TtKyP|A?0LeR;m_cLV}F4G21Y_@UC zr|0$fJ%x02T5>WDgAKsMszbC+Oh!%@Iugr@Vt4xAotlj#AKQ^|Rj*YI}e=r21S$b>|2^f|y z{yU_?$Ch+h1|DmIX|wiYr}pnJaYh#vzGWO7G+INIzEc(n4d?Ornq{@u_aQ>INmShC zYd@#2nD`2t-hZ0Y-g51&pruo!7zz6*Xbp7Hs) zv?9#2-}mDG>lDQR?R($ht_TP@kwK#2biALWZvuezQbzuB6pKT^CA`5dAhgZ{nF6cb zWDHR^O9EgQ#f^vG!-~z;#;~y0{!-a)|eAI3?NfJ`zv4jHtHAd=2Sxg2Sha z{e~DO;N#72+X(x#y^F&Pz+M_iC>Ri!NV$$6OlsGvE}Y%+2iA(MM>1WbHb0r=M$&)? z`#@i!^@~N<$D4wr{74H9{zyM8dSI$|9Z5rZ?EQV+@EyX+>1I z&xjHZAw}?qUm#0BAVDv7Qhg6mA{^m45>~-p$JR|!^KIu(q?{Q;6cs5$Mdj@jtw58> z@x2YUa^>;IEaRaY_9ilOmu!_zAWJf1e(+{kRUW?PS3BL%W9@#vkxtmyAP_;ZM7HU8 zaQW7rFAYDWwMEIgY-6m-?m{t9ju`M6Di14=%k@ghEetnKjKX0^S19|rL&$h}n>#mR z=7gZ^&1urd?us`UT!OYmBow?6zuIV8xL|VNJ#ki4$#0{)z(w88@6+XCYG#bnkvKtM zyJ4oG%@_Z7NeEf+O1h!7-wBbdZ%?JY%k(V+&ep_M8qb@s^AIUFdiix|3v-y81}_~m zu1t4BOz&_H#csd^($D#6aT;-bXpn+7Qk|+N^9e|pZmsUEfN9Y{_7%;iB!8}m?H@O~ zB^}(Vhh)`W7XLT9qd)H(R+-AKRF0vA-@p#pzaUv)rk|40pRt9GIyb+c%(UbVnl79f zZdN-e?qv=QQG30j$&B82^8E+;W;JTQ_*lp zgOc!3&s|^jtJhleI+P)b5f?{Wgydd+xm-SMv;N)ur6yqu`qQZz4?rbiE!m};#5r0? z!6XlV{-R)8tOZNkgqqhlxBMcN6V_~1EtfonF|QwR>_f|hJW`LhrM1E}Anh;#z8)Hf zhz=87-^OK0=I0VjTWawPyghOgwhNb^sZ|{L@HiHxnCBnN&BRwRy%%Gh23ix72{(ku z8TGev&9&8rNFv;CE0Au%Ja?e*;vjk0qz4lD$;BgoYq(82f7KEPN>vPu)efwS3B{dl zW5;meSlD?l?C+jN(J0P&JU8pRfOuXbpO})h&Suy)NkR&UW1aViC*B%_#@_txEz|W# zZtV+T@N##@*Uef`e7Yes-nE<~(Ck+pbB?O>w%)Yp;go;$CI3?)H(RGBP1n$dz)~HN z;Rb&k%va=Yw5sCY@H|`inT|I@Je5O9IE}TQV%KHmeWGUq@gP*6;EUYfy^nz8(6?Rx zXVQJ-*RJoaHx8J{3K>|;jO!1u7**OYfajG&yNRu_le43Vfeq9@$taL&K_TnZMX6DZL zEUZj)>i?CQ8QA{EfS{nAyA}-tBR&ly6B|A&3q3wN1A`8ogtLLQg^_@*nY9T%J)M%X ziH+(%%k*@j)&^!y_)JXyGgsEY#)MAD&c)Hf#PNSRL@oXeXZq)*A}{ZMeP;PTK5PA( z{2v4Vd;jk{_}?|~|K1wV`7a!>{$B`_HnBBxHfO+RV5R4v`#%aJJ~I}LyLrKTh{X9mYF3y@dX-rYIO2j{g=&8zeVd2n^{M6rK2{t2Sw;0WBF-U*Z~;3ro} ziKO`Zf^2LA^)cG==PnV}zTqRO$)3^emkd2uz2vvg%Tb_&UyKc4Y~eET41~TBL>*u| z>sqFp&&D@^qZ8=&IHdE>-26u`w?06dreU6pk%>$E^_OSON@-PA90cvWFCvS0G?t~0dT>F<$;ddCly z0Q2t?%ylVp37Txo%MJjv6qUOv3E7<403h?PnTjdUS1jtgZ{E-^5$F#d#qDqJ!Ott! z_v+Zfm)+=Zp~uhdoZ`*Pi)0C0F6>?HG0@wpn1b}wIP~7+*u*ffzVV^KcUH9=y8Al&*RNjG7j)S3F8}WtWk!Iu zzb?S{thk2yFX}BH!|$$b$S8wK9VXA0@78a#BMnVA_4IzM(SC{y6gWoBeGaRihH>D>N7iWzXx4Zk z9M)mBD8&=JRA&CF>O*`VwtV8Hs!!G+^6~c^?9%-+gx#X&d#h6iK^MH|2MzLf8xLi% z43&bY$pT`#LBow2pG;V3|E9N&rw{)_0RPM5`&Vt(SVRnC%kIFObT}xbbwzs{s~!$X zhAV$gxqiS7byIuHkn_i_ct?m4V48jWqMlj`-ZHNvs}}@>vymT$FuMLn0jHi1yKp`< z2eYlQJ;c$}tSNeZg2K*ctnulyrf(--v5RzRt00T;xGN3l#WEG}$TrDMD~^e}No8WZ z@*}b6+S)BnAp@ENgG_1jhxJEYOMU9{jU_242}BRE8*Rlmj$ragEu`u7_jiv?hFKYX zz_LugiVDo5w&zN=E<@fv86t$%(>y{b?^Z*rd$i>BGl8G7pTj3B81G?M z)39caP^^=kFE1oHUV)zqORoCk{*(9fm5%#Nb(sSk$mO+JgIsRROgg0J9?LTb#*0`Qlsa(!b z^?=ad24c*V{UqDscIUhDLz=vvt`>lXRbYd8u9pp%uDW%@k$K<5I!st0Ty~7Xwxy2+yMU~9NB;b*~ zCysKx58nz&i7qojn5?A*^xp%r)uo%zD=V2sVkn@iSOk2E=;C|Z1=qb5bJh8+#yi&)SGBDSIoUZNBb4O4~Qy_%kQFaxm)PI4f(7k>xlxSn>SAPt;x3069y#&xBp6umvOkR(Uq(CMEM6f{r)f!{ zE${gVSx&ZHhA1>bJ@5($ao@*h!PJSlsb0DOm1-lT*V(yjmb=ClK-C)6;Ci*U^H1}|KC=O&MoLA`(|UT=<^|J{ z^BCG<+$4=m+wE&Dxf7adaTO2FWAH9y>lg`ISuX2_DjpllZ0Jhltk3$_XuKloihJRQ z))}UES=-w3=pQ{CAvJvAl9Ev05cpOol06vv1BR+M!3qWQUUVEca1l1UmCyorLx?`EwoqI5Z4i`5 z1BrdlrSf_&VC#?1`dXmA#EG#)CRDUFFNWoxgyz z1JZpNou*T;w=jzZsrk#4&T26_Lb8iBy($U|Wb_I>cOIdUK+6k|BboCJ@{@Zis6ap? zS_CNbi*$@;>9~RMXe8CSf4b0U2cu`!Ydx%M!%+C6dz!e8fyJREcsb$gs#PjN8ziD+ z;>3-fn4I`*kxpB~%pw)dmNTH4Wueie#N$861 z6gMv0UE4XdU7?!zVQdDU-0dD4{S)(y8F%P`--U3#A%(0GcFd-oBLwvTvoj)`b6+o$`4Z>@-?|?CcacoDH#mCbFcD zYqg7ZGAXoa3awTK;==E2lKKi{E0^#~vTkX2mFywya=uVlbU>^@fuCR7l5Mb6#WCBz z$T>laCCa{pR;QeV9S}?5Q*$J<$R!l$FVk_5j@@g+^LQheaYHPzK;maME5urQ;W_i z`$;QIvxZwu_gEvR*PN)}|8%~E`#{Mi=}49<6V=Y6y?w9DcUk(BB%-EBG3@<@82T(tWAtWk)pw~bHD-^X8&;%!tiGr$$4RN6aKpemr^ zpF9oGs8eV08Wt^I)k5))O#=GG-X&we$4x&3^%zaVJ|gP0uMjBaDZk+BTU=-) z^{zk9KLaG=&V^EPFyJQ0CHvMzt9nHt7Q%U9^H=g5(`@$F!yqZYy`d>Nbd9Z(l~F7M z;BWZK8^4awpWD9{mJuOq?8Vv8)nkmJ0GVqfph1A4mQJ{J^s3CIU|f=o2Gpx0NuiNzXBvk)@qbY2>`9M?XcgeR$#`uy;rRsu_%h zYHrNPvW4rE#&QJA7zUJgw3GE#C2_ebI5JJ+YjuThr%0-3jDYpn=4V=+dMq5AB2v6t z%SQa7Tm`GH7-dZ4mD`-uYkk!Fu&ze_eK4T#iV#_lAWULfr*=2#fqtufrT$^{kCz4xFYp72bGT?^<|x0`Q7YU37Q9+YQvz0<~qmTS$Q@E}gz(Sqv^436<4TtQum zDjr&$sifz?g^k(_q-E5G?je-m< zBI>|*4<*rMDXgX211Sw(FV@_y9ZUO3oi=WHluNv|zkn~Jzq57++3MgfmYi2;HBI6L zdIkvlnTa=+CtSQFgj{T1+2g7fcJGJ&p(^t)m?_5^dsZb{3{=&nTk?03gb^Uh>Y}7! zCq+vuay#dtkPMFZ->9Y>NZgbh(tf`8yi@9hemj)LPqbcqyQYl4puE3iO&_|V2Z%ra z9{@K%$iKI?KPh35-945S*i{zx+NcoW`?9FlK}AXh|En*?h1)z+?XLyu(Rl6kv!LY; z#_S^#NZr9fmswi0>&3lSHZd4Rw!#k|WPyG3EK&XcMprwS*JSWF&U z#8&RFnBCk|w{G$a`q_$UZ0){PE)7{VpOaY5zFk~dfi9G%g`|8T?aFV+6ZriCTJ`Z7 zs%04=;RF5vw{v@}>Af3)YK=c32PhQFHm)JQ8m{qx7_|=dHiuG-p8dCUcd=t7^G<=Q zfs^(T_N+Mfg)n1OJEC-zmu-IzYx6E9D>HSa?Cf_dw+wYn8l>G~1oQctmn6kbr%@kO z&m6IPZtn+6eD+vC~^-5CLy1Ksv z7X~^(ca|KSM|P|9ts**^C{%TF=HpZ_)Sveu0R zrA&Tjr!i4Hh(K{-podvWatuMH?KD~xL*U6t-|sY-8In-<-6K0|99@j8pYeG7-aVru z^s@WGqs0(NU#;$=uO-NJ{aUWB#$lT_|NCGDl{;l1>ryx{oK>W=WIQz~_hw%BG+oh& zd;qhZYcT!j84|{|Z{tD9dKe=|-Fzs**DB+R6k-E`dMdNZ9~5&Ho?2KT%!l!9TkCPV z{I5rTj*Y#hh47z_ydRv(LIstAS=?ViiWgoH8aqf=?m2SDdMv*ypt3R$=B&w3J!Uq} z5@p5e_Zy=ZAi{Ub8vhi19~ket!29h3?O+$5#J49O-1WNb7R#?FU^YLo!sWr^OoKcQ zH>?*_d5*Zm4S3GP%@bq^my;V>T+^;Cu%iqQ4dEX{%aHWvAS3f#ZhnHw)RonDm249ZQ9- zxTq!xpSiNNLQ?yE#F+$c@MAbY~2;=(a+O9nTVxv-YL0w)2g;##^< zRDM?q|4WoTA!<@}l2yW`M@a93%LH>X{OfB1$luk|gSUgizJdm-LV%_e*N)&RHuIp2 z|6Ok6QRb9R$C(Htvc~Zj$jZ6O?1TX>kCea2*WoM8$!gTKHITVlUpP*JBI&R!m+|U5 zJRh3RRrnpak$7{ltqLlJQ-=7OyAIJgP@A4W zAVY8dqeqa7}N@omC{Z0 zB1oJx&T~D5swreu_<8{RXMJh)Z<3_zyf^(8kSNzgH7dEgBWgbk?lDNWo8Zf^9f&ZK zI>@I33#+*JLZySP$FS={iVe!eywOPdn z$I`EV6G3fA&BvzJ#(mXrC8DcBd$E8Mo_kp9@_wJjy^X5Co-bl~y`;c0I3{1ju{H`Y zA0ITK-2%Z_cr!;w(@=kiRqOl|t*L+sLKmI93c543y`o3l(b!+E@IpVh9x3hoC%;!P zQE*zzcs}>Cn5J=wW9oDc~!h@WB zcc3iCw;KD^W@S(Oz+W`_S}wmXGF1RSnjX_T?|+{nNFoPk9mfQ=N(%GAec)OT zdpm=I(Cgk+NKV`Hy1+!rlO{2(?>mVBd!lJG>vk?R5}YyiqNEdzhzR@u`&OlSDoZzr zlsj9CnZxL#P6j=(CI-*fA34quTa?U)@x3s1JU+8vKi1Zt2`#Se>2`qKSkrqzik>-Q z9y5I`d1NPhlX**lR#mkJSj-m1ypf;-I?*_WW8553qhoPw3Kf~N4XWPSG9Ue;s9DkW z9L~v7T;?a?^j7F-v}vI}taAHYiO`}c@%y)5IJE}N8t!9@_AR-{Yw%vddB<0TXw`u! zu*=)8r_zBjxv?P}yx|v_Mk_YCS9-bxsLXsd;Lh0Zx)VpG$Ij<8q}@rT{tZ{V%&jecJ`3f)~b2^WLV3hJjLY~mRb6yf?c5!#+Jp`9YqEI zQ$#s~GY;1K3oc2?Qld$h&Sq*Wv(x!Zn3S2(dCq>{ZkAxiv!Ayp9~HA6rgzZM_@*Ox z9=O9AFjZo-)qn@jX21#-Uq`4m85^9UnF_VCRXc{Z@Af04ai0=&)0L72wZz${H(y;e zi&G|#7{b<9nK%d#-w;E4{(yr!r0_kQ4seC;xASN+r|R5W_32W{#6INf_!{b#u){a* zLtjHmZWU$WHQ%g^4x^bXv_Ww#keyT(eebzvLfIxNZq)xqwgsdLl&QjkXx~0NmWSfK6KCiqPmft4R?W4*@>mBCtlAG&x zlJv^czo@-{s+?(=t{j3$=&Xov*GaBDW z=ia54XTh}wY1}L{yXM$ron`sgja8I^_n!cMa zzICzGcjGJjZmBRNol%s2sq5`2yWis8Aa+K7FnsA_krIlMt^tYdiytp zH~Jfi%HvaBk^9jUfa(I`YsU7nOl%rSTo87#9nG|{|0P!}97WiE`UG_O04Eq^>gMj? zL@NH1eUWsb?94&MLZ*oJEpPdU?Btw7q5wTOwk4LZ)T!++zVkR4X$#wLV!k7_rm!bL z+>vNr*)`;ZkmVN}^RG=Nx56s`fPn<0gL(?; zAgDt)Dr%sb^`Ok742Ktrk-Wqrst6r?dPyZ7;o22@2-VTX&`Gf0Q|VF& z9Yd)*9JCsDQXTK8bwWu4x%1hkv;Hbdes1p7kQ=!=ej^q%pGKeJ)=iYdo5|5d5EOkb zkRBf%Y&Ebz@G@tjO*Z#>UdmS=miF!O5$Xd^nE`KUnu|WfV1|&Q9!{nfDzCzjmVkM_ zx+N!bT`uouCATHZCLSnb?k^qCECZ)TK;t#Y6f@Kl(k)3B`qt~SEY7E1&aV=aiL$tf zxl;LJ0&@pi#$Ds94QIhi3_oe^7);mkaVS4$DlwO<9p~_{R_zH{G3A}0W9;tQ5BM0S zz~IUIcHf%U(Kz?(uRMKjnT0z!Gx8&|M40YZZ8M55^AZe;Yc@|wO`xJs$sqwnJ;_Hs zuYkDiP|c_lkxTg6^Rw^?BDVX0x-+eydQ}6zgf}Q-l2A%qjo*E? z1;zOmn*BCVobBmhNf``|9Z`+G2As3*Lzp`o)FuKEYUZLrf5S(x;F&XFsd;@+0_(i} zI@^D9`}gUqJ7PlFC5+}M`FcJe&zQes?IjQ1vdd@;Q}!^UxCl9F_2XkL0Oc)a7R_A38310;RNVA^#XTF)(8gOB~#w?~UvO z3%0cbo&OgK7e7KSCx*chp+|5ZLun|lY~2xY6v%s=9OPIZN1#}YdskiC71|>sTg~e| z|F;5XWSMsyIRKN1gSwnKXJ;b!+;_46{ey?OR1Vg7lm3vn?Dt=!Oz2tPm4lzMkG<{C zFW!0Jl_9+MVUiNgul2l`V^}K~=C#4GQX$bcbwDs^IN9-gyK8Y_DT%y4jk%P0)RE_) ziEDEUQ+`=~ka0RYcCwwkR-CC;qaC60B^;G%^v+#X_?L5HhL#r*mB}0Nv>BkDP)?JScY4QOAy)hB};-K(cXwDlR%;?V= zRKnN!adFoe@}OnHP4jm4a80$A_NNT@#ZvC2;L$y1wbIo3xHouZnsk^X(@V}DC(QwZ zDQWnSl%{v#p$X-C?PCX!HR*bTw(X%^bTlz7)FeNrVP-{NQ{#LbPZel!nL_es(i6=I zCcxqyn&IjkSGe@Fn_2o@uACXBqEh@y6Rcz4NdDy4z`RPRE}{i zD3(hPWFzj%ZSCD~F7?$=QJ(u?pNyEx-FdP#Pm!;)6rSxGI-0f(KLaser#Z24?ql@~ zzdMKDBo+6R18WXVcX1uTG?dEv+^C<4XIj|IK)Z|i=ROuGn|8GAD3#M?FfaP#rlM3u zX-ygt6lQ6z&Ft-Joh91z*q0(J4HTYTn1XZXWTYWMF!~JOM8Bs}VfDEGSPPllYL1;+ z27I<1^0@9>4L-OrCd6;!^wF?~pryhLz|%3~Wr^w5hpP=5y3QQ;(K#uS0zMQ6^juu> zhvi;jFE_WlAAa2(W1{5skK~bkQdcnT{ngV);(dl*M<4l*i|wbOckXBG_>Fg+m?ZgxOryw`I?+-8I<+eWWzbG(4oOL&sFHc=5FVy8 zEScItt*qlVBcz53!<07R!W{pCw)`z3);^=cizM6FTI>MHxQ=4HsP|&N2YF;JBN>N? zHjRW*8OB{tyob0E2)P1*IBz~X#BN>^EAqOu+DICH7(PHT&AhKfY(pQFqb_ulhi$0TW9mzmg4&Kql!2CnGSP$jYW|mjAl#o3b!`5i z@ON^27Ji+IKLvo&Q_M5ajHEhS<}3%C;S$8ZOSBA0(NIHWCijSU$}+>7%69G@L9gamZYbSC1OPV`u+`R&8+j|OYR62X9a%Ap1Yq$VECzKQYFWp|x0;cq@ zvxki|8;ry+RB*hQdgS0~NA!zDg*5vm(+|X3&d_pwJmH z+4J$HcJldEwXjg9^0=4m-tZOxZG=V=RMmG;jPv$0RU$H7a81~1I#yb6vHqk-##I@G zHTVXnpJ}$VM!=%#2gh0au;DhS&FU4jbq&!3y`PP?Dg__zi@O$0sy@lbo^B6CS}^bo zdJFP_K3v!W4t3#i6o3Ie7`0`Zw2IO8J)VjtC8FSDwDn{ z7tX#5fKlC6ldK^9#o7U&NS(eDWh+hUMf~hRL&F!3Eo3G=X(~V*$u|swn~D3opzscr zIj0e6rc{T=nj(szSHH$J&Dtlk!(e2BL;gG5i~nMiXV z6b7oMO^6bKvPQ~lJb1?(QtrM>^C5}$7HtvO+ETfwSf z#am`ya7~-uMT0D~n`6Mmk2@XlTpE1c2IIUa-XT)Ij}#WrC@L-^FN-zCkV)|)Eoyba zFB`7Tnp1S%TbXBOI)H>`y~e<;SUV5`(RSG2L-4d%w>HRn1~ML84i zizs+6J|6Wk=yCEdpV3X?+~BvV#cuevdLx3o*d;LoB`tBz>w(s}-x`oQ=hE_SbJ;m) zy;f5!emOmHefL_bq3Bmdt2yHPds!6St&`-J>4VEkd@V&oP`koaoFpjZP$c*8M_9bJ zdvIjUm1)MmUg4MG2Hi7vr^ZliT{!)2cTP{ai9vg_$KUUMY1|7%S=dHgZOTxslejP5 z<~s_V?z?2tN+4rw=d=7@V%;VTkMzpgwCeeCrfGFKt?zPkm@tmsZ`p;Qu)3U*ywdGj zWeCYP23BYkj4|4o>Qg*!IBq02QHw^Z@n3^l2+ilrK@je`WsRZ2lCH6As zZG6?_cx`B}-@x?^3bF#+=+2rLp%b1maegE)tN;1&En8z_tdfXMj)K~jA&b5r_(T^8 z?d9I6t8g~s(pID}0o@AqF8!;3)cyKvP4Gd|( zPM6tgLEW$0yOce12G8!%BpqpX8Qdzeci$gkxR z1&m_Ss=KQC)+!3ChKnQdiln{bw&5a2=M>0sGZW$-xeefm{)efqp0y*~`k4LdHRWe> zC@fyHbmg(cwQ;BBMx8LYNymc9JX$0#Qzh9fooe76y^ zH>mB)^{qQl#P>d$=ZYj`TvjigmB*q(H$x6M-^`zxAsno|4C?2%9|zdx)Kh;Nj>J4u zziCiL^3D#*rGKT25mhR1tAhnxWlF*7#!6mH?()I!>%wK{%D@^$_ z*Bcjl4-AS~n$4hC8M-`MHL8{tnPL#i~%`^Nu=uP3|)~t(Iyon&s4n%L|6_=Ftv@>J-TjQxUH5oQO7-^)W)=NW z`06SIwaQ+Yw27=o6P*OrU*g8N+aH_c6)C^$v(D4K$zKbPL-8^gT@zry+g_e>Ak<~c zY=%CDbR?Ig?EX@aGv8zg2tOkywC4?ls5Cp+fbWl`I;6W!QNh2Gisl?IU>MYj^W4}Z z(&*0z?W!b->M)g}U@IWY08o7cP6*JF-|?toU5C7S!-+G@#fjLj)Iy$`=~l zozp~Z%yeWg=D)~!0q>k_$qhgv;VQ!0JOyx89gaV~03A7q<<$jZTZ`f?nXU(GCr+HE zg_CwzTn8|}cd0bu+^TpWf)`%3K1aqax*1>Itw2~8c3iQgk^m2}3?ht40%BrQj`OxM zw%i!X^X5a@u6$zGJ(8kN=^ahJa2yfmZj;1kHp?x#_3^xQbz(?$nPu4bJa0p42(I^Q97+uGPhX5Fy6<%@dfC zD+ePg29?VN1*I!}(RvxFl%&u1UR%lRf&Hx>wi!K2N)bY|>-}^?)OeBLnZyLhXjbmf1_qWyP$NZWiANd8U!F1CYWGE=0Rd(S{ zuZL8))+5556`4WFLFY~@^B>2no`#z`{u?njgsngD;Cu$G=(8UiKU@i;=wG?BWD3UX zcZx<6!W37aKVlxK-x+40-Ws#>8nwUMF9lHEf-BYJ!c3ok3sbYibL;pG!J^FK*!7k@PbTLa)J_ z@;8=w#Cceb$*%bOgU(OfI;!>bBqKb~&h@KWWinIPmt=)R0N^%55nCMZi{alkbXTxf z%|A5#-1*{OCA5$X-z|PEmK+udXX*kHwJm=(hvEd-lmFB|TdHSRz!MaUNK`VR>J&UfK2VNdnLbet!bKGf4Ga4o?STQoED*+9|X)(N=5M=FX(-@jKyDPawhUm@5MF>`VWi zfNZjvFb20p6U{s=VwApZT*cGyRKZe+ar_ynJJC|{6U-Hd^EvOGvV~mSX;&#g+E>JV z+-+3Z6{y`~<3kBAW!CX6|ADWlplvx+joQ^T7@bb=a!U_Q>@}?55>3zjAVO#386JK( zjyM&hUri}Cd!Dj>fnTEZyOb%rxL9kR+)bMjN*FG@J@Q7LOe%Hj>znaj!K4MkO~Z4I$}wya7r?(9I|+9g`7v<5T^%l%O^F*O&rYHk zT6D2-`wQ&Qf?-51C=%6F?p^*XO3x$C#%_n`KI(OSKc?#B#YL=*e*pREyjWoRU1$Mn zZa*bS+4<`=H+$}$YW&)tTo-G5PdloT6@knL2C1|yK5bcr%J1gn9Gx264_YpXv>S`D zI3}ZLMJR{wDt=kpbb6LKiE$Ve21Fo@2fvKvzftEn>!($c($hlkbG@bdj79jts3$R82fXSS~SVup*NMfTt%!$>F@XxXPy%m2fI9dhCkmJohuF znjA#JQ;EKWQQ0LwcUsR_mzgvPCJ;sa=STnbpLex{jCrO19rQk0(P&~ z&jrHUM)Nn?fjcHA#DX=~yIjMFu5E|Y^l^boK4D2@TwmIaT!#c=Ub!tSCsu6n9 z*1(A;K9Aa0hNWiv*_cZwDrgPj!$GfIH_2+RSjvqmNZ|4&rB^~p%j#6u7^YUt5A~KN z&jC3zrtYW?yXJwr=8{tfKISzh>57d;8av^eIY%sXq8WV{Y}3>cebV6XS`0!X8&H(%jn*iiK<^vy268rTTH%!fuUH*}UF3bY@Ly>Eb?}lab>G@wmnMYHA_X&zq9lT1+AHo6Iy}d9DAb zpddVy)7YBfX}*t;lsO{%g{;hRVjlx!#Qigu#3WPAQTbiQ`&H(YA3iANn=&#Ck5y%5 z?|?qL!t>ut@rTik>7msKB`Fp>y%J-kneppEQhhFNNiEJ40&fW_Fs@BLb6djR?+~l; zSZ!hGQqy2`r(X3`%z^iErCkU@rvtyti%jzbT@xv{dJ$+1NXeo#KVsa#*&{Tqy78r#755*IV=Nk}wGu7Sl#ddHAs9lIi!Uv!^Equ= zW=ifj(dm#yppUW_aMEQ;`>o6R_-3IimXZ|hNVis#sR0V6>qUQKZ~F|-Vz~U!;hw!X z1}t)_>nRY3!;LK~M5x(W6sJc%Q8>)E(N_V7oT@Sk&Z#;+Ti^mMnMd7-uK7a~C2CTB zM`63~Co_)DoR{rF*6!Z=dArZF^bqlh-z@RR&+QyWHH<#Gh{wlFn{a23wGY@w^ zDEU#=1-gd`+gn4rax_PJ&EVxmN&!V!9{Q!#b&;O(ZtdrVp`IPah^3w#CfshKm;nYC z#h4yX$24@6tUpew*iZ~{7E3O9;c}n|pJwu)OC106K=hAD{3_?E$SpC+5bS`@ufCvh zq>oy&)oph5du2GG)9`Z{E)UIm%w zdn{W^zHhXgDLwgn1+78~Mfn;XR#m6PH@!KEtuRQTXp)Y(WKiN2me4Ff0DVOlWfYFM z$Q}`T9VMtHoGW(vEt&`6%3ez@#^HnV*eTSc-!B3`=>$w&s&fv*gN#4l1@{s&SrAoax4Wz=-^?FUl zADI$?8ZvNM!p>Pz-gOquTX@`f-gUOA0SZ5dnbRh z*5`CV15_hnJl1`JH?<Tl9bnBQRsCF&g^1a(o%lprPNt6P*%ZjH>W-)|j1k0@PzUF%!jT2TBxH=g839NbQvt?u(U=_#y8rXX$e*URSQ-&@tAa=rjjxf@2oK5_D=j^AD) z3PxMXi<8n*NLoKMZtj-5%qT=zCsS-{lxPnP^q)`h5SDgNqkGPHHyo4|3N_CF&x?=v ziDcN-2T>U!B~@^w%`~sFm8SVtR~MXbejjp&y`3B<9m+1%^(zJH-BpaGbVi`x+US3{ zZVco{*+^zc$%o7XrKlHAJbA!gRsKM~6()aS|L84Uh^Q&w@1t0cW6Kxu05Dt#__VsF zFP*xkn6OW=^iyoVBSJop{{j5x^N;XX;vTCENK=D?-L=Ulbem6!y1I`CT%c3 zoTguM7qnBd%HviY-v$<)FUPu`$45cKocJNg%j{eJe@-mpD`$Vck`0xV^<3D-A}vI% zRE#%CwL7SRnOtp|xe_yyQm9$q>@Fu7n_KUY+m}P%^(?9pv2cJ85*HXQ0rAN^#qm)g zeX`jO;A3!8Zt|nh4Cvkc{y4eYCoWsIIcXyrh|c#n%u=MrRW%VsEX-i>UTf2O8hy_3 zP0LgY(QhkdpO2Gab>*-ap>*vAyosu)C|YxS)USPA4PdSR+*LcMU~HyN9ovnq(cw!d3nfcS{Ra2HRZJOqq^wi9mv?QL2&U#{OwhH`aw|Gg1^g_T+*bu+R_Yxr!0 zC87o_1E>E%(fZcFQ_sBjRI~Y49{Cxh&7J{;ZDb@82`t&wDDZpMa!`6_XZ^F?GID3g^(BL&hF&Ldf zXtRXe^umiMlz?d7M?CVlpkkZ5q=Rlxvobrr92L$gaEB@{6!scJJ2@zt<=YaERuQ24LF~JcT-S%@6*Y3^(*LhTti18u7o6=mk1U$Oo{n0 zp+LhYIY2caPiSsDfRN23G1gAbHT<$Kg06_i{0Akat}?t1z7&0?I5be=YjPnB z4Ls3xU9#sO&4}6|o4p9qbov61ob4qWT~ta$x;h%^reto+`f%}NdiUDt-TI&uLYAEM zLsY!Zz@C=YWPWUyRgZRxp5e8y8e6V=)BQFz_MD|hQA~-QD&herw?zaj0&c3);ZMNQ zjCfCpL<9j^kAzgUq@$!hB*PG3M&u<|2&NHTheE*i5#5 z^5hLsTEW#~0~@cc}3~|?V`0`{OhCr&_$;=^^%WK&h zA*&jPKcS&(m1SIiO+!jtNL7>H$scWo;plfFL53+Xu+k6q^s$8s1gI^ygSZ4v-C3QVUK_kHW|F{DQI;GZQ^<+aO|t z$?0DBniqtsJiTKmJkix}xP44qic;H%o?$BPn!UCzHeZ3xD}hRA4F>RWR#Jn;E1O_t z636B&FyvIZ=RX-xS>$hEj@xBv2zD%R#=pJcb3xY=y^F0re^YS|* zHFD|cQX8Vh%w!K#ygBQ;!_l+I1OZ9zzTMsotd9spCePJ`YoJfJy@CB?K}BXc+OY29pv; zt@;2@U!5TGz!+iekElCGpNI4nQ(WV1`Gl+r`LO%Gc(OV|7_l(T$pGDl`d)29WkRA d6Bob3YyqPQTm;gcTc1{rh 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%0Dd;wq+Rbns-SNO1+v>UKZ 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

~)`2tju2REF~mgS3Y4+DEZmK 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�& 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 diff --git a/src/mod/endpoints/mod_khomp/docs/README_en.html b/src/mod/endpoints/mod_khomp/docs/README_en.html deleted file mode 100644 index c72b84270c..0000000000 --- a/src/mod/endpoints/mod_khomp/docs/README_en.html +++ /dev/null @@ -1,39 +0,0 @@ -Mod Khomp: README: en

Quick guide

-

After installing the card in the system and run the installation program for the first time, the drivers and Khomp services will be added at system startup, and automatically loaded. -

If your system has at least one E1 trunk card and / or an FXO card, a basic setup screen will be presented at the end of the process, questioning signaling parameters - if there are signs E1 - and/or performing the adjustment cadences - where that FXO cards. -

If all these steps were performed successfully, proceed to the item Using Khomp Endpoint. If a problem occurs, see the User Guide, in the section Troubleshooting. -

-

Using the Khomp Endpoint

-

After installation and startup services required by Khomp, FreeSWITCH can now be loaded or initialized. -

-
  • WARNING: Avoid using the -nort, as it disables real-time scheduling, it is essential that the FreeSwitch are using real-time scheduling, especially if it is running side-by-side with web servers or database . Use the -nort may result in loss of audio quality, causing a serious commitment on the progress of system connections. -
-

After initialization of FreeSWITCH, you can verify that the module was loaded Khomp through the following command:
-

-
 freeswitch@hostname> module_exists mod_khomp
-
-

The next line should answer something like: -

-
 true
-
-

To verify that the FreeSwitch recognize all the cards, type: -

-
 freeswitch@hostname> khomp summary
-
-

The output of this command will show details of all cards accepted. -

In the case of an E1 card, you can check the status of links with the following command: -

-
 freeswitch@hostname> khomp show links
-
-

The state of individual channels, in turn, can be measured with the command: -

-
 freeswitch@hostname> khomp show channels
-
-

For more details on the commands of the Endpoint khomp type in the console of FreeSWITCH: -

-
 freeswitch@hostname> help khomp
-
-
  • IMPORTANT: To make full use of your card Khomp, you must configure your dialing rules, either through the extension.conf or from an external application by setting specific rules for conduct by receiving connections.
    In the User Guide, information can be found on the format of input contexts (responsible for receiving calls) and on the options available on application Dial (responsible for make calls) that can be used with the Endpoint Khomp, and other special features provided by it. -
-


-

\ No newline at end of file diff --git a/src/mod/endpoints/mod_khomp/docs/README_en.pdf b/src/mod/endpoints/mod_khomp/docs/README_en.pdf deleted file mode 100644 index 8931da91471c97852a627979755929e13ee52c4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 314423 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 S3`_P zIkp*8i}|pyzQBk;U!r?>l-r)n++|t4&e$_p!k`S{nTd`H3IS#X=%i=m9gD&UP~K#N zHaxJO{WbaOLD^m8-QSpH^-^bfVZwLohZ^cq7E7?PZ2@+K|HxZ5^_LWU!=I%0SZ4A# zA&_G3t9fcQqxY9%$hUaYnbsZwIG7CsvsIRZ(s0??0=%jYS%BJ+Y|m0Rw}mMqYKo2q zV%4hS#X>qM zk?j@J;s#C=WIoltu|{j!qNoz459(KJmnj~NC8@x>DGwMK&1$c8XQd5EBLVZ1-B@bE zwg}bt>~R|=B5Nq2C``MTbt7~21EG0?gQxK3mYm4)*vy&P#XsXeaoeN4} z@2!@sOEShi8|N~O&lKF><}XmRGVJ1m*iMmmCXy{_y( zYsQy9NZfr9e(i=aY&^kvBwW-Yb`phy5pUaCiIm|r)k2DD+wC-2HY=3!CdJnodKPUFsfJvJOOy>`!$}NRL>F6W6*#(V3=0U?VRC3c^|hKz zjX5h>e>yKn_CGq3_*s`)=53!9e>kPdx+GejSGs4!cP<{WX)-ye(@$dtj^0X06$OSDB*|DrhvmEyejYLf;W|5B|p&Ve_!5)>q9blb1}D zu=fu;UBUiLG`H)5;+~~dHPa)Cv&VB|>z~ZaP(j``s&1B3*qP1wiHRFofsy6V5mf8D zv<%6)7+48JNh5LnBOgQcOq~oP{>9f|ASnJ#1H^v+GY^-nM3!JW)ZY2fJeFq`k8Z5U z_^daiHTn}x0Te9_Q|Pp8jb>%`MG%{�P|1zXoog4PGQ>CM}h0roq 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 d6Bob3YyqPQTm;gcT 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

cjx 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%0Dd;wq+Rbns-SNO1+ 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᚛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 Khomp: User Guide -

First considerations

-

This document covers information about the Endpoint of Khomp as a whole, include the options, applications, CLI commands, among others. -

For first installation procedures, please see the README. -
-

-

Configuration

-

Configuring the Khomp Endpoint is a task that consists of three steps: -

-
  • Configuration of the boards through the K3L; -
  • Setting up the Endpoint; -
  • Setting up the FreeSWITCH. -
-

These steps are described more fully below. -
-

-

K3L API Configuration

-

This step is carried out in a semi-automated way using the khompwizard program, a wizard that configures the basic parameters of the system boards. This wizard initializes the configuration files using information from the user when they are needed, initializing the standard settings to default values. -

Typically, this program runs automatically after installation of the system. However, you may need to run it manually if an update is being performed, or if new cards were added to the system after installing new drivers. -


-If you need to set advanced parameters of the board and/or signaling, the program k3lconfig allows you to access all the available settings for each installed card. For more information about this program, check the k3lconfig User's Guide. For solving synchronization issues, check the Troubleshooting section for manual configuration of the boards. -
-

-

Endpoint Configuration

-

The system's default configuration normally meet most user's needs. However, the configuration of the Endpoint Khomp can be modified through the configuration file '/usr/local/freeswitch/conf/autoload_configs/khomp.conf.xml'. -

The list of options is as follows: -

-

<channels>

-

Define general settings of all channels of Khomp: -

-
Sintaxe: <param name="..." value="..."/>
-
-
  • accountcode: Sets the default account code to calls in the Endpoint. This option can be any alphanumeric string; -
  • dialplan: Name of the dialplan module in use. -
  • auto-fax-adjustment: Enable ("yes") or disables ("no") the automatic adjustment of the channel (disable the echo canceller and the suppression DTMF) tone to detect FAX (local option) ; -
  • auto-gain-control:Enable ("yes") or disables ("no") the activation of the automatic gain control (AGC) by the Endpoint (local option); -
  • context-digital: Context for incoming connections on digital boards (the default is "khomp-DD-LL", where "DD" will be replaced at the time of connection by the device number, "LL" by the number of the link, "CCC" by channel number and "SSSS" for the device serial number); -
  • context-fxo: Context for incoming connections on FXO cards (the default is "khomp-CC-DD", where "DD" will be replaced at the time of connection by the device number, "CC" by channel number, and "SSSS" by the device serial number); -
  • context-fxs: Context for incoming connections on FXS cards (the default is "khomp-CC-DD", where "DD" will be replaced at the time of connection by the device number, "CC" by channel number, and "SSSS" by the device serial number); -
  • context-gsm-call (or context-gsm): Context of entry for GSM boards (the default is "khomp-CC-DD", where "DD" will be replaced at the time of connection by the device number, "CC" by channel number, and "SSSS" by the device serial number); -
  • context-gsm-sms: Context for incoming SMSs (the default is "khomp-sms-CC-DD", where "DD" will be replaced by the number of device, "CC" by channel number and "SSSS" by the device's serial number); -
  • context-pr: Context for incoming connections on boards KPR (default is "khomp-CC-DD", where "DD" will be replaced at the time of connection by the device number, "CC "by channel number); -
  • delay-ringback-co: Sets the delay to enable the generation of call control tone (ringback) by the Endpoint Khomp when there is an ringback indication from signaling and there is no audio being sent by the channel which indicated the situation (local option); -
  • delay-ringback-pbx: Sets the delay to enable the generation of call control tone (ringback) by the Endpoint Khomp when there is an ringback indication, and the audio has no tone (silence) (local option); -
  • disconnect-delay: Sets the time in milliseconds to perform processing a disconnect event, to ignore situations where other equipment performing the double service to overthrow collect calls (local option); -
  • drop-collect-call: Enables/Disables the action of dropping collect calls. If enabled, all collect calls will be dropped no matter what KDropCollectCall is set to (the default value is "no"); -
  • echo-canceller (former 'echocanceller): Active ("yes") or disables ("no") echo cancellation automatic Endpoint (local option); -
  • flash-to-digits: Defines the digits to be sent when the FLASH is detected on FXS channels; -
  • fxo-send-pre-audio: When enabled ("yes") releases audio channel before the outgoing call connection boards KFXO (the default value is "yes"); -
  • fxs-digit-timeout: Defines the timeout, in seconds, between digits of a FXS board's extension; -
  • fxs-global-orig: Start number for sequencial branch numbering in FXS cards that are not listed in the [fxs-branches] section (the numbering follows ascending order from board number and physical channel number) (default is "0"); -
  • fxs-co-dialtone: Sequences of numbers, separated by commas, which fires a continuous tone (of central office) in FXS branches (eg: "0,99" means that, when you dial "0" or "99", the user will hear a continuous dial tone) (default is empty); -
  • fxs-bina: When enabled ("yes"), calls to FXS lines will send digits corresponding to the source phone identification using BINA DTMF signaling (the default value is "no") (local option); -
  • ignore-letter-dtmfs: Defines if the channel should ignore some uncommon DTMF digits detected by the board (A, B, C and D). However, if you need to pass those digits througth the board, you may need to set this option to 'no' (the default value is "yes"); -
  • input-volume: Sets the volume gain for incoming audio (entering the board), from -10 to +10 (local option); -
  • kommuter-activation: Sets whether to activate devices kommuter found in the system will be done automatically ("auto") by the channel, or manually ("manual") by the user through the command "khomp kommuter on/off" -
  • kommuter-timeout: Sets the timeout (in seconds) for initializing the kommuter devices. If this timeout is reached without receiving notification of the channel, the devices will switch back to "off" condition. The minimum value is "0", where the links will always remain switched "on", and the maximum is "255"; -
  • language: Set language to Khomp board calls; -
  • log-to-console: Set log messages to be printed on the console; -
  • log-to-disk (old "log"): Set log messages to be saved to disk; -
  • out-of-band-DTMF (former dtmfsuppression): Activate ("yes") or disables ("no") the removal and DTMF sending these out-of-band (local option); -
  • output-volume: Define o volume de sada das ligaes, varia de -10 a +10 ; -
  • pulse-forwarding (former 'pulsedetection): Active ("yes") or disables ("no") for the detection of pulses and converting them into DTMF (local option); -
  • r2-preconnect-wait (former 'r2preconnectwait): Sets the timeout sending the ringback signaling, protocol R2/MFC to start sending audio silence. Only used when "r2-strict-Behavior" is set to "no" (local option); -
  • r2-strict-Behaviour: Enable ("yes") or disables ("no") the behavior of signaling R2/MFC as the standard sets. The default is "no", and can be changed to "yes" if needed to receive / send data precise signaling protocol (condition B, for example) (local option); -
  • suppression-delay (former suppressiondelay): Activate ("yes") or disables ("no") the delay necessary to suppress DTMF. If disabled ("no"), also disables suppression of DTMF (local option); -
  • trace: Set debugging options. Should not be used in production unless absolutely necessary; -
  • user-transfer-digits: Defines a sequence of DTMF digits to initiate the transfer between FreeSWITCH® and another PBX (using user signaling, like QSig or FXO FLASH); -
-


-

-

<groups>

-

Defines the groups to be used in channel allocation. -

In this case, the options are used to define names for strings allocation of channels. The format follows the standard <group name> = <allocation string>, where the allocation string is the same string used in the bridge application, and group name is an arbitrary name chosen by the user. -

-
For example, to define the group pstn as the channels 0 and 5 of the board 0, the following line could be used: -
-
<param name="pstn" value="b0c0 + b0c5"/> 
-
-

This group, in turn, could be used in the bridge application as <action application="bridge" data="Khomp/Gpstn/..."/>. -

-
You can associate a given input context to a channel group, simply specify a name of context string after the allocation, separated by ':'. -
-

For example, to define the same group pstn as channels 0 to 20 of card 0, and defining the incoming context to for channels in this groups to from-pstn, one could use the line: -

-
<param name="pstn" value="b0c0-20:from-pstn"/>
-
-

This group would be used the same way as before in the bridge application, and all the calls coming from these channels would be treated in context from-pstn. -
-

-

<cadences>

-

Defines settings for the Endpoint cadences. -

In this case, the options are names cadences, followed by one or two pairs of numbers - that define the ranges of tone and silence to be used in cadences. -For details, please refer to the configuration file for examples. -
-

-

<fxs-branches>

-

Defines source numbers for the board KFXS. -

In this case, the options are sequences of prefixes of branches and serial numbers of the boards, which define the basic numbers of source addresses, and the numerical order of the boards. The format of the options is: -

-
<param name="prefixo" value="serial1, serial2, ...."/>
-
-

For example, if two KFXS-300 SPX boards with serial numbers K0374 and K2352 must be numbered sequentially, starting from branch 200, you may write: -

-
<param name="200" value="374, 2352"/>
-
-

This will define the first branch of board 'K0374 as number 200, the second as 201, and so one. The first branch from board K2352 will have number 230 (as K0374 has 30 channels), the second will be numbered 231, and so on - until the last channel, numbered 259. -

For more details, please refer to the configuration file for other exemples. -
-

-

<fxs-hotlines>

-

Sets hotlines for the KFXS based boards -

In this case, the options are sequences of branches and sequences of destination numbers, which define branches to be treated as "hotlines" and numbers to be dialed when they are take off hook. For instance: -

-
<param name="100" value="1234"/>
-<param name="200" value="4321"/> 
-
-

In the first line, the branch numbered 100 will call extension 1234 when taken off hook, while in the second one, branch 200 will call number 4321 when taken off hook. -
-

-

<fxs-options>

-

Allows you to set specific settings for FXS extension. -

In this case, the settings are extension numbers (based on those defined in the <fxs-branches>), and the options and their values. -

-
  • context; -
  • input-volume; -
  • output-volume; -
  • calleridnum; -
  • calleridname; -
  • language; -
  • accountcode; -
  • flash-to-digits. -
-

Each option is separated from each other by a pipe "|" or a slash "/" and defined after the colon ":". Example: -

-
<param name="200" value="input-volume:1|context:master-branch" />
-
-

For more information on the syntax and examples, please refer to the configuration file. -

For more information visit the configuration file 'khomp.conf.xml'. -
-

-

FreeSWITCH Configuration

-

When connections are received on the boards and devices Khomp, they are forwarded by the Endpoint to specific contexts within the dialplan of FreeSWITCH®. These settings can be changed via the configuration file khomp.conf.xml, available on the FreeSWITCH configuration directory (by default, "/usr/local/freeswitch/conf/autoload_configs"). -

For details about the specific contexts, see section Endpoint configuration. -

Below are details of how to configure the settings for incoming calls -
-


-

-

Contexts for E1 channels

-

For E1 boards, inbound contexts are predefined as option context-digital with default value as following: -

-
<param name="context-digital" value="khomp-DD-LL"/>
-
-

This standard defines the context that links will be redirected in accordance with the number of the board and number of the link: DD is the device number (two digits), and LL is the number of the link (also with two digits). -

However, it is possible to configure other inbound contexts, with different formats. There is format CCC, which means the channel number on the card (three digits), and SSSS, which represents the serial board number (with four digits). -

Examples for configuration entries (khomp.conf.xml): -

-
<!-- Serial board number and sequential link (ex: khomp-01-00) -->
-<param name="context-digital" value="khomp-DD-LL"/>
-
-
<!-- Serial board number and sequential link (ex: khomp-3049-00) -->
-<param name="context-digital" value="khomp-SSSS-LL"/>
-
-
<!-- Sequential board number and the channel (ex: khomp-00-001) -->
-<param name="context-digital" value="khomp-DD-CCC"/>
-
-
<!-- Receive all calls in one context (khomp-digital) -->
-<param name="context-digital" value="khomp-digital"/>
-
-

Follows an example the context usage inside the dialplan: - -

-
<!--
-The present context in 'extensions.conf' will handle calls
-that come from the link 0 (first link) of the board 0.
--->
-<context name="khomp-00-00">
-             .
-             .
-             .
-</context>
-
-

Another example, using the same format: - -

-
<!-- 
-The present context in 'extensions.conf' will handle calls
-that come from the link 1 (second link) of the board 0.
--->
-<context name="khomp-00-01>
-             .
-             .
-             .
-</context>
-
-

A complete example, with a few simple actions: - -

-
<context name="khomp-00-00">
-    <extension name="exemplo_1">
-        <condition field="destination_number" expression="^1234$">
-            <action application="bridge" data="Khomp/b0L1/2345"/>
-        </condition>
-    </extension>
-    <extension name="exemplo_2">
-        <condition field="destination_number" expression="^23(\d{2})$">
-            <action application="bridge" data="sofia/${use_profile}/11$1@${sip_from_host}"/>
-        </condition>
-    </extension>
-</context>
-
-
<context name="khomp-00-01">
-    <extension name="exemplo_3">
-        <condition field="destination_number" expression="^1111$">
-            <action application="bridge" data="Khomp/b0L0/2345"/>
-        </condition>
-    </extension>
-</context>
-
-

This dialplan defines that: -

-
  1. The incoming calls on the link 0 of the board 0 will have the following handling: -
    • Calls to the extension 1234 for will be redirected to the second link on the first board (b0L1), calling number 2345; -
    • Calls to any four digit number starting with23 will be redirected to SIP phones numbered 11 plus the last two digits of the number dialed. -
    -
  2. The incoming calls on the link 1 of the board 0 for the number 1111 will be redirected to the first link of the first board (b0L0) calling number 2345. -
-

Contexts of FXS/FXO/GSM channels

-

Just as in the context of E1 cards, inbound links are forwarded to the Endpoint FreeSwitch. -

The context is pre-defined as follows, according to the file khomp.conf.xml: -

-
<param name="context-gsm" value="khomp-DD-CC"/> ;placas GSM
-
-
<param name="context-fxs" value="khomp-DD-CC"/> ; placas FXS
-
-
<param name="context-fxo" value="khomp-DD-CC"/> ; placas FXO
-
-

For these options, DD is the device number (two digits), and CC is the channel number (also two digits). There is also the SSSS format, which represents the serial number board. -

-
  • NOTE: In the KGSM board, incoming calls are always redirected to the "s" extension, since the GSM protocol does not identify the target number, only the originator - if not omitted. -
-

Priority settings on the FXS branches

-

On calls originated from an FXS branch, the Endpoint searches for a valid extension (digits sent) after the DTMF # or after the timeout (option fxs-digit-timeout). That search is done in the context defined in section <fxs-options>, or if no context configured, the search is done in context defined in context-fxs. -
-

-

Contexts for SMS messages (GSM only)

-

SMS messages are received by the Khomp Endpoint and forwarded to FreeSWITCH as a normal connection but no audio, which has some variables set with information received in the message - for more information on these variables, see the documentation of the variables of the Endpoint. This context can also be modified in the same way as the above contexts. -

The default value for this option follows (khomp.conf.xml): -

-
<param name="context-gsm-sms" value="khomp-sms-DD-CC"/> 
-
-

Where DD is the device number (two digits), and CC is the channel number (also with two digits). For example: -

-
<context name="khomp-sms-00-01">
-    <extension name="sms">
-        <condition field="destination_number" expression="^s$">
-            <action application="log" data="DEBUG KSmsType=${KSmsType}"/>
-            <action application="log" data="DEBUG KSmsBody=${KSmsBody}"/>
-        </condition>
-    </extension>
-</context>
-
-

Contexts for Khomp_PR channels (KPR)

-

For these cards, inbound links have a pre-defined context, as shown below: -

-
<param name="context-pr" value="khomp-DD-CC"/> 
-
-

In this case, DD is the device number (two digits), andCC is the channel number (also two digits). The name and format of this context can also be changed through the "context-pr" in the configuration file. -
-

-

Groups contexts

-

The section groups, in the configuration file khomp.conf.xml, can be used to define specific settings for certain groups of channels. -

This section is detailed in the section Endpoint Configuration. -
-

-

Using the bridge application

-

The bridge application is responsible for generating calls from the FreeSWITCH from a dialplan. This application can be used to generate calls from different Endpoints technologies, following a specific format to define destination, dialing options and define the communication Endpoint to be used. -

-

Fields relating to the Khomp Endpoint

-

When used for Khomp channels, the bridge string can have two, three or four fields separated by slash (/). Some example strings: - -

-
<action application="bridge" data="Khomp/B2L0/32625644"/>
-<action application="bridge" data="Khomp/*B2L0/32625644"/>
-<action application="bridge" data="Khomp/S0411/99991234"/>
-<action application="bridge" data="Khomp/Gpstn/99991234"/>
-<action application="bridge" data="Khomp/*Gpstn/99991234"/>
-<action application="bridge" data="Khomp/B2C58/32625644/category=4:orig=4855553232"/>
-<action application="bridge" data="Khomp/b0c9"/>
-<action application="bridge" data="Khomp/b0c1+b0c14"/>
-<action application="bridge" data="Khomp/r304"/>
-
-

In the first five examples, three fields have been specified; in the sixth, four fields are used; in the last three examples, just two are used. -

The fields description for the Khomp Endpoint: -

-
  • 1st field: Khomp: identifying the type of Endpoint in question; -
  • 2nd field: B2L0, S0411, Gpstn, etc: represents the Policy for channel allocation (detailed below); -
  • 3rd field: 32625644 and 99991234: the destination numbers (missing for calls to KFXS channels); -
  • 4th field: category=4:orig=4855553232: additional options, detailed below. -
-

NOTE: The bridge allocation string with only two fields is specific to the KFXS boards, where the destination is the channel itself. -

-

Policy for channel allocation

-

The policy for allocation of channels on the Khomp Endpoint can be specified in the bridge string itself or in the groups section (inside the configuration file khomp.conx.conf). To specify boards, links and channels, the following syntax is available (considering X, Y and Z as any numbers): -

-
  • bX -- search the channels on the board X, ascending order; -
  • bXLY -- search channel on the link Y from X board, ascending order; -
  • bXcY -- try to allocate channel Y from board X; -
  • bXcY-Z -- search for channels starting from channel Y to channel Z (inclusive) of board X, ascending order; -
  • BXcY-Z -- same as above, but descending order; -
  • sX -- search the channels on the board of serial number X, ascending order; -
  • sXLY -- search channel on the link Y from board of serial number X, ascending order; -
  • sXcY -- try to allocate channel Y from board of serial number X; -
  • sXcY-Z -- search for channels starting from channel Y to channel Z (inclusive) from board of serial number X, ascending order; -
  • SXcY-Z-- same as above, but descending order. -
-

To search for extensions of cardsKFXS according to the extension number, can be used the following syntax (whereas X and Y valid extension numbers): -

-
  • rX- search branch numbered X; -
  • RX- equivalent to the above; -
  • rX-Y- search from branch X to Y, ascending order; -
  • RX-Y- search from branch X to Y, descending order. -
-

The capitalization of the letter 'B', 'S' or 'R' defines the search order of the channels: if capitalized, order is descending; otherwise, ascending. -

As for the allocation of channels across groups, the following syntax is available: -

-
  • ggroupname - uses the string defined the group "groupname" in the configuration file (detailed in the configuration section of the Endpoint). -
  • Ggroupname - equivalent to the above. -
-

Grouping channel allocations

-

There are cases where you need to get more channels for a particular device or particular group of extensions. For this, there is an extension available in string allocation, with respect to the use of token sum (+) to concatenate multiple stringsbinding, as follows: - -

-
<action application="bridge" data="Khomp/B1L0+B2L0/32332933"/>
-<action application="bridge" data="Khomp/*B2+B3+B4/99887766"/>
-<action application="bridge" data="Khomp/S0411+B1L0/99887766"/>
-<action application="bridge" data="Khomp/Gpstn1+Gpstn2/99991234"/>
-<action application="bridge" data="Khomp/*gOperadora1+gOperadora2/98891234"/>
-
-

This grouping is available for the application bridge and on the specification of groups. The processing of allocation takes place from left to right - except when using cyclic channel allocation, whereall the specified channels are scanned simultaneously. -

-

Cyclical and/or fair allocation

-

Another way for allocation of channels is the cyclic and/or fair allocation, which chooses the channel that has completed the the lowest number of outgoing calls. This mode of allocation may be used by passing an asterisk (*) before the allocation string of channels (as can be seen in the section above, in the second and fifth examples). -

When started with an asterisk (*), other forms of allocation (increasing, decreasing, etc) are used to decide what channel will be allocated when there are two or more channels with less number of outgoing calls. -

-
  • WARNING: The use of fair and/or cyclic is recommended only for analog (KFXO), branches (KFXS) and cellular interface (KGSM) boards. E1 connections should allocate channels in one way (ascending/descending) from one side and the opposite on the other to avoid problems of double seizure (which may occur in R2/MFC signaling). Fair/cyclic allocation also costs more in memory and processor footprint, which tends to be a higher cost in E1 due to the higher number of channels (30 in each link).

    For these reasons, fair/cyclic allocations should only be used on signalizations where it can represent any real difference, like equalizing the charge costs of the lines, the total usage, or the number of connections received by each branch. -
-

Available options

-
  • orig: Sets the originator number, without changing the variable ${CALLERID(num)}. That is, the option orig serves only to pass a number of different source of${origination_caller_id_number}. If FreeSWITCH has already set the variable ${origination_caller_id_number}, which is the default behavior, Endpoint automatically uses this value as a reference to the number of origin, without having to pass any additional options.

    On the boards KGSM, is set to restricted, omits the number of origin. Example:
    -
-
- <action application="bridge" data="Khomp/b0/99887766/orig=restricted"/>
-
-
  • category: When set to a numeric value, sets the category of outgoing call to this value (available only in R2/MFC signaling); -
  • uui: When adjusted for a number and a string of text, separated by hash ("#"), sends a "UserToUser" to the other end before making the call - the first value will be the descriptor and the second one will be the message as the text (available only in ISDN signaling); -
  • ring_cadence: When set to a cadence name (listed in the [cadences] section), uses this for ringing FXS channels; -
  • ring: When set to two numbers separated by a dot ("."), defines the cadences to be used while ringing a FXS channel - the first time is the ringing time, and the second one, the silence time; -
  • ring_ext: When set to two numbers separated by a dot ("."), defines the extended cadences to be used while ringing a FXS channel, executed after the ring specification - the first time -
  • usr_xfer: Defines a group of DTMF digits to initiate a transfer between PBXes (using QSig or FXO FLASH, for instance); -
  • drop_on: When set to "message_box", "human_answer", "answering_machine", "carrier_message", "unknown" or a list them - separated by plus sign ("+") or dot ("." ) - drops the call when detect voice mail box, human answer, answering machine messages, operator messages, or unknown answer pattern - respectively. Available in digital signals (E1 links and boards KGSM). Additionally, the information service is reported to the user in the variableKCallAnswerInfo; -
  • answer_info: When specified (take no parameters), report answer information to the user through the variableKCallAnswerInfo -
  • pre: When set to a string of DTMF digits, uses these to pre-allocate an output channel in an analog PABX, dial the desired number of B below. Only available for signaling analog (FXO); -
  • pre_answer: When set (need no value), answers the channel before the connection is completed - allowing, for instance, DTMF tones to sent (useful for use in a DISA); -
  • output_volume: Sets the output volume of the link (ranges from -10 to +10); -
  • input_volume: Sets the volume of inbound link (ranges from -10 to +10); -
-


-

-

List of variables

-

Here's a list of variables available in the Endpoint: -

-
  • KDropCollectCall: When set before ringing or answer an incoming call, enables ("yes") or disables ("no", default) the drop of collect calls based on signaling received from the central public, double answer, audio tone recognition (can be defined globally); -
  • KR2SendCondition: When set to a numeric value, before the ringing an incoming call, adjusts the condition for this Endpoint to this value (available only on R2 signaling); -
  • KR2GotCategory: Adjusted by the Endpoint when an incoming call is received, with the category number of the caller (only available on R2 signaling); -
  • KR2GotCondition *: Adjusted by the Endpoint, available after returning from a call made by FreeSWITCH (bridge application). Has the condition of the remote end received when making the call (available only for R2 signaling); -
  • KISDNGotCause *: Adjusted by the Endpoint, available after returning from a call made by FreeSWITCH (bridge application). Has the ISDN "cause" code received when making the call (available only for ISDN signaling); -
  • KCallAnswerInfo *: Adjusted by the Endpoint, available after returning from a call made by FreeSWITCH (bridge application). Contains the service information identified to make the call (available only for digital signaling - E1 and GSM); -
  • KSmsDelivered: Adjusted by the Endpoint when sending a SMS message with the application KSendSMS, saying whether the message was delivered successfully ("yes") or not ("no"); -
  • KSmsErrorCode: Adjusted by the Endpoint when sending a SMS message with the application KSendSMS, containing the error code that happened when sending the message; -
  • KSmsErrorName: Adjusted by the Endpoint when sending a SMS message with the application KSendSMS, contains the name of the error or "None" if there has been no error; -
  • KSmsType: Adjusted for the input Endpoint in the context of SMS messages, defines the type of message received (can contain the values "message", "confirm" or "broadcast"; -
  • KSmsFrom: Adjusted for the input Endpoint in the context of SMS messages, sets the number of origin of the received message (available on types" message "and" confirm "); -
  • KSmsDate: Adjusted for the input Endpoint in the context of SMS messages, sets the date of sending the message (available on types "message" and "confirm"); -
  • KSmsSize: Adjusted for the input Endpoint in the context of SMS messages, contains the size (in bytes) of the received message (available on types "message" and "broadcast"); -
  • KSmsMode: Adjusted for the input Endpoint in the context of SMS messages, contains the encoding type of the received message (available on types "message" and "broadcast"); -
  • KSmsBody: Adjusted for the input Endpoint in the context of SMS messages, contains the text of the received message (available in types "message" and "broadcast"); -
  • KSmsDelivery: Adjusted for the input Endpoint in the context of SMS messages, containing the date of delivery of the message sent earlier (available in type "confirm"); -
  • KSmsStatus: Adjusted for the input Endpoint in the context of SMS messages, contains the status of the message sent earlier (available on the type "confirm"); -
  • KSmsSerial: Adjusted for the input Endpoint in the context of SMS messages, contains the serial number of the received message (available on the type "broadcast"); -
  • KSmsPage: Adjusted for the input Endpoint in the context of SMS messages, contains the page number of the received message (available on the type broadcast"); -
  • KSmsPages: Adjusted for the input Endpoint in the context of SMS messages, contains the total number of pages to be received (available in type "broadcast"); -
  • KUserInfoDescriptor: Sets/reports protocol descriptor of the User-to-User Information message (ISDN). -
  • KUserInfoData: Sets/reports data in the User-to-User Information message (ISDN). -
  • KFaxSent: Adjusted by the Endpoint when sending FAX with KSendFax application, and determines whether the fax was successfully sent ("yes") or not ("No"); -
  • KFaxReceived: Adjusted by channel when receiving FAX with KReceiveFax application, and determines whether the fax was successfully received ("yes") or not ("no"); -
  • KFaxResult: Adjusted by the channel when sending or receiving FAX with the application KSendFax or KReceiveFax (respectively), and defines the result of execution. -
-


-

-

Description of variables

-

Below, follows an explanation on how to use variables of Khomp Endpoint in the dialplan, to communicate and/or to receive information: -


-

-

KDropCollectCall

-

When activated, causes the Endpoint to drop Khomp collect calls through dual service (available for signaling 'R2 Digital' and FXO), through information available on the ISDN protocol and R2/MFC, or by detecting the audio call collect (available for any digital signage for E1, and GSM signaling). -

This variable is useful to filter collect calls to certain extensions, and must be set before making any type of answer - applications such as playback and bridge should always be executed after setting this variable, for example. -

For better functionality, is also recommended that no call status (ringback) is sent before this variable is set, so applications should be performed only after the correct setting of this variable. -

This variable can be set locally and globally, both to yes or no. The adjustment of global variable to yes will drop all the collect calls, unless the particular call is set to no - this allows the creation of a global filter of collect calls, with few exceptions. -

Enabling the variable in context default: -

-<context name="default"> -

-
<extension name="example">
- .
- .
- .
- <action aplication="set" data="KDropCollectCall=yes"/>
- .
- .
- .
-</extension>
-
-

</context> -

Enabling the variable in the global context, remembering that it must be configured in the file vars.xml: - -

-
<X-PRE-PROCESS cmd="set" data="KDropCollectCall=yes"/>
-
-

KR2SendCondition

-

When you receive a call, can be set before sending ringback by FreeSWITCH (ie, before the run FreeSWITCH applications answer, bridge). When used in signaling R2/MFC, this variable sets the condition for B to the numeric value desired. -

Exemplo: - -

-
<!-- Condition "NUMBER CHANGED" warns the caller that the number of B has changed. -->
-<action application="KR2SendCondition" data="3"/>
-
-

KR2GotCategory

-

When you receive a call, is set by the Endpoint with the category received from the number that originated the call. It is set in signaling R2/MFC, and can be found anywhere in the dialplan. -

Example: - -

-
<action application="log" data="DEBUG KR2GotCategory [${KR2GotCategory}]"/>
-
-

KR2GotCondition

-

Variable adjusted by the Endpoint, and available after returning from a call made by FreeSWITCH. Has the condition of B received when making the call. Available only for signaling R2/MFC. -

Example: - -

-
<action application="log" data="DEBUG KR2GotCondition [${KR2GotCondition}]"/>
-
-

KUserInfoDescriptor

-

Variable adjusted by the Endpoint in the context of entry, from information received by the ISDN network functionality through user-to-User Information. Contains the descriptor number of the protocol used by the other end, and usually contains the value '0 ', but this is dependent on application. -

For further information, consult the specification ITU-T Q931 (more precisely, the specification table 4-26). -

Example (working with the descriptor number of the protocol): - -

-
<action application="log" data="DEBUG KUserInfoDescriptor [${KUserInfoDescriptor}]"/>
-
-

KUserInfoData

-

Variable adjusted by the channel in the context of entry, from information received by the ISDN network functionality through user-to-User Information. Contains the actual data, which were received in the form of a string of text. -

More information about this feature, see the specification ITU-T Q931. -

Example (working with the data received): - -

-
<action application="log" data="DEBUG KUserInfoData [${KUserInfoData}]"/>
-
-

It is important to note that the variables are sensitive to the capitalization of letters (case sensitive). -

-

KCallAnswerInfo

-

Variable adjusted by the Endpoint. It is set in outbound connections, representing the type of answer performed by the other end. May contain the following values: -

-
  • "MessageBox" (*): detected mailbox of a cell phone; -
  • "CarrierMessage": message sent before the service provider; -
  • "AnsweringMachine" (**): answering answering machine; -
  • "HumanAnswer" (**): human service; -
  • "Fax": reported when a fax tone is detected. -
  • "Unknown": unknown type of care; -
-
-

(*) This type of service is detected by signals at certain frequencies that are sent before the call comes into a mailbox, and vary by operator. The algorithm captures most of the mailboxes, but can fail if there is not a clear signal, or if it is not within the standards most commonly used; -

(**) The difference between these two types of care depends on the specific configuration using the program k3lanswerinfoconfig, with the detection only based on heuristics and never with an accuracy of 100%. -
-

-

Console commands

-

List of available commands in the console for the FreeSWITCH Endpoint of Khomp: -


-

-
  • khomp channels disconnect : Disconnect one or more channels. This command sends a message directly to the physical channel of the card in question, requesting a disconnection. Use with caution; -
  • khomp channels unblock : Unlock blocked channels for input or output. Only available in digital signage via E1; -
  • khomp clear links: Clears error counters on the links; -
  • khomp clear statistics: Clears the statistics of channel connections, or statistics for a particular channel; -
  • khomp get : Gets the number of options Endpoint Khomp; -
  • khomp kommuter : Enables or disables kommuters connected via USB on this machine. Only accessible when the configuration "kommuter-activation" is set to "manual". -
  • khomp kommuter count: Gets the amount of kommuters connected via USB on this machine; -
  • khomp log console: Sets options in the console logs; -
  • khomp log disk: Sets logging options to disk; -
    • khomp log console and khomp log disk have auxiliary options No, which reverses the selection of messages, and just, which generalizes the choice. Examples: -
      • khomp log disk just commands events (Enables only logging to the disk of commands and events); -
      • khomp log disk no commands (Disable logging to the disk of commands sent to board); -
      • khomp log disk warnings (Enables also logging to the disk of warnings from Endpoint). -
      -
    • More information on options for the log command, type: "help khomp log disk" or "help console log khomp". -
    -
  • khomp log rotate: Rotate log files from the Endpoint; -
  • khomp log status: Shows log messages currently being written to disk and displayed on the console; -
  • khomp log trace isdn: Enable Debugging ISDN signaling; -
  • khomp log trace k3l : Enables debugging low-level API K3L; -
  • khomp log trace r2 : Enables debugging low-level signaling R2/MFC; -
  • khomp reset links: Sends a reset command for a specific E1 of a particular card; -
  • khomp revision: Shows version number and revision of the Endpoint; -
  • khomp select sim: Select the SIM card, available on the boards KGSM; -
  • khomp send command : Sends command API K3L directly to the board (only for debugging, may compromise the stability of the system if used improperly); -
  • khomp send raw command : Sends a command directly to the DSP board (only for debugging, may compromise the stability of the system if used improperly); -
  • khomp set : Sets various options of the Endpoint Khomp; -
  • khomp show calls : Shows states for calls, may also listing specific channels or boards; -
  • khomp show channels : Shows the status of the channels Khomp and may also list specific adapter; -
  • khomp show links: Display states of E1 links available. -
  • khomp show statistics : Shows the statistics of channel connections, or statistics for a particular channel; -
  • khomp sms : Send an SMS message for a given number, using KGSM channels; -
  • khomp summary : Prints a summary of system boards and their features; -
-


-

-

Additional features

-

This chapter discusses additional features of the Endpoint, related to the special features present in certain signs. -
-

-

Aplicaes (applications) e canais

-

The Endpoint Khomp, and to record a type of communication channel "Khomp" also records the following items: -
-

-

"KUserTransfer" application

-

Performs the transfer process from the current channel number for the extension using the signaling protocol QSig (Single Step Call Transfer) for boards configured with E1 ISDN signaling (ISDN), or use the FLASH command for FXO. -

The syntax follows: -

-
 <action application="KUserTransfer" data="number[,options])"/>
-
-

Example: -

-
<action application="answer"/>
-<action application="KUserTransfer" data="2345"/>
-
-

The fields have the following meanings: -

-
  • number: Number where the link should be transferred. -
  • options: Sets the transfer options to be used, which are: -
    • N: Wait until the channel is disconnected. -
    -
-


-

-

Application "KSendSMS"

-

This application has the function of sending SMS messages through the boards of KGSM Khomp using modules and SIM cards in the board to do so. The syntax of the application is as follows: -

-
<action application="KSendSMS" data="resource | destination | message" />
-
-

Each field can be summarized in: -

-
  • resource: The following is a syntax identical to the allocation of channels Dial application, and defines what modem use; -
  • destination: Number where to send the message, may be preceded or succeeded by! to request a confirmation of transmission; -
  • message: Text (without quotes) to be sent todestination. -
-

After sending the message, the variables KSmsDelivered and KSmsErrorCode will contain the result of the post. For more information about these, please consult the section on variables used in the Endpoint. -

Examples of use of this application are as follows: -

-
  • Sends "Test message." phone for "99887766" using the modem "1" (second modem) card "0": -
-
<action application="log" data="DEBUG Sending SMS ..." />
-<action application="KSendSMS" data="b0c1|99887766|Test message" />
-
-
  • Sends "Test message." phone for "99887766" using the first free modem card "0", and checks the return shipment: -
-
<action application="log" data="DEBUG  Sending SMS ..." />
-<action application="KSendSMS" data="b0|99887766|Test message" />
-<action application="log" data="DEBUG Sent? ${KSmsDelivered}" />
-<action application="log" data="DEBUG Code: ${KSmsErrorCode}" />
-<action application="log" data="DEBUG Desc: ${KSmsErrorName}" />
-
-
  • Sends "Test message." phone for "99887766" using the first free modem card "0", or the first free channel board "1" (if no free channel at the first sign): -
-
<action application="log" data="DEBUG Sending SMS ..." />
-<action application="KSendSMS" data="b0+b1|99887766|Test message" />
-
-
  • Sends "Test message." phone for "99887766" using the first free modem card "0", requesting confirmation: -
-
<action application="log" data="DEBUG Sending SMS ..." />
-<action application="KSendSMS" data="b0|99887766!|Test message" />
-
-


-

-

Application "KEchoCanceller"

-

This application has the function to enable or disable the echo canceller channel. -

-
<action application="KEchoCanceller" data="action[,options])"/>
-
-

Where: -

-
  • actions: It is on to enable the echo canceller, and off to disable; -
-

Example usage of this application: -

-
<action application="KEchoCanceller" data="off"/>
-
-


-

-

Application "KAutoGainControl"

-

This application has the function to enable or disable the automatic gain control in the channel. -

-
<action application="KAutoGainControl" data="action[,options])"/>
-
-

Where: -

-
  • actions: It is on to enable the automatic gain control, and off to disable; -
-

Example usage of this application: -

-
  <action application="KAutoGainControl" data="on"/>
-
-


-

-

Application "KDTMFSuppression"

-

This application has the function to enable or disable the suppression of DTMF channel. The syntax of the application is as follows: -

-
<action applicatin="KDTMFSuppression" value="action[,options])"/>
-
-

Where: -

-
  • actions: It ison to enable DTMF suppression, and off to disable; -
-

It is important to note that when disabled suppression of DTMF, DTMF tones are passed inband and will not be reported to FreeSWITCH. Thus FreeSWITCH does not recognize the DTMF tones, which may result in malfunction of applications such as IVR. -

Example usage of this application: -

-
<action applicatin="KDTMFSuppression" value="off"/>
-
-


-

-

Application "KSetVolume"

-

This application has the function to adjust the volume of incoming and outgoing channels Khomp, and its syntax as follows: -

-
<action application="KSetVolume" data="<volume>"/>
-<action application="KSetVolume" data="<output-volume>|<input-volume>"/>
-
-

Where the fields have the following meanings: -

-
  • volume: Sets the volume of input and output (-10 to +10); -
  • output-volume: Sets the output volume (-10 to +10, "none" for no change); -
  • input-volume: Sets the input level (-10 to +10, "none" for no change). -
-


-

-

Application "KAdjustForFax"

-

This application has the function of setting a channel for receiving Khomp signal FAX/modem, optimizing the communication channel for data traffic. Syntax: -

-
<action application="KAdjustForFax" data=""/>
-
-

This application does not receive parameters. Example of use: -

-
<action application="KAdjustForFax" data=""/>
-
-


-

-

Application "KSendFax"

-

This application has the function to send faxes using digital channels or FXO connections Khomp in pre-established, and its syntax as follows: -

-
<action application="KSendFax" data="<file>[:<file2>[:...]][|<faxid>]"/>
-
-

This application requires a license purchased separately to be used in digital (non-FXO) channels. Fields have the following meanings: -

-
  • file: Files to be sent to the fax should be encapsulated in TIFF format and have a resolution of 98, 196 or 392 dpi; -
  • faxid: the fax number. If not specified, the value is obtained by the id of the link, and if this also is not valid, the fax number will be set as default in K3L. -
-

Example usage of this application: -

-
<action application="KSendFax" data="/tmp/fax.tif:/home/root/fax2.tif,1234"/>
-
-


-

-

Application "KReceiveFax"

-

This application has the function of receiving digital channels or fax using the FXO Khomp, and its syntax as follows: -

-
<action application="KReceiveFax" data="<file>[|<faxid>]/>
-
-

This application requires a license purchased separately to be used in digital (non-FXO) channels. Fields have the following meanings: -

-
  • file: Name that file will be assigned to incoming fax. -
  • faxid: the fax number. If not specified, the value is obtained by the id of the link, and if this also is not valid, the fax number will be set as default in K3L. -
-

Example usage of this application: -

-
<action application="answer" />
-<action application="KReceiveFax" data="/tmp/fax.tif"/>
-
-


-

-

Channel "Khomp_SMS"

-

This communication channel is used to receive SMS and create incoming links in FreeSWITCH for each message received. This channel does not have any treatment or audio processing, and is called with five variables set: -

-
  • KSmsFrom, containing the number of source who sent the message; -
  • KSmsDate, which sets the date/time of receipt of the message; -
  • KSmsSize, representing the message size (in bytes); -
  • KSmsMode, containing the encoding used to transmit the message; -
  • KSmsBody, that is the message itself. -
-

The FreeSWITCH dialplan processing can be used to store this message in a database, run any application, among others. However, the only action accepted by this channel is shutdown (Hangup), so this incoming call should be considered a special dialplan execution without audio streams or channel allocation. -
-

-

Channel "Khomp_PR"

-

This communication channel is used to receive calls on boards passive recording (KPR family and KFXO-HI), creating incoming links on FreeSWITCH for each incoming call. This channel allows only receiving audio captured the linkby not allowing both the transmission of audio signalings as the control. -

The FreeSWITCH dialplan processing can be used to record data on this link in a database, perform some special application and/or some recording application (such as record), among others. However, the only action accepted by this channel is shutdown (Hangup), so this should not be considered a common call. -
-

-

Codes and meanings

-

This chapter presents the codes present in the channel Khomp and their meanings, used in both events as in the AMI console commands: -
-

-

Channel state

-

Reflect the state of the channel on the board. In the case of E1 links, the state may have one or more of the following: -

-
  • Free: the channel is free; -
  • Busy: the channel is not free (or occupied, or failure); -
  • Outgoing: the channel has an output connection; -
  • Incoming: the channel has an input connection; -
  • Locked: the channel is blocked; -
  • Outgoing Lock: The channel is blocked for outgoing calls; -
  • Local Fail: The channel has a fault (at this point); -
  • Incoming Lock: the channel is blocked for incoming calls; -
  • Remote Lock: there is a remote lock (at the other end) in this channel. -
-

In the case of a FXS channel, the state is defined by one of these values: -

-
  • On Hook: the phone connected to this channel is on-hook or disconnected; -
  • Off Hook: the phone connected to this channel is off the hook; -
  • Ringing: the channel is being called; -
  • Failure: the channel is in failure due to communication problems between the central and the plate. -
-

In the case of a GSM channel, the state is defined by one of the following values: -

-
  • Idle: the channel is free and available for calls; -
  • Call In Progress: the channel is busy on a call; -
  • SMS In Progress: the channel is busy sending / receiving SMS messages; -
  • Modem Error: an error occurred communicating with the modem channel; -
  • SIM Card Error: The SIM card is not present or is not inserted / detected correctly; -
  • Network Error: an error occurred while communicating with the network; -
  • Not Ready: The modem is initializing the channel. -
-

And in the case of an FXO channel, the states are as follows: -

-
  • Disabled: the channel is disabled; -
  • Enabled: the channel is enabled. -
-


-

-

Call state

-

Defines the logical state for each channel, which can be: -

-
  • Free: the channel is free; -
  • Incoming: the channel is receiving a call; -
  • Outgoing: the channel is making a call; -
  • Failure: the channel is in fault. -
-


-

-

FreeSWITCH call states

-

Directly reflects the call state controlled by FreeSWITCH, which can be: -


-

-
  • new: Channel is newly created; -
  • init: Channel has been initialized; -
  • routing: Channel is looking for an extension to execute; -
  • execute: Channel is executing its dialplan; -
  • ex_media: Channel is exchanging media with another channel; -
  • cs_media: Channel is consuming all media; -
  • hangup: Channel is flagged for hangup and ready to end. -
-


-

-

GSM Codes

-

The following numeric codes are reported: -

-

SMS codes (SMS causes)

-
1	Unassigned number
-8	Operator determined barring
-10	Call barred
-21	SMS transfer rejected
-27	Destination out of service
-28	Unidentified subscriber
-29	Facility rejected
-30	Unknown subscriber
-38	Network out of order
-41	Temporary failure
-42	Congestion
-47	Resources unavailable
-50	Facility not subscribed
-69	Facility not implemented
-81	Invalid SMS transfer reference value
-95	Invalid message
-96	Invalid mandatory information
-97	Message type non existent
-98	Message not compatible with SMS protection state
-99	Information element non existent
-111	Protocol error
-127	Interworking
-128	Telematic interworking not supported
-129	SMS type zero not supported
-130	Cannot replace SMS
-143	Unspecified TPPID error
-144	Alphabet not supported
-145	Message class not supported
-159	Unspecified TPDCS error
-160	Command cannot be actioned
-161	Command unsupported
-175	Unspecified TP command error
-176	TPDU not supported
-192	SC busy
-193	No SC subscription
-194	SC system failure
-195	Invalid SME address
-196	Destination SME barred
-197	SM rejected duplicate SM
-198	TPVPF not supported
-199	TPVP not supported
-208	SIM SMS storage full
-209	No SMS storage capability in SIM
-210	Error in SMS
-211	Memory capatity exceeded
-213	SIM data download error
-255	Unspecified error
-300	Phone failure
-301	SMS service reserved
-302	Operation not allowed
-303	Operation not supported
-304	Invalid PDU mode parameter
-305	Invalid text mode parameter
-310	SIM not inserted
-311	SIM PIN necessary
-312	Phone SIM PIN necessary
-313	SIM failure
-314	SIM busy
-315	SIM wrong
-320	Memory failure
-321	Invalid memory index
-322	Memory full
-330	SMSC address unknown
-331	No network service
-332	Network timeout
-500	Unknown error
-512	Network busy
-513	Invalid destination address
-514	Invalid message body length
-515	Phone is not in service
-516	Invalid preferred memory storage
-517	User terminated
-
-

Call codes (call causes)

-
1	Unallocated number
-3	No route to destination
-6	Channel unacceptable
-8	Operator determined barring
-16	Normal call clear
-17	User busy
-18	No user responding
-19	No answer from user
-21	Call rejected
-22	Number changed
-26	Non Selected user clear
-27	Destination out of order
-28	Invalid number format
-29	Facility rejected
-30	Response status enquiry
-31	Normal, unspecified
-34	No circuit channel available
-38	Network out of order
-41	Temporary failure
-42	Switch congestion
-43	Access information discarded
-44	Requested channel unavailable
-47	Resource unavailable
-49	QoS unavailable
-50	Request facility not subscribed
-55	Call barred with UG
-57	Bearer capability not authorized
-58	Bearer capability not available
-63	Service not available
-65	Bearer capability not implemented
-69	Request facility not implemented
-70	Only restricted bearer capability available
-79	Service not implemented
-81	Invalid call reference value
-82	User not member of UG
-88	Incompatible destination
-91	Invalid transit network selected
-95	Invalid message
-96	Missing mandatory information element
-97	Message type not implemented
-98	Message incompatible with state
-99	Information element not implemented
-100	Invalid information element
-101	Message incompatible with state (2)
-102	Recovery on timer expiry
-111	Protocol error
-127	Interworking
-
-

General codes (mobile causes)

-
0	Phone failure
-1	No connection to phone
-2	Phone adaptor link reserved
-3	Operation not allowed
-4	Operation not supported
-5	Phone SIM PIN required
-6	Phone FSIM PIN required
-7	Phone FSIM PUK required
-10	SIM not inserted
-11	SIM PIN required
-12	SIM PUK required
-13	SIM failure
-14	SIM busy
-15	SIM wrong
-16	Incorrect password
-17	SIM PIN2 required
-18	SIM PUK2 required
-20	Memory full
-21	Invalid index
-22	Not found
-23	Memory failure
-24	Text string too long
-25	Invalid character in text string
-26	Dial string too long
-27	Invalid character in dial string
-30	No network service
-31	Network timeout
-32	Network not allowed
-33	Command aborted
-34	Number parameter instead of text parameter
-35	Text parameter instead of number parameter
-36	Numeric parameter out of bounds
-37	Text string too short
-40	Network PIN required
-41	Network PUK required
-42	Network subset PIN required
-43	Network subset PUK required
-44	Network service provider PIN required
-45	Network service provider PUK required
-46	Corporate PIN required
-47	Corporate PUK required
-60	SIM Service option not supported
-100	Unknown
-103	Illegal MS #3
-106	Illegal MS #6
-107	GPRS service not allowed #7
-111	PLMN not allowed #11
-112	Location area not allowed #12
-113	Roaming not allowed #13
-132	Service option not supported #32
-133	Registration service option not subscribed #33
-134	Service option temporary out of order #34
-147	Long context activation
-148	Unspecified GPRS error
-149	PDP authentication failure
-150	Invalid mobile class
-151	GPRS disconnection TMR active
-256	Too many active calls
-257	Call rejected
-258	Unanswered call pending
-259	Unknown calling error
-260	No phone number recognized
-261	Call state not idle
-262	Call in progress
-263	Dial state error
-264	Unlock code required
-265	Network busy
-266	Invalid phone number
-267	Number entry already started
-268	Cancelled by user
-269	Number entry could not be started
-280	Data lost
-281	Invalid message body length
-282	Inactive socket
-283	Socket already open
-
-


-

-

Troubleshooting

-

In this section, errors and their most common solutions are presented. -

-

Error during installation of kernel module

-

During installation of the Endpointof Khomp may occur the following messages: - -

-
K3L: WARNING: Unable to find a module for [...]
-
-

or - -

-
install: ******  THE KERNEL MODULE HAS NOT BEEN INSTALLED: *******
-install: 
-install: ** Please, untar the file kpdriver*.tar.gz located in: **
-install: **                 '/usr/src/khomp/'                   **
-install: **             then check the README.txt               **
-install: **  for knowing how to proceed with the installation.  **
-
-

In this case, you must compile the drivers manually to your system. Proceed to the item below for more information. -
-

-

Compiling the drivers and starting the services

-

Just follow to the directory /usr/src/khomp, unpack the file "kpdriver_2.0.0XX.tar.gz", and follow procedures described in the file README_en.txt. -

After performing compilation and installation of the module, just load it into the system, configuring the boards and start the server processes Khomp. -

To load the kernel driver, you must run the following command: - -

-
# /etc/init.d/khompdrv start
-
-

To set up the boards, in turn, must run the command: - -

-
# khompwizard
-
-

This will run a setup wizard that will ask the signaling used in the system, as well as other parameters of use of the boards. -

If necessary configure other additional parameters you can use the following command: - -

-
# k3lconfig
-
-

This configurator, in turn, shows all possible options for card configuration. The parameters that are not configured automatically assume the default values, and are compatible with most systems. More details about this program can be obtained from the section number '2 '. -

-
  • ATTENTION: To start FreeSWITCH®, it is necessary that the Khomp board is configured and all modules are running (as shown above).

    If you want to run the system without the Khomp board, you need to configure FreeSWITCH for it does not load the module Khomp. To do this, open the /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml and comment the line:
    -
-
 
-<!-- <load module="mod_khomp" /> -->
-

-

When the board Khomp is properly configured and loaded modules khomp (explained above), remember to uncomment this line in the file. -

Finally, to load the server process, simply run the following command: - -

-
# kserver start
-
-

After performing these procedures, the Endpoint is already operational, and FreeSWITCH can now be loaded. -
-

-

Setting up special parameters for audio or signaling

-

To set specific parameters of timing and/or signaling, you can use the program "k3lconfig": simply select the card you want, and options of the boards will be presented, divided into sections and subsections for easy access. It is not necessary to effect the configuration of all parameters: default values are assumed, if not configured. -

To adjust the signaling link, simply - after selecting the card - enter the "Options signaling, and then in" Signs of the line. " To choose a particular signaling, just use the direction keys (arrows) to select it, press 'space', and confirm the option by pressing 'Enter' on the "Confirm" button. -

Finally, to save the modified settings, just exit the program: it will display a window with options to save the changes made or not. -

Please not that the following options are required to be unchanged from the defaults: -

-
  • Automatic echo cancellation; -
  • DTMF suppression; -
  • Automatic Gain Control (AGC). -
-

These options are controlled by Endpoint and should be disabled in 'k3lconfig' (the default configuration). -
-

-

Automatic load of services and kernel modules

-

If the loading of kernel module or Khomp services startup is not performed automatically at startup, you can perform this installation manually, creating a link for the scripts /etc/init.d/khompdrv and /etc/init.d/kserver in the system startup directory. -

In the case of Debian-based distributions the script for loading kernel modules would be linked within the directory /etc/rcS.d, while the services loader would be linked within the directories /etc/rc2.d, /etc/rc3.d, /etc/rc4.d, /etc/rc5.d as follows: -

-

-
# ln -s /etc/init.d/khompdrv  /etc/rcS.d/S19khompdrv
-# ln -s /etc/init.d/kserver   /etc/rc2.d/S20kserver
-# ln -s /etc/init.d/kserver   /etc/rc3.d/S20kserver
-# ln -s /etc/init.d/kserver   /etc/rc4.d/S20kserver
-# ln -s /etc/init.d/kserver   /etc/rc5.d/S20kserver
-
-

Please check the rules of your distribution to initialize the services in accordance with what is expected by the start of it. -
-

-

Apndice

-

This section presents useful informations about Endpoint and related components. -

-

Arrangement of installed files

-

The directories created/modified in this facility are: - -

-
/etc/init.d/                -- Startup scripts;
-
-/etc/khomp/                 -- Firmware files and settings;
-
-/usr/local/freeswitch/conf/ -- Settings for FreeSWITCH and Endpoint;
-
-/usr/doc/khomp/             -- Docs for the boards, Channel, and utilities;
-
-/usr/sbin/                  -- Utilities and server processes;
-
-/usr/lib/                   -- Shared libraries;
-
-/usr/local/freeswitch/mod/  -- Endpoint module;
- 
-/var/log/khomp2.1/          -- Log directory for K3L and Endpoint;
-
-

The script /etc/init.d/khompdrv is responsible for loading modules kpci9030.ko and kpex8311.ko in the kernel, which should be carried out automatically at system startup. In case of problems, check the Troubleshooting section. -


-

For more details: http://www.khomp.com.br -


-

\ No newline at end of file diff --git a/src/mod/endpoints/mod_khomp/docs/User_Guide.pdf b/src/mod/endpoints/mod_khomp/docs/User_Guide.pdf deleted file mode 100644 index a0645460e5a05443c2026f07f4307206db8a1ed3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464991 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%0AQ`KcxHBBInoN2Y3hGdY&X#;|ywcIhdFcXEMD< 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 d6Bob3YyqPQTm;gcTc1{rhli!mMkR-95&RHvH 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

rHqf!>p+g{w=y2|cXYWEwaL@Vtvgw0mxbOPf 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%0AMyMkG+;e&X{fstALr6cO^p&k#b(}18D8Es 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

4N9o9YksJcFhkbRmn9Aq0}7&QlxD#;o2PZ6 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

34vj4w8=|;Ho>j5 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

K}<)OltaC`xbyGLK!w+Bth+Qn5edc5f} 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 z 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 - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_khomp/examples/transfer.xml b/src/mod/endpoints/mod_khomp/examples/transfer.xml deleted file mode 100644 index 5c66633574..0000000000 --- a/src/mod/endpoints/mod_khomp/examples/transfer.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_khomp/include/applications.h b/src/mod/endpoints/mod_khomp/include/applications.h deleted file mode 100644 index 14ba1d3323..0000000000 --- a/src/mod/endpoints/mod_khomp/include/applications.h +++ /dev/null @@ -1,1037 +0,0 @@ -/******************************************************************************* - - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2010 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file - under the MPL, indicate your decision by deleting the provisions above and - replace them with the notice and other provisions required by the LGPL - License. If you do not delete the provisions above, a recipient may use your - version of this file under either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*******************************************************************************/ - -#ifndef _APPLICATIONS_H_ -#define _APPLICATIONS_H_ - -#include "lock.h" -#include "khomp_pvt.h" - -struct Application -{ - Application(Board::KhompPvt * pvt) : _pvt(pvt) {} - ~Application() {} - - Statistics * statistics() { return _app_statistics; } - - template - T* statistics() { return static_cast(_app_statistics); } - - Board::KhompPvt *_pvt; - Statistics *_app_statistics; -}; - -/*************************** FAX **********************************************/ -struct Fax -{ - Fax(Board::KhompPvt * pvt) : _pvt(pvt) {} - - /* - bool clear(Board::KhompPvt * pvt) - { - _pvt = pvt; - return true; - } - */ - - bool adjustForFax(); - - bool sendFax(switch_core_session_t * session, const char *data); - bool receiveFax(switch_core_session_t * session, const char *data); - - bool onFaxChannelRelease(K3L_EVENT *e); - - bool startFaxTX(const char * orig_addr = NULL); - bool stopFaxTX(); - bool startFaxRX(const char * filename, const char * orig_addr = NULL); - bool stopFaxRX(); - bool addFaxFile(const char * filename, bool last = true); - - - Board::KhompPvt *_pvt; - - /* used by app FAX */ - SavedCondition _fax_cond; - KFaxResult _fax_result; - -}; - -/*************************** TRANSFER *****************************************/ -template -struct Transfer -{ - Transfer(Board::KhompPvt * pvt) : _pvt(pvt), _is_ok(false) {} - - bool clear() - { - if(!_is_ok) - { - _call = dynamic_cast(_pvt->call()); - - _is_ok = true; - - if(!_call) - { - DBG(FUNC, D("Error in cast")); - _is_ok = false; - } - } - - _call->_flags.clear(Kflags::XFER_DIALING); - - return true; - } - - bool userTransfer(switch_core_session_t * session, const char *data) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "c")); - - std::string dest(""); - std::string opts(""); - - try - { - Strings::vector_type params; - - Strings::tokenize((const char *)data, params, "|,", 2); - - dest = params[0]; - - if (params.size() > 1) - { - // other options go here... - } - - ScopedPvtLock lock(_pvt); - - int timeout = 5; - - if(!_pvt->call()->_flags.check(Kflags::REALLY_CONNECTED) && !_pvt->loopWhileFlagTimed(Kflags::REALLY_CONNECTED, timeout, false)) - return false; - - DBG(FUNC, PVT_FMT(_pvt->target(), "flashing channel!")); - - _pvt->command(KHOMP_LOG, CM_FLASH); - - lock.unlock(); - - timeout = 15; // 15 * 200000 = 3s - - do - { - usleep(200000); - timeout--; - - ScopedPvtLock lock2(_pvt); - - if(!_pvt->call()->_flags.check(Kflags::IS_INCOMING) && !_pvt->call()->_flags.check(Kflags::IS_OUTGOING)) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "unable to do a user transfer, channel disconnected")); - return false; - } - - } - while(timeout); - - ScopedPvtLock lock3(_pvt); - - _pvt->command(KHOMP_LOG, CM_DIAL_DTMF, dest.c_str()); - - _pvt->call()->_flags.set(Kflags::WAIT_SEND_DTMF); - - lock3.unlock(); - - timeout = 300; // 300 * 200000 = 60s - - do - { - usleep(200000); - timeout--; - - ScopedPvtLock lock4(_pvt); - - if(!_pvt->call()->_flags.check(Kflags::WAIT_SEND_DTMF)) - break; - } - while(timeout); - - } - catch (ScopedLockFailed & err) - { - LOG(ERROR, PVT_FMT(_pvt->target(),"r (unable to lock %s!)") % err._msg.c_str() ); - return false; - } - - - DBG(FUNC, PVT_FMT(_pvt->target(), "r")); - return true; - } - - /* User transfer functions */ - bool doUserXferUnlocked() - { - DBG(FUNC, PVT_FMT(_pvt->target(), "c (flashing channel!)")); - - bool ret = false; - - ret = _pvt->command(KHOMP_LOG, CM_FLASH); - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (%s)") % (ret ? "true" : "false")); - return ret; - } - - bool checkUserXferUnlocked(std::string digit) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "c (CM_FLASH)")); - - - if (_call->_user_xfer_digits.empty()) - { - _call->_digits_buffer += digit; - DBG(FUNC, PVT_FMT(_pvt->target(), "r (disabled)")); - return false; - } - - _call->_user_xfer_buffer += digit; - - /* temporary buffer */ - std::string tmp = _call->_user_xfer_buffer; - - unsigned int amount = tmp.size(); - - try - { - - if (amount == _call->_user_xfer_digits.size()) - { - if (tmp == _call->_user_xfer_digits) - { - bool ret = doUserXferUnlocked(); - - _call->_user_xfer_buffer.clear(); - _call->_digits_buffer.clear(); - - Board::board(_pvt->target().device)->_timers.del(_idx_xfer_dial); - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (ret=%s, done xfer)") % (ret ? "true" : "false")); - return ret; - } - - _call->_digits_buffer += tmp[0]; - _call->_user_xfer_buffer.erase(0, 1); - DBG(FUNC, PVT_FMT(_pvt->target(), "r (false, no xfer)")); - return false; - } - - if (tmp == _call->_user_xfer_digits.substr(0,amount)) - { - if (!(_call->_flags.check(Kflags::XFER_DIALING))) - { - _call->_flags.set(Kflags::XFER_DIALING); - _idx_xfer_dial = Board::board(_pvt->target().device)->_timers.add(Opt::_options._transferdigittimeout(), &userXferTimer, _pvt, TM_VAL_CALL); - } - else - { - Board::board(_pvt->target().device)->_timers.restart(_idx_xfer_dial); - } - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (true, buffering)")); - return true; - } - - } - catch (K3LAPITraits::invalid_device & err) - { - LOG(ERROR, PVT_FMT(_pvt->target(), "Unable to get device: %d!") % err.device); - } - - _call->_digits_buffer += tmp[0]; - _call->_user_xfer_buffer.erase(0, 1); - DBG(FUNC, PVT_FMT(_pvt->target(), "r (false, buffering)")); - - return false; - - } - - static void userXferTimer(Board::KhompPvt * pvt) - { - DBG(FUNC, PVT_FMT(pvt->target(), "c")); - - T * call = static_cast(pvt->call()); - - try - { - ScopedPvtLock lock(pvt); - - if (!call->_user_xfer_buffer.empty()) - { - pvt->command(KHOMP_LOG, CM_DIAL_DTMF, call->_user_xfer_buffer.c_str()); - - /* clear the buffer that has been send */ - call->_user_xfer_buffer.clear(); - } - - call->_flags.clear(Kflags::XFER_DIALING); - } - catch (ScopedLockFailed & err) - { - LOG(ERROR, PVT_FMT(pvt->target(),"r (unable to lock %s!)") % err._msg.c_str() ); - return; - } - - DBG(FUNC, PVT_FMT(pvt->target(), "r")); - } - - bool _is_ok; - T * _call; - Board::KhompPvt * _pvt; - Board::ChanTimer::Index _idx_xfer_dial; -}; - -template -struct Transfer -{ - Transfer(Board::KhompPvt * pvt) : _pvt(pvt), _is_ok(false) {} - - bool clear() - { - if(!_is_ok) - { - _call = dynamic_cast(_pvt->call()); - - _is_ok = true; - - if(!_call) - { - DBG(FUNC, D("Error in cast")); - _is_ok = false; - } - } - - _call->_flags.clear(Kflags::XFER_DIALING); - _call->_flags.clear(Kflags::XFER_QSIG_DIALING); - - return true; - } - - bool userTransfer(switch_core_session_t * session, const char *data) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "c")); - - std::string dest(""); - - bool opt_nowait = false; - - try - { - Strings::vector_type params; - - Strings::tokenize((const char *)data, params, "|,", 2); - - dest = params[0]; - - if (params.size() > 1) - { - opt_nowait = (params[1].find('n') != std::string::npos); - - // other options go here... - } - - ScopedPvtLock lock(_pvt); - - int timeout = 5; - - if(!_pvt->call()->_flags.check(Kflags::REALLY_CONNECTED) && !_pvt->loopWhileFlagTimed(Kflags::REALLY_CONNECTED, timeout, false)) - return false; - - DBG(FUNC, PVT_FMT(_pvt->target(), "ss_transfer on channel!")); - - _pvt->command(KHOMP_LOG, CM_SS_TRANSFER, - STG(FMT("transferred_to=\"%s\" await_connect=\"%d\"") - % dest % (opt_nowait ? 0 : 1)).c_str()); - - } - catch (ScopedLockFailed & err) - { - LOG(ERROR, PVT_FMT(_pvt->target(),"r (unable to lock %s!)") % err._msg.c_str() ); - return false; - } - - - DBG(FUNC, PVT_FMT(_pvt->target(), "r")); - return true; - } - - /* User transfer functions */ - bool doUserXferUnlocked(void) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "c")); - - bool ret = false; - - if (_call->_flags.check(Kflags::XFER_QSIG_DIALING)) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "ss_transfer on channel!")); - - _call->_flags.clear(Kflags::XFER_DIALING); - _call->_flags.clear(Kflags::XFER_QSIG_DIALING); - - ret = _pvt->command(KHOMP_LOG, CM_SS_TRANSFER, - STG(FMT("transferred_to=\"%s\" await_connect=\"1\"") % _call->_qsig_number).c_str()); - } - else - { - DBG(FUNC, PVT_FMT(_pvt->target(), "starting to store digits for ss_transfer...")); - _call->_flags.set(Kflags::XFER_QSIG_DIALING); - - _xfer_thread = threadCreate(Transfer::userXferPlayback,(void*) _pvt); - _xfer_thread->start(); - - ret = true; - } - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (%s)") % (ret ? "true" : "false")); - return ret; - - } - - bool checkUserXferUnlocked(std::string digit) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "c (CM_SS_TRANSFER)")); - - - if (_call->_user_xfer_digits.empty()) - { - _call->_digits_buffer += digit; - DBG(FUNC, PVT_FMT(_pvt->target(), "r (disabled)")); - return false; - } - - _call->_user_xfer_buffer += digit; - - DBG(FUNC, PVT_FMT(_pvt->target(), "c digits=[%s] buffer=[%s]") % _call->_user_xfer_digits % _call->_user_xfer_buffer ); - - /* temporary buffer */ - std::string tmp = _call->_user_xfer_buffer; - - unsigned int amount = tmp.size(); - - try - { - - if (amount == _call->_user_xfer_digits.size()) - { - if (tmp == _call->_user_xfer_digits) - { - bool ret = doUserXferUnlocked(); - - _call->_user_xfer_buffer.clear(); - _call->_qsig_number.clear(); - _call->_digits_buffer.clear(); - - if(!_call->_flags.check(Kflags::XFER_QSIG_DIALING)) - { - Board::board(_pvt->target().device)->_timers.del(_idx_xfer_dial); - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (ret=%s, done xfer)") % (ret ? "true" : "false")); - } - else - { - Board::board(_pvt->target().device)->_timers.restart(_idx_xfer_dial); - DBG(FUNC, PVT_FMT(_pvt->target(), "r (waiting digits for transfer)")); - } - return ret; - } - - if (_call->_flags.check(Kflags::XFER_QSIG_DIALING)) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "putting digits ('%s') on transfer-to number!") % tmp); - - _call->_qsig_number += tmp[0]; - _call->_user_xfer_buffer.erase(0, 1); - Board::board(_pvt->target().device)->_timers.restart(_idx_xfer_dial); - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (true, qsig transfer)")); - return true; - } - - _call->_digits_buffer += tmp[0]; - _call->_user_xfer_buffer.erase(0, 1); - DBG(FUNC, PVT_FMT(_pvt->target(), "r (false, no qsig)")); - return false; - } - - if (tmp == _call->_user_xfer_digits.substr(0,amount)) - { - if (!(_call->_flags.check(Kflags::XFER_DIALING) || _call->_flags.check(Kflags::XFER_QSIG_DIALING))) - { - _call->_flags.set(Kflags::XFER_DIALING); - _idx_xfer_dial = Board::board(_pvt->target().device)->_timers.add(Opt::_options._transferdigittimeout(), &userXferTimer, _pvt, TM_VAL_CALL); - } - else - { - Board::board(_pvt->target().device)->_timers.restart(_idx_xfer_dial); - } - - DBG(FUNC, PVT_FMT(_pvt->target(), "r (true, buffering)")); - return true; - } - - if (_call->_flags.check(Kflags::XFER_QSIG_DIALING)) - { - DBG(FUNC, PVT_FMT(_pvt->target(), "putting digits ('%s') on transfer-to number!") % tmp); - - _call->_qsig_number += tmp[0]; - _call->_user_xfer_buffer.erase(0, 1); - - Board::board(_pvt->target().device)->_timers.restart(_idx_xfer_dial); - DBG(FUNC, PVT_FMT(_pvt->target(), "r (true, qsig buffering)")); - return true; - } - - } - catch (K3LAPITraits::invalid_device & err) - { - LOG(ERROR, PVT_FMT(_pvt->target(), "Unable to get device: %d!") % err.device); - } - - _call->_digits_buffer += tmp[0]; - _call->_user_xfer_buffer.erase(0, 1); - DBG(FUNC, PVT_FMT(_pvt->target(), "r (false, buffering)")); - - return false; - } - - static void userXferTimer(Board::KhompPvt * pvt) - { - DBG(FUNC, PVT_FMT(pvt->target(), "c")); - - T * call = static_cast(pvt->call()); - - try - { - ScopedPvtLock lock(pvt); - - if (!call->_user_xfer_buffer.empty()) - { - pvt->command(KHOMP_LOG, CM_DIAL_DTMF, call->_user_xfer_buffer.c_str()); - - /* clear the buffer that has been send */ - call->_user_xfer_buffer.clear(); - } - - if (!call->_qsig_number.empty()) - { - pvt->command(KHOMP_LOG, CM_SS_TRANSFER, - STG(FMT("transferred_to=\"%s\" await_connect=\"1\"") % call->_qsig_number).c_str()); - - /* clear the buffer that has been send */ - call->_qsig_number.clear(); - } - - call->_flags.clear(Kflags::XFER_DIALING); - call->_flags.clear(Kflags::XFER_QSIG_DIALING); - } - catch (ScopedLockFailed & err) - { - LOG(ERROR, PVT_FMT(pvt->target(),"r (unable to lock %s!)") % err._msg.c_str() ); - return; - } - - DBG(FUNC, PVT_FMT(pvt->target(), "r")); - } - - static switch_status_t dtmfCallback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) - { - char sbuf[3]; - - if(!session) - { - DBG(FUNC,D("session is NULL")) - return SWITCH_STATUS_FALSE; - } - - switch_channel_t * chan = switch_core_session_get_channel(session); - - if(!chan) - { - DBG(FUNC,D("channel is NULL")) - return SWITCH_STATUS_FALSE; - } - - switch_core_session_t *peer_session = switch_core_session_locate(switch_channel_get_partner_uuid(chan)); - - if(!peer_session) - { - DBG(FUNC,D("session is NULL")) - return SWITCH_STATUS_FALSE; - } - - switch (itype) - { - case SWITCH_INPUT_TYPE_DTMF: - { - switch_dtmf_t *dtmf = (switch_dtmf_t *) input; - - Board::KhompPvt * tech_pvt = static_cast< Board::KhompPvt* >(switch_core_session_get_private(peer_session)); - if(!tech_pvt) - { - DBG(FUNC,D("Init: pvt is NULL")) - switch_core_session_rwunlock(peer_session); - return SWITCH_STATUS_FALSE; - } - - char s[] = { dtmf->digit, '\0' }; - tech_pvt->sendDtmf(s); - - break; - } - default: - break; - } - - switch_core_session_rwunlock(peer_session); - return SWITCH_STATUS_SUCCESS; - } - - - static int userXferPlayback(void * pvt_ptr) - { - /* get pointer... */ - Board::KhompPvt * pvt = static_cast < Board::KhompPvt * > (pvt_ptr); - - DBG(FUNC, PVT_FMT(pvt->target(), "c")); - - try - { - ScopedPvtLock lock(pvt); - - /* get the owner */ - switch_channel_t * chan = pvt->getFSChannel(); - - /* get other side of the bridge */ - switch_core_session_t * peer_session = NULL; - switch_core_session_get_partner(pvt->session(),&peer_session); - - if(!peer_session) - { - DBG(FUNC, PVT_FMT(pvt->target(), "r (session is null)")); - return NULL; - } - - switch_channel_t * peer = switch_core_session_get_channel(peer_session); - - /* put the channel in hold */ - //switch_core_session_t *session = switch_core_session_locate(switch_channel_get_partner_uuid(chan)); - //switch_channel_t *chan_core = switch_core_session_get_channel(session); - - const char *stream; - - if (!(stream = switch_channel_get_variable(chan, SWITCH_HOLD_MUSIC_VARIABLE))) - { - stream = "silence"; - } - - DBG(FUNC, PVT_FMT(pvt->target(), "stream=%s") % stream); - - if (stream && strcasecmp(stream, "silence")) - { - /* Freeswitch not get/put frames */ - //switch_channel_set_flag(channel, CF_HOLD); - switch_ivr_broadcast(switch_core_session_get_uuid(pvt->session()),stream, SMF_ECHO_ALEG | SMF_LOOP | SMF_PRIORITY); - } - - switch_core_session_rwunlock(peer_session); - lock.unlock(); - - /* kickstart my heart */ - switch_input_args_t args = {0}; - args.input_callback = dtmfCallback; - - /* wait while xfering... */ - while (true) - { - switch_ivr_collect_digits_callback(peer_session,&args,1000,0); - ScopedPvtLock lock2(pvt); - - if (!pvt->call()->_flags.check(Kflags::XFER_QSIG_DIALING)) - { - break; - } - - lock2.unlock(); - } - - //switch_channel_clear_flag(channel, CF_HOLD); - - switch_channel_stop_broadcast(chan); - switch_channel_wait_for_flag(chan, CF_BROADCAST, SWITCH_FALSE, 5000, NULL); - switch_core_session_rwunlock(pvt->session()); - switch_core_session_rwunlock(peer_session); - - //switch_ivr_unhold_uuid(switch_channel_get_partner_uuid(chan)); - } - catch (ScopedLockFailed & err) - { - LOG(ERROR, PVT_FMT(pvt->target(),"r (unable to lock %s!)") % err._msg.c_str() ); - return NULL; - } - catch (Board::KhompPvt::InvalidSwitchChannel & err) - { - LOG(ERROR, PVT_FMT(pvt->target(), "r (%s)") % err._msg.c_str() ); - return NULL; - } - - DBG(FUNC, PVT_FMT(pvt->target(), "r")); - - return NULL; - } - - bool _is_ok; - T * _call; - Board::KhompPvt * _pvt; - Thread * _xfer_thread; - Board::ChanTimer::Index _idx_xfer_dial; -}; - -/*************************** SMS **********************************************/ -#define ESL_SMS_RECEIVED "khomp::sms_received" -#define ESL_SMS_SENT "khomp::sms_sent" - -struct SMS : public Application -{ - typedef std::list< switch_core_session_t *> OwnersList; - - struct SMSStatistics : public Statistics - { - SMSStatistics(): - _sms_number_incoming(0), - _sms_number_outgoing(0), - _sms_number_confirm(0), - _sms_number_broadcast(0) {}; - - void incrementIncoming() - { - _sms_number_incoming++; - } - - void incrementOutgoing() - { - _sms_number_outgoing++; - } - - void incrementConfirm() - { - _sms_number_confirm++; - } - - void incrementBroadcast() - { - _sms_number_broadcast++; - } - - std::string getDetailed() - { - std::string tmpBuffer; - - tmpBuffer.append(STG(FMT("Number of incoming SMS: \t%d\n") % _sms_number_incoming)); - tmpBuffer.append(STG(FMT("Number of outgoing SMS: \t%d\n") % _sms_number_outgoing)); - tmpBuffer.append(STG(FMT("Number of broadcast SMS: \t%d\n") % _sms_number_broadcast)); - tmpBuffer.append(STG(FMT("Number of confirm SMS: \t%d\n") % _sms_number_confirm)); - - return tmpBuffer; - } - - void clear() - { - _sms_number_incoming = 0; - _sms_number_outgoing = 0; - _sms_number_confirm = 0; - _sms_number_broadcast = 0; - } - - unsigned int _sms_number_incoming; - unsigned int _sms_number_outgoing; - unsigned int _sms_number_confirm; - unsigned int _sms_number_broadcast; - }; - - SMS(Board::KhompPvt * pvt) : - Application(pvt), - _thread(NULL), - _shutdown(false), - _can_receive(false), - _can_send(false), - _result(0), - _mutex(Globals::module_pool), - _cond(Globals::module_pool), - _buffer(8) - { - _cond.reset(); - _app_statistics = new SMSStatistics(); - } - - ~SMS() - { - stop(); - delete _app_statistics; - } - - struct ReceiveData - { - ReceiveData() {}; - - ReceiveData(const ReceiveData & o) - { - _type = o._type; - _from = o._from; - _date = o._date; - _size = o._size; - _coding = o._coding; - _serial = o._serial; - _id = o._id; - _page = o._page; - _pages = o._pages; - _sc_date = o._sc_date; - _status = o._status; - _body = o._body; - }; - - void clear(void) - { - /* reset data stuff */ - _type.clear(); - _from.clear(); - _date.clear(); - _size.clear(); - _coding.clear(); - _serial.clear(); - _id.clear(); - _page.clear(); - _pages.clear(); - _sc_date.clear(); - _status.clear(); - _body.clear(); - }; - - std::string _type; - std::string _from; - std::string _date; - std::string _size; - std::string _coding; - std::string _serial; - std::string _id; - std::string _page; - std::string _pages; - std::string _sc_date; - std::string _status; - std::string _body; - }; - - struct SendData - { - SendData(): _conf(false) {}; - - SendData(const SendData & o) - { - _dest = o._dest; - _body = o._body; - _conf = o._conf; - }; - - void clear(void) - { - /* reset data stuff */ - _dest.clear(); - _body.clear(); - _conf = false; - }; - - std::string _dest; - std::string _body; - bool _conf; - }; - - static struct _SMSEvent : public ESL - { - - _SMSEvent() : ESL("khomp::sms") - { - if(_events) - { - _events->push_back(ESL_SMS_RECEIVED); - _events->push_back(ESL_SMS_SENT); - } - } - - ~_SMSEvent() - { - if(_events) - { - //Remove two from vector - _events->pop_back(); - _events->pop_back(); - } - } - - bool operator()(Board::KhompPvt * pvt, ReceiveData & data) - { - switch_event_t *event = create(ESL_SMS_RECEIVED); - - if(!event) - { - LOG(ERROR, "Cannot create SMS ESL"); - return false; - } - - add(event, pvt->target()); - add(event, "Type", data._type); - add(event, "From", data._from); - add(event, "Date", data._date); - add(event, "Size", data._size); - add(event, "Coding", data._coding); - add(event, "Serial", data._serial); - add(event, "Id", data._id); - add(event, "Page", data._page); - add(event, "Pages", data._pages); - add(event, "Sc_date", data._sc_date); - add(event, "Status", data._status); - add(event, "Body", data._body); - - return fire(&event); - } - - bool operator()(Board::KhompPvt * pvt, SendData & data) - { - switch_event_t *event = create(ESL_SMS_SENT); - - if(!event) - { - LOG(ERROR, "Cannot create SMS ESL"); - return false; - } - - add(event, pvt->target()); - add(event, "Dest", data._dest); - add(event, "Body", data._body); - add(event, "Confirmation?", (data._conf ? "Yes" : "No")); - - - return fire(&event); - } - - - - } SMSEvent; - - struct Request - { - /* "empty" constructor */ - Request(): _finished(NULL), _cause(NULL) {}; - - /* "real" constructor */ - Request(SendData & send_sms, volatile bool * finished, volatile KGsmCallCause * cause) - : _send_sms(send_sms), _finished(finished), _cause(cause) - {}; - - SendData _send_sms; - - volatile bool * _finished; - volatile KGsmCallCause * _cause; - }; - - bool start() - { - _pvt->call()->_flags.clear(Kflags::SMS_DOING_UPLOAD); - - _thread = threadCreate(&smsThread, (void*) this); - _thread->start(); - } - - bool stop() - { - if(!_thread) - { - return false; - } - - _shutdown = true; - _cond.signal(); - _thread->join(); - delete _thread; - _thread = NULL; - - return true; - } - - bool justAlloc(unsigned int count = 0); - bool justStart(); - - bool sendSMS(switch_core_session_t * session, const char *data); - - - bool onNewSMS(K3L_EVENT *e); - bool onSMSInfo(K3L_EVENT *e); - bool onSMSData(K3L_EVENT *e); - bool onSMSSendResult(K3L_EVENT *e); - - Thread *_thread; - bool _shutdown; - bool _can_receive; - bool _can_send; - ReceiveData _got_sms; - SendData _send_sms; - int _result; - SavedCondition _cond; - Globals::Mutex _mutex; - Ringbuffer < SMS::Request > _buffer; - OwnersList _owners; - - static int smsThread(void * sms_ptr); -}; - -/******************************************************************************/ - - -#endif /* _APPLICATIONS_H_ */ - diff --git a/src/mod/endpoints/mod_khomp/include/cli.h b/src/mod/endpoints/mod_khomp/include/cli.h deleted file mode 100644 index 5df472bb66..0000000000 --- a/src/mod/endpoints/mod_khomp/include/cli.h +++ /dev/null @@ -1,1273 +0,0 @@ -/******************************************************************************* - - KHOMP generic endpoint/channel library. - Copyright (C) 2007-2010 Khomp Ind. & Com. - - 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. - - Alternatively, the contents of this file may be used under the terms of the - "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which - case the provisions of "LGPL License" are applicable instead of those above. - - If you wish to allow use of your version of this file only under the terms of - the LGPL License and not to allow others to use your version of this file - under the MPL, indicate your decision by deleting the provisions above and - replace them with the notice and other provisions required by the LGPL - License. If you do not delete the provisions above, a recipient may use your - version of this file under either the MPL or the LGPL License. - - The LGPL header follows below: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this library; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*******************************************************************************/ - -#ifndef _CLI_H_ -#define _CLI_H_ - -#include "globals.h" -#include "logger.h" - -struct Command -{ - /* print in client the usage */ - void printUsage(switch_stream_handle_t *stream) - { - if(stream) - { - printBrief(stream); - K::Logger::Logg2(C_CLI,stream, -"------------------------------ Description --------------------------------"); - K::Logger::Logg2(C_CLI,stream, -"---------------------------------------------------------------------------"); - K::Logger::Logg2(C_CLI,stream,(char*) usage.c_str()); - K::Logger::Logg2(C_CLI,stream, -"---------------------------------------------------------------------------"); - } - else - { - LOG(ERROR,FMT("Invalid stream for commmand: %s") % complete_name); - } - } - - /* print in client the brief */ - void printBrief(switch_stream_handle_t *stream) - { - if(stream) - { - K::Logger::Logg2(C_CLI,stream, -"---------------------------------------------------------------------------"); - K::Logger::Logg2(C_CLI,stream, -"-------------------------------- Brief ------------------------------------"); - K::Logger::Logg2(C_CLI,stream, -"---------------------------------------------------------------------------"); - K::Logger::Logg2(C_CLI,stream,(char*) brief.c_str()); - K::Logger::Logg2(C_CLI,stream, -"---------------------------------------------------------------------------"); - } - else - { - LOG(ERROR,FMT("Invalid stream for commmand: %s") % complete_name); - } - } - - /* pure virtual */ - virtual bool execute(int argc, char *argv[]) = 0; - - std::string complete_name; /* specify the command in console */ - std::vector options; /* extra options for command */ - std::string brief; /* brief of the command, a path */ - std::string usage; /* usage of the command, a help */ -}; - -struct CommandXMLOutput : public Command -{ - void createRoot(const char *name) - { - root = switch_xml_new(name); - } - - void insertXML(switch_xml_t xml) - { - switch_xml_insert(xml,root,0); - } - - void clearRoot() - { - if(root) - { - switch_xml_free(root); - root = NULL; - } - } - - void printXMLOutput(switch_stream_handle_t *stream) - { - K::Logger::Logg2(C_CLI,stream,switch_xml_toxml(root,SWITCH_FALSE)); - } - - CommandXMLOutput() : root(NULL) {}; - - switch_xml_t root; /* for commands that ouput as xml */ -}; - -struct Cli -{ - /* Useful definitions --------------------------------------------------- */ - typedef switch_status_t (APIFunc)(const char*, switch_core_session_t*, switch_stream_handle_t*); - typedef std::vector Commands; - - /* Define the output types form commands */ - typedef enum - { - VERBOSE = 1, - CONCISE, - DETAILED, - XML - } OutputType; - - /* register our commands, but you must create the command function */ - static void registerCommands(APIFunc func,switch_loadable_module_interface_t **mod_int); - - /* delete the commands */ - static void unregisterCommands() - { - switch_console_set_complete("del khomp"); - } - - /* stream is very useful */ - static void setStream(switch_stream_handle_t *s) - { - if(!s) - { - LOG(ERROR,"Invalid stream passed"); - return; - } - - stream = s; - } - - /* gets the khomp usage */ - static void printKhompUsage() - { - if(stream) - { - K::Logger::Logg2(C_CLI,stream,(char*) _khomp_usage.c_str()); - } - else - { - LOG(ERROR,"Invalid stream for command: printKhompUsage"); - } - } - - /* is responsible for parse and execute all commands */ - static bool parseCommands(int argc, char *argv[]); - - /* The Commands --------------------------------------------------------- */ - - /* khomp summary */ - static struct _KhompSummary : public CommandXMLOutput - { - _KhompSummary(bool on_cli_term = true): - CommandXMLOutput(), - _on_cli_term(on_cli_term), - xdevs(NULL) - { - complete_name = "summary"; - - options.push_back("verbose"); - options.push_back("concise"); - options.push_back("xml"); - - brief = "Print system info."; - usage = \ -"Prints detailed info about the system like API version and \n" \ -"boards characteristics like DSPs version.\n\n" \ -"Usage: khomp summary [concise|verbose|xml]"; - - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - bool _on_cli_term; /* indicates if message is sent to fs_cli */ - switch_xml_t xdevs; /* support xml needed to help the interation */ - } KhompSummary; - - /* khomp show calls */ - static struct _KhompShowCalls : public Command - { - _KhompShowCalls() - { - complete_name = "show calls"; - brief = \ -"Show each Khomp channel which have more than one call state associated."; - - usage = \ -"Show each Khomp channel which have more than one call state associated.\n\n" \ -"Usage: khomp show calls [ []]"; - - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - - /* support function for _KhompShowCalls */ - void showCalls(unsigned int device, unsigned int object, std::string &buffer); - } KhompShowCalls; - - /* khomp channels disconnect */ - static struct _KhompChannelsDisconnect : public Command - { - _KhompChannelsDisconnect() - { - complete_name = "channels disconnect"; - brief = "Disconnect a(ll) channel(s)."; - usage = \ -"Disconnects channels in boards, or specific board/channel if parameter \n" \ -"is supplied.\n\n" \ -"Usage: khomp channels disconnect {all | all | }\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"\tchannel -- Number of the channel (start from 0).\n" \ -"e.g. khomp channels disconnect all - Disconnect all channels of all boards.\n"\ -"e.g. khomp channels disconnect 0 5 - Disconnect channel 5 of board 0."; - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - - /* support function for _KhompChannelsDisconnect */ - bool forceDisconnect(unsigned int device, unsigned int channel); - } KhompChannelsDisconnect; - - /* khomp channels unblock */ - static struct _KhompChannelsUnblock : public Command - { - _KhompChannelsUnblock() - { - complete_name = "channels unblock"; - brief = "Unblock a(ll) channel(s)."; - - usage = \ -"The board will request to the PBX or network where it is connected to \n" \ -"unblock the channel if its blocked.\n\n" \ -"Usage: khomp channels unblock {all | all | }\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"\tchannel -- Number of the channel (start from 0).\n" \ -"e.g. khomp channels unblock all - Unblock all channels of all boards.\n" \ -"e.g. khomp channels unblock 0 all - Unblock all channels of board 0.\n" \ -"e.g. khomp channels unblock 1 20 - Unblock channel 20 of board 1."; - - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - } KhompChannelsUnblock; - - /* khomp show statistics */ - static struct _KhompShowStatistics : public CommandXMLOutput - { - _KhompShowStatistics() : CommandXMLOutput(), xdevs(NULL) - { - complete_name = "show statistics"; - - options.push_back("verbose"); - options.push_back("detailed"); - options.push_back("xml"); - - brief = "Shows statistics of the channels."; - - usage = \ -"Shows statistics of the channels, like number of calls incoming \n" \ -"and outgoing, status, status time.\n\n" \ -"Usage: khomp show statistics [{{verbose|xml} [ []]} | \n" \ -" {detailed }]\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"\tchannel -- Number of the channel (start from 0).\n" \ -"e.g. khomp channels statistics - Shows general statistics \n" \ -" of all boards.\n" \ -"e.g. khomp channels statistics 0 - Shows general statistics \n" \ -" of board 0.\n" \ -"e.g. khomp channels statistics verbose - Shows general statistics \n" \ -" of all boards.\n" \ -"e.g. khomp channels statistics verbose 0 - Shows general statistics \n" \ -" of board 0.\n" \ -"e.g. khomp channels statistics detailed 0 2 - Shows detailed statistics \n" \ -" of channel 2 on board 0."; - - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - - /* support functions */ - void cliStatistics(unsigned int device, OutputType output_type); - void cliDetailedStatistics(unsigned int device, unsigned int channel, OutputType output_type); - switch_xml_t xdevs; /* support xml needed to help the interation */ - - } KhompShowStatistics; - - /* khomp show channels */ - static struct _KhompShowChannels: public CommandXMLOutput - { - _KhompShowChannels() : CommandXMLOutput(), xdev(NULL) - { - complete_name = "show channels"; - - options.push_back("verbose"); - options.push_back("concise"); - options.push_back("xml"); - - brief = "Show all channels status."; - usage = \ -"List the status of each channel, both on asterisk point of view and on \n" \ -"khomp API point of view.\n\n" \ -"Usage: \n" \ -"khomp show channels [{ []} | \n" \ - "{{concise|verbose|xml} [ []]}]\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"e.g. khomp show channels - List status of all channels of all boards.\n" \ -"e.g. khomp show channels concise 0 - List status of all channels of \n" \ -" board 0 in a concise way.\n" \ -"e.g. khomp show channels xml 0 - List status of all channels of \n" \ -" board 0 in a xml structure."; - - _commands.push_back(this); - }; - - /* support function for _KhompShowChannels */ - void showChannel(unsigned int device, unsigned int channel, OutputType output_type = Cli::VERBOSE); - void showChannels(unsigned int device, OutputType output_type = Cli::VERBOSE); - - bool execute(int argc, char *argv[]); - switch_xml_t xdev; /* support xml needed to help the interation */ - - } KhompShowChannels; - - /* khomp show links */ - static struct _KhompShowLinks: public CommandXMLOutput - { - _KhompShowLinks() : CommandXMLOutput(), xdev(NULL) - { - complete_name = "show links"; - - options.push_back("verbose"); - options.push_back("concise"); - options.push_back("xml"); - options.push_back("errors"); - options.push_back("errors verbose"); - options.push_back("errors concise"); - options.push_back("errors xml"); - - brief = "Show E1 link(s) status/errors counters in a concise \n" \ - "way or not."; - - usage = \ -"Prints information about the signaling, syncronization and general \n" \ -"status/the error counters of each link on the board. It prints in \n" \ -"a concise way for parsing facilities.\n\n" \ -"Usage: \n" \ -"khomp show links [[errors] [{} | {{concise|verbose|xml} []}]]\n"\ -"e.g. khomp show links - Show all links of all boards.\n" \ -"e.g. khomp show links xml - Show all links of all boards in xml.\n" \ -"e.g. khomp show links errors - Show error counters of all links of \n" \ -" all boards.\n" \ -"e.g. khomp show links errors 0 - Show error counters of all links of \n" \ -" board 0."; - - _commands.push_back(this); - }; - - /* support function for _KhompShowLinks */ - void showLinks(unsigned int device, OutputType output_type = Cli::VERBOSE); - void showErrors(unsigned int device, OutputType output_type = Cli::VERBOSE); - std::string getLinkStatus(int dev, int obj, Verbose::Presentation fmt); - - bool execute(int argc, char *argv[]); - switch_xml_t xdev; /* support xml needed to help the interation */ - } KhompShowLinks; - - /* khomp clear links */ - static struct _KhompClearLinks: public Command - { - _KhompClearLinks() - { - complete_name = "clear links"; - - brief = "Clear the error counters of the links."; - - usage = \ -"Clear the error counters of the links.\n\n" \ -"Usage: khomp clear links [ []]\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"\tlink -- Number of the link (start from 0).\n" \ -"e.g. khomp clear links 0 -- Clear error counters of all links of board 0."; - - _commands.push_back(this); - }; - - /* support function for _KhompClearLinks */ - void clearLink(unsigned int device, unsigned int link); - - bool execute(int argc, char *argv[]); - } KhompClearLinks; - - /* khomp clear statistics */ - static struct _KhompClearStatistics: public Command - { - _KhompClearStatistics() - { - complete_name = "clear statistics"; - - brief = "Clear statistics of the channels."; - - usage = \ -"Clear statistics of the channels, like number of calls incoming \n" \ -"and outgoing, status, status time.\n\n" \ -"Usage: khomp clear statistics [ []]\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"\tchannel -- Number of the channel (start from 0).\n" \ -"e.g. khomp clear statistics 0 -- Clear statistics of board 0."; - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - } KhompClearStatistics; - - - /* khomp reset links */ - static struct _KhompResetLinks: public Command - { - _KhompResetLinks() - { - complete_name = "reset links"; - - brief = "Reset the specified link."; - - usage = \ -"Reset the specified link.\n\n" \ -"Usage: khomp reset links [ []]\n" \ -"\tboard -- Number of the board (start from 0).\n" \ -"\tlink -- Number of the link (start from 0).\n" \ -"e.g. khomp reset links 0 1 -- Reset link 1 of board 0."; - - _commands.push_back(this); - }; - - /* support function for _KhompResetLinks */ - void resetLink(unsigned int device, unsigned int link); - - bool execute(int argc, char *argv[]); - } KhompResetLinks; - - /* khomp sms */ - static struct _KhompSMS : public Command - { - _KhompSMS() - { - complete_name = "sms"; - brief = "Send an SMS message using a Khomp KGSM board."; - - usage = \ -"Send an SMS message using a Khomp KGSM board.\n\n" \ -"Usage: khomp sms \n" \ -"\tdevice -- Device to use (same string used in Dial for \n" \ -"\t channel allocation).\n" \ -"\tdestination -- Phone number of the destination.\n" \ -"\tmessage -- Message to send.\n" \ -"e.g. khomp sms b0 99887766 Oi, tudo bem?"; - - _commands.push_back(this); - }; - - bool execute(int argc, char *argv[]); - } KhompSMS; - - /* khomp log console */ - static struct _KhompLogConsole : public Command - { - _KhompLogConsole() - { - complete_name = "log console"; - - options.push_back("errors"); - options.push_back("warnings"); - options.push_back("messages"); - options.push_back("events"); - options.push_back("commands"); - options.push_back("audio"); - options.push_back("modem"); - options.push_back("link"); - options.push_back("cas"); - options.push_back("standard"); - options.push_back("all"); - options.push_back("no"); - options.push_back("just"); - - brief = "Enables/disables showing console messages for the channel."; - usage = \ -"Enables/disables showing channel messages, where can be:\n" \ -"\terrors -- Error messages, when something goes really \n" \ -"\t wrong. Enabled by default.\n" \ -"\twarnings -- Warnings, used when something might not be \n" \ -"\t going as expected. Enabled by default.\n" \ -"\tmessages -- Generic messages, used to indicate some \n" \ -"\t information. Enabled by default.\n" \ -"\tevents -- Show received K3L events as console \n" \ -"\t messages. Disabled by default.\n" \ -"\tcommands -- Show sent K3L commands as console \n" \ -"\t messages. Disabled by default.\n" \ -"\taudio -- Enable messages for K3L audio events. \n" \ -"\t Disabled by default (very verbose!).\n" \ -"\tmodem -- Enable messages for data received from \n" \ -"\t KGSM modems. Disabled by default.\n" \ -"\tlink -- Enable logging of link status changes. \n" \ -"\t Enabled by default.\n" \ -"\tcas -- Enable logging of MFCs and line state \n" \ -"\t changes in KPR board. Disabled by default.\n" \ -"\tstandard -- Special identifier, enable default \n" \ -"\t console messages.\n" \ -"\tall -- Special identifier, enable ALL console \n" \ -"\t messages (should not be used naively).\n\n" \ -"Usage: khomp log console \n" \ -"e.g. khomp log console standard"; - - _commands.push_back(this); - } - - bool execute(int argc, char *argv[]); - } KhompLogConsole; - - /* khomp log disk */ - static struct _KhompLogDisk : public Command - { - _KhompLogDisk() - { - complete_name = "log disk"; - - options.push_back("errors"); - options.push_back("warnings"); - options.push_back("messages"); - options.push_back("events"); - options.push_back("commands"); - options.push_back("audio"); - options.push_back("modem"); - options.push_back("link"); - options.push_back("cas"); - options.push_back("functions"); - options.push_back("threads"); - options.push_back("locks"); - options.push_back("streams"); - options.push_back("standard"); - options.push_back("debugging"); - options.push_back("all"); - options.push_back("no"); - options.push_back("just"); - - brief = "Enables/disables logging to file messages for the channel."; - usage = \ -"Enables/disables the logging of channel messages to disk, where \n" \ -"can be:\n" \ -"\terrors -- Error messages, when something goes really \n" \ -"\t wrong. Enabled by default.\n" \ -"\twarnings -- Warnings, used when something might not be \n" \ -"\t going as expected. Enabled by default.\n" \ -"\tmessages -- Generic messages, used to indicate some \n" \ -"\t information. Enabled by default.\n" \ -"\tevents -- Record received K3L events as log messages. \n" \ -"\t Disabled by default.\n" \ -"\tcommands -- Record sent K3L commands as log messages. \n" \ -"\t Disabled by default.\n" \ -"\taudio -- Enable messages for K3L audio events. \n" \ -"\t Disabled by default (very verbose!).\n" \ -"\tmodem -- Enable messages for data received from \n" \ -"\t KGSM modems. Disabled by default.\n" \ -"\tlink -- Enable logging of link status changes. \n" \ -"\t Enabled by default.\n" \ -"\tcas -- Enable logging of MFCs and line state \n" \ -"\t changes in KPR board. Disabled by default.\n" \ -"\tfunctions -- Enable debugging for functions. Disabled \n" \ -"\t by default (should not be used naively!).\n" \ -"\tthreads -- Enable debugging for threads. Disabled by \n" \ -"\t default (should not be used naively!).\n" \ -"\tlocks -- Enable debugging for locks. Disabled by \n" \ -"\t default (should not be used naively!).\n" \ -"\tstreams -- Enable debugging for streams. Disabled by \n" \ -"\t default (should not be used naively!).\n" \ -"\tstandard -- Special identifier, enable default messages.\n" \ -"\tdebugging -- Special identifier, enable debugging messages \n" \ -"\t (should not be used naively).\n" \ -"\tall -- Special identifier, enable ALL disk \n" \ -"\t messages (DO NOT USE THIS!).\n\n" \ -"Usage: khomp log disk \n" \ -"e.g. khomp log disk "; - - _commands.push_back(this); - } - - bool execute(int argc, char *argv[]); - } KhompLogDisk; - - /* khomp log trace k3l */ - static struct _KhompLogTraceK3L : public Command - { - _KhompLogTraceK3L() - { - complete_name = "log trace k3l"; - - options.push_back("on"); - options.push_back("off"); - - brief = "Set K3L tracing (debug) option."; - - usage = \ -"Sets the low-level log for K3L API. Should not be set for long time \n" \ -"periods.\n\n" \ -"Usage: khomp log trace k3l {on|off}\n" \ -"e.g. khomp log trace k3l on"; - - _commands.push_back(this); - } - - bool execute(int argc, char *argv[]); - } KhompLogTraceK3L; - - /* khomp log trace ISDN */ - static struct _KhompLogTraceISDN : public Command - { - _KhompLogTraceISDN() - { - complete_name = "log trace isdn"; - - options.push_back("q931"); - options.push_back("lapd"); - options.push_back("system"); - options.push_back("off"); - - brief = "Set ISDN signaling trace."; - - usage = \ -"Sets the low-level log for ISDN signalling. Should not be set for \n" \ -"long time periods.\n\n" \ -"Usage: khomp log trace isdn [,[,..]]\n" \ -"\twhat -- \"q931\", \"lapd\", \"system\" or \"off\" \n" \ -"\t (comma-separated values).\n" \ -"e.g. khomp log trace isdn q931,system"; - - _commands.push_back(this); - } - - bool execute(int argc, char *argv[]); - } KhompLogTraceISDN; - - /* khomp log trace R2 */ - static struct _KhompLogTraceR2 : public Command - { - _KhompLogTraceR2() - { - complete_name = "log trace r2"; - - options.push_back("on"); - options.push_back("off"); - - brief = "Set R2 signaling trace."; - - usage = \ -"Sets the low-level log monitor for R2 digital signalling. Should not \n" \ -"be set for long time periods.\n\n" \ -"Usage: khomp log trace r2 {on|off}\n" \ -"e.g. khomp log trace r2 on"; - - _commands.push_back(this); - } - - bool execute(int argc, char *argv[]); - } KhompLogTraceR2; - - /* khomp get */ - static struct _KhompGet : public Command - { - _KhompGet() - { - complete_name = "get"; - - options.push_back("dialplan"); - options.push_back("echo-canceller"); - options.push_back("auto-gain-control"); - options.push_back("out-of-band-dtmfs"); - options.push_back("suppression-delay"); - options.push_back("auto-fax-adjustment"); - options.push_back("fax-adjustment-timeout"); - options.push_back("pulse-forwarding"); - options.push_back("r2-strict-behaviour"); - options.push_back("r2-preconnect-wait"); - options.push_back("context-digital"); - options.push_back("context-fxs"); - options.push_back("context-fxo"); - options.push_back("context-gsm-call"); - options.push_back("context-gsm-sms"); - options.push_back("context-pr"); - options.push_back("log-to-console"); - options.push_back("log-to-disk"); - options.push_back("trace"); - options.push_back("output-volume"); - options.push_back("input-volume"); - options.push_back("fxs-global-orig"); - options.push_back("fxs-co-dialtone"); - options.push_back("fxs-bina"); - options.push_back("fxs-sharp-dial"); - options.push_back("disconnect-delay"); - options.push_back("delay-ringback-co"); - options.push_back("delay-ringback-pbx"); - options.push_back("ignore-letter-dtmfs"); - options.push_back("fxo-send-pre-audio"); - options.push_back("fxo-busy-disconnection"); - options.push_back("fxs-digit-timeout"); - options.push_back("drop-collect-call"); - options.push_back("kommuter-activation"); - options.push_back("kommuter-timeout"); - options.push_back("user-transfer-digits"); - options.push_back("flash-to-digits"); - options.push_back("accountcode"); - options.push_back("audio-packet-length"); - - brief = "Get configuration options in the Khomp channel."; - - usage = \ -"Usage: khomp get